以HelloWord为例,客户端的LogicalHandler可以拦截出站的请求消息以检查调用sayHello服务操作的输入参数。如果参数name值为“老板”则修改为“刘诗诗”。示例如下:
服务端:
HelloWord.java
package ch03.ts; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.xml.ws.Holder; @WebService public interface HelloWord { @WebMethod void sayHello(@WebParam(name="name") String name, @WebParam(name="wh",mode=WebParam.Mode.INOUT) Holder<String> wh, @WebParam(name="hf",mode=WebParam.Mode.OUT) Holder<String> hf); }
HelloWordImpl.java
package ch03.ts; import javax.jws.WebService; import javax.xml.ws.Holder; @WebService(endpointInterface = "ch03.ts.HelloWord") public class HelloWordImpl implements HelloWord { @Override public void sayHello(String name, Holder<String> wh, Holder<String> hf) { System.out.println(name + "!" + wh.value); wh.value = "你们好"; hf.value = "同学们"; } }
HelloWordPublisher.java
package ch03.ts; import javax.xml.ws.Endpoint; public class HelloWordPublisher { public static void main(String[] args) { Endpoint.publish("http://localhost:7654/ts", new HelloWordImpl()); } }
客户端:
HelloWord.java
package hw4; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.Action; import javax.xml.ws.Holder; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; /** * This class was generated by the JAX-WS RI. * JAX-WS RI 2.2.4-b01 * Generated source version: 2.2 */ @WebService(name = "HelloWord", targetNamespace = "http://ts.ch03/") @XmlSeeAlso({ ObjectFactory.class }) public interface HelloWord { /** * @param wh * @param name * @param hf */ @WebMethod @RequestWrapper(localName = "sayHello", targetNamespace = "http://ts.ch03/", className = "hw4.SayHello") @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://ts.ch03/", className = "hw4.SayHelloResponse") @Action(input = "http://ts.ch03/HelloWord/sayHelloRequest", output = "http://ts.ch03/HelloWord/sayHelloResponse") public void sayHello( @WebParam(name = "name", targetNamespace = "") String name, @WebParam(name = "wh", targetNamespace = "", mode = WebParam.Mode.INOUT) Holder<String> wh, @WebParam(name = "hf", targetNamespace = "", mode = WebParam.Mode.OUT) Holder<String> hf); }
HelloWordImplService.java(注意:这里添加了注解 @HandlerChain(file="handler-chain1.xml")):
package hw4; import java.net.MalformedURLException; import java.net.URL; import javax.jws.HandlerChain; import javax.xml.namespace.QName; import javax.xml.ws.Service; import javax.xml.ws.WebEndpoint; import javax.xml.ws.WebServiceClient; import javax.xml.ws.WebServiceException; import javax.xml.ws.WebServiceFeature; /** * This class was generated by the JAX-WS RI. * JAX-WS RI 2.2.4-b01 * Generated source version: 2.2 */ @WebServiceClient(name = "HelloWordImplService", targetNamespace = "http://ts.ch03/", wsdlLocation = "http://localhost:7654/ts?wsdl") @HandlerChain(file = "handler-chain1.xml") public class HelloWordImplService extends Service{ private final static URL HELLOWORDIMPLSERVICE_WSDL_LOCATION; private final static WebServiceException HELLOWORDIMPLSERVICE_EXCEPTION; private final static QName HELLOWORDIMPLSERVICE_QNAME = new QName("http://ts.ch03/", "HelloWordImplService"); static { URL url = null; WebServiceException e = null; try { url = new URL("http://localhost:7654/ts?wsdl"); } catch (MalformedURLException ex) { e = new WebServiceException(ex); } HELLOWORDIMPLSERVICE_WSDL_LOCATION = url; HELLOWORDIMPLSERVICE_EXCEPTION = e; } public HelloWordImplService() { super(__getWsdlLocation(), HELLOWORDIMPLSERVICE_QNAME); } public HelloWordImplService(WebServiceFeature... features) { super(__getWsdlLocation(), HELLOWORDIMPLSERVICE_QNAME, features); } public HelloWordImplService(URL wsdlLocation) { super(wsdlLocation, HELLOWORDIMPLSERVICE_QNAME); } public HelloWordImplService(URL wsdlLocation, WebServiceFeature... features) { super(wsdlLocation, HELLOWORDIMPLSERVICE_QNAME, features); } public HelloWordImplService(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } public HelloWordImplService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) { super(wsdlLocation, serviceName, features); } /** * @return * returns HelloWord */ @WebEndpoint(name = "HelloWordImplPort") public HelloWord getHelloWordImplPort() { return super.getPort(new QName("http://ts.ch03/", "HelloWordImplPort"), HelloWord.class); } /** * * @param features * A list of {@link javax.xml.ws.WebServiceFeature} to configure on t * he proxy. Supported features not in the <code>features</code> parameter * will have their default values. * @return * returns HelloWord */ @WebEndpoint(name = "HelloWordImplPort") public HelloWord getHelloWordImplPort(WebServiceFeature... features) { return super.getPort(new QName("http://ts.ch03/", "HelloWordImplPort"), HelloWord.class, features); } private static URL __getWsdlLocation() { if (HELLOWORDIMPLSERVICE_EXCEPTION!= null) { throw HELLOWORDIMPLSERVICE_EXCEPTION; } return HELLOWORDIMPLSERVICE_WSDL_LOCATION; } }
SayHello.java:
package hw4; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; /** * <p>Java class for sayHello complex type. * <p>The following schema fragment specifies the expected content * contained within this class. * <pre> * <complexType name="sayHello"> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <sequence> * <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" * minOccurs="0"/> * <element name="wh" type="{http://www.w3.org/2001/XMLSchema}string" * minOccurs="0"/> * </sequence> * </restriction> * </complexContent> * </complexType> * </pre> */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "sayHello", propOrder = { "name", "wh" }) public class SayHello { protected String name; protected String wh; /** * Gets the value of the name property. * @return * possible object is * {@link String } */ public String getName() { return name; } /** * Sets the value of the name property. * @param value * allowed object is * {@link String } */ public void setName(String value) { this.name = value; } /** * Gets the value of the wh property. * @return * possible object is * {@link String } */ public String getWh() { return wh; } /** * Sets the value of the wh property. * @param value * allowed object is * {@link String } */ public void setWh(String value) { this.wh = value; } }
SayHelloResponse.java:
package hw4; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; /** * <p>Java class for sayHelloResponse complex type. * <p>The following schema fragment specifies the expected content * contained within this class. * <pre> * <complexType name="sayHelloResponse"> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <sequence> * <element name="wh" type="{http://www.w3.org/2001/XMLSchema}string" * minOccurs="0"/> * <element name="hf" type="{http://www.w3.org/2001/XMLSchema}string" * minOccurs="0"/> * </sequence> * </restriction> * </complexContent> * </complexType> * </pre> */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "sayHelloResponse", propOrder = { "wh", "hf" }) public class SayHelloResponse { protected String wh; protected String hf; /** * Gets the value of the wh property. * @return * possible object is * {@link String } */ public String getWh() { return wh; } /** * Sets the value of the wh property. * @param value * allowed object is * {@link String } */ public void setWh(String value) { this.wh = value; } /** * Gets the value of the hf property. * @return * possible object is * {@link String } */ public String getHf() { return hf; } /** * Sets the value of the hf property. * @param value * allowed object is * {@link String } */ public void setHf(String value) { this.hf = value; } }
ObjectFactory.java与package-info.java省略。
HelloWordClient1.java:
package hw4; import javax.xml.ws.Holder; public class HelloWordClient1 { public static void main(String[] args) { String name = "老板"; Holder<String> wh = new Holder<String>(); wh.value = "你好"; Holder<String> hf = new Holder<String>(); HelloWordImplService service = new HelloWordImplService(); HelloWord port = service.getPort(HelloWord.class); port.sayHello(name, wh, hf); System.out.println(hf.value + "," + wh.value); } }
ArgHandler.java:
package fibC; import hw4.SayHello; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.ws.LogicalMessage; import javax.xml.ws.handler.LogicalHandler; import javax.xml.ws.handler.LogicalMessageContext; import javax.xml.ws.handler.MessageContext; /** * 如果称呼不正确,对称呼进行修正 * @author fuhd */ public class ArgHandler implements LogicalHandler<LogicalMessageContext> { @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public boolean handleMessage(LogicalMessageContext context) { Boolean b = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if(b){ System.out.println("ArgHandler.handleMessage"); LogicalMessage msg = context.getMessage(); try { JAXBContext jaxb_ctx = JAXBContext.newInstance("hw4"); Object payload = msg.getPayload(jaxb_ctx); if(payload instanceof JAXBElement){ Object obj = ((JAXBElement)payload).getValue(); SayHello sayH = (SayHello)obj; String name1 = sayH.getName(); if("老板".equals(name1)){ sayH.setName("刘诗诗"); ((JAXBElement)payload).setValue(obj); msg.setPayload(payload, jaxb_ctx); } } } catch (Exception e) { e.printStackTrace(); } } return true; } @Override public boolean handleFault(LogicalMessageContext context) { return true; } @Override public void close(MessageContext context) { } }
handler-chain1.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>fibC.ArgHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>
ArgHandler利用JAXBContext对象实例从LogicalMessage中解析出消息单元。这个消息单元就是出站的SOAP消息。LogicalMessage中还有一个无参数的getPayload方法,该方法返回一个XML源对象,可以从这个源对象中的XML编码为一个Java对象。拥有一个输入参数的getPayload方法中,参数可以是一个类,也可以是一个或多个包名称(注:上面这个例子中,hw4是wsimport生成的工件所在包的名称)。消息单元解析成一个JAXBElement对象,对应XML中描述SayHello对象的元素。SayHello是wsimport生成的工具集合中的一个类。尤其是Java对象类hw4.SayHello对应于服务操作sayHello中一个SOAP请求消息。请求参数修改完之后,通过JAXBElement更新转换参数值,最后通过调用方法setPayload更新消息体内容。