0 ssl axis2 apache-httpclient-4.x
由于 httpClient 3 已经过时,我需要替换代码:
SSLProtocolSocketFactory.setSSL(trustStore, keyStore, pasw);
ProtocolSocketFactory factory = new SSLProtocolSocketFactory();
Protocol.registerProtocol("https", new Protocol("https", factory, 443));
Run Code Online (Sandbox Code Playgroud)
如果有人尝试过,请分享。
在java代码中,我试图使用 OperationClient 对象 operationClientObject.execute(true); 调用 webservice;
提前致谢..
axis2 httpclient4 迁移并不是那么容易,正如从“文档”中看到的那样。
在此过程中,我使用了最新的 Axis 2 版本 1.7.8。
轴 2 1.7.0 发行说明包含一个单行,用于 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.
Run Code Online (Sandbox Code Playgroud)
注意最后一句话。Axis 2 1.7.8 pom 文件,二进制分发版包含 httpclient-4.5.3.jar,但不能使用它。所以改用httpclient 4.4.1。
启用日志记录
在升级之前,我想您已经有一个工作轴 2 项目。我建议启用轴 2 调试日志记录,看看会发生什么。要启用日志记录,请使用 jvm 参数定义自定义 log4j 属性文件:
-Dlog4j.configuration=file:/c:/work/sources/debug_log4j.properties
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
Axis2 + Httpclient4
如果您没有axis2.xml,您可以在axis2 二进制包中找到它(包含所有依赖项和示例配置)
根据发行说明,您需要将传输发送方从 CommonsHTTPTransportSender 更改为 HTTPClient4TransportSender。
如果您查看(或调试)axis2 配置器,您会看到,xml 必须包含特定部分,否则axis2 不会读取它。
所以我配置为使用 HttpClient4 后的axis2.xml 内容(并删除了未使用的部分,但保留了必要的部分):
<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>
Run Code Online (Sandbox Code Playgroud)
在java端,需要创建自定义axis2配置上下文,来使用我们自定义的axis2.xml。Axis2 提供多个配置器,我更喜欢基于文件的配置器:
final ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(
"c:\\work\\sources\\axis2conf",
"c:\\work\\sources\\axis2conf\\axis2.xml");
Run Code Online (Sandbox Code Playgroud)
您可以在构造函数期间将配置上下文分配给客户端存根:
FileNet_UploadDocumentWSStub stub = new FileNet_UploadDocumentWSStub(ctx, "https://testserver/test.asp");
Run Code Online (Sandbox Code Playgroud)
因此,如果您不想使用自定义 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);
Run Code Online (Sandbox Code Playgroud)
新的实现 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.
Run Code Online (Sandbox Code Playgroud)
您需要在 httpclient4 端设置 ssl 上下文。这不是问题,因为轴允许您使用 HTTPConstants.CACHED_HTTP_CLIENT 属性为 ws 调用定义 httpclient:
options.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
Run Code Online (Sandbox Code Playgroud)
但是,如果您为标准方式创建一个 httpclient4:
...
HttpClientBuilder builder = HttpClientBuilder.create();
...
Run Code Online (Sandbox Code Playgroud)
并将其分配给axis2 客户端存根,您会得到一个ClassCastException,因为所有新的httpclient Builder、工厂等方法都基于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");
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4771 次 |
最近记录: |