由于原项目中包含的JAR包太多,直接在里面加可能会引起JAR包冲突造成各种报错,所以推荐另开个项目专门用于接口的编写。
使用到的框架有HIBERNATE(本不想用,原有数据库ID生成策略用了它,不知不用是否可行)、SPRING,个人使用到的最简的JAR包如下:
1、首选配置服务端
与spring整合的配置文件applicationContext-webservice-server.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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
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" />
<!-- 添加implementorClass属性来指定实现接口,可以直接看到这些接口参数信息 否则生成的wsdl看不到参数-->
<!-- 个人会员信息WS-->
<jaxws:endpoint id="userServer" implementorClass="com.*.webservice.user.IUserWebService" implementor="#userWebServiceImpl" address="http://localhost:8083/userServer" >
<jaxws:inInterceptors><!-- 日志输出以及安全验证 -->
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType" value="PasswordText" /><!-- 明文的方式传递密码 -->
<entry key="user" value="cxfServer" /><!-- 取一个用户名 -->
<entry key="passwordCallbackRef">
<ref bean="serverPasswordCallback" /><!-- 密码回调的bean -->
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
</jaxws:outInterceptors>
<jaxws:inFaultInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
</jaxws:inFaultInterceptors>
<jaxws:outFaultInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
</jaxws:outFaultInterceptors>
</jaxws:endpoint>
</beans>
对应的验证的回调BEAN ServerPasswordCallback.java
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
/**
* WS验证
* @author
*
*/
public class ServerPasswordCallback implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
// TODO Auto-generated method stub
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
String idf = pc.getIdentifier();
if("admin".equals(idf)){
pc.setPassword("password");
}
else{
throw new SecurityException("用户不存在");
}
}
}
}
2、业务配置文件applicationContext-common.xml , WS安全验证的回调BEAN以及业务SERVICE在此文件里统一管理
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- -->
<bean id="serverPasswordCallback" class=" com.*.webservice.security.ServerPasswordCallback" /><!--服务端回调密码的BEAN -->
<bean id="userWebServiceImpl" class="com.*.webservice.user.imp.UserWebServiceImpl">
<!--<property name="commonJdbcDao">
<ref bean="commonJdbcDao"/>
</property>
<property name="commonDao">
<ref bean="commonDao"/>
</property> --><!-- 测试时无须用到 -->
</bean>
</beans>
3、客户端与SPRING整合的配置文件applicationContext-webservice-client.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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
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" />
<bean id="clientPasswordCallback" class=" com.*.webservice.security.ClientPasswordCallback" />
<!-- userService -->
<bean id="userClient" class="com.*.webservice.user.IUserWebService" factory-bean="userClientFactory" factory-method="create"/>
<bean id="userClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.*.webservice.user.IUserWebService"/>
<property name="address" value="http://localhost:8083/userServer"/>
<property name="outInterceptors">
<list>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean 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="cxfClient" />
<entry key="passwordCallbackRef">
<ref bean="clientPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
</list>
</property>
<property name="inInterceptors">
<list>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</list>
</property>
</bean>
</beans>
客户端回调验证的BEAN ClientPasswordCallback.java
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
/**
* WS验证
* @author
*
*/
public class ClientPasswordCallback implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
// TODO Auto-generated method stub
for(int i = 0; i < callbacks.length; i++){
WSPasswordCallback ps = (WSPasswordCallback) callbacks[i];
ps.setPassword("password");
ps.setIdentifier("admin");
}
}
}
4、接口以及测试类
接口
import javax.jws.WebService;
@WebService
public interface IUserWebService {
public String getUserService(String s);
}
实现
import java.util.List;
import javax.jws.WebService;
import org.apache.log4j.Logger;
import com.fw.webservice.user.IUserWebService;
/**
*
* @author
*
*/
@WebService(endpointInterface="com.*.webservice.user.IUserWebService")
public class UserWebServiceImpl implements IUserWebService {
//private ICommonJdbcDao commonJdbcDao;
//private ICommonDao commonDao;
public String getUserService(String s) {
return "456";
}
测试类:
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestWs {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext("applicationContext*.xml");
IUserWebService client = (IUserWebService)context.getBean("userClient");
String response = client.getUserService("123");
System.out.println("Response: " + response);
System.exit(0);
}
}
测试打印出456.
可以单独载入服务端配置文件,浏览器中输入你配置文件中发布的address 本例中的http://localhost:8083/userServer?wsdl查看发布情况
作为WEB项目发布还需要对web.xml配置
<!-- CXF -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXFServlet</display-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webservice</url-pattern>
</servlet-mapping>
发布后输入http://localhost:8083/userServer?wsdl查看发布情况
客户端中调用
JaxWsProxyFactoryBean bean = new JaxWsProxyFactoryBean();
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME_TOKEN);
outProps.put(WSHandlerConstants.USER, "cxfClient");
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
ClientPasswordCallback.class.getName());
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
bean.getOutInterceptors().add(wssOut);
bean.setServiceClass(IUserWebService.class);
bean.setAddress("http://localhost:8083/userServer");
IUserWebService service = (IUserWebService) bean.create();
service.getUserService("123");