Servlet第四天会话与状态

 

1.会话

什么是会话?

会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。

会话过程中要解决的一些问题?

  • 每个用户与服务器进行交互的过程中,各自会有一些数据,程序要想办法保存每个用户的数据。
2.Cookie

  Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。

1.案例:返回上次访问时间

public class CookieTest extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.print("<a href='/day07/CookieTest2'>清除上次访问时间</a>");
        out.print("你上次访问时间是:");
        // 获得用户的时间cookie
        //获取cookie数组
        Cookie[] cookies = request.getCookies();
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            if (cookies[i].getName().equals("lastAccessTime")) {
                // 获取上次访问的时间
                long value = Long.parseLong(cookies[i].getValue());
                Date date = new Date(value);
                out.print(date.toLocaleString());
            }
        }
        // 返回新的访问时间
        Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()
                + "");
        // setMaxAge() 设置有效期 单位是秒 默认有效期是浏览器进程
        cookie.setMaxAge(30 * 24 * 3600);
        // 设置cookie path
        cookie.setPath("/day07");
        response.addCookie(cookie);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

  2.Cookie细节

一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。

一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。

浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。

注意,删除cookie时,path必须一致,否则不会删除(默认:产生cookie服务器资源所在path)

删除上次访问时间

public class CookieTest2 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()
                + "");
        // 设置有效期
        cookie.setMaxAge(0);
        cookie.setPath("/day07");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

3.Session

    在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。

Session生命周期:

session创建:当客户端访问服务器,服务器端还没有该会话的session对象时,创建。request.getSession()--创建

session销毁:三种情况:1.服务器停止,2.session.invalidate 3.session过期(session.setMaxInactiveInterval)、配置web.xml(单位分钟 ,默认30分钟)

案例 1:购买商品

/**
* 购买商品
*
* @author malinkang
*
*/
public class SessionTest extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取用户的Session
        HttpSession session = request.getSession();
        // 获取Session Id
        String sessionid = session.getId();
        //session将id存入cookie 从而区分是那个用户的session
        Cookie cookie = new Cookie("JSESSIONID", sessionid);
        cookie.setPath("/day07");
        cookie.setMaxAge(30 * 60);
        response.addCookie(cookie);
        // 获取Session的重载形式
        // request.getSession(false);
        //
        session.setAttribute("product", "洗衣机");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

public class SessionTest2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        String product = (String) session.getAttribute("product");
        out.write("你购买的商品是" + product);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

 

浏览器禁用cookie处理方案:

 

案例:防止表单提交

客户端防止提交

<script type="text/javascript">
var isCommitted false;
function checkPost(){
    if(!isCommitted){
        isCommitted=true;
        return true;
    }else{
        return false;
    }
}
</script>

服务端防止重复提交

1.表单页面由servlet程序生成,servlet为每次产生的表单页面分配一个唯一的随机标识号,并在FORM表单的一个隐藏字段中设置这个标识号,同时在当前用户的Session域中保存这个标识号。

2.当用户提交FORM表单时,负责处理表单提交的serlvet得到表单提交的标识号,并与session中存储的标识号比较,如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。

在下列情况下,服务器程序将拒绝用户提交的表单请求:

1.存储Session域中的表单标识号与表单提交的标识号不同

2.当前用户的Session中不存在表单标识号

3.用户提交的表单数据中没有标识号字段

工具类:

import java.util.UUID;

//令牌
public class TokenProcessor {
    // 生成唯一标识
    public static String getToken() {
        // UUID技术
        return UUID.randomUUID().toString();
    }
}

表单提交

<%
//获取令牌
String token=TokenProcessor.getToken();
session.setAttribute("session_token",token);
%>
<form method="post" action="/day07/SessionTest3" onsubmit="return checkPost()">
用户名:<input type="text" name="username"/>"
密码:<input type="text" name="password"/>
<input type="hidden" name="token" value="<%=token %>"/>
<input type="submit" value="登陆"/>
</form>

处理方法

public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    // 模拟网路延时
    try {
        Thread.sleep(5 * 1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    String token = request.getParameter("token");
    String session_token = (String) request.getSession().getAttribute(
            "session_token");
    request.getSession().removeAttribute("session_token");
    if (token.equals(session_token)) {
        String username = request.getParameter("username");
        System.out.println(username);
    }

}

案例三:用户登陆注销

登陆界面

<form action="/day07/LoginServlet" method="post">
用户名:<input type="text"  name="username"/><br/>
密码:<input type="password" name="password" /><br/>
<input type="submit" value="提交"/>"
</form>"

 

登陆处理:

public class LoginServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        DB db = new DB();
        List<User> users = db.getAll();
        for (User user : users) {
            if (username.equals(user.getUsername())
                    && password.equals(user.getPassword())) {
                request.getSession().setAttribute("user", user);
                response.sendRedirect("/day07/index.jsp");
                return;
            }
        }
        out.write("用户名或密码错误");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

class DB {
    private static List<User> list = new ArrayList<User>();
    static {
        list.add(new User("aaa", "123"));
        list.add(new User("bbb", "123"));
        list.add(new User("ccc", "123"));
    }

    public static List<User> getAll() {
        return list;
    }
}

跳转到首页处理:  欢迎你:${user.username}

注销 :删除session

 

案例四:用户一次验证

posted @ 2012-10-04 15:09  Carve_Time  阅读(189)  评论(0)    收藏  举报