读书人

经过HEADER传递信息-做权限控制

发布时间: 2013-08-10 21:14:06 作者: rapoo

通过HEADER传递信息-做权限控制

通过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转换对象为xmlJAXBContext 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");//第二步:转换为DOMDocument 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.wsdlhas 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@Resourceprivate WebServiceContext ctx;@Overridepublic void add(User user) throws UserException{for(User u:users) {if(u.getName().equals(user.getName())) {throw new UserException("用户已存在!",null);}}users.add(user);}@Overridepublic void delete(int id) {for (Iterator iterator = users.iterator(); iterator.hasNext();) {User user = (User) iterator.next();if(id==user.getId()) {users.remove(user);break;}}}@Overridepublic List<User> list() {return users;}@Overridepublic 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();}}}

?

读书人网 >编程

热点推荐