web service 过程(cxf)


org.apache.cxf.phase.Phase

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.cxf.phase;

public class Phase implements Comparable {
    
    // can be removed from once defined as default value in configuration metadata for bus
  
    public static final String SETUP = "setup";
    public static final String SETUP_ENDING = "setup-ending";
    public static final String PRE_LOGICAL = "pre-logical";
    public static final String PRE_LOGICAL_ENDING = "pre-logical-ending";
    public static final String USER_LOGICAL = "user-logical";
    public static final String USER_LOGICAL_ENDING = "user-logical-ending";
    public static final String POST_LOGICAL = "post-logical";
    public static final String POST_LOGICAL_ENDING = "post-logical-ending";
    public static final String PRE_MARSHAL = "pre-marshal";
    public static final String MARSHAL = "marshal";
    public static final String POST_MARSHAL = "post-marshal";
    public static final String MARSHAL_ENDING = "marshal-ending";
    public static final String PRE_PROTOCOL = "pre-protocol";
    public static final String PRE_PROTOCOL_FRONTEND = "pre-protocol-frontend";
    public static final String PRE_PROTOCOL_ENDING = "pre-protocol-ending";
    public static final String USER_PROTOCOL = "user-protocol";
    public static final String USER_PROTOCOL_ENDING = "user-protocol-ending";
    public static final String POST_PROTOCOL = "post-protocol";
    public static final String POST_PROTOCOL_ENDING = "post-protocol-ending";
    public static final String PREPARE_SEND = "prepare-send";
    public static final String PREPARE_SEND_ENDING = "prepare-send-ending";
    public static final String PRE_STREAM = "pre-stream";
    public static final String PRE_STREAM_ENDING = "pre-stream-ending";
    public static final String USER_STREAM = "user-stream";
    public static final String USER_STREAM_ENDING = "user-stream-ending";
    public static final String POST_STREAM = "post-stream";
    public static final String POST_STREAM_ENDING = "post-stream-ending";
    public static final String WRITE = "write";
    public static final String WRITE_ENDING = "write-ending";
    public static final String SEND = "send";
    public static final String SEND_ENDING = "send-ending";
   
    public static final String RECEIVE = "receive";
    public static final String READ = "read";
    public static final String PROTOCOL = "protocol";
    public static final String UNMARSHAL = "unmarshal";
    public static final String PRE_INVOKE = "pre-invoke";
    public static final String INVOKE = "invoke";
    public static final String POST_INVOKE = "post-invoke";
    
    
    private String name;
    private int priority;
    
    public Phase() {
    }
    
    public Phase(String n, int p) {
        this.name = n;
        this.priority = p;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String n) {
        this.name = n;
    }
    public int getPriority() {
        return priority;
    }
    public void setPriority(int p) {
        this.priority = p;
    }
    
    public int hashCode() {
        return priority;
    }
    public boolean equals(Object o) {
        Phase p = (Phase)o;
        
        return p.priority == priority
            && p.name.equals(name);
    }

    public int compareTo(Object o) {
        Phase p = (Phase)o;
        
        if (priority == p.priority) {
            return name.compareTo(p.name); 
        }
        return priority - p.priority;
    }
    
    public String toString() {
        return "Phase(" + getName() + ")";
    }
}

cxf 把web service 的过程分为以上很多个片段,下面我们分析一下如何去开发一个cxf拦截器:

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.cxf.phase;

import java.util.Collection;
import java.util.Set;

import javax.xml.stream.XMLStreamReader;

import org.apache.cxf.common.util.SortedArraySet;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;

/**
 * Provides a starting point implementation for a interceptors that 
 * participate in phased message processing. Developers should extend from 
 * this class when implementing custom interceptors.
 * Developers need to provide an implementation for handleMessage() and 
 * can overide the handleFault() implementation. They should not overide 
 * the other methods.
 */
public abstract class AbstractPhaseInterceptor<T extends Message> implements PhaseInterceptor<T> {
    private final String id;
    private final String phase;
    private final Set<String> before = new SortedArraySet<String>();
    private final Set<String> after = new SortedArraySet<String>();

    /**
     * Instantiates the interceptor to live in a specified phase. The 
     * interceptor's id will be set to the name of the implementing class.
     *
     * @param phase the interceptor's phase
     */
    public AbstractPhaseInterceptor(String phase) {
        this(null, phase, false);
    }

    /**
     * Instantiates the interceptor with a specified id.
     *
     * @param i the interceptor's id
     * @param p the interceptor's phase
     */
    public AbstractPhaseInterceptor(String i, String p) {
        this(i, p, false);
    }

