Java for Web学习笔记(十八):Session(2)Session的使用

session-config

我们可以在web.xml对app的session进行设置:

<!-- 1、在session-config以及其里面的cookie-config参数是可选的,但是他们必须按顺序出现。 -->
<!-- 2、这些值都有缺省值,我们可以不做处理,但是基于安全考虑,建议设置。  -->
<session-config>
	<!-- session-timeout 单位分钟,如果<=0,则表示无限期,tomcat的缺省值是30分钟,表示如果30分钟内没有收到新的request,认为session无效 -->
	<session-timeout>30</session-timeout> 
	<cookie-config>
		<name>JSESSIONID</name> 	<!-- 名字,缺省是JSESSIONID -->
<!-- domain和path对应Cookie中的Domain和Path属性,这两个数值一般采用缺省,不要去设置,path缺省是应用的context名字 -->
		<domain>flowingflying.com</domain>
		<path>/aaa</path> 
<!-- comment是Cookie头中的Comment属性,用于向用户解析cookie的用途,并引导用户到网站的隐私条例 -->
		<comment>![CDATA[Keeps you logged in.See our private policy for more informcation.]]</comment>
		<http-only>true</http-only> <!-- Cookie头中的Http-Only属性 -->
		<secure>false</secure> <!-- Cookie头中的Secure属性 -->
<!-- Cookie头中的Max-Age属性,单位为秒,一般不设置,当浏览器关闭时cookie结束,如果设置-1,效果也一样。可以设置为某个值,但这有可能用户在浏览器用了半道,session就结束了。因此一般不设置。(注)很多浏览器选择在关闭时仍记忆cookie,特别是桌面浏览器 -->
		<max-age>1800</max-age> 
	</cookie-config>
	<!-- track-mode是在Servlet 3.0加入,表示container需要使用什么技术跟踪session id。-->
	<!-- 1、URL:container将session ID嵌入到URL中,这种方式不安全 -->
	<!-- 2、COOKIE:使用COOKIE,这种方式安全 -->
	<!-- 3、SSL:使用SSL Session ID作为HTTP的session ID,这种最为安全,但是要求所以的请求都是HTTPS的。-->
	<!-- 可以使用其中一种或者多种,如果不提供URL,则不会在URL中嵌入Session ID,-->
	<!-- 如果同时采用URL,COOKIE,则优先采用COOKIE,同时也支持URL方式 -->
	<!-- 如果采用了SSL,就不能采用URL或者COOKIE。	 -->
	<tracking-mode>COOKIE</tracking-mode>
	<tracking-mode>URL</tracking-mode>
	<tracking-mode>SSL</tracking-mode>
</session-config>

在代码中,可以在ServletContextListener的contextInitialized()和ServletContainerInitializer的onStartup()中设置tracking mode和cookie-config。对ServletContext使用setSessionTrackingModes()进行设置;通过getSessionCookieConfig()获取javax.servlet. SessionCookieConfig,然后进行设置。

下面是一个配置的例子:

<session-config>
	<session-timeout>30</session-timeout> 
	<cookie-config>
		<path>/chapter05</path>
		<http-only>true</http-only>
	</cookie-config>
	<tracking-mode>COOKIE</tracking-mode>
</session-config>

我们注意到有些浏览器关闭,然后重新开启,发送的请求仍然会携带session ID在cookie中,例如firefox,很多桌面的浏览器均会如此,也即:浏览器关闭,cookie仍旧保持,在重启后有效。这是由浏览器来决定如何处理的。

一个小例子

这是一个在购物车cart上加入货品的例子,不使用数据库,利用session进行存放。

//products是用来存放货品id和货品名称的列表
private final Map<Integer, String> products = new Hashtable<>();

