示例用的是spring+CXF來配置webservice
首先是web.xml配置,将spring,CXF的配置檔案加載進去,由于我用戶端跟服務端在同一個工程裡面,是以配置檔案在一塊。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/spring-cxf.xml,<!--服務端用到的配置-->
/WEB-INF/classes/spring-cxf-client.xml<!--用戶端用到的配置檔案-->
</param-value>
</context-param>
<servlet>
<servlet-name>cxf-jeeek</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf-jeeek</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
一、服務端
<1>CXF的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.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-servlet.xml" />
<import resource="classpath:/META-INF/cxf/cxf-extension-soap.xml" />
<!--配置攔截器,用來驗證Token資訊-->
<bean id="exampleServiceInterceptor" class="com.ekservice.interceptor.ExampleServiceInterceptor">
</bean>
<bean id="exampleServiceImpl" class="com.ekservice.impl.ExampleServiceImpl" />
<jaxws:endpoint implementor="#exampleServiceImpl" address="/ExampleService">
<!-- -->
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<!-- 這個地方不知道為什麼,官方文檔說CXF2.0.x需要加這個過濾器,但是我用的是CXF2.7.7不加SAAJInInterceptor過濾器報錯 -->
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken"></entry>
<entry key="passwordType" value="PasswordText"></entry>
<!-- 設定密碼類型為加密
<entry key="passwordType" value="PasswordDigest" />-->
<entry key="passwordCallbackClass" value="com.ekservice.interceptor.ExampleServiceInterceptor"></entry>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:outInterceptors>
</jaxws:endpoint>
</beans>
<2>攔截器ExampleServiceInterceptor.java的代碼,有詳細注釋
package com.ekservice.interceptor;
import org.apache.log4j.Logger;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSecurityException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author EK
* @version 建立時間:2015-5-14 下午04:13:47
* 類說明
*/
public class ExampleServiceInterceptor implements CallbackHandler{
Logger logger = Logger.getLogger(ExampleServiceInterceptor.class);
private Map<String, String> passwords = new HashMap<String, String>();
public ExampleServiceInterceptor() {
passwords.put("admin", "password");
}
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
String identifier = pc.getIdentifier();
int usage = pc.getUsage();
logger.info("Client Token [username: " + identifier+", password: "+ passwords.get(identifier) + "] Exist user: "+passwords.containsKey(identifier));
if (usage == WSPasswordCallback.USERNAME_TOKEN) {// 密鑰方式USERNAME_TOKEN
if (!passwords.containsKey(identifier)) {
try {
throw new WSSecurityException("User not match - "+identifier);
} catch (WSSecurityException e) {
e.printStackTrace();
}
}
// username token pwd...
// ▲這裡的值必須和用戶端設的值相同,從cxf2.4.x後校驗方式改為cxf内部實作校驗,不必自己比較password是否相同
// 請參考:http://cxf.apache.org/docs/24-migration-guide.html的Runtime
// Changes片段
pc.setPassword(passwords.get(identifier));// ▲【這裡非常重要】▲
// ▲PS 如果和用戶端不同将抛出org.apache.ws.security.WSSecurityException:
// The
// security token could not be authenticated or
// authorized異常,服務端會認為用戶端為非法調用
}else if (usage == WSPasswordCallback.SIGNATURE) {// 密鑰方式SIGNATURE
if (!passwords.containsKey(identifier)) {
try {
throw new WSSecurityException("User not match - "+identifier);
} catch (WSSecurityException e) {
e.printStackTrace();
}
}
// set the password for client's keystore.keyPassword
// ▲這裡的值必須和用戶端設的值相同,從cxf2.4.x後校驗方式改為cxf内部實作校驗,不必自己比較password是否相同;
// 請參考:http://cxf.apache.org/docs/24-migration-guide.html的Runtime
// Changes片段
pc.setPassword(passwords.get(identifier));// //▲【這裡非常重要】▲
// ▲PS:如果和用戶端不同将抛出org.apache.ws.security.WSSecurityException:The
// security token could not be authenticated or
// authorized異常,服務端會認為用戶端為非法調用
}
}
}
}
<3>接口及其實作類的代碼,比較簡單,隻是做個示例
package com.ekservice.service;
import com.ek.entry.user.User;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
/**
* @author EK
* @version 建立時間:2015-5-14 下午02:17:59
* 類說明
*/
@WebService(targetNamespace="http://jeeek-dp/", name="ExampleService")
public interface ExampleService {
@WebResult(name="password")
@WebMethod(action="http://jeeek-dp/ExampleService/getStr")
public User getStr(@WebParam(name="name")String userName);
@WebMethod(action="http://jeeek-dp/ExampleService/receive")
public void receive();
@WebResult(name="tokenId")
@WebMethod(action="http://jeeek-dp/ExampleService/getTokenId")
public String getTokenId();
@WebResult(name="sendUnitInfo")
@WebMethod(action="http://jeeek-dp/ExampleService/getSendUnitInfo")
public int getSendUnitInfo(@WebParam(name="orgAccountId")long orgAccountId, @WebParam(name="recOrgType")int recOrgType, @WebParam(name="recOrgId")long recOrgId);
}
package com.ekservice.impl;
import com.ek.entry.user.User;
import com.ekservice.service.ExampleService;
import org.apache.log4j.Logger;
import javax.jws.WebService;
/**
* @author EK
* @version 建立時間:2015-5-14 下午02:30:35
* 類說明
*/
@WebService(targetNamespace="http://jeeek-dp/", serviceName="ExampleService", name="ExampleService")
public class ExampleServiceImpl implements ExampleService {
Logger logger = Logger.getLogger(ExampleServiceImpl.class);
public User getStr(String userName) {
User user = new User();
user.setAddress("北京市海澱區222号");
user.setMobilePhone("010-1101111");
System.out.println(userName+" "+user.getAddress());
return user;
}
@Override
public void receive() {
this.logger.info("Call reveive() method....");
}
@Override
public String getTokenId() {
this.logger.info("Call getTokenId() method....");
return "success";
}
@Override
public int getSendUnitInfo(long orgAccountId, int recOrgType, long recOrgId) {
this.logger.info("Call getSendUnitInfo() method...."+orgAccountId+", "+recOrgType+", "+recOrgId);
return 0;
}
}
二、用戶端
<1>CXF配置檔案,基本類似于服務端配置
<?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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<bean id="exampleServiceClientInterceptor"
class="com.ek.client.interceptor.ExampleServiceClientInterceptor"></bean>
<bean id="WSS4JOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType" value="PasswordText" />
<entry key="user" value="admin" />
<!-- <entry key="mustUnderstand" value="false"></entry> -->
<entry key="passwordCallbackRef">
<ref bean="exampleServiceClientInterceptor" />
</entry>
</map>
</constructor-arg>
</bean>
<jaxws:client id="exampleService"
address="http://localhost:8080/jeeek-dp/services/ExampleService"
serviceClass="com.ek.client.services.example.ExampleService">
<jaxws:outInterceptors>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"></bean>
<ref bean="WSS4JOutInterceptor"/>
</jaxws:outInterceptors>
</jaxws:client>
<bean id="eperpServiceClientInterceptor"
class="com.ek.client.interceptor.CPERPServiceClientInterceptor"></bean>
<bean id="cperp" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType" value="PasswordText" />
<entry key="user" value="cpweb" />
<entry key="passwordCallbackRef">
<ref bean="eperpServiceClientInterceptor" />
</entry>
</map>
</constructor-arg>
</bean>
</beans>
<2>用戶端攔截器代碼
package com.ek.client.interceptor;
import org.apache.log4j.Logger;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSecurityException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author EK
* @version 建立時間:2015年5月15日 上午11:36:20
* 類說明
*/
public class ExampleServiceClientInterceptor implements CallbackHandler{
Logger logger = Logger.getLogger(ExampleServiceClientInterceptor.class);
private Map<String, String> passwords = new HashMap<String, String>();
public ExampleServiceClientInterceptor() {
passwords.put("admin", "password");
}
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
String identifier = pc.getIdentifier();
int usage = pc.getUsage();
if (usage == WSPasswordCallback.USERNAME_TOKEN) {// 密鑰方式USERNAME_TOKEN
logger.info("Client Token [username: " + identifier+", password: "+ passwords.get(identifier) + "] Exist user= "+passwords.containsKey(identifier));
if (!passwords.containsKey(identifier)) {
try {
throw new WSSecurityException("User not match - "+identifier);
} catch (WSSecurityException e) {
e.printStackTrace();
}
}
pc.setPassword(passwords.get(identifier));// //▲【這裡非常重要】▲
}else if (usage == WSPasswordCallback.SIGNATURE) {// 密鑰方式SIGNATURE
if (!passwords.containsKey(identifier)) {
try {
throw new WSSecurityException("User not match - "+identifier);
} catch (WSSecurityException e) {
e.printStackTrace();
}
}
pc.setPassword(passwords.get(identifier));// //▲【這裡非常重要】▲
}
}
}
}
<3>用戶端接口代碼
package com.ek.client.services.example;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
/**
*
*/
@WebService(targetNamespace = "http://jeeek-dp/", name = "ExampleService")
public interface ExampleService {
@WebResult(name = "password", targetNamespace = "")
@RequestWrapper(localName = "getStr", targetNamespace = "http://jeeek-dp/")
@WebMethod(action = "http://jeeek-dp/ExampleService/getStr")
@ResponseWrapper(localName = "getStrResponse", targetNamespace = "http://jeeek-dp/")
public User getStr(
@WebParam(name = "name", targetNamespace = "")
java.lang.String name
);
@RequestWrapper(localName = "receive", targetNamespace = "http://jeeek-dp/")
@WebMethod(action = "http://jeeek-dp/ExampleService/receive")
public void receive();
@WebResult(name = "tokenId", targetNamespace = "")
@RequestWrapper(localName = "getTokenId", targetNamespace = "http://jeeek-dp/")
@WebMethod(action = "http://jeeek-dp/ExampleService/getTokenId")
@ResponseWrapper(localName = "getTokenIdResponse", targetNamespace = "http://jeeek-dp/")
public java.lang.String getTokenId();
@WebResult(name = "sendUnitInfo", targetNamespace = "")
@RequestWrapper(localName = "getSendUnitInfo", targetNamespace = "http://jeeek-dp/")
@WebMethod(action = "http://jeeek-dp/ExampleService/getSendUnitInfo")
@ResponseWrapper(localName = "getSendUnitInfoResponse", targetNamespace = "http://jeeek-dp/")
public java.lang.Integer getSendUnitInfo(
@WebParam(name = "orgAccountId", targetNamespace = "")
java.lang.Long orgAccountId,
@WebParam(name = "recOrgType", targetNamespace = "")
java.lang.Integer recOrgType,
@WebParam(name = "recOrgId", targetNamespace = "")
java.lang.Long recOrgId
);
}
<4>用戶端調用類
package com.ek.client.call;
import com.ek.client.interceptor.ExampleServiceClientInterceptor;
import com.ek.client.services.example.ExampleService;
import com.ek.client.services.example.User;
import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author EK
* @version 建立時間:2015年5月15日 上午11:05:06
* 類說明
*/
public class ExampleServiceClient {
public static void main(String[] args) {
// ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-cxf-client.xml");
// ExampleService es = (ExampleService) ctx.getBean("exampleService");
Map<String, Object> map = new HashMap<String, Object>();
map.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
map.put(WSHandlerConstants.USER, "admin");
map.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
map.put(WSHandlerConstants.PW_CALLBACK_CLASS, ExampleServiceClientInterceptor.class.getName());
List list = new ArrayList();
list.add(new SAAJOutInterceptor());
list.add(new WSS4JOutInterceptor(map));
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(ExampleService.class);
factory.setAddress("http://localhost:8080/jeeek-dp/services/ExampleService");
factory.getOutInterceptors().addAll(list);
ExampleService es = (ExampleService) factory.create();
User u = es.getStr("ssss");
//Integer sui = es.getSendUnitInfo(1L, 2, 3L);
String tokenId = es.getTokenId();
//es.receive();
System.out.println("的, " + tokenId);
//System.out.println("的" + sui);
}
}
轉載于:https://www.cnblogs.com/edi-kai/p/6549353.html