bean:
package org.senssic.jaxweb;
@XmlRootElement
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
服务接口:
package org.senssic.jaxweb.impl;
import java.util.List;
import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import org.senssic.jaxweb.User;
@WebService(name = "WebServer", targetNamespace = "http://jaxweb.senssic.org/")
@HandlerChain(file = "handler-chain.xml")
// 使用handler过滤连
public interface WebServer {
@WebMethod
public int getAgeByName(@WebParam(name = "name") String arg0);
@WebMethod
public List<String> getNamesByAges(
@WebParam(name = "age", targetNamespace = "") List<Integer> arg0);
@WebMethod
public List<User> getLUser();
@WebMethod
public List<User> getSUser();
@WebMethod
@WebResult(targetNamespace = "",header=ture)//位于头信息
@RequestWrapper(localName = "getBFile", targetNamespace = "http://jaxweb.senssic.org/", className = "org.senssic.jaxweb.GetBFile")
@ResponseWrapper(localName = "getBFileResponse", targetNamespace = "http://jaxweb.senssic.org/", className = "org.senssic.jaxweb.GetBFileResponse")
public byte[] getBFile(
@WebParam(name = "byt", targetNamespace = "") byte arg0);
}
服务接口实现类:
package org.senssic.jaxweb.impl;
import java.util.List;
import javax.jws.WebService;
import org.senssic.jaxweb.User;
@WebService(endpointInterface = "org.senssic.jaxweb.impl.WebServer", portName = "senssicServer")
public class WebServceImpl implements WebServer {
@Override
public int getAgeByName(String arg0) {
return 0;
}
@Override
public List<String> getNamesByAges(List<Integer> arg0) {
return null;
}
@Override
public List<User> getLUser() {
return null;
}
@Override
public List<User> getSUser() {
return null;
}
@Override
public byte[] getBFile(byte arg0) {
return null;
}
}
handler过滤链类
package org.senssic.jaxweb.handler;
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;
public class LicenseHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
try {
Boolean out = (Boolean) context
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!out) {
SOAPMessage message = context.getMessage();
SOAPEnvelope enve = message.getSOAPPart().getEnvelope();
SOAPHeader header = enve.getHeader();
SOAPBody body = enve.getBody();
Node bn = body.getChildNodes().item(0);
String partname = bn.getLocalName();
if ("list".equals(partname) || "addUser".equals(partname)) {
if (header == null) {
// 添加一个错误信息
System.out.println("ttt");
SOAPFault fault = body.addFault();
fault.setFaultString("头部信息不能为空!");
throw new SOAPFaultException(fault);
}
@SuppressWarnings("unchecked")
Iterator<SOAPHeaderElement> iterator = header
.extractAllHeaderElements();
if (!iterator.hasNext()) {
// 添加一个错误信息
System.out.println("ttt");
SOAPFault fault = body.addFault();
fault.setFaultString("头部信息不正确!");
throw new SOAPFaultException(fault);
}
while (iterator.hasNext()) {
SOAPHeaderElement ele = iterator.next();
System.out.println(ele.getTextContent());
// 获取头部信息
}
}
}
} catch (SOAPException e) {
e.printStackTrace();
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
return false;
}
@Override
public void close(MessageContext context) {
}
@Override
public Set<QName> getHeaders() {
return null;
}
}
发布测试类:
package senssic.main;
import javax.xml.ws.Endpoint;
import org.senssic.jaxweb.impl.WebServceImpl;
public class Test {
public static void main(String[] args) {
String address = "http://localhost:2014/ns";
Endpoint.publish(address, new WebServceImpl());
}
}
过滤链配置文件位于:src下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.senssic.jaxweb.handler.LicenseHandler</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
运行test,打开浏览器输入即可看到wsdl文件信息
然后使用java自带的工具jsimport导出即可直接使用客户端编写代码:
package org.senssic.jaxweb.impl;
public class Test {
public static void main(String[] args) {
WebServceImplService wService = new WebServceImplService();
WebServer wServer = wService.getPort(WebServer.class);
wServer.getLUser();
wServer.getSUser();
}
}
使用Soap底层操作(互联网):
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.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
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.soap.service.User;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class SenSoap {
private String ns = "http://service.soap.org/";
private String wsdlUrl = "http://localhost:8989/ms?wsdl";
@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("http://java.zttc.edu.cn/webservice",
"add","ns");//<ns:add xmlns="http://java.zttc.edu.cn/webservice"/>
//如果使用以下方式进行设置,会见<>转换为<和>
//body.addBodyElement(qname).setValue("<a>1</a><b>2</b>");
SOAPBodyElement ele = body.addBodyElement(qname);
ele.addChildElement("a").setValue("22");
ele.addChildElement("b").setValue("33");
//打印消息信息
message.writeTo(System.out);
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test02() {
try {
//1、创建服务(Service)
URL url = new URL(wsdlUrl);
QName sname = new QName(ns,"MyServiceImplService");
Service service = Service.create(url,sname);
//2、创建Dispatch
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);
System.out.println();
//将响应的消息转换为dom对象
Document doc = response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
String str = doc.getElementsByTagName("addResult").item(0).getTextContent();
System.out.println(str);
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test03() {
try {
//1、创建服务(Service)
URL url = new URL(wsdlUrl);
QName sname = new QName(ns,"MyServiceImplService");
Service service = Service.create(url,sname);
//2、创建Dispatch(通过源数据的方式传递)
Dispatch<Source> dispatch = service.createDispatch(new QName(ns,"MyServiceImplPort"),
Source.class, Service.Mode.PAYLOAD);
//3、根据用户对象创建相应的xml
User user = new User(3,"zs","张三","11111");
JAXBContext ctx = JAXBContext.newInstance(User.class);
Marshaller mar = ctx.createMarshaller();
mar.setProperty(Marshaller.JAXB_FRAGMENT, true);
StringWriter writer= new StringWriter();
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 = (Source)dispatch.invoke(rs);
//6、将Source转化为DOM进行操作,使用Transform对象转换
Transformer tran = TransformerFactory.newInstance().newTransformer();
DOMResult result = new DOMResult();
tran.transform(response, result);
//7、处理相应信息(通过xpath处理)
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nl = (NodeList)xpath.evaluate("//user", result.getNode(),XPathConstants.NODESET);
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 (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
@Test
public void test04() {
try {
//1、创建服务(Service)
URL url = new URL(wsdlUrl);
QName sname = new QName(ns,"MyServiceImplService");
Service service = Service.create(url,sname);
//2、创建Dispatch
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();
//3.2、处理header信息
SOAPHeader header = envelope.getHeader();
if(header==null) header = envelope.addHeader();
QName hname = new QName(ns,"authInfo","nn");
header.addHeaderElement(hname).setValue("aabbccdd");
//4、创建QName来指定消息中传递数据
QName ename = new QName(ns,"list","nn");//<nn:add xmlns="xx"/>
body.addBodyElement(ename);
msg.writeTo(System.out);
System.out.println("\n invoking.....");
//5、通过Dispatch传递消息,会返回响应消息
SOAPMessage response = dispatch.invoke(msg);
response.writeTo(System.out);
System.out.println();
//将响应的消息转换为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();
}
}
@Test
public void test05() {
try {
//1、创建服务(Service)
URL url = new URL(wsdlUrl);
QName sname = new QName(ns,"MyServiceImplService");
Service service = Service.create(url,sname);
//2、创建Dispatch
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("dd");
msg.writeTo(System.out);
System.out.println("\n invoking.....");
//5、通过Dispatch传递消息,会返回响应消息
SOAPMessage response = dispatch.invoke(msg);
response.writeTo(System.out);
System.out.println();
} catch(SOAPFaultException e){
System.out.println(e.getMessage());
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Annotation class: | Annotation: | Properties: |
---|---|---|
javax.jws.WebService | The @WebService annotation marks a Java class as implementing a Web service or marks a service endpoint interface (SEI) as implementing a Web service interface. Important: • A Java class that implements a Web service must specify either the @WebService or @WebServiceProvider annotation. Both annotations cannot be present. This annotation is applicablek on a client or server SEI or a server endpoint implementation class for a JavaBeans endpoint. • If the annotation references an SEI through the endpointInterface attribute, the SEI must also be annotated with the @WebService annotation. • See Rules for methods on classes annotated with @WebService for additional information. |
|
javax.jws.WebMethod | The @WebMethod annotation denotes a method that is a Web service operation. Apply this annotation to methods on a client or server Service Endpoint Interface (SEI) or a server endpoint implementation class for a JavaBeans endpoint. Important: • The @WebMethod annotation is only supported on classes that are annotated with the @WebService annotation. |
|
javax.jws.Oneway | The @Oneway annotation denotes a method as a Web service one-way operation that only has an input message and no output message. Apply this annotation to methods on a client or server Service Endpoint Interface (SEI) or a server endpoint implementation class for a JavaBeans endpoint. |
|
javax.jws.WebParam | The @WebParam annotation customizes the mapping of an individual parameter to a Web service message part and XML element. Apply this annotation to methods on a client or server Service Endpoint Interface (SEI) or a server endpoint implementation class for a JavaBeans endpoint. |
|
javax.jws.WebResult | The @WebResult annotation customizes the mapping of a return value to a WSDL part or XML element. Apply this annotation to methods on a client or server Service Endpoint Interface (SEI) or a server endpoint implementation class for a JavaBeans endpoint. |
|
javax.jws.HandlerChain | The @HandlerChain annotation associates the Web service with an externally defined handler chain. You can only configure the server side handler by using the @HandlerChain annotation on the SEI or implementation class. Use one of several ways to configure a client side handler. You can configure a client side handler by using the @HandlerChain annotation on the generated service class or SEI. Additionally, you can programatically register your own implementation of the HandlerResolver interface on the Service, or programatically set the handler chain on the Binding object. |
|
javax.jws.SOAPBinding | The @SOAPBinding annotation specifies the mapping of the Web service onto the SOAP message protocol. Apply this annotation to a type or methods on a client or server Service Endpoint Interface (SEI) or a server endpoint implementation class for a JavaBeans endpoint. The method level annotation is limited in what it can specify and is only used if the styleproperty isDOCUMENT. If the method level annotation is not specified, the@SOAPBinding behavior from the type is used. |
|
Annotation class: | Annotation: | Properties: |
---|---|---|
javax.xml.ws.BindingType | The @BindingType annotation specifies the binding to use when publishing an endpoint of this type. Apply this annotation to a server endpoint implementation class for a JavaBeans endpoint or a Provider endpoint. Important: • You can use the @BindingType annotation on the Java bean endpoint implementation class to enable MTOM by specifying eitherjavax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDINGorjavax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDINGas the value for the annotation. |
|
javax.xml.ws.RequestWrapper | The @RequestWrapper annotation supplies the JAXB generated request wrapper bean, the element name, and the namespace for serialization and deserialization with the request wrapper bean that is used at runtime. When starting with a Java object, this element is used to resolve overloading conflicts in document literal mode. Only the classNameattribute is required in this case. Apply this annotation to methods on a client or server Service Endpoint Interface (SEI) or a server endpoint implementation class for a JavaBeans endpoint. |
|
javax.xml.ws.ResponseWrapper | The @ResponseWrapper annotation supplies the JAXB generated response wrapper bean, the element name, and the namespace for serialization and deserialization with the response wrapper bean that is used at runtime. When starting with a Java object, this element is used to resolve overloading conflicts in document literal mode. Only the classNameattribute is required in this case. Apply this annotation to methods on a client or server Service Endpoint Interface (SEI) or a server endpoint implementation class for a JavaBeans endpoint. |
|
javax.xml.ws.ServiceMode | The @ServiceMode annotation specifies whether a service provider needs to have access to an entire protocol message or just the message payload. Important: • The @ServiceMode annotation is only supported on classes that are annotated with the @WebServiceProvider annotation. |
|
javax.xml.ws.WebFault | The @WebFault annotation maps WSDL faults to Java exceptions. It is used to capture the name of the fault during the serialization of the JAXB type that is generated from a global element referenced by a WSDL fault message. It can also be used to customize the mapping of service specific exceptions to WSDL faults. This annotation can only be applied to a fault implementation class on the client or server. |
|
javax.xml.ws.WebServiceProvider | The @WebServiceProvider annotation denotes that a class satisfies requirements for a JAX-WS Provider implementation class. Important: • A Java class that implements a Web service must specify either the @WebService or @WebServiceProvider annotation. Both annotations cannot be present. • The @WebServiceProvider annotation is only supported on the service implementation class. • Any class with the @WebServiceProvider annotation must have an operation named invoke. |
|
Annotation class: | Annotation: | Properties: |
---|---|---|
javax.annotation.Resource | The @Resource annotation marks a WebServiceContext resource needed by the application. Apply this annotation to a server endpoint implementation class for a JavaBeans endpoint or a Provider endpoint. The container will inject an instance of the WebServiceContext resource into the endpoint implementation when it is initialized. |
|
javax.annotation.PostConstruct | The @PostConstructannotation marks a method that needs to be executed after dependency injection is performed on the class. Apply this annotation to a JAX-WS application handler, a server endpoint implementation class for a JavaBeans endpoint or a Provider endpoint. |
|
javax.annotation.PreDestroy | The @PreDestroy annotation marks a method that must be executed when the instance is in the process of being removed by the container. Apply this annotation to a JAX-WS application handler, a server endpoint implementation class for a JavaBeans endpoint or a Provider endpoint. |
|
Rules for methods on classes annotated with @WebService
- If the @WebService annotation of an implementation class references an SEI, the implementation class must not have any @WebMethod annotations.
- All public methods for an SEI are considered exposed methods regardless of whether the @WebMethod annotation is specified or not. It is incorrect to have an @WebMethod annotation on an SEI that contains the exclude attribute.
- For an implementation class that does not reference an SEI, if the @WebMethod annotation is specified with a value ofexclude=true, that method is not exposed. If the @WebMethod annotation is not specified, all public methods are exposed including the inherited methods with the exception of methods inherited from java.lang.Object.