zoukankan      html  css  js  c++  java
  • Java_web——Session技术

    1、Session当服务器运行到request.getSession()时就会被创建(当此用户Session已存在就不会再创建)

    2、Session默认当30分钟没人使用就会摧毁(或者你调用Session.invalidate()就会被摧毁)

    3、request.getSession(false)只会获取已存在的Session,就算对这个用户的Session不存在也不会创建

    4、Session的多长时间没人使用就摧毁可以定义在web.xml文件中

    //10分钟不使用的Session就摧毁掉
    <session-config>
        <session-timeout>10</session-timeout>
    </session-config>

    5、request.getSession()是怎么样判断这个用户的session是否存在呢?

    其实每一个session都有一个id号,服务器把这个id号以cookie的形式写会用户浏览器,但是这个cookie的生存时间是默认的(也就是说当用户的浏览器进程一旦终止,这个cookie也就没有了)

    下面我们写一个设置session的id有效期的代码:

    购买SessionDemo.java

    package test;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * Servlet implementation class SessionDemo
     */
    @WebServlet("/SessionDemo")
    public class SessionDemo extends HttpServlet {    //购买
        private static final long serialVersionUID = 1L;
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            HttpSession session = request.getSession();
            String sessionid = session.getId(); //获取session的id
            Cookie cookie = new Cookie("JSESSIONID",sessionid); //session把id写回浏览器时用的Cookie名为JSESSIONID
            cookie.setPath("/day02");
            cookie.setMaxAge(30*60); //设置cookie有效期为30分钟
            response.addCookie(cookie);
            session.setAttribute("name", "洗衣机");
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }

    结账SessionDemo1.java

    package test;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * Servlet implementation class SessionDemo1
     */
    @WebServlet("/SessionDemo1")
    public class SessionDemo1 extends HttpServlet {  //结账
        private static final long serialVersionUID = 1L;
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            
            HttpSession session = request.getSession();
            String product = (String) session.getAttribute("name");
            out.write("你购买得商品为:"+product);
            
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }

    ind.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <a href="/day02/SessionDemo">购买</a>
    <a href="/day02/SessionDemo1">结账</a>
    </body>
    </html>

    5、response有一个方法encodeURL(示例:response.encodeURL("/day02/SessionDemo")),这个方法你需要提供给它一个链接,它会返回给你一个链接,返回给你的链接后面可能会把session的id追加到后面(为什么说可能,因为如果服务器检测到你带cookie来了,那就说明你的浏览器没有禁用cookie,那么session就可以正常工作,那么就不会把session的id追加到链接后面。但是如果你禁用session了,那么这个函数就会把session的id追加到你提供链接后面)。当第一次访问这个网站,服务器不知道你禁用cookie了没有,那么服务器即会给你以cookie形式返回session的id,还会给你提供的链接后面把session的id追加上去。

    6、用session解决表单重复提交的问题

    表单重复提交:当提交表单之后一旦刷新你之前做的事情就会重新做一次

    或者是由于网络延迟,导致你点击提交按钮多次,都会让服务器接收到多次提交表单的信息

    这个问题可以由JavaScript来解决,代码如下:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
        <script type="text/javascript">
            /* 第一种JavaScript解决表单重复提交
            var issub = false;
            function dosubmit(){
                if(!issub){
                    issub=true;
                    return true;
                }else {
                    return false;
                }
            }*/
            //第二种解决表单重复提交
            function dosubmit(){
                var input = document.getElementById("submit");
                input.disable='disable';
                return true;
            }
        </script>
    </head>
    <body>
        <form action="/day02/SessionDemo2" method="post" onsubmit="return dosubmit()">
        用户名2:<input name="username" type="text"><br/>
        <input id="submit" type="submit" value="提交" ><br/>
        </form>
    </body>
    </html>

    但是这种方法是不彻底的,因为JavaScript代码可以在用户浏览器上被用户更改而使得没有彻底解决问题,或者用户提交表单之后刷新,或者用户不断地点击前进和后退按钮。

    在这种情况下我们使用session来解决这个问题,我们给予每一个表单一个表单号,存放到session中,如果这个表单被提交过了就把相应的表单号从session中删除,一个表单号只能用于提交一次。

    formRandom.java

    package test;
    
    import java.io.IOException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Random;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import sun.misc.BASE64Encoder;
    
    /**
     * Servlet implementation class formRandom
     */
    //产生表单
    @WebServlet("/formRandom")
    public class formRandom extends HttpServlet {
        private static final long serialVersionUID = 1L;
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            //产生表单号
            TokenRandom tr = TokenRandom.getRandom();
            String token = tr.generateRandom();
            request.getSession().setAttribute("token", token);
            request.getRequestDispatcher("/form.jsp").forward(request, response);
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    class TokenRandom{
        //采用单例模式:在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。
        /*步骤
         * 1、构造方法私有化
         * 2、自己创建一个
         * 3、对外暴露一个方法,允许获得上面创建的对象
         */
        private TokenRandom() {}
        private static final TokenRandom random = new TokenRandom();
        public static TokenRandom getRandom() {
            return random;
        }
        public String generateRandom() {
            String token = System.currentTimeMillis()+new Random().nextInt()+"";
            //上面产生的字符串长度不一致,我们需要使用md5得到token字符串的摘要,获得的字符串md5摘要长度为128位
            try {
                MessageDigest md = MessageDigest.getInstance("md5");
                byte[] md5 = md.digest(token.getBytes());
                //又因为我们需要获得一个字符串,所以我们采用base64把md5摘要过的byte数组转换为字符串
                BASE64Encoder encoder = new BASE64Encoder();
                return encoder.encode(md5);
            }catch(NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            }
        }
    }

     给一个Base64算法的内部实现:https://blog.csdn.net/benbenxiongyuan/article/details/7756912

    SessionDemo2.java

    package test;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class SessionDemo2
     */
    @WebServlet("/SessionDemo2")
    public class SessionDemo2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            boolean b = isTokenValid(request);
            if(!b) {
                out.print("请不要重复提交"+"<br/>");
                return;
            }
            request.getSession().removeAttribute("token");
            System.out.println("向数据库注册用户");
        }
        
        
    
        private boolean isTokenValid(HttpServletRequest request) {
            // TODO Auto-generated method stub
            String client_token = request.getParameter("token");
            if(client_token==null) {
                return false;
            }
            String server_token = (String) request.getSession().getAttribute("token");
            if(server_token==null) {
                return false;
            }
            if(!server_token.equals(client_token)) {
                return false;
            }
            return true;
        }
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }

    form.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <form action="/day02/SessionDemo2" method="post">
        <input type="hidden" name="token" value="${ token}">
        用户名2:<input name="username" type="text"><br/>
        <input id="submit" type="submit" value="提交" ><br/>
        </form>
    </body>
    </html>
  • 相关阅读:
    【AS3代码】类的分包
    语句include和require的区别是什么?
    php创建多级目录的函数
    【AS3代码】打砖块
    【AS3代码】弧度的转换
    【AS3代码】是男人就坚持30秒
    每天问女儿的四个问题
    PowerDesigner16生成SQL2005列注释
    做分析师=盖房子【转】
    用gephi自动分析网站链接方式
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/14531478.html
Copyright © 2011-2022 走看看