服务器端代码:
package org.sid.service; import java.util.List; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; @WebService(targetNamespace="http://www.sid.com/webservice") public interface IMyService { @WebResult(name="add") public int add(@WebParam(name="a")int a,@WebParam(name="b")int b); @WebResult(name="user") public User addUser(@WebParam(name="user")User user); @WebResult(name="user") public User login(@WebParam(name="username")String username, @WebParam(name="password")String password) throws UserException; /** * 设置验证信息 * 并且验证信息已头的方式来进行传递,不通过body来传递 * @param authInfo * @return */ @WebResult(name="user") public List<User> list(@WebParam(header=true,name="authInfo")String authInfo); }
package org.sid.service; import java.util.ArrayList; import java.util.List; import javax.jws.HandlerChain; import javax.jws.WebService; @WebService(targetNamespace="http://www.sid.com/webservice",endpointInterface="org.sid.service.IMyService") @HandlerChain(file="handler_chain.xml") public class MyServiceImpl implements IMyService { private static List<User> users = new ArrayList<User>(); public MyServiceImpl(){ users.add(new User(1, "admin", "管理员", "admin")); } @Override public int add(int a, int b) { System.out.println("a+b="+(a+b)); return a+b; } @Override public User addUser(User user) { users.add(user); return user; } @Override public User login(String username, String password) throws UserException{ for (User user : users) { if (username.equals(user.getUsername())&&password.equals(user.getPassword())) { return user; } } throw new UserException("用户不存在"); } @Override public List<User> list(String authInfo) { System.out.println(authInfo); return users; } }
package org.sid.service; import javax.xml.ws.Endpoint; public class MyServer { public static void main(String[] args) { Endpoint.publish("http://localhost:8989/ms", new MyServiceImpl()); } }
package org.sid.service; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class User { private int id; private String username; private String nickname; private String password; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public User(int id, String username, String nickname, String password) { super(); this.id = id; this.username = username; this.nickname = nickname; this.password = password; } public User() { super(); } }
package org.sid.service; public class UserException extends Exception { public UserException() { super(); } public UserException(String arg0, Throwable arg1, boolean arg2, boolean arg3) { super(arg0, arg1, arg2, arg3); } public UserException(String arg0, Throwable arg1) { super(arg0, arg1); } public UserException(String arg0) { super(arg0); } public UserException(Throwable arg0) { super(arg0); } }
package org.sid.test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.namespace.QName; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPBodyElement; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPMessage; import javax.xml.soap.SOAPPart; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.stream.StreamSource; import javax.xml.ws.Dispatch; import javax.xml.ws.Service; import javax.xml.ws.soap.SOAPFaultException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.junit.Test; import org.sid.service.User; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * SAAJ * 没有之前的client是因为;之前的是将soap包装了,而这个方法是更底层的soap * Soap attachment api for java * */ public class TestSoap { String ns = "http://www.sid.com/webservice"; String wsdlUrl = "http://localhost:8989/ms?wsdl"; /** * soap消息的分析和创建 */ @Test public void test01(){ try { //1.创建消息工厂 MessageFactory factory = MessageFactory.newInstance(); //2.根据消息工厂创建soapMessage SOAPMessage message = factory.createMessage(); //3.创建SoapPart SOAPPart part = message.getSOAPPart(); //4.获取SOAPEnvelope SOAPEnvelope envelope = part.getEnvelope(); //5.可以通过soapEnvelope有效的获取相应的body和header等信息 SOAPBody body = envelope.getBody(); //6.根据Qname创建相应的节点(Qname就是一个带有命名空间的节点) QName qname = new QName(ns, "add", "ns"); body.addBodyElement(qname).setValue("123123"); //如果用一下方式进行设置会将<>转换为<和> // body.addBodyElement(qname).setValue("<a>2</a><a>2</a>"); SOAPBodyElement ele = body.addBodyElement(qname); ele.addChildElement("a").setValue("11"); ele.addChildElement("b").setValue("22"); //打印消息 message.writeTo(System.out); } catch (SOAPException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * soap消息的传递和处理 * 加入了schema的命名空间问题 */ @Test public void test02(){ try { //1.创建服务(Service) URL url = new URL(wsdlUrl); QName qname = new QName(ns, "MyServiceImplService"); Service service = Service.create(url, qname); //2.创建Dispatch //Service.Mode.MESSAGE会将<>转换了 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,"add","nn");//<nn:add xmlns="xx"> SOAPBodyElement ele = body.addBodyElement(ename); ele.addChildElement("a").setValue("22"); ele.addChildElement("b").setValue("33"); msg.writeTo(System.out); System.out.println("\n invoking……"); //5.通过Dispatch传递消息 SOAPMessage response = dispatch.invoke(msg); response.writeTo(System.out); //将响应的消息转换为dom对象 Document doc = response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument(); String str = doc.getElementsByTagName("add").item(0).getTextContent(); System.out.println("\n"+str); } catch (SOAPException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * payload方式 * add用户 */ @Test public void test03(){ try { //1.创建服务(Service) URL url = new URL(wsdlUrl); QName qname = new QName(ns, "MyServiceImplService"); Service service = Service.create(url, qname); //2.创建Dispatch,通过Source方式传递 Dispatch<Source> dispatch = service.createDispatch(new QName(ns,"MyServiceImplPort"), Source.class, Service.Mode.PAYLOAD); //3.根据用户对象创建相应的xml User user = new User(3,"zhangsan","张三","zhangsan"); JAXBContext ctx = JAXBContext.newInstance(User.class); Marshaller mar = ctx.createMarshaller(); StringWriter writer = new StringWriter(); //去掉startDocument和endDocument mar.setProperty(Marshaller.JAXB_FRAGMENT, true); mar.marshal(user, writer); //4.封装相应的part addUser String payload = "<nn:addUser xmlns:nn=\""+ns+"\">"+writer.toString()+"</nn:addUser>"; System.out.println(payload); StreamSource rs = new StreamSource(new StringReader(payload)); //5.通过dispatch传递payload Source response = dispatch.invoke(rs); //6.将Source转换为DOM进行操作,使用Transform对象转换 Transformer tran = TransformerFactory.newInstance().newTransformer(); DOMResult result = new DOMResult(); tran.transform(response, result); //7.处理响应信息 XPath xPath = XPathFactory.newInstance().newXPath(); NodeList nl = (NodeList) xPath.evaluate("//user", result.getNode(),XPathConstants.NODESET); System.out.println(nl.item(0).getNodeName()); //反编排 User ru = (User) ctx.createUnmarshaller().unmarshal(nl.item(0)); System.out.println(ru.getNickname()); } catch (IOException e) { e.printStackTrace(); } catch (JAXBException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } catch (XPathExpressionException e) { e.printStackTrace(); } } /** * message方式处理list */ @Test public void test04(){ try { //1.创建服务(Service) URL url = new URL(wsdlUrl); QName qname = new QName(ns, "MyServiceImplService"); Service service = Service.create(url, qname); //2.创建Dispatch //Service.Mode.MESSAGE会将<>转换了 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(); //处理header信息 SOAPHeader header = envelope.getHeader(); if (header==null) { header = envelope.addHeader(); } QName hname = new QName(ns,"authInfo","nn"); header.addHeaderElement(hname).setValue("USER"); //4.创建Qname来制定消息中传递的数据 QName ename = new QName(ns,"list","nn");//<nn:add xmlns="xx"> SOAPBodyElement ele = body.addBodyElement(ename); msg.writeTo(System.out); System.out.println("\n invoking……"); //5.通过Dispatch传递消息 SOAPMessage response = dispatch.invoke(msg); response.writeTo(System.out); //将响应的消息转换为dom对象 Document doc = response.getSOAPBody().extractContentAsDocument(); NodeList nl = doc.getElementsByTagName("user"); JAXBContext ctx = JAXBContext.newInstance(User.class); for (int i = 0; i < nl.getLength(); i++) { Node n = nl.item(i); User u = (User) ctx.createUnmarshaller().unmarshal(n); System.out.println(u.getNickname()); } } catch (SOAPException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JAXBException e) { e.printStackTrace(); } } /** * message方式处理login * 加入异常处理方式 * 异常这样加入和定义: * <fault message="tns:UserException" name="UserException" wsam:Action="http://www.sid.com/webservice/IMyService/login/Fault/UserException"/> * fault标签要位于output标签之后 * */ @Test public void test05(){ try { //1.创建服务(Service) URL url = new URL(wsdlUrl); QName qname = new QName(ns, "MyServiceImplService"); Service service = Service.create(url, qname); //2.创建Dispatch //Service.Mode.MESSAGE会将<>转换了 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="xx"> SOAPBodyElement ele = body.addBodyElement(ename); ele.addChildElement("username").setValue("ss"); ele.addChildElement("password").setValue("ss"); msg.writeTo(System.out); System.out.println("\n invoking……"); //5.通过Dispatch传递消息 SOAPMessage response = dispatch.invoke(msg); response.writeTo(System.out); } catch (SOAPException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (SOAPFaultException e) { System.out.println(e.getMessage());; } } }
package org.sid.handler; import java.io.IOException; import java.util.Iterator; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPFault; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPHeaderElement; import javax.xml.soap.SOAPMessage; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import javax.xml.ws.soap.SOAPFaultException; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class LicenseHandler implements SOAPHandler<SOAPMessageContext> { String ns = "http://www.sid.com/webservice"; @Override public void close(MessageContext context) { } @Override public boolean handleFault(SOAPMessageContext context) { return false; } @Override public boolean handleMessage(SOAPMessageContext context) { System.out.println("=========Server handleMessage========="); try { //往服务器发信息 Boolean out = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (!out) { SOAPMessage message = context.getMessage(); //1.判断message中是否存在header SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); SOAPHeader header = envelope.getHeader(); SOAPBody body = envelope.getBody(); Node bn = body.getChildNodes().item(0); //获取part的name String partName = bn.getLocalName(); if ("list".equals(partName)||"addUser".equals(partName)) { System.out.println("list or addUser"); Iterator<SOAPHeaderElement> iterator = header.examineAllHeaderElements(); if (header==null||!iterator.hasNext()) { //添加一个错误信息 SOAPFault fault = body.addFault(); fault.setFaultString("头部信息不能为空"); throw new SOAPFaultException(fault); }else{ while (iterator.hasNext()) { SOAPHeaderElement ele = iterator.next(); System.out.println(ele.getTextContent()); } } message.writeTo(System.out); } } } catch (SOAPException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return true; } @Override public Set<QName> getHeaders() { return null; } }
handler_chain.xml文件内容如下:
<?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>org.sid.handler.LicenseHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>
客户端代码实例:
先wsimport之后,加入client测试
package com.sid.test; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Holder; import javax.xml.ws.soap.SOAPFaultException; import com.sid.webservice.IMyService; import com.sid.webservice.MyServiceImplService; import com.sid.webservice.User; public class SoapClient { public static void main(String[] args) throws Exception { URL url = new URL("http://localhost:9898/ms?wsdl"); QName qname = new QName("http://www.sid.com/webservice", "MyServiceImplService"); MyServiceImplService mis = new MyServiceImplService(url,qname); IMyService ms = mis.getMyServiceImplPort(); try { // ms.login("admin","admin"); User u = new User(); u.setId(1); u.setUsername("123"); u.setPassword("23"); u.setNickname("23"); Holder<User> user = new Holder<User>(u); ms.addUser(user); } catch (SOAPFaultException e) { System.out.println(e.getMessage()); } } }
package org.sid.handler; import java.io.IOException; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPMessage; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import org.w3c.dom.Node; public class HeaderHandler implements SOAPHandler<SOAPMessageContext> { String ns = "http://www.sid.com/webservice"; @Override public void close(MessageContext arg0) { } @Override public boolean handleFault(SOAPMessageContext context) { return false; } /** * * LogicalHandler只能获得SOAPBody信息 * SOAPHandler可以获取SOAPMessage信息 * 客户端先处理LogicalHandler * 服务器端先处理SOAPHandler * 1.创建一个类实现SOAPHandler(并加入<SOAPMessageContext>) * 2.在handlerMessage中编写代码 * 3.配置Handler * 4.在服务上开启handler(在客户端MyServiceImplService中加上@HandlerChain(file="handler_chain.xml")) * * 服务器获取 * 1.编写handler * 2.在服务器端显示声明一个变量(基于契约优先) */ @Override public boolean handleMessage(SOAPMessageContext context) { System.out.println("=========handleMessage========="); try { //往服务器发信息 Boolean out = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (out) { SOAPMessage message = context.getMessage(); //1.判断message中是否存在header SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); //2.获取body,判断是partName SOAPBody body = envelope.getBody(); Node node = body.getChildNodes().item(0); String partname = node.getLocalName(); if ("list".equals(partname)||"addUser".equals(partname)) { System.out.println("list or addUser"); SOAPHeader header = envelope.getHeader(); if (header==null) { header = envelope.addHeader(); } QName qname = new QName(ns, "licenseInfo","nn"); header.addHeaderElement(qname).setValue("123123"); message.writeTo(System.out); System.out.println(); } } } catch (SOAPException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return true; } @Override public Set<QName> getHeaders() { return null; } }
名字在wsimport之后的服务器实现(MyServiceImplService)类名之上中添加:
@HandlerChain(file="handler_chain.xml")
handler_chain.xml文件内容如下:
<?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>org.sid.handler.HeaderHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>