复用 org.apache.cxf 生成的客户端,而不是总是重新生成。

huangapple 未分类评论51阅读模式
英文:

Reuse org.apache.cxf generated client instead of always regenerate

问题

我正在尝试将自动生成的客户端存储在一个bean中,因为我总是在控制台中看到以下输出,这意味着它总是会发送一个请求到SOAP服务器来生成客户端,这大约需要1 - 1 1/2秒甚至更长时间。

创建来自WSDL的服务 {http://example.com/soap/example}ExampleService:https://test.example.com/soap/example?wsdl

生成的代码如下所示

  1. @WebService(targetNamespace = "http://example.com/soap/example", name = "Example")
  2. @XmlSeeAlso({com.example.soap.packe.ObjectFactory.class, ObjectFactory.class})
  3. @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
  4. public interface Example { ... }
  5. @WebServiceClient(name = "ExampleService",
  6. wsdlLocation = "http://example.com/soap/example?wsdl",
  7. targetNamespace = "http://example.com/soap/example")
  8. public class ExampleService extends Service {
  9. @WebEndpoint(name = "ExampleServiceProd")
  10. public Example getExampleForProd() {
  11. return super.getPort(ExampleServiceProd, Example.class);
  12. }
  13. @WebEndpoint(name = "ExampleServiceTest")
  14. public Example getExampleForTest() {
  15. return super.getPort(ExampleServiceTest, Example.class);
  16. }

我尝试过以下方法:

  1. private final ExampleService exampleService;
  2. @Bean
  3. @RequestScope
  4. public Example getExample() {
  5. final EnvConfig envConfig = someService.getEnvConfig();
  6. if (envConfig.isProd())
  7. return someService.getExampleForTest();
  8. return someService.getExampleForProd();
  9. }

它使用@RequestScope进行注释,因为配置可能在运行时发生变化。调用getExampleForXXX 似乎总是会重新生成客户端(关于上述日志),这需要大约1 - 1 1/2秒。

然后,我尝试了以下方法:

  1. private final Map<EnvConfig, Example> examples = new HashMap<>();
  2. private final ExampleService exampleService;
  3. @Bean
  4. @RequestScope
  5. public Example getExample() {
  6. final EnvConfig envConfig = someService.getEnvConfig();
  7. if (!examples.containsKey(accessDataEntity)) {
  8. if (envConfig.isProd())
  9. examples.put(envConfig, exampleService.getExampleForProd());
  10. else
  11. examples.put(envConfig, exampleService.getExampleForTest());
  12. }
  13. return wallets.get(envConfig);
  14. }

这似乎起初是有效的,但在第二次请求时,从Map获取Example时,我总是遇到以下异常:

  1. Caused by: java.lang.IllegalStateException: The client has been closed.
  2. at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:99)
  3. at com.sun.proxy.$Proxy246.hashCode(Unknown Source)
  4. at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
  5. at java.base/java.util.concurrent.ConcurrentHashMap.containsKey(ConcurrentHashMap.java:964)
  6. ...

在名为scopedTarget.getExample的bean创建过程中出现错误,定义在类路径资源 [com/example/ExampleConfig.class],出现了意外异常;嵌套异常是 java.lang.IllegalStateException: The client has been closed.

有没有一种方法可以仅生成一次客户端并重用它,以避免在每次请求时都生成客户端?

英文:

I am trying to store the automated generated client in a bean because I always see the following output in console which means it will always send a request to the SOAP server to generate the client which takes about 1 - 1 1/2 seconds or even longer.

  1. Creating Service {http://example.com/soap/example}ExampleService from WSDL: https://test.example.com/soap/example?wsdl

The generated looks like following

  1. @WebService(targetNamespace = &quot;http://example.com/soap/example&quot;, name = &quot;Example&quot;)
  2. @XmlSeeAlso({com.example.soap.packe.ObjectFactory.class, ObjectFactory.class})
  3. @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
  4. public interface Example { ... }
  5. @WebServiceClient(name = &quot;ExampleService&quot;,
  6. wsdlLocation = &quot;http://example.com/soap/example?wsdl&quot;,
  7. targetNamespace = &quot;http://example.com/soap/example&quot;)
  8. public class ExampleService extends Service {
  9. @WebEndpoint(name = &quot;ExampleServiceProd&quot;)
  10. public Example getExampleForProd() {
  11. return super.getPort(ExampleServiceProd, Example.class);
  12. }
  13. @WebEndpoint(name = &quot;ExampleServiceTest&quot;)
  14. public Example getExampleForTest() {
  15. return super.getPort(ExampleServiceTest, Example.class);
  16. }

What I have tried:

  1. private final ExampleService exampleService;
  2. @Bean
  3. @RequestScope
  4. public Example getExample() {
  5. final EnvConfig envConfig = someService.getEnvConfig();
  6. if (envConfig.isProd())
  7. return someService.getExampleForTest();
  8. return someService.getExampleForProd();
  9. }

It is annotated with @RequestScope as configuration may change during runtime. Calling getExampleForXXX seems to always regenerate the client (regarding the above posted log) which takes about 1 - 1 1/2 seconds.

Then I've tried the following approach

  1. private final Map&lt;EnvConfig, Example&gt; examples = new HashMap&lt;&gt;();
  2. private final ExampleService exampleService;
  3. @Bean
  4. @RequestScope
  5. public Example getExample() {
  6. final EnvConfig envConfig = someService.getEnvConfig();
  7. if (!examples.containsKey(accessDataEntity)) {
  8. if (envConfig.isProd())
  9. examples.put(envConfig, exampleService.getExampleForProd());
  10. else
  11. examples.put(envConfig, exampleService.getExampleForTest());
  12. }
  13. return wallets.get(envConfig);
  14. }

This seems to work at first but on the second request, when getting Example from the Map, I always face the following exception

  1. Caused by: java.lang.IllegalStateException: The client has been closed.
  2. at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:99)
  3. at com.sun.proxy.$Proxy246.hashCode(Unknown Source)
  4. at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
  5. at java.base/java.util.concurrent.ConcurrentHashMap.containsKey(ConcurrentHashMap.java:964)
  6. at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.requiresDestruction(PersistenceAnnotationBeanPostProcessor.java:393)
  7. at org.springframework.beans.factory.support.DisposableBeanAdapter.filterPostProcessors(DisposableBeanAdapter.java:223)
  8. at org.springframework.beans.factory.support.DisposableBeanAdapter.&lt;init&gt;(DisposableBeanAdapter.java:136)
  9. at org.springframework.beans.factory.support.AbstractBeanFactory.registerDisposableBeanIfNecessary(AbstractBeanFactory.java:1878)
  10. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:636)
  11. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
  12. ... 127 common frames omitted
  13. Error creating bean with name &#39;scopedTarget.getExample&#39; defined in class path resource [com/example/ExampleConfig.class]: Unexpected exception during bean creation; nested exception is java.lang.IllegalStateException: The client has been closed.]

Is there a way to generate the client once and reuse it to avoid generating the client on each request

huangapple
  • 本文由 发表于 2020年6月29日 15:14:00
  • 转载请务必保留本文链接:https://java.coder-hub.com/62632985.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定