WebService学习笔记(五)拦截器与SOAP协议

来源:互联网 发布:淘宝2017双11广告视频 编辑:程序博客网 时间:2024/06/05 22:45

Web Service急需解决的问题:如何进行权限控制?

解决思路:

要求Input消息总是携带用户名密码,如果没有,拒绝执行。


如果不用CXF框架,由程序员可自己完成SOAP协议;

如果使用CXF框架,则是由框架定义SOAP协议,为了能够让程序员修改SOAP协议,CXF提供了拦截器。

(一)服务端拦截器:

方式一:Endpoint方式

HelloWorldService service = new HelloWorldServiceImpl();  String address = "http://localhost:8080/hello";    EndpointImpl endpoint = (EndpointImpl)Endpoint.publish(address, service);  endpoint.getInInterceptors().add(new AuthInterceptor());  

方式二:JaxWsServerFactoryBean方式

package com.skymr.hello.ws.pub;import org.apache.cxf.interceptor.LoggingInInterceptor;import org.apache.cxf.interceptor.LoggingOutInterceptor;import org.apache.cxf.jaxws.JaxWsServerFactoryBean;import com.skymr.hello.ws.HelloWorld;import com.skymr.hello.ws.impl.HelloWorldBean;public class ServerMain {public static void main(String[] args){HelloWorld hw = new HelloWorldBean();JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();factory.setServiceClass(HelloWorldBean.class);factory.setAddress("http://192.168.2.102/helloWorld");factory.setServiceBean(hw);factory.getInInterceptors().add(new LoggingInInterceptor());factory.getOutInterceptors().add(new LoggingOutInterceptor());factory.create();System.out.println("Web Service发布成功");}}

import org.apache.cxf.endpoint.Server;import org.apache.cxf.frontend.ServerFactoryBean;... MyInterceptor myInterceptor = new MyInterceptor(); Server server = serverFactoryBean.create();server.getEndpoint().getInInterceptor().add(myInterceptor);

方式三:注解

