在接受soap消息的时候,可能需要对消息做预处理!可以使用拦截器实现这一目的!
cxf有2种拦截器,InInterceptor、OutInterceptor,顾名思义,InInterceptor可以处理soap请求消息,OutInterceptor可以处理soap响应消息。
所有的拦截器都继承自AbstractPhaseInterceptor<?>,此抽象拦截器实现了Interceptor接口!
可以通过注解和配置文件2种方式来启用自定义的拦截器。
先来看一个InInterceptor
package XXX.web.webservice.interceptor;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.log4j.Logger;
public class ArtifactInInterceptor extends AbstractPhaseInterceptor<Message> {
private static final Logger log = Logger.getLogger(ArtifactInInterceptor.class);
public ArtifactInInterceptor() {
//这儿使用receive,接收的意思
super(Phase.RECEIVE);
}
public void handleMessage(Message message){
try {
InputStream is = message.getContent(InputStream.class);
//这里可以对流做处理,从流中读取数据,然后修改为自己想要的数据
//处理完毕,写回到message中
//在这里需要注意一点的是,如果修改后的soap消息格式不符合webservice框架格式,比如:框架封装后的格式为
//<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" <soap:Body>
//<这里是调用服务端方法的命名空间><这是参数名称>
//这里才是真正的消息
//</这里是调用服务端方法的命名空间></这是参数名称>
//</soap:Body>
//</soap:Envelope>
//如果是以上这种格式,在暴露的接口方法里才会真正接收到消息,而如果请求中在body里边,没有加方法命名空间和参数名称,直接就是消息体
//那接口方法里是接收不到消息的,因为cxf是按照上面的这种格式去解析的,所以如果不符合上面的格式,就应该在这里做处理
//……………………处理代码……………………
if(is != null)
message.setContent(InputStream.class, is);
} catch (Exception e) {
log.error("Error when split original inputStream. CausedBy : "+"\n"+e);
}
}
}
然后使用注解@InInterceptors(interceptors="XXX.ArtifactInInterceptor")加到实现类上。
InInterceptor相比OutInterceptor来说简单多了,我在使用OutInterceptor的时候,始终从流里边读不到数据,官网上没有例子,网上也搜了好多好多,最后在一个国外的论坛上搜到了,使用方式如下:
package XXX.web.webservice.interceptor;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.log4j.Logger;
public class ArtifactOutInterceptor extends AbstractPhaseInterceptor<Message>{
private static final Logger log = Logger.getLogger(ArtifactOutInterceptor.class);
public ArtifactOutInterceptor() {
//这儿使用pre_stream,意思为在流关闭之前
super(Phase.PRE_STREAM);
}
public void handleMessage(Message message) {
try {
OutputStream os = message.getContent(OutputStream.class);
CachedStream cs = new CachedStream();
message.setContent(OutputStream.class, cs);
message.getInterceptorChain().doIntercept(message);
CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);
InputStream in = csnew.getInputStream();
String xml = IOUtils.toString(in);
//这里对xml做处理,处理完后同理,写回流中
IOUtils.copy(new ByteArrayInputStream(xml.getBytes()), os);
cs.close();
os.flush();
message.setContent(OutputStream.class, os);
} catch (Exception e) {
log.error("Error when split original inputStream. CausedBy : " + "\n" + e);
}
}
private class CachedStream extends CachedOutputStream {
public CachedStream() {
super();
}
protected void doFlush() throws IOException {
currentStream.flush();
}
protected void doClose() throws IOException {
}
protected void onWrite() throws IOException {
}
}
}
然后使用注解@OutInterceptors(interceptors="XXX.ArtifactOutInterceptor")加到实现类上。
cxf框架中,有默认的拦截器链,可以使用addAfter()和addBefore()方法来指定自己的拦截器放到什么位置。
分享到:
相关推荐
08.CXF拦截器的理论以及如何为CXF的客户端和服务器端添加拦截器
讲解了cxf实现拦截器的原因、核心API及使用方法
Cxf拦截器示例的源码,包含客户端和服务器端的内容。
CXF3.0 Spring3.2 自定义拦截器
CXF使用EndpointImpl发布WebService加入拦截器
11.为CXF客户端添加自定义拦截器完成权限控制
Web Service学习-CXF开发Web Service的权限控制(二)
spring4+cxf3,因为自己项目要用到接口开发,所以综合现有网上所有教程,终于成功写出能自动注入的demo,这个是含拦截器
webservice拦截器demo-服务端和调用端
10.为CXF服务器端添加自定义拦截器进行权限检查
包含表结构(mysql表创建语句),字段说明与使用;拦截器代码(可根据业务进行修改);
webservice的cxf框架拦截器demo.rar
CXF发布WebService加入拦截器
本文根据java代理实现CXF拦截器异常时只能进入fault拦截器而不能继续向下执行的问题。 利用java代理让RMI具有拦截器的功能。
13.为CXF与Spring整合发布WebService添加拦截器进行权限控制
CXF 自定义拦截器实现的 webservice安全机制实例工程, 带jar包 ,代码注释详细 内有说明文档, 由于资源过大 ,所以客户端jar包 删除掉了, 只需要把服务端的jar 拷贝到 客户端即可 , 小弟刚刚研究完 CXF 安全 。...
CXF-拦截器-权限控制-登录校验
CXF spring 提供rest服务输出xml或json等格式数据
注册自定义拦截器,添加拦截路径和排除拦截路径WebAppConfig
实现了客户端和服务端,客户端添加header服务端获取验证!