Webservice整合Spring进行校验
服务端代码:
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Archetype Created Web Application</display-name> <!--1. cxfsevlet配置--> <servlet> <servlet-name>cxfservlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>cxfservlet</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping> <!--2.spring容器配置--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 欢迎页面配置 --> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
applicationContext.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"> <!-- Spring整合cxf发布服务,关键点: 1. 服务地址 2. 服务类 服务完整访问地址: http://localhost:8080/ws/hello --> <jaxws:server address="/hello"> <jaxws:serviceBean> <bean class="webservice.com.topcheer.impl.HelloServiceImpl"></bean> </jaxws:serviceBean> <jaxws:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> </jaxws:outInterceptors> <jaxws:inInterceptors> <bean class="webservice.com.topcheer.interceptor.AuthInterceptor"></bean> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> </jaxws:inInterceptors> </jaxws:server> </beans>
拦截器
/** * @author WGR * @create 2020/2/14 -- 14:40 */ public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> { public AuthInterceptor() { super(Phase.PRE_INVOKE);//调用之前拦截soap消息 System.out.println("服务器端拦截器初始化"); } @Override public void handleMessage(SoapMessage msg) throws Fault { System.out.println("服务端拦截器="+msg); List<Header> headers=msg.getHeaders(); if(headers==null||headers.size()<=0){ throw new Fault(new IllegalArgumentException("没有header 不能调用")); } Header firstHeader=headers.get(0); Element ele=(Element)firstHeader.getObject(); NodeList userIds= ele.getElementsByTagName("userId"); NodeList passwards= ele.getElementsByTagName("password"); System.out.println("用户名个数="+userIds.getLength()); System.out.println("密码个数="+passwards.getLength()); if(userIds.getLength()!=1 || passwards.getLength()!=1 ){ throw new Fault(new IllegalArgumentException("格式不对")); } String userId= userIds.item(0).getTextContent(); String passward= passwards.item(0).getTextContent(); System.out.println("用户名="+userId); System.out.println("密码="+passward); if(!"wl".equals(userId)||!"1985310".equals(passward) ){ throw new Fault(new IllegalArgumentException("用户名或者密码不对")); } System.out.println("通过服务端拦截器"); } }
客户端代码:
<?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"> <!-- Spring整合cxf客户端配置: 1. 服务地址 http://localhost:8080/ws/hello 2. 服务接口类型 --> <jaxws:client id="helloService" serviceClass="webservice.impl.HelloService" address="http://localhost:8080/ws/hello"> <jaxws:outInterceptors> <bean class="webservice.impl.AddHeaderInterceptor"> <constructor-arg name="userId" value="wl"/> <constructor-arg name="password" value="1985310"/> </bean> </jaxws:outInterceptors> </jaxws:client> </beans>
拦截器代码:
/** * @author WGR * @create 2020/2/14 -- 14:49 */ public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private String userId; private String password; public AddHeaderInterceptor(String userId,String password) { super(Phase.PREPARE_SEND);//准备发送soap消息的时候 this.userId=userId; this.password=password; System.out.println("客户端端拦截器初始化"); } @Override public void handleMessage(SoapMessage msg) throws Fault { System.out.println("客户端拦截器"+msg); List<Header> headers=msg.getHeaders(); Document doc= DOMUtils.createDocument(); Element ele=doc.createElement("authHeader"); Element idEle=doc.createElement("userId"); idEle.setTextContent(userId); Element passwordEle=doc.createElement("password"); passwordEle.setTextContent(password); ele.appendChild(idEle); ele.appendChild(passwordEle); headers.add(new Header( new QName("www.xxx") ,ele)); } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
测试类
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class Client { // 注入对象 @Resource private HelloService helloService; @Test public void remote(){ // 查看接口的代理对象类型 // class com.sun.proxy.$Proxy45 System.out.println(helloService.getClass()); // 远程访问服务端方法 System.out.println(helloService.sayHello("Jerry")); } }
测试端的日志:
二月 14, 2020 5:02:03 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.HelloService 信息: Inbound Message ---------------------------- ID: 1 Address: http://localhost:8080/ws/hello Encoding: UTF-8 Http-Method: POST Content-Type: text/xml; charset=UTF-8 Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[299], content-type=[text/xml; charset=UTF-8], host=[localhost:8080], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 3.0.1]} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><authHeader><userId>wl</userId><password>1985310</password></authHeader></soap:Header><soap:Body><ns2:sayHello xmlns:ns2="http://topcheer.com.webservice/"><arg0>Jerry</arg0></ns2:sayHello></soap:Body></soap:Envelope> -------------------------------------- 服务端拦截器={org.apache.cxf.message.MessageFIXED_PARAMETER_ORDER=false, http.base.path=http://localhost:8080, HTTP.REQUEST=org.apache.catalina.connector.RequestFacade@51c6f68a, org.apache.cxf.transport.Destination=org.apache.cxf.transport.servlet.ServletDestination@338495c9, HTTP.CONFIG=org.apache.catalina.core.StandardWrapperFacade@26a01655, org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@606e1db, org.apache.cxf.message.Message.QUERY_STRING=null, javax.xml.ws.wsdl.operation={http://topcheer.com.webservice/}sayHello, javax.xml.ws.wsdl.service={http://impl.topcheer.com.webservice/}HelloServiceImplService, org.apache.cxf.message.Message.ENCODING=UTF-8, HTTP.CONTEXT=org.apache.catalina.core.ApplicationContextFacade@60122537, Content-Type=text/xml; charset=UTF-8, org.apache.cxf.security.SecurityContext=org.apache.cxf.transport.http.AbstractHTTPDestination$2@772fce21, org.apache.cxf.message.Message.PROTOCOL_HEADERS={Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[299], content-type=[text/xml; charset=UTF-8], host=[localhost:8080], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 3.0.1]}, org.apache.cxf.request.url=http://localhost:8080/ws/hello, Accept=*/*, org.apache.cxf.request.uri=/ws/hello, org.apache.cxf.service.model.MessageInfo=[MessageInfo INPUT: {http://topcheer.com.webservice/}sayHello], org.apache.cxf.message.Message.PATH_INFO=/ws/hello, org.apache.cxf.transport.https.CertConstraints=null, HTTP.RESPONSE=org.apache.catalina.connector.ResponseFacade@519b7c2f, org.apache.cxf.headers.Header.list=[org.apache.cxf.binding.soap.SoapHeader@602247fe], schema-validation-enabled=NONE, org.apache.cxf.request.method=POST, org.apache.cxf.async.post.response.dispatch=true, org.apache.cxf.message.Message.IN_INTERCEPTORS=[org.apache.cxf.transport.https.CertConstraintsInterceptor@1168fd50], HTTP_CONTEXT_MATCH_STRATEGY=stem, http.service.redirection=null, org.apache.cxf.message.Message.BASE_PATH=/ws/hello, org.apache.cxf.service.model.BindingMessageInfo=org.apache.cxf.service.model.BindingMessageInfo@18bf779a, javax.xml.ws.wsdl.port={http://impl.topcheer.com.webservice/}HelloServiceImplPort, org.apache.cxf.configuration.security.AuthorizationPolicy=null, javax.xml.ws.wsdl.interface={http://topcheer.com.webservice/}HelloService, javax.xml.ws.wsdl.description=/hello?wsdl, org.apache.cxf.interceptor.LoggingMessage.ID=1} 用户名个数=1 密码个数=1 用户名=wl 密码=1985310 通过服务端拦截器 二月 14, 2020 5:02:03 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.HelloService 信息: Outbound Message --------------------------- ID: 1 Response-Code: 200 Encoding: UTF-8 Content-Type: text/xml Headers: {} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHelloResponse xmlns:ns2="http://topcheer.com.webservice/"><return>Jerry,Welcome to Itheima!</return></ns2:sayHelloResponse></soap:Body></soap:Envelope> --------------------------------------
客户端的日志:
客户端端拦截器初始化 二月 14, 2020 5:02:01 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass 信息: Creating Service {http://topcheer.com.webservice/}HelloServiceService from class webservice.impl.HelloService class com.sun.proxy.$Proxy45 客户端拦截器{org.apache.cxf.message.Message.PROTOCOL_HEADERS={SOAPAction=[""]}, org.apache.cxf.transport.Conduit=conduit: class org.apache.cxf.transport.http.URLConnectionHTTPConduit1925352804target: http://localhost:8080/ws/hello, org.apache.cxf.service.model.MessageInfo=[MessageInfo INPUT: {http://topcheer.com.webservice/}sayHello], org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@6492fab5, org.apache.cxf.message.Message.ENDPOINT_ADDRESS=http://localhost:8080/ws/hello, org.apache.cxf.headers.Header.list=[], org.apache.cxf.service.model.BindingMessageInfo=org.apache.cxf.service.model.BindingMessageInfo@2c5529ab, org.apache.cxf.invocation.context={ResponseContext={}, RequestContext={org.apache.cxf.jaxws.context.WrappedMessageContext.SCOPES={org.apache.cxf.message.Message.ENDPOINT_ADDRESS=APPLICATION}, org.apache.cxf.message.Message.ENDPOINT_ADDRESS=http://localhost:8080/ws/hello, java.lang.reflect.Method=public abstract java.lang.String webservice.impl.HelloService.sayHello(java.lang.String)}}, org.apache.cxf.client=true, client.holders=[null], org.apache.cxf.jaxws.context.WrappedMessageContext.SCOPES={org.apache.cxf.message.Message.ENDPOINT_ADDRESS=APPLICATION}, org.apache.cxf.mime.headers={}, org.apache.cxf.message.inbound=false, org.apache.cxf.ws.policy.EffectivePolicy=org.apache.cxf.ws.policy.EffectivePolicyImpl@39a8312f, java.lang.reflect.Method=public abstract java.lang.String webservice.impl.HelloService.sayHello(java.lang.String), Content-Type=text/xml} Jerry,Welcome to WebService! Process finished with exit code 0
=========================================================================================
假如是用WebService Client根据wsdl生成的代码,就用一下方式添加拦截器
/** * @author WGR * @create 2020/2/14 -- 19:44 */ public class Main { public static void main(String[] args) { HelloServiceImplService h = new HelloServiceImplService(); HelloService hello = h.getHelloServiceImplPort(); Client client = ClientProxy.getClient(hello); //客户端的系统日志出拦截器 List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors(); String u = "wl"; String p = "1985310"; AddHeaderInterceptor a = new AddHeaderInterceptor(u,p); outInterceptors.add(a); outInterceptors.add(new LoggingOutInterceptor()); //客户端的系统日志入拦截器 List<Interceptor<? extends Message>> inInterceptors = client.getInInterceptors(); inInterceptors.add(new LoggingInInterceptor()); String result = hello.sayHello("webService"); System.out.println(result); } }