use*_*611 30 java java-metro-framework jax-ws webservice-client
由于WS客户端服务和端口的初始化需要很长时间,所以我喜欢在启动时初始化它们并重用相同的端口实例.初始化看起来像这样:
private static RequestContext requestContext = null;
static
{
MyService service = new MyService();
MyPort myPort = service.getMyServicePort();
Map<String, Object> requestContextMap = ((BindingProvider) myPort).getRequestContext();
requestContextMap = ((BindingProvider)myPort).getRequestContext();
requestContextMap.put(BindingProvider.USERNAME_PROPERTY, uName);
requestContextMap.put(BindingProvider.PASSWORD_PROPERTY, pWord);
rc = new RequestContext();
rc.setApplication("test");
rc.setUserId("test");
}
Run Code Online (Sandbox Code Playgroud)
我班上某个地方的电话:
myPort.someFunctionCall(requestContext, "someValue");
Run Code Online (Sandbox Code Playgroud)
我的问题:这个调用是否是线程安全的?
kyi*_*yiu 31
根据CXF FAQ:
JAX-WS客户端代理是否安全?
官方JAX-WS回答:不可以.根据JAX-WS规范,客户端代理不是线程安全的.要编写可移植代码,您应将它们视为非线程安全并同步访问或使用实例池或类似代码.
CXF回答:对于许多用例,CXF代理是线程安全的.例外情况是:
使用
((BindingProvider)proxy).getRequestContext()- 根据JAX-WS规范,请求上下文是PER INSTANCE.因此,那里设置的任何东西都会影响其他线程的请求.使用CXF,您可以:Run Code Online (Sandbox Code Playgroud)((BindingProvider)proxy).getRequestContext().put("thread.local.request.context","true");以及对getRequestContext()的调用将使用线程本地请求上下文.这允许请求上下文是线程安全的.(注意:响应上下文始终是CXF中的线程本地)
管道上的设置 - 如果使用代码或配置直接操作管道(如设置TLS设置或类似设置),则这些设置不是线程安全的.管道是每个实例,因此将共享这些设置.此外,如果使用FailoverFeature和LoadBalanceFeatures,则会立即替换管道.因此,在设置线程上使用之前,管道上设置的设置可能会丢失.
- 会话支持 - 如果启用会话支持(请参阅jaxws规范),会话cookie将存储在管道中.因此,它将落入管道设置的上述规则,因此可以跨线程共享.
- WS-Security令牌 - 如果使用WS-SecureConversation或WS-Trust,则检索到的令牌将缓存在端点/代理中,以避免对STS进行额外(且昂贵)调用以获取令牌.因此,多个线程将共享令牌.如果每个线程具有不同的安全凭据或要求,则需要使用单独的代理实例.
对于管道问题,您可以安装一个使用本地或类似线程的新ConduitSelector.虽然这有点复杂.
对于大多数"简单"用例,您可以在多个线程上使用CXF代理.以上概述了其他人的解决方法.
| 归档时间: |
|
| 查看次数: |
19363 次 |
| 最近记录: |