`
schy_hqh
  • 浏览: 542336 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

通过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转换对象为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();
		}
		
	}

}

 

分享到:
评论

相关推荐

    java的实现权限控制shiro jwt.docx

    但是这样做有一个缺点,就是不能够对GET,POST等请求进行分别过滤鉴权(因为我们重写了官方的方法),但实际上对应用影响不大 */ @Override protected boolean isAccessAllowed... // 认证出现异常,传递错误信息msg

    微信开发网页获取用户信息封装类 传入(AppID AppSecret)

    微信开发网页获取用户信息封装类2.0授权 传入(AppID AppSecret)即可获取用户信息 直接获取openid不需要用户授权。 友情提示:需要认证的服务号才有获取权限的资格

    Nepxion Discovery【探索】框架指南 V5.4.0.pdf

    基于Header传递的全链路灰度路由,网关为路由触发点。采用配置中心配置路由规则映射在网 关过滤器中植入Header信息而实现,路由规则传递到全链路服务中。路由方式主要包括版本和 区域的匹配路由、版本和区域的权重...

    xmljava系统源码-JWT-DEMO:SpringBoot整合JWT完成权限验证功能示例

    对象行使安全的传递信息。因为数字签名的存在,这些信息是可信的。 广义上讲JWT是一个标准的名称;狭义上讲JWT指的就是用来传递的那个token字符串。 JWT的组成 JWT含有三个部分: 头部(header) 载荷(payload) ...

    autobob-teams:Autobob,适用于团队

    漫游器/消息传递扩展Bot允许用户通过文本,交互卡和任务模块与您的Web服务进行交互。 消息传递扩展允许用户通过Microsoft Teams客户端中的按钮和表单与您的Web服务进行交互。 他们可以在外部系统中从撰写消息区域,...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例229 通过header函数进行下载 295 4.3 文件遍历 296 实例230 读取整个文件的内容 296 实例231 文本文件的分页读取 298 4.4 文件操作 300 实例232 文件操作汇总 300 实例233 目录、文件定位器 302 实例234 ...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例229 通过header函数进行下载 295 4.3 文件遍历 296 实例230 读取整个文件的内容 296 实例231 文本文件的分页读取 298 4.4 文件操作 300 实例232 文件操作汇总 300 实例233 目录、文件定位器 302 实例234 ...

    PHP程序开发范例宝典III

    实例188 通过ADO方式实现指定时间段的信息检索 294 实例189 通过函数实现商品信息的检索 296 实例190 通过ADO方式实现输入页码跳转到指定页 297 实例191 通过函数实现单击页码跳转到指定页 300 实例192 ...

    超级有影响力霸气的Java面试题大全文档

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    pgen:低级网络数据包生成器-开源

    用于基于用户传递的配置文件创建各种网络数据包。 pgen 从 ether-header 本身构建数据包,并使用 RAW 套接字发送数据包。 所以你需要拥有root权限才能使用pgen。 pgen 是一个独立的二进制文件。 截至目前,它不依赖...

    幻影Webzine.1.7z

    赖于Http协议实现,Http是无状态的协议,所以为了在各个会话之间传递信息,就不可避免地 用到Cookie或者Session等技术来标记访问者的状态,而无论是Cookie还是Session,一般都 是利用Cookie来实现的(Session其实是...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

Global site tag (gtag.js) - Google Analytics