package org.ws.soap.test;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.crypto.dsig.Transform;
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.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.ws.soap.bean.User;
public class TestSoap {
/**
*
*
SOAP Request Envelope:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://service.soap.ws.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:add>
<a>1</a>
<b>2</b>
</q0:add>
</soapenv:Body>
</soapenv:Envelope>
*
*
SOAP Response Envelope:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:addResponse xmlns:ns2="http://service.soap.ws.org/">
<addResult>3</addResult>
</ns2:addResponse>
</S:Body>
</S:Envelope>
* Envelope 信封
* @throws IOException
* */
@Test
public void test01() throws SOAPException, IOException{
//1、创建消息工厂
MessageFactory messageFactory=MessageFactory.newInstance();
//2、根据消息工厂创建soap message
SOAPMessage soapMessage=messageFactory.createMessage();
//3、创建soappart
SOAPPart soapPart=soapMessage.getSOAPPart();
//4、获取SOAP信封 <soapenv:Envelope> SoapEnvelope
SOAPEnvelope soapEnvelope=soapPart.getEnvelope();
//5、通过soapEnvelope 有效获取 body与header等信息
SOAPBody soapBody=soapEnvelope.getBody();
//6、根据Qname创建相应的节点(Qname就是一个带有命名空间的节点)
QName qname= new QName("http://org.ws.soap/webservice", "add", "ns");//创建的结果对应<ns:add xmlns=">
//7、将qname添加到body中并设值:1222
soapBody.addBodyElement(qname).setValue("11222");
//8、打印消息信息
soapMessage.writeTo(System.out);
/**打印结果为:
* <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
* <SOAP-ENV:Header/>
* <SOAP-ENV:Body>
* <ns:add xmlns:ns="http://org.ws.soap/webservice">
* 11222
* </ns:add>
* </SOAP-ENV:Body>
* </SOAP-ENV:Envelope>
*
* */
}
@Test
public void test02() throws SOAPException, IOException{
//1、创建消息工厂
MessageFactory messageFactory=MessageFactory.newInstance();
//2、根据消息工厂创建soap message
SOAPMessage soapMessage=messageFactory.createMessage();
//3、创建soappart
SOAPPart soapPart=soapMessage.getSOAPPart();
//4、获取SOAP信封 <soapenv:Envelope> SoapEnvelope
SOAPEnvelope soapEnvelope=soapPart.getEnvelope();
//5、通过soapEnvelope 有效获取 body与header等信息
SOAPBody soapBody=soapEnvelope.getBody();
//6、根据Qname创建相应的节点(Qname就是一个带有命名空间的节点)
QName qname= new QName("http://org.ws.soap/webservice", "add", "ns");//创建的结果对应<ns:add xmlns=">
//如果用一下方式传递<a></a><b></b> 会将<>转换成<和>
//soapBody.addBodyElement(qname).setValue("<a>12</a><b>1</b>");
//改进方法 实现添加<a>12</a><b>1</b>
SOAPBodyElement soapBodyElement=soapBody.addBodyElement(qname);
soapBodyElement.addChildElement("a").setValue("11");
soapBodyElement.addChildElement("b").setValue("12");
//8、打印消息信息
soapMessage.writeTo(System.out);
/**打印结果为:
* <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
* <SOAP-ENV:Header/>
* <SOAP-ENV:Body>
* <ns:add xmlns:ns="http://org.ws.soap/webservice">
* <a>11</a>
* <b>12</b>
* </ns:add>
* </SOAP-ENV:Body>
* </SOAP-ENV:Envelope>
*
* */
}
@Test/**将消息提交给服务器,此示例就是整个soap发送接收*/
public void test03() throws SOAPException, IOException{
String wsdlURL="http://localhost:8787/ws?wsdl";
String ns="http://org.ws.soap/webservice";
//1、创建服务
URL url= new URL(wsdlURL);
QName qname= new QName(ns,"MyServiceImplService");
Service service=Service.create(url, qname);
//2、创建Dispatch
Dispatch<SOAPMessage> dispathc=service.createDispatch(new QName(ns,"MyServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE);
//3、创建SOAPmessage
SOAPMessage soapMessage=MessageFactory.newInstance().createMessage();
//4、获取信封envelope
SOAPEnvelope soapEnvelope=soapMessage.getSOAPPart().getEnvelope();
//5、获取SOAPBody
SOAPBody soapBody=soapEnvelope.getBody();
//6、创建QName获取消息传递中的信息
QName elementName= new QName(ns, "add", "nn");
SOAPBodyElement soapBodyElement=soapBody.addBodyElement(elementName);
soapBodyElement.addChildElement("a").setValue("11");
soapBodyElement.addChildElement("b").setValue("12");
//输出消息,输出到控制台中
soapMessage.writeTo(System.out);
System.out.println("\n");
//7、通过Dispatch传递消息,返回响应消息
SOAPMessage response=dispathc.invoke(soapMessage);
//打印响应消息到控制台中
response.writeTo(System.out);
//将SOAP响应消息转换成document
Document document=response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
//获取返回值
String responseValue=document.getElementsByTagName("addResult").item(0).getTextContent();
System.out.println("\n\n"+responseValue);
}
@Test/**传递的是对象,主要是传递字符串的方式payload*/
public void test04() throws SOAPException, IOException, JAXBException, TransformerFactoryConfigurationError, TransformerException, XPathExpressionException{
String wsdlURL="http://localhost:8787/ws?wsdl";
String ns="http://org.ws.soap/webservice";
String soapns="http://org.ws.soap/webservice";//soapns的命名空间 在MyService接口中有定义
//1、创建服务
URL url= new URL(wsdlURL);
QName qname= new QName(ns,"MyServiceImplService");
Service service=Service.create(url, qname);
//2、创建Dispatch,这里用的是Source通过源数据传递
Dispatch<Source> dispathc=service.createDispatch(
new QName(ns,"MyServiceImplPort"),
Source.class,
Service.Mode.PAYLOAD);
//3、根据用户对象创建xml
User user= new User("2", "zs", "123456", "张三");
JAXBContext jaxbContext=JAXBContext.newInstance(user.getClass());
Marshaller marshaller=jaxbContext.createMarshaller();
StringWriter writer= new StringWriter();
/***这里是去除表头,之后转义的xml就是这样的
* <user>
* <id>2</id>
* <nickname>张三</nickname>
* <password>123456</password>
* <username>zs</username>
* </user>
*/
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.marshal(user, writer);
//封装响应的part addUser 这里是通过字符串传递,只能手动指定
String payload="<nn:addUser xmlns:nn=\""+soapns+"\">"+writer.toString()+"</nn:addUser>";
System.out.println(payload);
/*** <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
* <user>
* <id>2</id>
* <nickname>张三</nickname>
* <password>123456</password>
* <username>zs</username>
* </user>
*/
//4、通过dispatch传递payload
StreamSource payloadSource= new StreamSource(new StringReader(payload));
Source response=(Source)dispathc.invoke(payloadSource);
//5、将响应的source转换成dom进行处理,使用Transformer 进行转换
Transformer transformer=TransformerFactory.newInstance().newTransformer();
DOMResult domResult= new DOMResult();
transformer.transform(response, domResult);
//6、处理信息用(xpath)
XPath xpath=XPathFactory.newInstance().newXPath();
NodeList nodeList=(NodeList) xpath.evaluate("//user", domResult.getNode(),XPathConstants.NODESET);
User responseUser=(User) jaxbContext.createUnmarshaller().unmarshal(nodeList.item(0));
System.out.println("\n\n nickname="+responseUser.getNickname());
}
@Test/**处理list对象 */
public void test05() throws SOAPException, IOException, JAXBException{
String wsdlURL="http://localhost:8787/ws?wsdl";
String ns="http://org.ws.soap/webservice";
//1、创建服务
URL url= new URL(wsdlURL);
QName qname= new QName(ns,"MyServiceImplService");
Service service=Service.create(url, qname);
//2、创建Dispatch
Dispatch<SOAPMessage> dispathc=service.createDispatch(new QName(ns,"MyServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE);
//3、创建SOAPmessage
SOAPMessage soapMessage=MessageFactory.newInstance().createMessage();
//4、获取信封envelope
SOAPEnvelope soapEnvelope=soapMessage.getSOAPPart().getEnvelope();
//5、获取SOAPBody
SOAPBody soapBody=soapEnvelope.getBody();
//6这里处理的是list part部分还是需要的
QName elementName= new QName(ns, "list", "nn");
SOAPBodyElement soapBodyElement=soapBody.addBodyElement(elementName);
//输出消息,输出到控制台中
soapMessage.writeTo(System.out);
System.out.println("\n");
//7、通过Dispatch传递消息,返回响应消息
SOAPMessage response=dispathc.invoke(soapMessage);
//打印响应消息到控制台中
response.writeTo(System.out);
//将SOAP响应消息转换成document
Document document=response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
//这里返回的是list,因此节点信息应该是nodeList,这里是获取user,设定的返回值是user
NodeList nodeList=document.getElementsByTagName("user");
JAXBContext jaxbContext=JAXBContext.newInstance(User.class);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node=nodeList.item(i);
//进行反编码 将xml编码成user对象
User user= (User) jaxbContext.createUnmarshaller().unmarshal(node);
System.out.println("\n\n nickname="+user.getNickname());
}
}
@Test/**
通过list处理消息 利用header进行加密 权限验证操作
显示头部的信息也是有不友好的地方,在导出的时候 list会创建两个,会影响原有的封装
隐身申明,解决办法,在创建服务的时候 就将header创建,在调用的时候在显示调用
*/
public void test06() throws SOAPException, IOException, JAXBException{
String wsdlURL="http://localhost:8787/ws?wsdl";
String ns="http://org.ws.soap/webservice";
//1、创建服务
URL url= new URL(wsdlURL);
QName qname= new QName(ns,"MyServiceImplService");
Service service=Service.create(url, qname);
//2、创建Dispatch
Dispatch<SOAPMessage> dispathc=service.createDispatch(new QName(ns,"MyServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE);
//3、创建SOAPmessage
SOAPMessage soapMessage=MessageFactory.newInstance().createMessage();
//4、获取信封envelope
SOAPEnvelope soapEnvelope=soapMessage.getSOAPPart().getEnvelope();
//5、获取SOAPBody
SOAPBody soapBody=soapEnvelope.getBody();
//处理header头部信息
SOAPHeader soapHeader=soapEnvelope.getHeader();
//此处header有可能是null,必须保持严谨
if(soapHeader==null)
soapHeader=soapEnvelope.addHeader();
//创建header 的qname
QName headerQname=new QName(ns, "authInfo", "nn");
soapHeader.addHeaderElement(headerQname).setValue("header");
/**<SOAP-ENV:Header>
* <nn:authInfo xmlns:nn="http://org.ws.soap/webservice">
* header
* </nn:authInfo>
* </SOAP-ENV:Header>
* */
//6这里处理的是list part部分还是需要的
QName elementName= new QName(ns, "list", "nn");
SOAPBodyElement soapBodyElement=soapBody.addBodyElement(elementName);
//输出消息,输出到控制台中
soapMessage.writeTo(System.out);
System.out.println("\n");
//7、通过Dispatch传递消息,返回响应消息
SOAPMessage response=dispathc.invoke(soapMessage);
//打印响应消息到控制台中
response.writeTo(System.out);
//将SOAP响应消息转换成document
Document document=response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
//这里返回的是list,因此节点信息应该是nodeList,这里是获取user,设定的返回值是user
NodeList nodeList=document.getElementsByTagName("user");
JAXBContext jaxbContext=JAXBContext.newInstance(User.class);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node=nodeList.item(i);
//进行反编码 将xml编码成user对象
User user= (User) jaxbContext.createUnmarshaller().unmarshal(node);
System.out.println("\n\n nickname="+user.getNickname());
}
}
/**异常处理信息
* @throws MalformedURLException
* @throws SOAPException
* @throws SOAPException */
@Test
public void test07() throws MalformedURLException, SOAPException {
String wsdlURL="http://localhost:8787/ws?wsdl";
String ns="http://org.ws.soap/webservice";
//1、创建服务
URL url= new URL(wsdlURL);
QName qname= new QName(ns,"MyServiceImplService");
Service service=Service.create(url, qname);
//2、创建Dispatch
Dispatch<SOAPMessage> dispathc=service.createDispatch(new QName(ns,"MyServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE);
//3、创建SOAPmessage
SOAPMessage soapMessage=MessageFactory.newInstance().createMessage();
//4、获取信封envelope
SOAPEnvelope soapEnvelope=soapMessage.getSOAPPart().getEnvelope();
//5、获取SOAPBody
SOAPBody soapBody=soapEnvelope.getBody();
//6这里处理的是list part部分还是需要的
QName elementName= new QName(ns, "login", "nn");
SOAPBodyElement soapBodyElement=soapBody.addBodyElement(elementName);
soapBodyElement.addChildElement("username").setValue("user111");
soapBodyElement.addChildElement("password").setValue("232");
try {
//输出消息,输出到控制台中
soapMessage.writeTo(System.out);
System.out.println("\n");
//7、通过Dispatch传递消息,返回响应消息
SOAPMessage response=dispathc.invoke(soapMessage);
//打印响应消息到控制台中
response.writeTo(System.out);
}catch (SOAPFaultException e) {
System.out.println(e.getMessage());
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* handler:相当于是过滤器
*
* LogicalHandler:只能获取SOAPBody的消息
* SOAPHandler:可以获取SOAPMessge消息
*
* */
@Test
public void test08(){
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------
package org.ws.soap.handler;
import java.io.IOException;
import java.util.Set;
import javax.xml.namespace.QName;
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;
public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
@Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
@Override
public boolean handleFault(SOAPMessageContext context) {
System.out.println("handleFault ...............");
return true;
}
public boolean handleMessage(SOAPMessageContext context) {
String ns="http://org.ws.soap/webservice";
Boolean out=(Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
System.out.println(out);
if(!out){
SOAPMessage soapMessage=context.getMessage();
//一定要判断message中是否有handler
try {
SOAPEnvelope soapEnvelope=soapMessage.getSOAPPart().getEnvelope();
SOAPHeader soapHeader=soapEnvelope.getHeader();
if(soapHeader==null)
soapHeader=soapEnvelope.addHeader();
QName headerName= new QName(ns, "lisenceInfo", "nn");
soapHeader.addHeaderElement(headerName).setValue("123");
soapMessage.writeTo(System.out);
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return true;
}
}
------------------------------------------------------------------------------------------------------------------------------------