WebService(CXF)中对HttpSession的控制

来源:互联网 发布:天刀成男脸型数据 编辑:程序博客网 时间:2024/05/18 09:21

我的收获:

平时基于Web开发动态网页时浏览器帮我们做了关于Session的很多工作,使得我们可能不是很理解客户端和服务器端对于Session究竟是如何管理的,在不基于浏览器的Web开发中,对于Session的管理需要在客户端自己处理,主要为获取Http请求返回的SessionID(如果在服务器端创建了Session),并在下次请求的时候带上这个SessionID,服务器端才能知道是同一个会话,从而可以取得服务器上该Session的信息。

以下内容是在学习过程中摘自网上一位大神的博客(http://lanyerzz.blog.163.com/blog/static/927350720117893254375/),思路清晰,讲解到位,最后为本人修改其代码后跑通的样例。

--------------------------------------------------------------------------------------------------------------------

服务端的session管理依赖 客户端 cookie


cookie中保存有sessionid信息 例如:JSESSIONID=BEE4AE5877D573CE774701566E93477B

原理:

当客户端第一次通过http访问服务端的时候,cookie 中的 sessionid 是空的,服务器就会创建新的session,service并把session信息(JSESSIONID)通过header 返回给客户端。

当客户端再次访问service的时候,http请求的header中存有 上次service创建的sessionid信息,service在session管理器中查找对应sessionid的session,如果找到(说明session未过期),服务端不会创建新的session。

如果未找到(说明session过期),服务端会创建新的session。

cxf:

因为cxf客户端每次访问service后,虽然服务端会把sessionid返回给客户端,但是cxf再次访问的时候,并不会把这个sessionid信息通过cookie传给服务端。因此服务端会对客户端的每次访问都会创建新的session。


如果客户端的访问过多,频率很高,会导致服务端的session未及时释放,内存溢出。

通常的做法是 把服务端的session 的timeout 设置的更短,保证session 及时释放。


让cxf客户端记住sessionid:


import java.util.HashMap;import java.util.List;import java.util.Map;import javax.xml.ws.handler.LogicalHandler;import javax.xml.ws.handler.LogicalMessageContext;import javax.xml.ws.handler.MessageContext;import org.apache.cxf.jaxws.handler.logical.LogicalMessageContextImpl;public class SessionLogicalHandler implementsLogicalHandler<LogicalMessageContext> {public SessionLogicalHandler() {super();}// 静态 所有的 SessionLogicalHandler 共享 一个 cookiepublic static List<String> http_headers_cookie = null;@Overridepublic boolean handleMessage(LogicalMessageContext context) {// TODO Auto-generated method stub// javax.xml.ws.handler.MessageContext.Scope s=// context.getScope(MessageContext.HTTP_REQUEST_HEADERS);// Set-Cookie=[JSESSIONID=48B10A68BB05F69F8ED82A33F566C5D8; Path=/myapp;// HttpOnly]LogicalMessageContextImpl c = (LogicalMessageContextImpl) context;// response 时记录服务端返回的session信息if (c.get(MessageContext.HTTP_RESPONSE_HEADERS) != null) {Map<String, List> header = (Map<String, List>) c.get(MessageContext.HTTP_RESPONSE_HEADERS);List<String> ls = header.get("Set-Cookie");// 获取header 中cookie的信息if (ls != null) {System.out.println(ls.get(0).split(";")[0]);this.http_headers_cookie = ls;// 保存cookie信息}} else if (c.get(MessageContext.HTTP_REQUEST_HEADERS) != null&& http_headers_cookie != null) {// request 请求的时候 把cookie信息设置进去Map<String, List> header = (Map<String, List>) c.get(MessageContext.HTTP_REQUEST_HEADERS);header.put("cookie", http_headers_cookie);} else if (c.get(MessageContext.HTTP_REQUEST_HEADERS) == null&& http_headers_cookie != null) {// request 请求的时候 把cookie信息设置进去Map<String, List> header = new HashMap<String, List>();header.put("cookie", http_headers_cookie);c.put(MessageContext.HTTP_REQUEST_HEADERS, header);}return true;}@Overridepublic boolean handleFault(LogicalMessageContext context) {// TODO Auto-generated method stubreturn false;}@Overridepublic void close(MessageContext context) {// TODO Auto-generated method stub}}

设置handler:

import java.util.HashMap;import java.util.Map;import org.apache.cxf.endpoint.Client;import org.apache.cxf.frontend.ClientProxy;import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;import org.apache.cxf.transport.http.HTTPConduit;import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;import com.cfets.fxo.u.wsp.ws.IWsServerInfo;public class WsClassLoader { // 本地private static String WS_HOST = "http://localhost:8080/fxoption/ws";private JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();private WsClassLoader() {}private static WsClassLoader instance;public static synchronized WsClassLoader getInstance() {if (instance == null) {instance = new WsClassLoader();// 设置 handlerinstance.factory.getHandlers().add(new SessionLogicalHandler());}return instance;}private Map<String, Object> wsCache = new HashMap<String, Object>();@SuppressWarnings("unchecked")public <T> T getWs(String address, Class<T> t) {if (wsCache.get(t.getName()) == null) {factory.setServiceClass(t);String addressFull = WS_HOST + address;factory.setAddress(addressFull);Object client = factory.create();// /开始超时设置Client proxy = ClientProxy.getClient(client);// proxy.get().add(new LogicalLoggingHandler());HTTPConduit conduit = (HTTPConduit) proxy.getConduit();HTTPClientPolicy policy = new HTTPClientPolicy();policy.setConnectionTimeout(3000);policy.setReceiveTimeout(0);conduit.setClient(policy);// /结束超时设置wsCache.put(t.getName(), client);}return (T) wsCache.get(t.getName());}public static void main(String[] args) {IWsServerInfo client = (IWsServerInfo) WsClassLoader.getInstance().getWs("/serverinfo", IWsServerInfo.class);client.setSessionInfo();String sessionInfo = client.getSessionInfo();System.out.println(sessionInfo);}}


0 0
原创粉丝点击