/* 请求中带有product Id,表明用户将该id对应的货品放入到自己的cart中*/
private void addToCart(HttpServletRequest request, HttpServletResponse response) throws IOException{
	int productId;
	try{
		productId = Integer.parseInt(request.getParameter("productId"));
	}catch(Exception e){
		response.sendRedirect("shop");
		return;
	}
	
	//getSession()等同于getSession(true),获取session,如无,则创建新的,因此不会返回null。如果是getSession(false),则获取session,如无,也不创建,返回null。
	HttpSession session = request.getSession();
	//在session中,用户的cart的键值对是("cart",HashMap对象),如无,包括request请求中没有session ID以及虽有session ID但是并不在web container中存在的(可能web server重启,可能过期什么的),则创建之。Session中键值对可以存放复杂的数据结构的对象,不只是简单的String。删除键值对有session.removeAttribute( )方法。
	if(session.getAttribute("cart") == null)
		session.setAttribute("cart", new HashMap<Integer,Integer>());
	
//在当中找到相应的货品id,如果创建之,数量+1。
	@SuppressWarnings("unchecked")
	HashMap<Integer,Integer> cart = (HashMap<Integer,Integer>)session.getAttribute("cart");
	if(!cart.containsKey(productId)){
		cart.put(productId, 0);
	}
	cart.put(productId,cart.get(productId) + 1);
	
//在用户session的购物车中增加货品后,调用购物车显示业务,显示给用户看
	response.sendRedirect("shop?action=viewCart");
}

private void viewCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
	request.setAttribute("products", products);
	request.getRequestDispatcher("/WEB-INF/jsp/view/viewCart.jsp").forward(request, response);
}

上面是个java中使用session的例子,显示购物车,通常采用jsp的方式,如上例将之forward到/WEB-INF/jsp/view/viewCart.jsp中进行处理。利用session.getAttribute()获取session中的信息。

<%@ page import="java.util.Map" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>View Cart</title>
</head>
<body>
	<h2>View Cart</h2>
	<%
	@SuppressWarnings("unchecked")
	Map<Integer,String> products = (Map<Integer,String>)request.getAttribute("products");
     //使用session.getAttribute()获取session中保存的信息
	@SuppressWarnings("unchecked")
	Map<Integer,Integer> cart = (Map<Integer,Integer>)session.getAttribute("cart");
	if(cart == null || cart.size() == 0){
		out.println("Your cart is empty.");
	}else{
		for(int id : cart.keySet()){
			out.println(products.get(id) + " (quantity:" + cart.get(id)+ ")<br/>");
		}
	}
	%>
</body>
</html>

其它常用方法

除了在小例子使用的方法,HttpSession还有以下常用的方法:

  • getId():获取session ID
  • getCreationTime():创建时间
  • getLastAccessedTime(): 用户最近一次request中带有该session ID的时间
  • isNew():是否是新建的session ID
  • getMaxInactiveInterval()是多长时间内无该session id的请求到达,则session无效。这个时间就是配置中的<session-timeout>的时间。相应的setMaxInactiveInterval可以用来针对该特定的session进行设定。例如管理员的权限比一般用户高,可以针对管理员的session,设置更短的时间。
  • invalidate():这个通常在用户logout时调用,相当于删除这个session

Login和Logout

下面是用户login成功后的处理:

//设置session的某个属性,例如用户名
session.setAttribute("username", username); 
//修改session ID,避免用户一直使用某个session id,这是避免fixation攻击的一种方式,在Java EE 7版本后支持。
request.changeSessionId();
//登录后重定向到某个页面
response.sendRedirect("/tickets"); 

其相应给出:

Java for Web学习笔记(十八):Session(2)Session的使用_第1张图片

而在其它的servlet中:

//如果没有注册,返回登记界面
if(request.getSession().getAttribute("username") == null){
	response.sendRedirect("/login");
	return;
}

当用户按logout,例如链接为/login?logout,那么在loginservletdoGet加上:

if(request.getParameter("logout") != null){
	session.invalidate();
	response.sendRedirect("login");
	return;
}

相关链接: 我的Professional Java for Web Applications相关文章

你可能感兴趣的:(Java for Web学习笔记(十八):Session(2)Session的使用)