環境信息:CXF2.7 Spring3.1 tomcat6.0java
1、建立webservice接口web
web.xml算法
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<!-- spring須要加載的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:com/server/spring-cxf.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- cxf服務啓動servlet -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServletspring
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>apache
spring-cxf.xml瀏覽器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:wsa="http://cxf.apache.org/ws/addressing"
xsi:schemaLocation="
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.1.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!-- <cxf:bus>
<cxf:features>
日誌攔截功能,用於監控soap內容,開發後能夠刪除
<cxf:logging/>
<wsa:addressing/>
</cxf:features>
</cxf:bus> -->
<bean id="hello" class="com.server.HelloWorldImpl" />
<jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" publish="true"/>
</beans>
tomcat
HelloWorld.java服務器
package com.server;
import javax.jws.WebService;
/**
* Web Service 接口聲明
*/
@WebService(targetNamespace = "server.com")
public interface HelloWorld {
/**
* sayHi
* @param text
* @return
*/
String sayHi(String text);
}
app
HelloWorldImpl.javafrontend
package com.server;
import javax.jws.WebService;
/**
* Web Service接口實現
*
*/
@WebService(endpointInterface = "com.server.HelloWorld")
public class HelloWorldImpl implements HelloWorld {
@Override
public String sayHi(String text) {
// TODO Auto-generated method stub
return "Hello, " + text;
}
}
部署代碼後可在瀏覽器打開http://locahost:8080/項目名稱/service/HelloWorld?wsdl
此時webservice接口開發完成!
2、添加SSL雙向認證
利用JDK自帶keytool工具:直接cmd後執行:
keytool -genkey -alias test -keyalg RSA -keystore test.keystore -validity 3650
名字和姓氏要填域名或者IP名:服務器端IP。其餘能夠隨便填
這步操做之後,獲得test.keystore
keytool -export -alias test -file test.cer -keystore test.keystore
獲得一個test.cer,而後把test.cer給到客戶端,客戶端用如下命令:
keytool -import -alias test -file test.cer -keystore server.keystore
獲得server.keystore,把這個文件做爲客戶端代碼的truststore,才能正常訪問到。能夠理解爲由於是用代碼 來訪問服務端,沒有用戶手工確認的過程,因此須要把證書加進來進行確認
那本地想要調用到服務端,就也須要作證書,一樣先用這個命令:
keytool -genkey -alias test1 -keyalg RSA -keystore test1.keystore -validity 3650
名字和姓氏要填域名或者IP名:客戶端IP。其餘能夠隨便填
獲得test1.keystore
而後:
keytool -export -alias test1 -file test1.cer -keystore test1.keystore
獲得test1.cer,把test1.cer發給服務端,服務端用如下命令:
keytool -import -alias test1 -file test1.cer -keystore client.keystore
獲得了client.keystore,這裏面就包含了客戶端IP地址信息的證書信息,能夠用如下命令查看:
keytool -list -v -keystore client.keystore
配置tomcat-》conf-》server.xml
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS" keystoreFile="conf/test.keystore"
keystorePass="密碼口令" keystoreType="jks" truststoreFile="conf/client.keystore"
truststorePass="密碼口 令" truststoreType="jks" />
客戶端調用代碼:ClientTest.java
package com.client;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.server.HelloWorld;
import com.util.ClientUtils;
/**
* 客戶端訪問服務器Web Service
*
*/
public final class ClientTest {
public static void main(String args[]) throws Exception {
HelloWorld client = ClientUtils.getInstance();
String response = client.sayHi("Joe");
System.out.println("Response: " + response);
System.exit(0);
}
}
ClientUtils.java
package com.util;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.security.KeyStore;import javax.net.ssl.KeyManager;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.TrustManager;import javax.net.ssl.TrustManagerFactory;import org.apache.cxf.configuration.jsse.TLSClientParameters;import org.apache.cxf.endpoint.Client;import org.apache.cxf.frontend.ClientProxy;import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;import org.apache.cxf.transport.http.HTTPConduit;import com.server.HelloWorld;public class ClientUtils { private static HelloWorld helloWorld; public static HelloWorld getInstance(){ if(null != helloWorld){ return helloWorld; } try{ String addr = "https://localhost:8443/cxf-demo/service/HelloWorld"; JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean(); factoryBean.setAddress(addr); factoryBean.setServiceClass(HelloWorld.class); helloWorld = (HelloWorld) factoryBean.create(); Client proxy = ClientProxy.getClient(helloWorld); HTTPConduit conduit = (HTTPConduit) proxy.getConduit(); TLSClientParameters tlsParams = conduit.getTlsClientParameters(); if (tlsParams == null) { tlsParams = new TLSClientParameters(); } tlsParams.setDisableCNCheck(true); //設置keystore tlsParams.setKeyManagers(ClientUtils.getKeyManagers()); // 設置信任證書 tlsParams.setTrustManagers(ClientUtils.getTrustManagers()); conduit.setTlsClientParameters(tlsParams); }catch(Exception e){ e.printStackTrace(); } return helloWorld; } public static KeyManager[] getKeyManagers() { InputStream is = null; try { // 獲取默認的 X509算法 String alg = KeyManagerFactory.getDefaultAlgorithm(); // 建立密鑰管理工廠 KeyManagerFactory factory = KeyManagerFactory.getInstance(alg); File certFile = new File("D://cer//222.keystore"); if (!certFile.exists() || !certFile.isFile()) { return null; } is = new FileInputStream(certFile); // 構建以證書相應格式的證書倉庫 KeyStore ks = KeyStore.getInstance("JKS"); // 加載證書 ks.load(is, "qfkj2015".toCharArray()); factory.init(ks, "qfkj2015".toCharArray()); KeyManager[] keyms = factory.getKeyManagers(); return keyms; } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } public static TrustManager[] getTrustManagers() { // 讀取證書倉庫輸入流 InputStream is = null; try { // 信任倉庫的默認算法X509 String alg = TrustManagerFactory.getDefaultAlgorithm(); // 獲取信任倉庫工廠 TrustManagerFactory factory = TrustManagerFactory.getInstance(alg); // 讀取信任倉庫 is = new FileInputStream(new File("D://cer//server.keystore")); // 密鑰類型 KeyStore ks = KeyStore.getInstance("JKS"); // 加載密鑰 ks.load(is, "qfkj2015".toCharArray()); factory.init(ks); TrustManager[] tms = factory.getTrustManagers(); return tms; } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; }}