您的位置:首页 > 编程语言

webservice(五)有关Soap协议的客户端和服务器端的实例代码(基础与进阶)

2012-12-27 09:53 615 查看
服务器端代码:

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());;
}
}
}


服务器端加入handler:

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());
}
}
}


在客户端加入handler,对header进行处理:

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: