webservice是一种规范,好比数据库的定义也是一种规范,基于这种规范诞生了很多的数据库,如:mysql、oracle等,现在市面流行的webservice的实现有很多,但我觉得cxf是比较适合于spring结合使用的。使用cxf向外提供webservice接口,势必会有安全问题,使用ws-security可以很好的解决安全问题。下面我们来看例子(采用maven构建项目):
1、项目目录结构
说明: pom.xml--maven构建项目所用到的jar及其他jetty的配置; web.xml--配置spring监听器和cxf过滤器; beans.xml--spring的配置; cxf-beans.xml--cxf服务器端的配置; cxfClient-beans.xml--cxf客户端的配置; log4j.properties--日志文件; Helloworld--webservice接口的定义; HelloworldImpl--webservice接口的实现; ServerPasswordCallback--服务器端安全校验; ClientPasswordCallback--客户端安全校验; WebServiceTest--junit单元测试
2、web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_id" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:beans.xml;classpath:cxf-beans.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <description>Apache CXF Endpoint</description> <display-name>cxf</display-name> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/ws/*</url-pattern><!-- 拦截所有以ws开头的地址 --> </servlet-mapping> </web-app>
3、接口的定义及实现
(1)、Helloworld
package com.luoshengsha.ws;import javax.jws.WebService; /** * webservice接口 * @author luoshengsha * 时间:2014-1-5 上午10:41:09 */ @WebService public interface Helloworld { public void say(String name); }
(2)、HelloworldImpl
package com.luoshengsha.ws.impl; import com.luoshengsha.ws.Helloworld; public class HelloworldImpl implements Helloworld { public void say(String name) { System.out.println("欢迎你,"+name+"!"); } }
4、安全校验的定义
(1)、ServerPasswordCallback
package com.luoshengsha.ws; 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; public class ServerPasswordCallback implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; if (pc.getIdentifier().equals("luoshengsha")) {//判断来自客户端的用户名是否是指定的用户名 // set the password on the callback. This will be compared to the // password which was sent from the client. pc.setPassword("lss123");//服务器端配置密码,与客户端的密码保持一致 } } }
(2)、ClientPasswordCallback
package com.luoshengsha.ws; 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; public class ClientPasswordCallback implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; pc.setPassword("lss123");//客户端配置密码 } }
5、spring相关配置文件
(1)、beans.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <context:annotation-config /> <aop:aspectj-autoproxy/> <aop:aspectj-autoproxy proxy-target-class="true"/> <context:component-scan base-package="com.luoshengsha" /> </beans>
(2)、cxf-beans.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-2.5.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" /> <!-- 定义安全校验器 --> <bean id="wss4jInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <constructor-arg> <map> <entry key="action" value="UsernameToken"/> <entry key="passwordType" value="PasswordText"/> <!-- <entry key="signaturePropFile" value="..."/> --> <entry key="user" value="luoshengsha"/><!--设置服务器端用户名--> <entry key="passwordCallbackClass" value="com.luoshengsha.ws.ServerPasswordCallback"/> </map> </constructor-arg> </bean> <!-- helloworld webservice接口 --> <jaxws:endpoint id="helloWebservice" implementor="com.luoshengsha.ws.impl.HelloworldImpl" address="/helloworld_ws"> <jaxws:inInterceptors> <ref bean="wss4jInInterceptor"/> </jaxws:inInterceptors> </jaxws:endpoint> </beans>
(3)、cxfClient-beans.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"> <!-- 定义安全校验器 --> <bean id="wss4jInInterceptor2" 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="luoshengsha"/><!--设置客户端用户名--> <entry key="passwordCallbackClass" value="com.luoshengsha.ws.ClientPasswordCallback"/> </map> </constructor-arg> </bean> <!-- 邮件客户端webservice --> <jaxws:client id="helloworldlClient" serviceClass="com.luoshengsha.ws.Helloworld" address="http://localhost:8080/ws/helloworld_ws" > <jaxws:outInterceptors> <ref bean="wss4jInInterceptor2"/> </jaxws:outInterceptors> </jaxws:client> </beans>
6、单元测试WebServiceTest.java
package com.luoshengsha.test; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.luoshengsha.ws.Helloworld; public class WebServiceTest { private static Helloworld helloworld; @BeforeClass public static void setUpBeforeClass() throws Exception { try { ApplicationContext cxt = new ClassPathXmlApplicationContext(new String[] {"beans.xml","cxfClient-beans.xml"}); helloworld = (Helloworld)cxt.getBean("helloworldlClient"); } catch (Exception e) { e.printStackTrace(); } } @Test public void say() { helloworld.say("罗生沙"); } } 7、源码下载地址:http://pan.baidu.com/s/1i3qkesH
本文出自 luoshengsha.com,欢迎转载,转载时请注明出处及相应链接。
本文永久链接: http://www.luoshengsha.com/356.html