05_JAX-WS Handler使用


1.Handlerはサーブレットのfilterと非常に似ており、すべてのWebServicerをブロックできます.このHandlerではログを記録できます.
権限制御、要求されたSOAPメッセージの暗号化、復号化などを行う.CXFもInterceptorがあって、どんな区别があることを知らないで、后で学ぶことができます
 
2.インタフェースjavax.xml.ws.handler.Handlerとjavax.xml.ws.handler.soap.SOAPHandler
自分のHandlerを定義するには、2つのHandlerを実装する必要があります.そのうちの1つのSOAPHandlerはHandlerのサブインタフェースです.
Handlerの3つの方法
 
   
void
     close(MessageContext context):1つのウェブサービス呼び出しが終了すると呼び出され、通常はリソースを解放する操作が行われます.  boolean    handleFault(C context):handlerMessageに異常が発生した場合に呼び出されます boolean    handleMessage(C context): webService inbound outbound , webService ,
メソッドが2回呼び出されます
 
 
 
3.Handlerの使用を説明するために、ユーザ認証を実装するHandler
3.1我々自身を定義するHandler
        public class AuthValidationHandler implements SOAPHandler {
	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
        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 {
	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));
		
	}

}

 
これで検証できます