1, 异常处理
package com.yangw.soap.service; public class UserException extends Exception { public UserException() { super(); } public UserException(String message, Throwable cause) { super(message, cause); } public UserException(String message) { super(message); } public UserException(Throwable cause) { super(cause); } }
为login()方法增加抛异常
package com.yangw.soap.service; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; //说明该接口是服务接口 @WebService public interface IMyService { ...... @WebResult(name="user") public User login(@WebParam(name="username")String username, @WebParam(name="password")String password) throws UserException;
...... }
package com.yangw.soap.service; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.jws.WebService; //说明该类是服务接口的实现类 @WebService(endpointInterface="com.yangw.soap.service.IMyService") public class MyServiceImpl implements IMyService { ...... @Override public User login(String username, String password) throws UserException{ for(User user:users){ if(user.getUserName().equals(username)&&user.getPassword().equals(password)){ return user; } } throw new UserException("用户不存在!"); } ...... }
/** * soap消息传递--测试异常处理 */ @Test public void test06() { try { //1,创建服务 URL url=new URL(wsdlUrl); QName qName=new QName(ns,"MyServiceImplService"); Service service=Service.create(url, qName); //2,创建Dispatch (创建Port的时候指定名称空间) Dispatch<SOAPMessage> dispatch=service.createDispatch(new QName(ns,"MyServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE); //3, 创建SOAPMessage SOAPMessage msg=MessageFactory.newInstance().createMessage(); SOAPEnvelope envelope=msg.getSOAPPart().getEnvelope(); SOAPBody body=envelope.getBody(); //4, 创建QName来指定消息中传递的数据 QName eName=new QName(ns,"login", "nn"); //前缀必须指定,名字可以任意 <nn:add xmlns="XXX" /> SOAPBodyElement bEle=body.addBodyElement(eName);
/*
* 因为username=yang password=wei,这个用户是不存在,因此会抛UserException,
* 这个异常会被SOAPFaultException捕获,Webservice会对他处理,因为服务器不会抛异常出来,而是在我们客户端打印我们的异常信息 “用户不存在!”
* webservice会将我们的异常转换为
* <message name="UserException"><part name="fault" element="tns:UserException"/></message>
*/
bEle.addChildElement("username").setValue("yang"); bEle.addChildElement("password").setValue("wei"); msg.writeTo(System.out); //输出消息到控制台 System.out.println(" invoke ..."); //5, 通过Dispatch传递消息 SOAPMessage resMsg= dispatch.invoke(msg); resMsg.writeTo(System.out); System.out.println(); }catch (SOAPFaultException e) { System.out.println(e.getMessage()); } catch (SOAPException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
控制台打印的信息 如下:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<nn:login xmlns:nn="http://service.soap.yangw.com/">
<username>yang</username>
<password>wei</password>
</nn:login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> invoke ... 用户不存在!
2,Handler处理SOAP消息
LogicalHandler: 只能获取SOAPBody的信息,下面简称 LH;
SOAPHandler: 可以 获取SOAPMessage的信息,下面简称 SH
客户端,服务器端都可以设置若干个 LH SH !
例子:客户端设置了 SH1 LH1 SH2 LH2 LH3,服务端设置了SH2 SH3 LH2 LH3 LH1
那么最终通过的Handler形式是: LH1 LH2 LH3 SH1 SH2 SH2 SH3 LH2 LH3 LH1
需要使用wsimport命令将代码导入到新的工程中!!!
创建SOAPHandler的顺序:
1> 创建一个类实现SOAPHandler接口
2>在handlerMessage()方法中编写相应的处理代码
package com.yangw.soap.service.handler; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; /** * 这里写了一个HeaderHandler类,实现了接口SOAPHandler,需要设置泛型为SOAPMessageContext * @author yangw */ public class HeaderHandler implements SOAPHandler<SOAPMessageContext> { @Override public boolean handleMessage(SOAPMessageContext context) { System.out.println("handler message"); return true; } @Override public boolean handleFault(SOAPMessageContext context) { System.out.println("fault"); return false; } @Override public void close(MessageContext context) { } @Override public Set<QName> getHeaders() { return null; } }
3>配置handler,配置文件名字可以随便起,放到类路径下即可
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <javaee:handler-chain> <javaee:handler> <javaee:handler-class>com.yangw.soap.service.handler.HeaderHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>
handler-chain.xml 文件放置在类路径下即可.
3>在服务上开启过滤器链 @HandlerChain(file="handler-chain.xml")
package com.yangw.soap.service; import javax.jws.HandlerChain; import javax.xml.ws.Service; import javax.xml.ws.WebServiceClient; @WebServiceClient(name = "MyServiceImplService", targetNamespace = "http://service.soap.yangw.com/", wsdlLocation = "http://localhost:8899/ns?wsdl") @HandlerChain(file="handler-chain.xml") public class MyServiceImplService extends Service { ...... }
4>测试类
package com.yangw.soap.service; public class Test { public static void main(String[] args) { MyServiceImplService mis=new MyServiceImplService(); IMyService service=mis.getMyServiceImplPort(); try { /** * 因为后端没有yangw wei 这个用户,因此控制台打印如下: * handler message * fault * 用户不存在! */ service.login("yangw", "123456"); System.out.println("over"); /** * 存在用户 yangw 123456,打印如下: * handler message * handler message * over */ } catch (UserException_Exception e) { System.out.println(e.getMessage()); } } }