CXF-06:Web Service暴露后如何进行权限控制,CXF拦截器的理论以及如何为CXF的客户端和服务器端添加拦截器

Web Service暴露后所有人都可以调用,如何进行权限控制?
解决思路是:服务器端要求input消息总是携带有用户名、密码信息,————如果没有或不正确,拒绝调用。
         * 如果不用CXF等框架,SOAP消息的生成、解析都是程序员负责的,因此无论是添加用户名、密码信息,还是提取用户名、密码信息,都可由程序员的代码完成;
         * 如果用CXF等框架,SOAP消息的生成、解析都是CXF等框架来完成的,为了让程序员能访问并修改CXF框架所生成的SOAP消息,CXF提供了拦截器;
         

          * 服务器端添加拦截器:

         * 1 . 获取Endpoint的publish方法返回值;

         * 2 . 调动该方法的返回值的 getInInterceptors()、getOutInterceptors() 方法获取In、Out拦截器列表,接下来添加拦截器;

                 在本文里不写自己的拦截器,CXF已经提供了很多拦截器,但CXF的API文档中一些类是没有的,查文档查不到但实际上是有的。

         操作 - 在暴露Web Service的main接口里直接修改代码增加拦截:

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.xml.ws.Endpoint;
import org.fjava.cxf.ws.HelloWorld;
import org.fjava.cxf.ws.impl.HelloWorldWs;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;
//发布Web Service
public class ServiceMain {
	public static void main(String[] args) throws IOException{
		HelloWorld hw = new HelloWorldWs();
		//调用Endpoint的publish("本机地址","服务的提供者:一个Web Service对象")方法发布Web Service
		//注:若导入的包报错或无此类,则是jar包没有Build Path,选中所有jar包->右击->选中Build Path->Add to build Path
		//或右击项目->Properties->Java Build Path->Libraries->Add JARs->选则本项目lib下的所有显示jar包->OK->OK
		EndpointImpl ep = (EndpointImpl) Endpoint.publish("http://192.168.0.159:6786/sayHello", hw);
		//添加In拦截器//in.txt文件位置:该项目的路径//因为IO缓存问题没有刷新出来,文件里暂时没有内容
		ep.getInInterceptors().add(new LoggingInInterceptor(new PrintWriter(new FileWriter("in.txt"))));
		//添加Out拦截器//LoggingInInterceptor()把传入的消息以日志的形式记录下来,如果是空参数则打印到控制台
		ep.getOutInterceptors().add(new LoggingOutInterceptor());
		System.out.println("Web Service暴露成功!");
		//暴露成功后可以被任何平台的任何语言调用
		//检查调用地址http://192.168.*.*/sayHello?wsdl
	}
}
         返回结果:

         

         后台输出信息:

十月 15, 2016 11:22:49 下午 org.apache.cxf.interceptor.AbstractLoggingInterceptor log
信息: Outbound Message
---------------------------
ID: 3
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllFoodsResponse xmlns:ns2="http://ws.cxf.fjava.org/"><return><entries><key>蟹王汉堡</key><value><describe>橙色,亮金色,我的宝贝,我的爱!</describe><id>3</id><name>蟹王汉堡</name></value></entries><entries><key>海绵金币</key><value><describe>吃着金币样的甜甜饼,想着海绵宝宝赚的钱被扣了,哈哈哈,爽气!</describe><id>4</id><name>海绵金币</name></value></entries><entries><key>一个汉堡</key><value><describe>是三层的,有夹层哦!</describe><id>1</id><name>一个汉堡</name></value></entries><entries><key>火腿肠</key><value><describe>这是章鱼哥从岸上偷运来的,据说很美味!</describe><id>2</id><name>火腿肠</name></value></entries></return></ns2:getAllFoodsResponse></soap:Body></soap:Envelope>
--------------------------------------

         * 客户端添加拦截器:
         * 1 . 调用ClientProxy的getClient()方法,调用该方法以远程Web Service的代理为参数;

         * 2 . 调用Client对象的getInInterceptors()、getOutInterceptors()方法来获取In、Out拦截器列表;

client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());

import java.util.List;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.fjava.cxf.ws.Cat;
import org.fjava.cxf.ws.Entry;
import org.fjava.cxf.ws.Food;
import org.fjava.cxf.ws.HelloWorld;
import org.fjava.cxf.ws.StringFood;
import org.fjava.cxf.ws.User;
import org.fjava.cxf.ws.impl.HelloWorldWs;
public class ClientMain {
	public static void main(String[] args) {
		//这是命令生成的类,该类的实例可当成工厂来使用
		HelloWorldWs factory = new HelloWorldWs();
		//无参的方法,返回的是远程Web Service服务端的代理,服务端不能关闭。
		HelloWorld helloWorld = factory.getHelloWorldWsPort();
		Client client = ClientProxy.getClient(helloWorld);
		client.getInInterceptors().add(new LoggingInInterceptor());
		client.getOutInterceptors().add(new LoggingOutInterceptor());
		StringFood allFoods = helloWorld.getAllFoods();
		List<Entry> entries = allFoods.getEntries();
		for (Entry entry : entries) {
			System.out.println(entry.getKey() + " " + entry.getValue().getDescribe());
		}
	}
}
         返回结果:
