WebService(CXF)中对HttpSession的控制

我的收获:

平时基于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 implements
		LogicalHandler<LogicalMessageContext> {

	public SessionLogicalHandler() {
		super();
	}

	// 静态 所有的 SessionLogicalHandler 共享 一个 cookie
	public static List<String> http_headers_cookie = null;

	@Override
	public 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;
	}

	@Override
	public boolean handleFault(LogicalMessageContext context) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public 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();
			// 设置 handler
			instance.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值