我有两个servlet,它们可以访问同一主机上的两个相应的Axis2 Web服务。这些servlet之一是只读的,而另一个则写入数据库。
每个Axis2 Web服务都使用BASIC身份验证。只读Web服务使用系统帐户,而写Web服务使用用户的凭据(作为Web表单的一部分提交)。
我遇到的问题是,名为second的servlet始终无法对其Web服务进行身份验证。例如,我可以通过它的全部servlet来查询只读服务,但是当我尝试使用写服务时却得到“ 401:需要授权”。如果我先调用写服务,则在尝试使用只读服务时会遇到相同的错误。
这是我为servlet中的连接设置凭据的方式:
Stub service = new Stub(serviceUrl);
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
auth.setUsername(username);
auth.setPassword(password);
auth.setPreemptiveAuthentication(true);
service._getServiceClient().getOptions().setProperty(HTTPConstants.AUTHENTICATE, auth);
访问只读服务的servlet在其构造函数中具有此代码。访问写服务的servlet的doGet / doPost方法中包含此代码。
似乎第一个调用的服务的凭据正在某个地方缓存,但是我找不到那里。我看到了可能的解决方案here,但是找不到
WSClientConstants.CACHED_HTTP_STATE
的定义位置。 The comments in this JIRA issue似乎暗示它是org.apache.axis2.transport.http.HTTPConstants
的一部分,但不存在。细节:
轴版本:1.5.1
Tomcat版本:6.0.26
Java版本:1.6.0_23
最佳答案
事实证明,使用相同的JSESSIONID到两个不同服务的连接。因此,与第二个Web服务的连接试图使用为第一个Web服务验证的会话,从而导致错误。
我的解决方案是为每个服务定义一个HttpClient
,具体操作如下
MultiThreadedHttpConnectionManager manager = new MuliThreadedHttpConnectionManager();
HttpClient client = new HttpClient(manager);
ConfigurationContext context = ConfigurationContextFactory.createDefaultConfigurationContext();
context.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, client);
context.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, true);
Stub service = new Stub(context, serviceUrl);
这允许两个servlet为其各自的服务拥有单独的会话。