05_JAX-WS Handler使用

1.Handler和Servlet中的filter极为相似,我们可以对所有WebServicer进行拦截,在这个Handler中我们可以记录日志、

   权限控制、对请求的SOAP消息进行加密,解密等。CXF也有Interceptor,不知道有什么区别,后面会学习

 

2.接口javax.xml.ws.handler.Handler和javax.xml.ws.handler.soap.SOAPHandler

  定义自己Handler需要实现两个Handler其中一个SOAPHandler是Handler的子接口

  Handler的三个方法

 

 

 

void

 

 

 close(MessageContext context) :一个webService调用结束时会调用,通常会做释放资源的操作
          

 

  boolean 

 

handleFault(C context) :当handlerMessage发生异常时,会调用
          

 

 boolean

 

 handleMessage(C context):调用webService inbound和outbound时都会调用,一次webService调用,

                                           会调用该方法两次

 

 

 

3.实现一个用户身份验证的Handler来说明Handler使用

   3.1定义我们自己Handler

        public class AuthValidationHandler implements SOAPHandler<SOAPMessageContext> {

	public Set<QName> getHeaders() {
		// TODO Auto-generated method stub
		return null;
	}

	public void close(MessageContext context) {
		
	}

	public boolean handleFault(SOAPMessageContext context) {
		return false;
	}

	public boolean handleMessage(SOAPMessageContext context) {
		
		HttpServletRequest request = (HttpServletRequest)context.get(AbstractHTTPDestination.HTTP_REQUEST);
		
		System.out.println("客户端IP:"+request.getRemoteAddr());
		
		Boolean outbound = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 

		  if (!outbound.booleanValue()) 
		  {
			  SOAPMessage soapMessage = context.getMessage();
			  
			  try {
				SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
				SOAPHeader soapHeader = soapEnvelope.getHeader();
				
				if(soapHeader == null)generateSoapFault(soapMessage, "No Message Header...");
				
				Iterator it = soapHeader.extractHeaderElements(SOAPConstants.URI_SOAP_1_2_ROLE_NEXT);
				
				if(it == null || !it.hasNext())generateSoapFault(soapMessage, "No Header block for role next");
				
				Node node = (Node)it.next();
				
				String value = node == null ? null : node.getValue();
				
				if(value == null)generateSoapFault(soapMessage, "No authation info in header blocks");
				
				String[] infos = value.split("&");
				
				return authValidate(infos[0], infos[1]);
				
				
			} catch (SOAPException e) {
				e.printStackTrace();
			}
			  
		  }

		  
		return false;
	}
	
	
	private boolean authValidate(String userName,String password){
		if(userName == null || password == null){
			return false;
		}
		
		if("admin".equals(userName) && "admin".equals(password)){
			return true;
		}
		return false;
	}
	
	private void generateSoapFault(SOAPMessage soapMessage,String reasion){
		try {
			SOAPBody soapBody = soapMessage.getSOAPBody();
			SOAPFault soapFault = soapBody.getFault();
			
			if(soapFault == null){
				soapFault = soapBody.addFault();
			}
			
			soapFault.setFaultString(reasion);
			
			throw new SOAPFaultException(soapFault);
			
		} catch (SOAPException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
}

   HttpServletRequest request = (HttpServletRequest)context.get(AbstractHTTPDestination.HTTP_REQUEST);

   可以获取request对象,从而拿到客户端Ip,可以进行非法地址ip排除

 

  Boolean outbound = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

  判断当前是Inbound还是outbound

  只在inbound时做用户校验

 

  我们将用户相信放在soapheader里

 

   3.2在SEI实现类UserServiceImpl上添加@HandlerChain(file = "handlers.xml")

 

   3.3在UserServiceImpl所在包下编写handlers.xml

       <handler-chains xmlns="http://java.sun.com/xml/ns/javaee"

                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee">
  <handler-chain>

    <handler>
      <handler-name>authHandler</handler-name>
      <handler-class>com.cxf.users.AuthValidationHandler</handler-class>
    </handler>
  </handler-chain>
</handler-chains>

 

  这样我们服务端就编写好了,我们还有在客户端将我们用户信息加到soapHeader中

 

4.客户端将我们用户信息加到soapHeader中

   4.1客户端Handler

        public class AuthenticationHandler implements SOAPHandler<SOAPMessageContext> {

	public Set<QName> getHeaders() {
		// TODO Auto-generated method stub
		return null;
	}

	public void close(MessageContext arg0) {
		// TODO Auto-generated method stub
		
	}

	public boolean handleFault(SOAPMessageContext arg0) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean handleMessage(SOAPMessageContext ctx) {
		Boolean request_p=(Boolean)ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
		
       if(request_p){
           try { 
              SOAPMessage msg=ctx.getMessage();
              SOAPEnvelope env=msg.getSOAPPart().getEnvelope();
              SOAPHeader hdr=env.getHeader();
              
              if(hdr==null)hdr=env.addHeader();
          
              //添加认证信息
              QName qname_user=new QName("http://com/auth/","auth");
              SOAPHeaderElement helem_user=hdr.addHeaderElement(qname_user);
              helem_user.setActor(SOAPConstants.URI_SOAP_1_2_ROLE_NEXT);
              helem_user.addTextNode("admin&admin");
              msg.saveChanges();
              //把SOAP消息输出到System.out,即控制台
              msg.writeTo(System.out);
              return true;
           } catch (Exception e) {
              e.printStackTrace();
           }
       }
	       return false;
	}

	
}

 

  4.2将Handler加到HandlerResolver中

      public class UserClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		UserServiceImplService userServiceImpl = new UserServiceImplService();
		
		userServiceImpl.setHandlerResolver(new HandlerResolver(){

			public List<Handler> getHandlerChain(PortInfo arg0) {
				
				List<Handler> handlerList = new ArrayList<Handler>();
	            //添加认证信息
	            handlerList.add(new AuthenticationHandler());
	              return handlerList;
			}
			
		});
		
		
		IUserService service = userServiceImpl.getUserServiceImplPort();
		
		
		User u = new User();
		u.setId(110);
		u.setUserName("张三");
		u.setAddress("杭州");
		u.setSex(0);
		System.out.println();
		System.out.println(service.addUser(u));
		
	}

}

 

   这样验证就做好了

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值