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 stubreturn 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 blocke.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 stubreturn null;}public void close(MessageContext arg0) {// TODO Auto-generated method stub}public boolean handleFault(SOAPMessageContext arg0) {// TODO Auto-generated method stubreturn 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));}}?
?? 这样验证就做好了
?
?
?
?
?