通过HEADER而不是BODY传递“LICENSE”
客户端往HEADER中加入信息;
服务端从HEADER中取出信息;
首先编写xsd和wsdl
user.xsd中代码片段
<xsd:element name="licenseInfo" type="tns:licenseInfo"></xsd:element> <xsd:complexType name="licenseInfo"> <xsd:sequence> <xsd:element name="licenseUser" type="tns:user"/> </xsd:sequence> </xsd:complexType>
wsdl中的代码片段
<wsdl:message name="licenseInfo"> <wsdl:part name="licenseInfo" element="tns:licenseInfo"></wsdl:part> </wsdl:message>
<wsdl:binding> <wsdl:operation name="login"> <wsdl:input> <soap:body use="literal" /> <!-- 添加头消息 --> <soap:header use="literal" part="licenseInfo" message="tns:licenseInfo"></soap:header> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> <!-- 异常 --> <wsdl:fault name="UserException"> <soap:fault name="UserException" use="literal" /> </wsdl:fault> </wsdl:operation> </wsdl:binding>
服务端编写好schema和wsdl后,使用wsimport将wsdl转换为java文件,放到客户端项目中
客户端访问UserServlet,调用login()时,加入头信息
package com.hqh.service.servlet;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import com.hqh.service.IUserService;
import com.hqh.service.LicenseInfo;
import com.hqh.service.User;
import com.hqh.service.UserException_Exception;
import com.hqh.service.UserService;
import com.sun.xml.internal.ws.api.message.Headers;
import com.sun.xml.internal.ws.developer.WSBindingProvider;
/**
* Servlet implementation class UserServlet
*/
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private IUserService service;
private UserService serviceImpl;
private String namespace = "http://service.hqh.com";
public UserServlet() {
super();
System.out.println("UserServlet.UserServlet()");
//初始化服务端口调用类
try {
//通过URL和QName主要是为了使用TCPM监控SOAP消息
URL wsdlLocation = new URL("http://localhost:8888/Demo/service");
QName qname = new QName(namespace, "UserService");
serviceImpl = new UserService(wsdlLocation,qname);
service = serviceImpl.getUserServicePort();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String method = request.getParameter("method");
if(method==null || "".equals(method)) {
list(request,response);
} else if("login".equals(method)) {
login();
}
}
/**
* 登陆的时候往HEADER中加入信息
*/
private void login() {
try {
//将对象转换为节点,作为头信息在SOAPmessage中进行传递
//第一步:使用jaxb转换对象为xml
JAXBContext ctx = JAXBContext.newInstance(LicenseInfo.class);
LicenseInfo info = new LicenseInfo();
User user = new User();
user.setId(100);
user.setName("admin");
user.setPwd("admin");
info.setLicenseUser(user);
QName qName = new QName(namespace,"licenseInfo");
//这里使用JAXBElement就可以不在LicenseInfo类上定义@XMLROOTELEMENT注解了
//由于该类为wsdl转换而成的,每次转换后都需要添加注解,很不方便
//所以,这里使用JAXBElement进行转换
JAXBElement<LicenseInfo> jaxbEle = new JAXBElement<LicenseInfo>(qName, LicenseInfo.class, info);
Marshaller marshaller = ctx.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
//第二步:转换为DOM
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
//将对象转换为xml并放到document中
marshaller.marshal(jaxbEle, doc);
marshaller.marshal(jaxbEle, System.out);
System.out.println();
//第三步:通过Headers.create完成header的添加
WSBindingProvider wsb = (WSBindingProvider)service;
wsb.setOutboundHeaders(Headers.create(doc.getDocumentElement()));
//调用服务
service.login("a", "n");
} catch (Exception e) {
e.printStackTrace();
}
}
private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<User> users = service.list();
request.setAttribute("users", users);
request.getRequestDispatcher("/list.jsp").forward(request, response);
}
}
服务端获取到HEADER中的信息,根据具体业务需求做处理...
package com.hqh.service;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import javax.xml.ws.WebServiceContext;
import com.hqh.model.User;
import com.sun.xml.ws.api.message.Header;
import com.sun.xml.ws.api.message.HeaderList;
import com.sun.xml.ws.api.server.WSWebServiceContext;
import com.sun.xml.ws.developer.JAXWSProperties;
/**必须指定targetNamespace,否则服务无法启动*/
/*file:/E:/technology-hqh/proj/webservice/JAX-WS/Demo/build/classes/META-INF/wsdl/user.wsdl
has the following services [{http://service.hqh.com}UserService]
but not {http://service.hqh.com/}UserService.
Maybe you forgot to specify a service name in @WebService/@WebServiceProvider?*/
@WebService(endpointInterface="com.hqh.service.IUserService",
wsdlLocation="WEB-INF/wsdl/user.wsdl",
serviceName="UserService",
portName="userServicePort",
targetNamespace="http://service.hqh.com")
public class UserServiceImpl implements IUserService {
private static List<User> users = new ArrayList<User>();
static {
users.add(new User(1,"zs","zs"));
}
//通过注入的WebServiceContext获取HEADER
@Resource
private WebServiceContext ctx;
@Override
public void add(User user) throws UserException{
for(User u:users) {
if(u.getName().equals(user.getName())) {
throw new UserException("用户已存在!",null);
}
}
users.add(user);
}
@Override
public void delete(int id) {
for (Iterator iterator = users.iterator(); iterator.hasNext();) {
User user = (User) iterator.next();
if(id==user.getId()) {
users.remove(user);
break;
}
}
}
@Override
public List<User> list() {
return users;
}
@Override
public User login(String name, String pwd) throws UserException{
checkAuthorized();
for(User user : users) {
if(name.equals(user.getName()) && pwd.equals(user.getPwd())) {
return user;
}
}
throw new UserException("用户不存在",null);
}
private void checkAuthorized() {
// 检查用户权限
// 从SOAP的HEADER中传入某些验证信息,作为权限的控制
User authUser = new User();
try {
HeaderList headers = (HeaderList) ctx.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
QName headerName = new QName("http://service.hqh.com","licenseInfo");
Header header = headers.get(headerName, true);
XMLStreamReader reader = header.readHeader();
while(reader.hasNext()) {
int code = reader.next();
if(code == XMLEvent.START_ELEMENT) {
String nodeName = reader.getName().toString();
if("id".equals(nodeName)) {
authUser.setId(Integer.parseInt(reader.getElementText()));
} else if("name".equals(nodeName)) {
authUser.setName(reader.getElementText());
} else if ("pwd".equals(nodeName)) {
authUser.setPwd(reader.getElementText());
}
}
}
System.out.println(authUser);
//获取到HEADER中的数据后,针对具体需求做处理...
} catch (XMLStreamException e) {
e.printStackTrace();
}
}
}