    /**
     * Instantiates the interceptor and specifies if it gets a system 
     * determined unique id. If <code>uniqueId</code> is set to true the 
     * interceptor's id will be determined by the runtime. If 
     * <code>uniqueId</code> is set to false, the implementing class' name 
     * is used as the id.
     *
     * @param phase the interceptor's phase
     * @param uniqueId true to have a unique ID generated
     */
    public AbstractPhaseInterceptor(String phase, boolean uniqueId) {
        this(null, phase, uniqueId);
    }

    /**
     * Instantiates the interceptor with a specified id or with a system 
     * determined unique id. The specified id will be used unless 
     * <code>uniqueId</code> is set to true.
     *
     * @param i the interceptor's id
     * @param p the interceptor's phase
     * @param uniqueId
     */
    public AbstractPhaseInterceptor(String i, String p, boolean uniqueId) {
        if (i == null) {
            i = getClass().getName();
        }
        if (uniqueId) {
            i += System.identityHashCode(this);
        }
        id = i;
        phase = p;
    }
    
    /**
     * Specifies that the current interceptor needs to be added to the 
     * interceptor chain before the specified collection of interceptors. 
     * This method replaces any existing list with the provided list.
     * 
     * @param i a collection of interceptor ids
     */
    public void setBefore(Collection<String> i) {
        before.clear();
        before.addAll(i);
    }

    /**
     * Specifies that the current interceptor needs to be added to the 
     * interceptor chain after the specified collection of interceptors.
     * This method replaces any existing list with the provided list.
     * 
     * @param i a collection of interceptor ids
     */
    public void setAfter(Collection<String> i) {
        after.clear();
        after.addAll(i);
    }

    /**
     * Specifies that the current interceptor needs to be added to the 
     * interceptor chain before the specified collection of interceptors.
     * 
     * @param i a collection of interceptor ids
     */
    public void addBefore(Collection<String> i) {
        before.addAll(i);
    }

    /**
     * Specifies that the current interceptor needs to be added to the 
     * interceptor chain after the specified collection of interceptors.
     * 
     * @param i a collection of interceptor ids
     */
    public void addAfter(Collection<String> i) {
        after.addAll(i);
    }
    
    /**
     * Specifies that the current interceptor needs to be added to the 
     * interceptor chain before the specified interceptor.
     * 
     * @param i an interceptor id
     */
    public void addBefore(String i) {
        before.add(i);
    }

    /**
     * Specifies that the current interceptor needs to be added to the 
     * interceptor chain after the specified interceptor.
     * 
     * @param i an interceptor id
     */
    public void addAfter(String i) {
        after.add(i);
    }


    public final Set<String> getAfter() {
        return after;
    }

    public final Set<String> getBefore() {
        return before;
    }
    
    public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors() {
        return null;
    }

    public final String getId() {
        return id;
    }

    public final String getPhase() {
        return phase;
    }


    public void handleFault(T message) {
    }

    public boolean isGET(T message) {
        String method = (String)message.get(Message.HTTP_REQUEST_METHOD);
        return "GET".equals(method) && message.getContent(XMLStreamReader.class) == null;
    }
    
    /**
     * Determine if current messaging role is that of requestor.
     * 
     * @param message the current Message
     * @return true if the current messaging role is that of requestor
     */
    protected boolean isRequestor(T message) {
        return MessageUtils.isRequestor(message);
    }  

}

 

AbstractPhaseInterceptor 类中有如下构造器,

 public AbstractPhaseInterceptor(String phase) {
        this(null, phase, false);
    }

    /**
     * Instantiates the interceptor with a specified id.
     *
     * @param i the interceptor's id
     * @param p the interceptor's phase
     */
    public AbstractPhaseInterceptor(String i, String p) {
        this(i, p, false);
    }

    /**
     * Instantiates the interceptor and specifies if it gets a system 
     * determined unique id. If <code>uniqueId</code> is set to true the 
     * interceptor's id will be determined by the runtime. If 
     * <code>uniqueId</code> is set to false, the implementing class' name 
     * is used as the id.
     *
     * @param phase the interceptor's phase
     * @param uniqueId true to have a unique ID generated
     */
    public AbstractPhaseInterceptor(String phase, boolean uniqueId) {
        this(null, phase, uniqueId);
    }

    /**
     * Instantiates the interceptor with a specified id or with a system 
     * determined unique id. The specified id will be used unless 
     * <code>uniqueId</code> is set to true.
     *
     * @param i the interceptor's id
     * @param p the interceptor's phase
     * @param uniqueId
     */
    public AbstractPhaseInterceptor(String i, String p, boolean uniqueId) {
        if (i == null) {
            i = getClass().getName();
        }
        if (uniqueId) {
            i += System.identityHashCode(this);
        }
        id = i;
        phase = p;
    }

  

    

      AbstractPhaseInterceptor 类中的private final String phase; 属性,是确定这个拦截器是在过程的哪个阶段拦截的,所有我们在创建拦截器是一定要指定phase 过程。


  cxf中的所有自定义拦截器都必须继承于AbstractPhaseInterceptor

 LoggingInInterceptor (系统日志入拦截器)

  LoggingOutInterceptor (系统日志出拦截器)


 webservice 服务器端获取拦截器集合

