Using session in Servlet:
/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().write("Servlet HelloWorld!"); HttpSession session = request.getSession(false); if(session == null) { response.sendRedirect("ServletLogin"); return; }else { System.out.println(session.getId()); Integer totalAccess = (Integer) session.getAttribute("totalAccess"); // Get session attribute; if(totalAccess == null) { totalAccess = 0; } totalAccess += 1; session.setAttribute("totalAccess", totalAccess); // set attribute response.getWriter().write("TotalAccess: " + session.getAttribute("totalAccess")); }
Using session in JSP:
Jsp page directive:
<%@ page
[ language=”java” ]
[ extends=”package.class” ]
[ import=”{package.class | package.*}, …” ]
[ session=”true | false” ]
[ buffer=”none | 8kb | sizekb” ]
[ autoFlush=”true | false” ]
[ isThreadSafe=”true | false” ]
[ info=”text” ]
[ errorPage=”relativeURL” ]
[ contentType=”mimeType [ ;charset=characterSet ]” | “text/html ; charset=ISO-8859-1” ]
[ isErrorPage=”true | false” ]
%>
“session = true” by default. when access “session”, if session is not existing, will create one by default.
we can set:
<%-- Prevent the creation of a session –%>
<%@ page session="false">
to prevent the Creation of a Session in a JSP Page.
We didn’t mention about the thread safe of session, here is a post from IBM DW:
http://www.ibm.com/developerworks/library/j-jtp09238/index.html
response.sendRedirect(“ServletLogin”); // User not login, redirect to the login page.
“redirect sets the response status to 302, and the new url in a
Location
header, and sends the response to the browser. Then the browser, according to the http specification, makes another request to the new url”And you can forward to any URL.
request.getServletContext().getRequestDispatcher(“/s/HelloWorld”).forward(request, response);
forward happens entirely on the server. The servlet container just forwards the same request to the target url, without the browser knowing about that. Hence you can use the same request attributes and the same request parameters when handling the new url. And the browser won’t know the url has changed (because it has happened entirely on the server)
So we can get the parameters in the target method:
request.getParameter(“userName”) // HelloWorld…doPost()..
Ref: http://stackoverflow.com/questions/6068891/difference-between-jsp-forward-and-redirect
this picture is from: http://lukejin.iteye.com/blog/586091
实践
创建一个简单的计算器, 当用户输入整数时, 输出其平方值. 但用户需要登录才能进行操作, 用户的登录信息放在web.xml中, 每次登录用户可以使用该计算器三次, 三次使用结束后, 提示用户推出后重新登录继续使用.
User Case 用例 |
登录系统 |
||
Brief description |
登录系统 |
||
Scope/Level |
AthenaES/User goal |
Primary actor/role |
Root |
Minimal & Success Guarantees 保证 |
Minimal: The system logs how far it may get |
||
Preconditions 前提 |
无 |
||
Triggers 引发条件 |
用户打开登录界面 |
||
Main Success Scenario 成功场景 |
1. 系统提示用户输入用户名及密码 |
||
Extension 扩展 #1 |
3a: 系统无法核实用户身份, 提示其用户名或密码错误, 并提示用户重新输入 |
||
Notes and Issues |
无 |
User Case 用例 |
计算平方 |
||
Brief description |
计算平方 |
||
Scope/Level |
AthenaES/User goal |
Primary actor/role |
Root |
Minimal & Success Guarantees 保证 |
Minimal: The system logs how far it may get |
||
Preconditions 前提 |
Actor is logged in |
||
Triggers 引发条件 |
用户点击”计算” |
||
Main Success Scenario 成功场景 |
1. 确认用户使用次数未达到上限 |
||
Extension 扩展 #1 |
1a: 用户使用次数达到上限, 系统提示用户重新登陆后继续使用 |
||
Extension 扩展 #2 |
4a: 系统检测到用户输入不合法, 系统提示用户重新输入 用户重新进行2~4 |
||
Notes and Issues |
无 |
1. ServltContext层次的数据: 由于用户名及最大限制次数等信息在整个Servlet进程中都会被使用, 因此使用Context的Listener来实现.
2. Session层次的数据: 用户本次登录已使用次数应记录在Seesion中, 在当前Session中使用
3. Request层次的数据: 用户输入的数值尽在当前Request中使用
Calc主页面实现: |
首先检查Session是否存在, 不存在则跳转到登录界面. |
package com.insprise.servletStu; //省略import public class Calc extends HttpServlet { public static final String MAX_CALCULATIONAS_PER_SESSION = “maxNumber”; // 最大使用次数的Key public static int MAX_CALCULATION_TIMES_PER_SESSION; // 最大使用次数 public static final String CURRENT_USER = “currentUser”; // 当前用户 public static final String URL_MAIN = “./Calc”; // 主页面 public static final String URL_LOGIN = “./Login”; // 登录页面 public static final String URL_LOGOUT = “./Logout”; // 注销页面 private static final String ACCESS_COUNT = “accessCount”; // 使用次数 private static final String INPUT_INT = “inputInt”; private static Logger log = Logger.getLogger(Calc.class); private static final int MAX_INT = 46340; // Math.sqrt(Integer.MAX_VALUE) private HttpSession session; private Integer accessCount; // 使用次数 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { session = request.getSession(false); if (validatUser(session)) { // 已登录 accessCount = (Integer) session.getAttribute(ACCESS_COUNT); if (accessCount == null) { // 如果Session中不存在accessCount, 则表明其为新登录用户, // 赋值为0; accessCount = 0; session.setAttribute(ACCESS_COUNT, accessCount); } if (checkUseTimes(accessCount)) { // 已登录, 且使用次数在限制之内, 进行操作. proccessRequet(request, response); } else { // 已登录, 但使用次数操过限制,提示用户重新登陆. accessOverTime(request, response); } } else { // 未登录 response.sendRedirect(URL_LOGIN); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { doGet(request, response); } // 检查用户是否已登录 private boolean validatUser(HttpSession s) { if (session != null) { return true; } return false; } // 检查用户使用次数是否超过限制 private boolean checkUseTimes(Integer number) { //省略 } // 使用次数超过限制之后 提示其登录; private void accessOverTime(HttpServletRequest request, HttpServletResponse response) throws IOException { request.getSession().invalidate(); response.getWriter().println("本次登录已使用完毕, 请重新登录"); return; } // 获得输入数值, 计算结果, 返回信息 private void proccessRequet(HttpServletRequest request, HttpServletResponse response) throws IOException { Integer i; String title = "求整数平方"; response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); // 不使用缓存 在点击推出后 按后退按钮时 不会出现缓存中的内容. response.setHeader("Cache-Control", "no-store"); response.setDateHeader("Expires", 0); response.setHeader("Pragma", "no-cache"); PrintWriter out = response.getWriter(); out.println(ServletUtilities.headwithTitle(title)); out.println("" + title + "
"); out.println("当前用户: " + session.getAttribute(CURRENT_USER) + " [退出]
"); String numberString = request.getParameter(INPUT_INT); if (numberString != null) { try { out.println("" + i + " 的平方是: " + calculator(i) + "
"); log.info("累计第[" + accessCount + "]次使用, 本次计算的参数为: " + i); } catch (Exception e) { out.println("您可能输入的不是整数 或您输入的整数绝对值过大请输入: 一个绝对值小于" + MAX_INT + " 的整数
"); } } out.println("您总共可以使用 " + MAX_CALCULATION_TIMES_PER_SESSION + "次, 您已累计使用:" + accessCount + "次
"); // 最后一次运行时, 停止输出Form; if (accessCount.equals(MAX_CALCULATION_TIMES_PER_SESSION)) { out.println("已达到最大使用次数限制, 请退出后重新登陆"); return; } printForm(out); out.println(""); } // 计算 private int calculator(int i) { accessCount = new Integer(accessCount.intValue() + 1); // 使用次数增加一次 session.setAttribute("accessCount", accessCount); return i * i; } // 打印一个Form private void printForm(PrintWriter out) { out.print("
// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.