大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > Java技巧 > java CXF之Interceptors拦截器的编写与配置

java CXF之Interceptors拦截器的编写与配置

关键词:JavajavaCXFjavaCXF之Interce  阅读(655) 赞(14)

[摘要]本文主要是对java CXF之Interceptors拦截器的编写与配置的讲解,希望对大家学习java CXF之Interceptors拦截器的编写与配置有所帮助。

    1.  Interceptors and Phases(拦截器与阶段)
   
    Interceptors是CXF内部的根本处理单元。当服务被调用时,一个InterceptorChain被创建并调用。每一个interceptor都有机会做他们想要处理的消息。包括:读取,转化,处理头部,验证消息 ,等。
   
    Interceptors可以用于CXF的客户端和服务端。当一个CXF客户端调用一个CXF服务端的时候,客户端有一个传出的interceptor链,服务端有一个传入的interceptor链。当服务端发送响应给客户端时,服务端有一个传出的interceptor链,客户端有一个传入的interceptor链。此外,在SOAPFaults情况下,一个CXF web服务将创建单独的对外输出错误处理链,客户端将创建一个传入的错误处理链。
    
    InterceptorChains被划分成阶段。每个阶段可以包含许多interceptors. 在传入链中,你将有以下几个阶段:
   
    Phase ---------------------------------------------Functions
   
    -----------------------------------------------------------------------------------------------------------------
   
    RECEIVE ------------------------------------------Transport level processing
   
    (PRE/USER/POST)_STREAM --------------------Stream level processing/transformations
   
    READ ----------------------------------------------This is where header reading typically occurs.
   
    (PRE/USER/POST)_PROTOCOL ----------------Protocol processing, such as JAX-WS SOAP handlers
   
    UNMARSHAL --------------------------------------Unmarshalling of the request
   
    (PRE/USER/POST)_LOGICAL -------------------Processing of the umarshalled request
   
    PRE_INVOKE --------------------------------------Pre invocation actions
   
    INVOKE --------------------------------------------Invocation of the service
   
    POST_INVOKE ------------------------------------Invocation of the outgoing chain if there is one
   
    传出链中,也有几个阶段:
   
    Phase Functions
   
    ----------------------------------------------------------------------------------------------------------------
   
    SETUP ----------------------------------------------Any set up for the following phases
   
    (PRE/USER/POST)_LOGICAL -------------------Processing of objects about to marshalled
   
    PREPARE_SEND ----------------------------------Opening of the connection
   
    PRE_STREAM
   
    PRE_PROTOCOL ----------------------------------Misc protocol actions.
   
    WRITE ----------------------------------------------Writing of the protocol message, such as the SOAP Envelope.
   
    MARSHAL -------------------------------------------Marshalling of the objects
   
    (USER/POST)_PROTOCOL -----------------------Processing of the protocol message.
   
    (USER/POST)_STREAM ---------------------------Processing of the byte level message
   
    SEND ------------------------------------------------Final sending of message and closing of transport stream
   
    2. InterceptorProviders
   
    CXF包含的几个不同的组件可以提供将interceptors放到InterceptorChain中。 它们实现了InterceptorProvider接口:
   
    public interface InterceptorProvider {
   
    List<Interceptor> getInInterceptors();
   
    List<Interceptor> getOutInterceptors();
   
    List<Interceptor> getOutFaultInterceptors();
   
    List<Interceptor> getInFaultInterceptors();
   
    }
   
    添加一个interceptor到一个interceptor链,你只需要把它添加到一个InterceptorProviders:
   
    MyInterceptor interceptor = new MyInterceptor();
   
    provider.getInInterceptors()。add(interceptor);
   
    CXF包含的一些InterceptorProviders是:
   
    . Client
   
    . Endpoint
   
    . Service
   
    . Bus
   
    . Binding
   


    3. 编写并配置一个Interceptor
   
    编写一个Interceptor
   
    写一个拦截器是相对简单的。你的interceptor需要继承AbstractPhaseInterceptor或者它的许多子类,例如AbstractSoapInterceptor.
   
    从AbstractPhaseInterceptor继承,允许你的interceptor访问消息接口的方法 .如例:
   
    import java.io.IOException;
   
    import org.apache.cxf.attachment.AttachmentDeserializer;
   
    import org.apache.cxf.message.Message;
   
    import org.apache.cxf.phase.AbstractPhaseInterceptor;
   
    import org.apache.cxf.phase.Phase;
   
    public class AttachmentInInterceptor extends AbstractPhaseInterceptor<Message> {
   
    public AttachmentInInterceptor() {
   
    super(Phase.RECEIVE);
   
    }
   
    public void handleMessage(Message message) {
   
    String contentType = (String) message.get(Message.CONTENT_TYPE);
   
    if (contentType != null && contentType.toLowerCase()。indexOf(“multipart/related”) != -1) {
   
    AttachmentDeserializer ad = new AttachmentDeserializer(message);
   
    try {
   
    ad.initializeAttachments();
   
    } catch (IOException e) {
   
    throw new Fault(e);
   
    }
   
    }
   
    }
   
    public void handleFault(Message messageParam) {
   
    }
   
    }
   
    继承自AbstractPhaseInterceptor的子类,允许你的interceptor访问比在Message接口中更多的信息。AbstractSoapInterceptor是AbstractPhaseInterceptor的子类。继承自这个类,允许你的interceptor访问SoapMessage类的SOAP头和版本消息。如例:
   
    import java.util.Collection;
   
    import java.util.List;
   
    import java.util.Map;
   
    import org.apache.cxf.binding.soap.Soap11;
   
    import org.apache.cxf.binding.soap.Soap12;
   
    import org.apache.cxf.binding.soap.SoapMessage;
   
    import org.apache.cxf.binding.soap.model.SoapOperationInfo;
   
    import org.apache.cxf.endpoint.Endpoint;
   
    import org.apache.cxf.helpers.CastUtils;
   
    import org.apache.cxf.interceptor.Fault;
   
    import org.apache.cxf.message.Exchange;
   
    import org.apache.cxf.message.Message;
   
    import org.apache.cxf.phase.Phase;
   
    import org.apache.cxf.service.model.BindingOperationInfo;
   
    import org.apache.cxf.service.model.OperationInfo;
   
    public class SoapActionInInterceptor extends AbstractSoapInterceptor {
   
    public SoapActionInInterceptor() {
   
    super(Phase.READ);
   
    addAfter(ReadHeadersInterceptor.class.getName());
   
    addAfter(EndpointSelectionInterceptor.class.getName());
   
    }
   
    public void handleMessage(SoapMessage message) throws Fault {
   
    if (message.getVersion() instanceof Soap11) {
   
    Map<String, List<String》 headers = CastUtils.cast((Map)message.get(Message.PROTOCOL_HEADERS));
   
    if (headers != null) {
   
    List<String> sa = headers.get(“SOAPAction”);
   
    if (sa != null && sa.size() > 0) {
   
    String action = sa.get(0);
   
    if (action.startsWith(“/”“)) {
   
    action = action.substring(1, action.length() - 1);
   
    }
   
    getAndSetOperation(message, action);
   
    }
   
    }
   
    } else if (message.getVersion() instanceof Soap12) {
   
    ……
   
    }
   
    }
   
    private void getAndSetOperation(SoapMessage message, String action) {
   
    if (”“.equals(action)) {
   
    return;
   
    }
   
    Exchange ex = message.getExchange();
   
    Endpoint ep = ex.get(Endpoint.class);
   
    BindingOperationInfo bindingOp = null;
   
    Collection<BindingOperationInfo> bops = ep.getBinding()。getBindingInfo()。getOperations();
   
    for (BindingOperationInfo boi : bops) {
   
    SoapOperationInfo soi = (SoapOperationInfo) boi.getExtensor(SoapOperationInfo.class);
   
    if (soi != null && soi.getAction()。equals(action)) {
   
    if (bindingOp != null) {
   
    //more than one op with the same action, will need to parse normally
   
    return;
   
    }
   
    bindingOp = boi;
   
    }
   
    }
   
    if (bindingOp != null) {
   
    ex.put(BindingOperationInfo.class, bindingOp);
   
    ex.put(OperationInfo.class, bindingOp.getOperationInfo());
   
    }
   
    }
   
    }
   
    你还可以在拦截器运行前/后在同一阶段定义某些其它拦截器:
   
    public class MyInterceptor extends AbstractSoapInterceptor{
   
    public MyInterceptor(){
   
    super(Phase.USER_PROTOCOL);
   
    }
   
    …
   
    }
   
    可以添加interceptors到interceptor链中,通过编程方式 或 配置方式。 ----略。



相关评论