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

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

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

生成的代码如下所示

@WebService(targetNamespace = "http://example.com/soap/example", name = "Example")
@XmlSeeAlso({com.example.soap.packe.ObjectFactory.class, ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface Example { ... }

@WebServiceClient(name = "ExampleService",
                  wsdlLocation = "http://example.com/soap/example?wsdl",
                  targetNamespace = "http://example.com/soap/example")
public class ExampleService extends Service {

@WebEndpoint(name = "ExampleServiceProd")
public Example getExampleForProd() {
    return super.getPort(ExampleServiceProd, Example.class);
}

@WebEndpoint(name = "ExampleServiceTest")
public Example getExampleForTest() {
    return super.getPort(ExampleServiceTest, Example.class);
}

我尝试过以下方法:

private final ExampleService exampleService;    
@Bean
@RequestScope
public Example getExample() {
    final EnvConfig envConfig = someService.getEnvConfig();
    if (envConfig.isProd())
        return someService.getExampleForTest();
    return someService.getExampleForProd();
}

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

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

private final Map<EnvConfig, Example> examples = new HashMap<>();
private final ExampleService exampleService;
@Bean
@RequestScope
public Example getExample() {
    final EnvConfig envConfig = someService.getEnvConfig();
    if (!examples.containsKey(accessDataEntity)) {
        if (envConfig.isProd())
            examples.put(envConfig, exampleService.getExampleForProd());
        else
            examples.put(envConfig, exampleService.getExampleForTest());
    }    
    return wallets.get(envConfig);
}

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

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

在名为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.

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

The generated looks like following

@WebService(targetNamespace = &quot;http://example.com/soap/example&quot;, name = &quot;Example&quot;)
@XmlSeeAlso({com.example.soap.packe.ObjectFactory.class, ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface Example { ... }



@WebServiceClient(name = &quot;ExampleService&quot;,
                  wsdlLocation = &quot;http://example.com/soap/example?wsdl&quot;,
                  targetNamespace = &quot;http://example.com/soap/example&quot;)
public class ExampleService extends Service {

@WebEndpoint(name = &quot;ExampleServiceProd&quot;)
public Example getExampleForProd() {
    return super.getPort(ExampleServiceProd, Example.class);
}

@WebEndpoint(name = &quot;ExampleServiceTest&quot;)
public Example getExampleForTest() {
    return super.getPort(ExampleServiceTest, Example.class);
}

What I have tried:

private final ExampleService exampleService;    
@Bean
    @RequestScope
    public Example getExample() {
        final EnvConfig envConfig = someService.getEnvConfig();
        if (envConfig.isProd())
            return someService.getExampleForTest();
        return someService.getExampleForProd();
    }

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

private final Map&lt;EnvConfig, Example&gt; examples = new HashMap&lt;&gt;();
private final ExampleService exampleService;
@Bean
@RequestScope
public Example getExample() {
    final EnvConfig envConfig = someService.getEnvConfig();
    if (!examples.containsKey(accessDataEntity)) {
        if (envConfig.isProd())
            examples.put(envConfig, exampleService.getExampleForProd());
        else
            examples.put(envConfig, exampleService.getExampleForTest());
    }    
    return wallets.get(envConfig);
}

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

Caused by: java.lang.IllegalStateException: The client has been closed.
	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:99)
	at com.sun.proxy.$Proxy246.hashCode(Unknown Source)
	at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
	at java.base/java.util.concurrent.ConcurrentHashMap.containsKey(ConcurrentHashMap.java:964)
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.requiresDestruction(PersistenceAnnotationBeanPostProcessor.java:393)
	at org.springframework.beans.factory.support.DisposableBeanAdapter.filterPostProcessors(DisposableBeanAdapter.java:223)
	at org.springframework.beans.factory.support.DisposableBeanAdapter.&lt;init&gt;(DisposableBeanAdapter.java:136)
	at org.springframework.beans.factory.support.AbstractBeanFactory.registerDisposableBeanIfNecessary(AbstractBeanFactory.java:1878)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:636)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
	... 127 common frames omitted

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:

确定