package com.skymr.hello.ws.impl;import javax.jws.WebService;import org.apache.cxf.interceptor.InInterceptors;import org.apache.cxf.interceptor.OutInterceptors;import com.skymr.hello.ws.HelloWorld;@InInterceptors(interceptors={"org.apache.cxf.interceptor.LoggingInInterceptor","com.skymr.hello.ws.interceptor.AuthInterceptor"})@OutInterceptors(interceptors={"org.apache.cxf.interceptor.LoggingOutInterceptor"})@WebService(endpointInterface="com.skymr.hello.ws.HelloWorld",serviceName="helloWorldws")public class HelloWorldBean implements HelloWorld{public String sayHello(String name) {return "你好"+name+",欢迎进入Web 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"      xmlns:tx="http://www.springframework.org/schema/tx"      xmlns:context="http://www.springframework.org/schema/context"       xmlns:jaxws="http://cxf.apache.org/jaxws"     xmlns:cxf="http://cxf.apache.org/core"    xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd       http://www.springframework.org/schema/tx       http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  http://cxf.apache.org/jaxws   http://cxf.apache.org/schemas/jaxws.xsdhttp://cxf.apache.org/corehttp://cxf.apache.org/schemas/core.xsd    http://www.springframework.org/schema/context      http://www.springframework.org/schema/context/spring-context-3.2.xsd">    <!-- 导入cxf xml配置 -->    <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="hello" class="com.skymr.hello.ws.impl.HelloWorldBean"/>      <bean id="userOperator" class="com.skymr.hello.ws.impl.UserOperatorBean"></bean>    <!-- 先导入命名空间和配置规范http://cxf.apache.org/jaxws   http://cxf.apache.org/schemas/jaxws.xsd     -->    <!-- implementor    可以是类全名,这样的话它的实例是new的,不受spring容器管理,不好    可以引用spring容器里的bean    address    wsdl的相对路径,不能是绝对路径,绝对路径是随服务器地址变动的。     -->    <jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />      <jaxws:endpoint id="userOp" implementor="#userOperator" address="/UserOperator" ></jaxws:endpoint>        <bean id="logInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>    <cxf:bus>    <cxf:inInterceptors>    <ref bean="logInterceptor"/>    </cxf:inInterceptors>    </cxf:bus></beans>

这种方式的拦截器对所有的endpoint都起作用;

还可以这么配置:

    <jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld">    <jaxws:inInterceptors>    <ref bean="logInterceptor"/>    <ref bean="authInterceptor"/>    <bean class=""></bean>    </jaxws:inInterceptors>    </jaxws:endpoint>    <jaxws:endpoint id="userOp" implementor="#userOperator" address="/UserOperator"></jaxws:endpoint>    <!-- 自带的拦截器 -->    <bean id="logInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>    <!-- 自定义拦截器,认证拦截 -->    <bean id="authInterceptor" class="com.skymr.hello.ws.interceptor.AuthInterceptor"></bean>


这样就只对当前的endpoint起作用了。

(二)客户端拦截器:

import org.apache.cxf.endpoint.Client;import org.apache.cxf.frontend.ClientProxy;... MyInterceptor myInterceptor = new MyInterceptor();FooService client = ... ; // created from ClientProxyFactoryBean or generated JAX-WS client //You could also call clientProxyFactroyBean.getInInterceptor().add(myInterceptor) to add the interceptor Client cxfClient = ClientProxy.getClient(client);cxfClient.getInInterceptors().add(myInterceptor); // then you can call the serviceclient.doSomething();

(三)协议分析

为服务端添加LoggingInInterceptor和LoggingOutInterceptor后,可在控制台查看输入输出消息,并分析SOAP协议。

INFO: Inbound Message----------------------------ID: 1Address: http://192.168.2.102/helloWorld?wsdlHttp-Method: GETContent-Type: Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Type=[null], Host=[192.168.2.102], User-Agent=[Java/1.7.0_21]}--------------------------------------九月 12, 2015 9:51:15 上午 org.apache.cxf.services.helloWorldws.HelloWorldBeanPort.HelloWorldINFO: Inbound Message----------------------------ID: 2Address: http://192.168.2.102/helloWorld?wsdl=HelloWorld.wsdlHttp-Method: GETContent-Type: Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Type=[null], Host=[192.168.2.102], User-Agent=[Java/1.7.0_21]}

前两个消息是请求WSDL的

下面的消息才是SOAP消息:

九月 12, 2015 9:51:15 上午 org.apache.cxf.services.helloWorldws.HelloWorldBeanPort.HelloWorldINFO: Inbound Message----------------------------ID: 2Address: http://192.168.2.102/helloWorld?wsdl=HelloWorld.wsdlHttp-Method: GETContent-Type: Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Type=[null], Host=[192.168.2.102], User-Agent=[Java/1.7.0_21]}--------------------------------------九月 12, 2015 9:51:16 上午 org.apache.cxf.services.helloWorldws.HelloWorldBeanPort.HelloWorldINFO: Inbound Message----------------------------ID: 3Address: http://192.168.2.102/helloWorldEncoding: UTF-8Http-Method: POSTContent-Type: text/xml; charset=UTF-8Headers: {Accept=[text/xml, multipart/related], connection=[keep-alive], Content-Length=[202], content-type=[text/xml; charset=UTF-8], Host=[192.168.2.102], SOAPAction=[""], User-Agent=[JAX-WS RI 2.2.4-b01]}Payload: <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:sayHello xmlns:ns2="http://ws.hello.skymr.com/"><arg0>skymr</arg0></ns2:sayHello></S:Body></S:Envelope>--------------------------------------九月 12, 2015 9:51:16 上午 org.apache.cxf.services.helloWorldws.HelloWorldBeanPort.HelloWorldINFO: Outbound Message-----------------------------------------------------------------

sayHello inBound消息

<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:sayHello xmlns:ns2="http://ws.hello.skymr.com/"><arg0>skymr</arg0></ns2:sayHello></S:Body></S:Envelope>

sayHello outBound消息

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHelloResponse xmlns:ns2="http://ws.hello.skymr.com/"><return>你好,skymr,欢迎进入Web Service学习课程</return></ns2:sayHelloResponse></soap:Body></soap:Envelope>

getAllUsers Inbound消息,没有参数标签

<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getAllUsers xmlns:ns2="http://ws.hello.skymr.com/"/></S:Body></S:Envelope>

getAllUsers OutBound消息

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllUsersResponse xmlns:ns2="http://ws.hello.skymr.com/"><return><entryList><key>aaa</key><user><address>aaaAdress</address><id>1</id><password>aaa</password><userName>aaa</userName></user></entryList><entryList><key>ccc</key><user><address>cccAdress</address><id>3</id><password>ccc</password><userName>ccc</userName></user></entryList><entryList><key>bbb</key><user><address>bbbAdress</address><id>2</id><password>bbb</password><userName>bbb</userName></user></entryList></return></ns2:getAllUsersResponse></soap:Body></soap:Envelope>





0 0
原创粉丝点击