由于httpClient 3已过时,因此我需要替换代码:
SSLProtocolSocketFactory.setSSL(trustStore, keyStore, pasw);
ProtocolSocketFactory factory = new SSLProtocolSocketFactory();
Protocol.registerProtocol("https", new Protocol("https", factory, 443));
如果有人尝试过,请分享。
在Java代码中,我正在尝试使用OperationClient对象调用Web服务 operationClientObject.execute(true);
先谢谢了。
答案 0 :(得分:1)
axis2 httpclient4迁移不是那么容易,因为它出现在“文档”中。
在此过程中,我使用了最新的Axis 2版本1.7.8。
第2轴1.7.0 release notes包含一个衬里,用于HttpClient v4集成:
Axis2 1.7.0 supports Apache HttpClient 4.x in addition to the no longer maintained Commons HttpClient 3.x. To enable the support for HttpClient 4.x, use org.apache.axis2.transport.http.impl.httpclient4.HTTPClient4TransportSender instead of org.apache.axis2.transport.http.CommonsHTTPTransportSender in axis2.xml. Please note that the code was written for HttpClient 4.2.x and should work with 4.3.x and 4.4.x, but is incompatible with 4.5.x.
当心最后的话。 Axis 2 1.7.8 pom文件,并且二进制发行版包含httpclient-4.5.3.jar,但不适用于它。因此,请改用httpclient 4.4.1。
启用日志记录
在升级之前,我想您已经有一个工作中的axis 2项目。我建议启用2轴调试日志记录,以查看会发生什么。要启用日志记录,请使用jvm参数定义一个自定义log4j属性文件:
-Dlog4j.configuration=file:/c:/work/sources/debug_log4j.properties
debug_log4j.properties文件的内容为:
log4j.rootCategory=DEBUG, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%p] %m%n
Axis2 + Httpclient4
如果没有axis2.xml,则可以在axis2 binary package中找到它(包含所有依赖项和示例配置)
根据发行说明,您需要将传输发件人从CommonsHTTPTransportSender更改为HTTPClient4TransportSender。
如果您查看(或调试)axis2配置器,就会看到,xml必须包含特定部分,否则axis2不会读取它。
因此,将我的axis2.xml内容配置为使用HttpClient4(并删除了未使用的部分,但保留了必不可少的部分):
<axisconfig name="AxisJava2.0">
<!-- ================================================= -->
<!-- Transport Outs -->
<!-- ================================================= -->
<parameter name="hotdeployment">true</parameter>
<parameter name="hotupdate">false</parameter>
<parameter name="enableMTOM">false</parameter>
<parameter name="enableSwA">false</parameter>
<transportSender name="local"
class="org.apache.axis2.transport.local.LocalTransportSender"/>
<transportSender name="http"
class="org.apache.axis2.transport.http.impl.httpclient4.HTTPClient4TransportSender">
<parameter name="PROTOCOL">HTTP/1.1</parameter>
<parameter name="Transfer-Encoding">chunked</parameter>
<!-- If following is set to 'true', optional action part of the Content-Type will not be added to the SOAP 1.2 messages -->
<!-- <parameter name="OmitSOAP12Action">true</parameter> -->
</transportSender>
<transportSender name="https"
class="org.apache.axis2.transport.http.impl.httpclient4.HTTPClient4TransportSender">
<parameter name="PROTOCOL">HTTP/1.1</parameter>
<parameter name="Transfer-Encoding">chunked</parameter>
</transportSender>
<!-- ================================================= -->
<!-- Phases -->
<!-- ================================================= -->
<phaseOrder type="InFlow">
<!-- System predefined phases -->
<phase name="Transport">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher">
<order phase="Transport"/>
</handler>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher">
<order phase="Transport"/>
</handler>
</phase>
<phase name="Addressing">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
<order phase="Addressing"/>
</handler>
</phase>
<phase name="Security"/>
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
<handler name="RequestURIOperationDispatcher"
class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
<handler name="HTTPLocationBasedDispatcher"
class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/>
<handler name="GenericProviderDispatcher"
class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/>
<handler name="MustUnderstandValidationDispatcher"
class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/>
</phase>
<phase name="RMPhase"/>
<!-- System predefined phases -->
<!-- After Postdispatch phase module author or service author can add any phase he want -->
<phase name="OperationInPhase">
<handler name="MustUnderstandChecker"
class="org.apache.axis2.jaxws.dispatchers.MustUnderstandChecker">
<order phase="OperationInPhase"/>
</handler>
</phase>
<phase name="soapmonitorPhase"/>
</phaseOrder>
<phaseOrder type="OutFlow">
<!-- user can add his own phases to this area -->
<phase name="soapmonitorPhase"/>
<phase name="OperationOutPhase"/>
<!--system predefined phase-->
<!--these phase will run irrespective of the service-->
<phase name="RMPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
<phase name="Security"/>
</phaseOrder>
<phaseOrder type="InFaultFlow">
<phase name="Addressing">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
<order phase="Addressing"/>
</handler>
</phase>
<phase name="Security"/>
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
<handler name="RequestURIOperationDispatcher"
class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
<handler name="HTTPLocationBasedDispatcher"
class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/>
<handler name="GenericProviderDispatcher"
class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/>
<handler name="MustUnderstandValidationDispatcher"
class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/>
</phase>
<phase name="RMPhase"/>
<!-- user can add his own phases to this area -->
<phase name="OperationInFaultPhase"/>
<phase name="soapmonitorPhase"/>
</phaseOrder>
<phaseOrder type="OutFaultFlow">
<!-- user can add his own phases to this area -->
<phase name="soapmonitorPhase"/>
<phase name="OperationOutFaultPhase"/>
<phase name="RMPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
<phase name="Security"/>
</phaseOrder>
</axisconfig>
在Java端,您需要创建一个自定义axis2配置上下文,以使用我们的自定义axis2.xml。 Axis2提供了多个配置器,我更喜欢基于文件的配置器:
final ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(
"c:\\work\\sources\\axis2conf",
"c:\\work\\sources\\axis2conf\\axis2.xml");
您可以在构造函数期间将配置上下文分配给客户端存根:
FileNet_UploadDocumentWSStub stub = new FileNet_UploadDocumentWSStub(ctx, "https://testserver/test.asp");
因此,如果您不想使用自定义ssl设置,则升级已完成。
Axis2 + Httpclient4 + SSL
升级到httpclient4后,该实现不再使用自定义协议处理程序属性(HTTPConstants.CUSTOM_PROTOCOL_HANDLER)。
org / apache / axis2 / transport / http / impl / httpclient3 / HTTPSenderImpl.java:524中的旧实现:
// one might need to set his own socket factory. Let's allow that case
// as well.
Protocol protocolHandler = (Protocol) msgCtx.getOptions().getProperty(
HTTPConstants.CUSTOM_PROTOCOL_HANDLER);
新的实现org / apache / axis2 / transport / http / impl / httpclient4 / HTTPSenderImpl.java:583:
// TODO : one might need to set his own socket factory. We have to allow that case as well.
您需要在httpclient4端设置ssl上下文。这不是问题,因为axis允许您使用HTTPConstants.CACHED_HTTP_CLIENT属性为ws调用定义httpclient:
options.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
但是,如果您以标准方式创建httpclient4:
...
HttpClientBuilder builder = HttpClientBuilder.create();
...
并将其分配给axis2客户端存根,您将得到ClassCastException,因为所有新的httpclient Builder,factory等方法都基于ClosableHttpClient创建了httpclient的“现代”实现。但是axis2的实现取决于不推荐使用的AbstractHttpClient。因此,您需要创建旧版本的httpclient。
完整的示例:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.Security;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.httpclient.contrib.ssl.AuthSSLProtocolSocketFactory;
import org.apache.http.client.HttpClient;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.BasicClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.ssl.SSLContexts;
public class SslTest {
public SslTest() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws Exception {
File keyFile = new File("c:\\work\\sources\\ConsoleApp25\\avp-pc.jks");
final ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(
"c:\\work\\sources\\axis2conf",
"c:\\work\\sources\\axis2conf\\axis2.xml");
FileNet_UploadocumentWSStub stub = new FileNet_UploadDocumentWSStub(ctx, "https://testserver/test.asp");
FileNet_UploadDocument wsMethodReq = new FileNet_UploadDocument();
ServiceClient serviceClient = stub._getServiceClient();
Options options = serviceClient.getOptions();
//keystore types: https://docs.oracle.com/javase/9/docs/specs/security/standard-names.html#keystore-types
KeyStore keyStore = KeyStore.getInstance("jks");
InputStream in = null;
try {
in = new FileInputStream(keyFile);
keyStore.load(in, "changeit".toCharArray());
} finally {
if (in != null) {
in.close();
}
}
//Factory instance types: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#T5
//on IBM servers use IbmX509 instead of SunX509
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, "changeit".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme httpsScheme = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(httpsScheme);
ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(cm);
options.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
stub.fileNet_UploadDocument(wsMethodReq);
System.out.println("done");
}