权限控制:(通过header来做)
1.将要传递的数据创建header元素
2.创建message并绑定消息
3.客户端进行header处理
3.1通过SAAJ(直接传递SoapBody和SOAPheader对象,通过Dispatcher传递消息)
客户端可以处理,服务器端无法获取
3.2使用SOAPHandler处理(SOAPMessageContext)
3.3基于JAXWS-RI的方法
Headers.create(element):可以吧一个dom的element转换为header元素
4.服务器端获取
本节代码基于webservice(七)中的代码,请在其基础上进行修改
服务器端修改代码片段
1.user.wsdl
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://service.zttc.edu.cn"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
name="UserService"
targetNamespace="http://service.zttc.edu.cn">
<!--
wrappered 推荐使用的方式
-->
<wsdl:types>
<xsd:schema targetNamespace="http://service.zttc.edu.cn">
<!-- import是在导入的时候加入了命名空间 -->
<!-- <xsd:import namespace="http://service.zttc.edu.cn" schemaLocation="user.xsd"/> -->
<!-- include是在当前的schema中加入了命名空间 -->
<!-- <xsd:include schemaLocation="user.xsd"/> -->
<xsd:element name="add" type="tns:add"></xsd:element>
<xsd:element name="addResponse" type="tns:addResponse"></xsd:element>
<xsd:element name="delete" type="tns:delete"></xsd:element>
<xsd:element name="deleteResponse" type="tns:deleteResponse"></xsd:element>
<xsd:element name="list" type="tns:list"></xsd:element>
<xsd:element name="listResponse" type="tns:listResponse"></xsd:element>
<xsd:element name="login" type="tns:login"></xsd:element>
<xsd:element name="loginResponse" type="tns:loginResponse"></xsd:element>
<!-- 1.添加异常 -->
<xsd:element name="UserRunTimeException" type="tns:UserRunTimeException"></xsd:element>
<xsd:complexType name="UserRunTimeException">
<xsd:sequence>
<xsd:element name="message" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- 1.header添加权限 -->
<xsd:element name="licenceInfo" type="tns:licenceInfo"></xsd:element>
<xsd:complexType name="licenceInfo">
<xsd:sequence>
<xsd:element name="registUser" type="tns:user"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="add">
<xsd:sequence>
<xsd:element name="user" type="tns:user"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="addResponse">
<xsd:sequence/>
</xsd:complexType>
<xsd:complexType name="delete">
<xsd:sequence>
<xsd:element name="username" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="deleteResponse">
<xsd:sequence/>
</xsd:complexType>
<xsd:complexType name="list">
<xsd:sequence/>
</xsd:complexType>
<xsd:complexType name="listResponse">
<xsd:sequence minOccurs="1" maxOccurs="unbounded">
<xsd:element name="user" type="tns:user"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="login">
<xsd:sequence>
<xsd:element name="username" type="xsd:string"/>
<xsd:element name="password" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="loginResponse">
<xsd:sequence>
<xsd:element name="user" type="tns:user"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="user">
<xsd:sequence>
<xsd:element name="username" type="xsd:string"/>
<xsd:element name="password" type="xsd:string"/>
<xsd:element name="nickname" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="add">
<wsdl:part element="tns:add" name="parameters" />
</wsdl:message>
<wsdl:message name="addResponse">
<wsdl:part element="tns:addResponse" name="parameters" />
</wsdl:message>
<wsdl:message name="delete">
<wsdl:part element="tns:delete" name="parameters" />
</wsdl:message>
<wsdl:message name="deleteResponse">
<wsdl:part element="tns:deleteResponse" name="parameters" />
</wsdl:message>
<wsdl:message name="list">
<wsdl:part element="tns:list" name="parameters" />
</wsdl:message>
<wsdl:message name="listResponse">
<wsdl:part element="tns:listResponse" name="parameters" />
</wsdl:message>
<wsdl:message name="login">
<wsdl:part element="tns:login" name="parameters" />
</wsdl:message>
<wsdl:message name="loginResponse">
<wsdl:part element="tns:loginResponse" name="parameters" />
</wsdl:message>
<!-- 2.创建异常消息 -->
<wsdl:message name="UserRunTimeException">
<wsdl:part element="tns:UserRunTimeException" name="fault" />
</wsdl:message>
<!-- 2.创建header消息消息 -->
<wsdl:message name="licenceInfo">
<wsdl:part element="tns:licenceInfo" name="licenceInfo" />
</wsdl:message>
<wsdl:portType name="IUserService">
<wsdl:operation name="add">
<wsdl:input message="tns:add" />
<wsdl:output message="tns:addResponse" />
<!-- 3.为方法设置异常 -->
<wsdl:fault name="UserRunTimeException" message="tns:UserRunTimeException"/>
</wsdl:operation>
<wsdl:operation name="delete">
<wsdl:input message="tns:delete" />
<wsdl:output message="tns:deleteResponse" />
<!-- 3.为方法设置异常 -->
<wsdl:fault name="UserRunTimeException" message="tns:UserRunTimeException"/>
</wsdl:operation>
<wsdl:operation name="list">
<wsdl:input message="tns:list" />
<wsdl:output message="tns:listResponse" />
</wsdl:operation>
<wsdl:operation name="login">
<wsdl:input message="tns:login" />
<wsdl:output message="tns:loginResponse" />
<!-- 3.为方法设置异常 -->
<wsdl:fault name="UserRunTimeException" message="tns:UserRunTimeException"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="userServiceSOAP" type="tns:IUserService">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="add">
<wsdl:input>
<soap:body use="literal" />
<!-- 3.设置头信息 -->
<soap:header use="literal" part="licenceInfo" message="tns:licenceInfo"></soap:header>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
<!-- 4.进行异常的fault绑定 -->
<wsdl:fault name="UserRunTimeException">
<soap:fault name="UserRunTimeException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="delete">
<wsdl:input>
<soap:body use="literal" />
<!-- 3.设置头信息 -->
<soap:header use="literal" part="licenceInfo" message="tns:licenceInfo"></soap:header>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
<!-- 4.进行异常的fault绑定 -->
<wsdl:fault name="UserRunTimeException">
<soap:fault name="UserRunTimeException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="list">
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="login">
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
<!-- 4.进行异常的fault绑定 -->
<wsdl:fault name="UserRunTimeException">
<soap:fault name="UserRunTimeException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<!-- 在当前文件的最上面的name中填写的 -->
<wsdl:service name="UserService">
<wsdl:port binding="tns:userServiceSOAP" name="userServicePort">
<soap:address location="http://localhost:8080/web-soa/us" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
服务器端service
package cn.edu.zttc.service;
import java.util.List;
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.zttc.dao.UserRunTimeException;
import org.zttc.vo.User;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.4-b01
* Generated source version: 2.2
*
*/
@WebService(name = "IUserService", targetNamespace = "http://service.zttc.edu.cn")
public interface IUserService {
/**
*
* @param user
* @throws UserRunTimeException_Exception
*/
@WebMethod
@RequestWrapper(localName = "add", targetNamespace = "http://service.zttc.edu.cn", className = "cn.edu.zttc.service.Add")
@ResponseWrapper(localName = "addResponse", targetNamespace = "http://service.zttc.edu.cn", className = "cn.edu.zttc.service.AddResponse")
public void add(
@WebParam(name = "user", targetNamespace = "")
User user)
throws UserRunTimeException
;
/**
*
* @param username
* @throws UserRunTimeException_Exception
*/
@WebMethod
@RequestWrapper(localName = "delete", targetNamespace = "http://service.zttc.edu.cn", className = "cn.edu.zttc.service.Delete")
@ResponseWrapper(localName = "deleteResponse", targetNamespace = "http://service.zttc.edu.cn", className = "cn.edu.zttc.service.DeleteResponse")
public void delete(
@WebParam(name = "username", targetNamespace = "")
String username)
throws UserRunTimeException
;
/**
*
* @return
* returns java.util.List<cn.edu.zttc.service.User>
*/
@WebMethod
@WebResult(name = "user", targetNamespace = "")
@RequestWrapper(localName = "list", targetNamespace = "http://service.zttc.edu.cn", className = "cn.edu.zttc.service.List")
@ResponseWrapper(localName = "listResponse", targetNamespace = "http://service.zttc.edu.cn", className = "cn.edu.zttc.service.ListResponse")
public List<User> list();
/**
*
* @param username
* @param password
* @return
* returns cn.edu.zttc.service.User
* @throws UserRunTimeException_Exception
*/
@WebMethod
@WebResult(name = "user", targetNamespace = "")
@RequestWrapper(localName = "login", targetNamespace = "http://service.zttc.edu.cn", className = "cn.edu.zttc.service.Login")
@ResponseWrapper(localName = "loginResponse", targetNamespace = "http://service.zttc.edu.cn", className = "cn.edu.zttc.service.LoginResponse")
public User login(
@WebParam(name = "username", targetNamespace = "")
String username,
@WebParam(name = "password", targetNamespace = "")
String password)
throws UserRunTimeException
;
}
服务器端实现类:(加入了权限控制)
package cn.edu.zttc.service;
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 org.zttc.dao.UserDao;
import org.zttc.dao.UserRunTimeException;
import org.zttc.vo.User;
import com.sun.xml.ws.api.message.Header;
import com.sun.xml.ws.api.message.HeaderList;
import com.sun.xml.ws.developer.JAXWSProperties;
@WebService(endpointInterface="cn.edu.zttc.service.IUserService",
wsdlLocation="WEB-INF/wsdl/user.wsdl",
serviceName="UserService",
portName="userServicePort",
targetNamespace="http://service.zttc.edu.cn")
public class UserServiceImpl implements IUserService {
private UserDao userDao = UserDao.newInstence();
@Resource
private WebServiceContext ctx;
@Override
public void add(User user) throws UserRunTimeException {
checkRegister();
userDao.add(user);
}
@Override
public void delete(String username) throws UserRunTimeException {
checkRegister();
userDao.delete(username);
}
@Override
public List<User> list() {
return userDao.list();
}
@Override
public User login(String username, String password) throws UserRunTimeException {
return userDao.login(username, password);
}
private void checkRegister() throws UserRunTimeException {
try {
HeaderList headers = (HeaderList)ctx.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
QName qname = new QName("http://service.zttc.edu.cn","licenceInfo");
if(headers==null) throw new UserRunTimeException("该功能需要进行权限控制");
Header header = headers.get(qname,true);
if(header==null) throw new UserRunTimeException("该功能需要进行权限控制");
XMLStreamReader xsr = header.readHeader();
User u = x2user(xsr);
User tu = userDao.loadByUsername(u.getUsername());
if(tu==null) throw new UserRunTimeException("你所使用的用户不是系统的授权用户");
if(!tu.getPassword().equals(u.getPassword()))
throw new UserRunTimeException("授权用户的密码信息不正确!");
} catch (XMLStreamException e) {
e.printStackTrace();
}
}
private User x2user(XMLStreamReader xsr) throws XMLStreamException {
User u = new User();
while(xsr.hasNext()) {
int event = xsr.next();
if(event==XMLEvent.START_ELEMENT) {
String name = xsr.getName().toString();
if(name.equals("username")) {
u.setUsername(xsr.getElementText());
} else if(name.equals("password")) {
u.setPassword(xsr.getElementText());
} else if(name.equals("nickname")) {
u.setNickname(xsr.getElementText());
}
}
}
return u;
}
}
修改了服务器端的Dao方法:
package org.zttc.dao;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.zttc.vo.User;
public class UserDao {
private static final Map<String,User> users = new HashMap<String, User>();
private static UserDao dao = null;
public UserDao(){
users.put("admin", new User("admin", "admin", "超级管理员"));
}
public static UserDao newInstence(){
if (null==dao)dao = new UserDao();
return dao;
}
public Set<String> listUsers() {
return users.keySet();
}
public User loadByUsername(String username) {
return users.get(username);
}
public void add(User user) throws UserRunTimeException{
System.out.println("---------add--------"+user);
System.out.println("---------user.getUsername()--------"+user.getUsername());
if (users.containsKey(user.getUsername())) {
throw new UserRunTimeException("用户已存在");
}
users.put(user.getUsername(), user);
}
public void delete(String username){
System.out.println("---------delete--------"+username);
users.remove(username);
}
public List<User> list(){
System.out.println("---------list--------"+users);
Set<String> keys = users.keySet();
List<User> list = new ArrayList<User>();
for (String key : keys) {
list.add(users.get(key));
}
return list;
}
public User login(String username,String password) throws UserRunTimeException{
System.out.println("---------login--------"+username+password);
if (!users.containsKey(username)) {
throw new UserRunTimeException("用户不存在");
}
User u = users.get(username);
if (!password.equals(u.getPassword())) {
throw new UserRunTimeException("用户密码不正确");
}
return u;
}
}
客户端代码:
修改servlet
package org.zttc.service.servlet;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.namespace.QName;
import cn.edu.zttc.service.IUserService;
import cn.edu.zttc.service.User;
import cn.edu.zttc.service.UserRunTimeException_Exception;
import cn.edu.zttc.service.UserService;
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private IUserService port;
private UserService userService;
private String ns = "http://service.zttc.edu.cn";
public UserServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String method= request.getParameter("method");
URL url = new URL("http://localhost:8989/web-soa/us?wsdl");
QName name = new QName(ns,"UserService");
userService = new UserService(url,name);
port = userService.getUserServicePort();
if (null==method||"".equals(method)) {
list(request, response);
}else if ("add".equals(method)) {
add(request, response);
}else if ("delete".equals(method)) {
delete(request, response);
}else if ("login".equals(method)) {
login(request, response);
}
}
private void login(HttpServletRequest request, HttpServletResponse response) {
String username = request.getParameter("username");
String password = request.getParameter("password");
try {
User u = port.login(username, password);
request.getSession().setAttribute("loginUser", u);
response.sendRedirect("user.do");
} catch (UserRunTimeException_Exception e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void delete(HttpServletRequest request, HttpServletResponse response) {
WebUtil.addLicenceHeader(port, request);
String username = request.getParameter("username");
try {
port.delete(username);
response.sendRedirect("user.do");
} catch (IOException e) {
e.printStackTrace();
} catch (UserRunTimeException_Exception e) {
e.printStackTrace();
}
}
private void add(HttpServletRequest request, HttpServletResponse response) {
WebUtil.addLicenceHeader(port, request);
String username = request.getParameter("username");
String password = request.getParameter("password");
String nickname = request.getParameter("nickname");
User u = new User();
u.setNickname(nickname);
u.setPassword(password);
u.setUsername(username);
try {
port.add(u);
response.sendRedirect("user.do");
} catch (IOException e) {
e.printStackTrace();
} catch (UserRunTimeException_Exception e) {
e.printStackTrace();
}
}
private void list(HttpServletRequest request, HttpServletResponse response) {
try {
List<User> list = port.list();
request.setAttribute("users", list);
RequestDispatcher dis = request.getRequestDispatcher("list.jsp");
dis.forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
加入工具类,将添加header信息作为一个公共方法抽取出来
package org.zttc.service.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import cn.edu.zttc.service.IUserService;
import cn.edu.zttc.service.LicenceInfo;
import cn.edu.zttc.service.User;
import com.sun.xml.ws.api.message.Headers;
import com.sun.xml.ws.developer.WSBindingProvider;
public class WebUtil {
private static String ns = "http://service.zttc.edu.cn";
public static void addLicenceHeader(IUserService port,HttpServletRequest request) {
try {
//1、将一个对象转换为xml通过JAXB
JAXBContext ctx = JAXBContext.newInstance(LicenceInfo.class);
User ru = (User)request.getSession().getAttribute("loginUser");
if(ru==null) return;
LicenceInfo info = new LicenceInfo();
info.setRegistUser(ru);
QName name = new QName(ns,"licenceInfo");
JAXBElement<LicenceInfo> jele = new JAXBElement<LicenceInfo>(name,LicenceInfo.class,info);
Marshaller mars = ctx.createMarshaller();
mars.setProperty(Marshaller.JAXB_FRAGMENT,true);
mars.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
//2、转换为DOM
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
mars.marshal(jele, doc);
//3、通过Headers.create方法完成header的添加
//获取WSBindingProvider
WSBindingProvider wsb = (WSBindingProvider)port;
wsb.setOutboundHeaders(Headers.create(doc.getDocumentElement()));
} catch (PropertyException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
}
}