String address="http://192.168.70.51:8888/ws/dataws";
		Endpoint endpoint=Endpoint.publish(address, new DataTypeWSImpl());
		System.out.println(endpoint);
		EndpointImpl endpointImpl=(EndpointImpl)endpoint;
		//获取拦截器链
		List<Interceptor<? extends Message>> inInterceptors=endpointImpl.getInInterceptors();
		//添加服务器端日志入拦截器
		inInterceptors.add(new LoggingInInterceptor());
		System.out.println("web service 发布成功");


webservice 客户端获取拦截器集合:

DataTypeWSImplService factory=new DataTypeWSImplService();
DataTypeWS ws=factory.getDataTypeWSImplPort();
Client client=ClientProxy.getClient(ws);
List<Interceptor<? extends Message>> outIntercepter=client.getOutInterceptors();
outIntercepter.add(new LoggingOutInterceptor());
List<Interceptor<? extends Message>> inIntercepter=client.getInInterceptors();
inIntercepter.add(new LoggingInInterceptor());


 自定义拦截器:


服务器端拦截器:


  a. 编写一个类继承AbstractPhaseInterceptor<SoapMessage>,并且实现 public void handleMessage(SoapMessage msg) throws Fault 方法,在里面实现拦截的业务逻辑


   注意,在自定拦截器中必须要指定父类的phase属性的值:

public CheckUserInterceptor() {
		super(Phase.PRE_PROTOCOL);
	}



package com.mscncn.ws.sayhi.interceptor;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;

public class CheckUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	public CheckUserInterceptor() {
		super(Phase.PRE_PROTOCOL);
	}

	public void handleMessage(SoapMessage msg) throws Fault {
		Header header=msg.getHeader(new QName("mscncn"));
		if(header!=null){
			Element rootEle=(Element) header.getObject();
			String name=rootEle.getElementsByTagName("name").item(0).getTextContent();
			String password=rootEle.getElementsByTagName("password").item(0).getTextContent();
			if(name.equals("zs")&&password.equals("123456")){
				System.out.println(" Service 通过了拦截器");
			}
		}
		//没有通过
		System.out.println("Service 没有通过拦截器");
	}

}


 b. 拦截器写好了,那么就需要在服务器端注册,然后才能使用:

String address="http://192.168.70.51:1111/day01_ws/hellows";
		Endpoint point=Endpoint.publish(address, new HelloWSImpl());
		EndpointImpl endpointImpl=(EndpointImpl)point;
		//获取服务器端入拦截器链
		List<Interceptor<? extends Message>> inTerceptors=endpointImpl.getInInterceptors();
		//注册自定义拦截器
		inTerceptors.add(new CheckUserInterceptor());
		System.out.println("web service 发布成功!");


服务器端入(in)拦截器的原理就是检查客服端的out拦截器是否符合规定

客户端(out)-> 服务端(in)->处理业务->服务端(out)->客户端(in),并不是每一步都需要拦截器。在这里我们用到的是客户端Out拦截器和服务端in拦截器。服务端in拦截器判断是否符合规范,客户端out浏览器发送用户信息给服务端。


客户端通过消息头的信息发送信息给服务器端in拦截器:

<Envelope>
	<head>
		<mscncn>
		 	<name></name>
		 	<password></password>
		</mscncn> 		
	</head>	 	
	<!--请求体-->
	<body>	 	
		<!--方法名-->
		<sayHello>
		 	<!--方法参数-->
		 	<arg0>tom</arg0>
		</sayHello>
	</body>
</Envelope>	 	 





转载于:https://my.oschina.net/KingPan/blog/314205

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值