十月 23, 2016 7:24:09 下午 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
信息: Creating Service {http://impl.ws.cxf.fjava.org/}HelloWorldWs from WSDL: http://192.168.0.159:6786/sayHello?wsdl
十月 23, 2016 7:24:10 下午 org.apache.cxf.interceptor.AbstractLoggingInterceptor log
信息: Outbound Message
---------------------------
ID: 1
Address: http://192.168.0.159:6786/sayHello
Encoding: UTF-8
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=[""]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllFoods xmlns:ns2="http://ws.cxf.fjava.org/"/></soap:Body></soap:Envelope>
--------------------------------------
十月 23, 2016 7:24:10 下午 org.apache.cxf.interceptor.AbstractLoggingInterceptor log
信息: Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml;charset=UTF-8
Headers: {Content-Length=[885], content-type=[text/xml;charset=UTF-8], Server=[Jetty(7.4.2.v20110526)]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllFoodsResponse xmlns:ns2="http://ws.cxf.fjava.org/"><return><entries><key>蟹王汉堡</key><value><describe>橙色,亮金色,我的宝贝,我的爱!</describe><id>3</id><name>蟹王汉堡</name></value></entries><entries><key>海绵金币</key><value><describe>吃着金币样的甜甜饼,想着海绵宝宝赚的钱被扣了,哈哈哈,爽气!</describe><id>4</id><name>海绵金币</name></value></entries><entries><key>一个汉堡</key><value><describe>是三层的,有夹层哦!</describe><id>1</id><name>一个汉堡</name></value></entries><entries><key>火腿肠</key><value><describe>这是章鱼哥从岸上偷运来的,据说很美味!</describe><id>2</id><name>火腿肠</name></value></entries></return></ns2:getAllFoodsResponse></soap:Body></soap:Envelope>
--------------------------------------
蟹王汉堡 橙色,亮金色,我的宝贝,我的爱!
海绵金币 吃着金币样的甜甜饼,想着海绵宝宝赚的钱被扣了,哈哈哈,爽气!
一个汉堡 是三层的,有夹层哦!
火腿肠 这是章鱼哥从岸上偷运来的,据说很美味!

希望对你有帮助,祝你有一个好心情,加油!

若有错误、不全、可优化的点,欢迎纠正与补充;转载请注明出处!


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将CXF SOAP消息中的`<SOAP-ENV:Header>`转换成`<SOAP-ENV:Header>`,可以使用CXF提供的拦截器来实现。 首先,创建一个拦截器类,继承自AbstractSoapInterceptor类,并实现handleRequest和handleResponse方法。在handleRequest方法中,将CXF SOAP消息中的`<SOAP-ENV:Header>`节点替换为`<SOAP-ENV:Header>`节点;在handleResponse方法中,将`<SOAP-ENV:Header>`节点替换为`<SOAP-ENV:Header>`节点。 ```java public class SoapHeaderInterceptor extends AbstractSoapInterceptor { public SoapHeaderInterceptor() { super(Phase.PRE_PROTOCOL); } @Override public void handleMessage(SoapMessage message) throws Fault { // 获取SOAP消息的头部 Header header = message.getHeaders().get(0); // 获取SOAP消息的DOM节点 Element headerElement = (Element) header.getObject(); // 创建新的SOAP消息头节点 Element newHeaderElement = headerElement.getOwnerDocument().createElementNS("http://schemas.xmlsoap.org/soap/envelope/", "SOAP-ENV:Header"); // 复制原来的SOAP消息头节点的所有子节点到新的SOAP消息头节点中 NodeList childNodes = headerElement.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { newHeaderElement.appendChild(headerElement.getOwnerDocument().importNode(childNodes.item(i), true)); } // 将新的SOAP消息头节点替换原来的SOAP消息头节点 header.setObject(newHeaderElement); } @Override public void handleFault(SoapMessage message) { // do nothing } } ``` 然后,在CXF服务端和客户端的配置文件中,添加拦截器: ```xml <jaxws:endpoint id="exampleService" implementor="com.example.ExampleServiceImpl" address="/exampleService"> <jaxws:inInterceptors> <bean class="com.example.SoapHeaderInterceptor" /> </jaxws:inInterceptors> </jaxws:endpoint> <jaxws:client id="exampleClient" serviceClass="com.example.ExampleService" address="http://localhost:8080/exampleService"> <jaxws:outInterceptors> <bean class="com.example.SoapHeaderInterceptor" /> </jaxws:outInterceptors> </jaxws:client> ``` 这样,在CXF SOAP消息发送和接收时,就可以将`<SOAP-ENV:Header>`转换成`<SOAP-ENV:Header>`了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值