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

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.xsd
	http://cxf.apache.org/core
	http://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 service
client.doSomething();

(三)协议分析

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

INFO: Inbound Message
----------------------------
ID: 1
Address: http://192.168.2.102/helloWorld?wsdl
Http-Method: GET
Content-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.HelloWorld
INFO: Inbound Message
----------------------------
ID: 2
Address: http://192.168.2.102/helloWorld?wsdl=HelloWorld.wsdl
Http-Method: GET
Content-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.HelloWorld
INFO: Inbound Message
----------------------------
ID: 2
Address: http://192.168.2.102/helloWorld?wsdl=HelloWorld.wsdl
Http-Method: GET
Content-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.HelloWorld
INFO: Inbound Message
----------------------------
ID: 3
Address: http://192.168.2.102/helloWorld
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {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.HelloWorld
INFO: 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值