zoukankan      html  css  js  c++  java
  • Servlet :Request,Response 对象,Servlet 表单数据,Cookie

    通过前面的学习我们能够创建并运行一个简单的Servlet 程序,完成浏览器和服务器的简单交互,但是我们编写的Servlet 代码是没有对浏览器的请求进行处理的。现在我们开始学习

    如何使用Servlet 进行浏览器请求的处理。

    Request 对象:

    问题:

    浏览器发起请求到服务器,会遵循HTTP 协议将请求数据发送给服务器。

    那么服务器接受到请求的数据改怎么存储呢?不但要存,而且要保证完成性。

    解决:

    使用对象进行存储,服务器每接受一个请求,就创建一个对象专门的存储此次请求的请求数据。

    request 对象解释:

    服务器接收到浏览器的请求后,会创建一个 Request 对象,对象中存储了此次请求相关的请求数据。服务器在调用 Servlet 时会将创建的Request 对象作为实参传递给 Servlet 的方法,比如:service 方法。

    使用:

    获取请求头数据

    获取请求行数据获取用户数据

    读取 HTTP 头的方法

    下面的方法可用在 Servlet 程序中读取 HTTP 头。这些方法通过 HttpServletRequest 对象可用。

    方法 & 描述:

    Cookie[]= getCookies()

    返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。

    Object= getAttribute(String name)

    以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。

    String= getCharacterEncoding()

    返回请求主体中使用的字符编码的名称

    String =getContextPath()

    返回指示请求上下文的请求 URI 部分。

    String= getHeader(String name)

    以字符串形式返回指定的请求头的值。

    String =getMethod()

    返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。

    String= getParameter(String name)

    以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。

    String= getPathInfo()

    当请求发出时,返回与客户端发送的 URL 相关的任何额外的路径信息。

    String= getProtocol()

    返回请求协议的名称和版本。

    String= getQueryString()

    返回包含在路径后的请求 URL 中的查询字符串。

    String= getRemoteAddr()

    返回发送请求的客户端的互联网协议(IP)地址。

    String getRequestURI()

    从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。

    String getServletPath()

    返回调用 JSP 的请求的 URL 的一部分。

    String[]= getParameterValues(String name)

    返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null。

    int =getIntHeader(String name)

    返回指定的请求头的值为一个 int 值。

    int= getServerPort()

    返回接收到这个请求的端口号。

    int= getParameterMap()

    将参数封装成 Map 类型

    案例解析:

    前端判断userAgent,显示PC还是移动端页面的流程

    User --> 发送请求http://www.baidu.com ---> 返回PC端页面(JS开始执行判断浏览器是什么浏览器(直接通过js自动适配移动端页面)) ----> location.href = http://m.baidu.com --> 发送请求到百度移动端页面

    后端判断userAgent,显示PC还是移动端页面的流程

    User --> 发送请求http://www.baidu.com -->servlet分析判断浏览器是什么浏览器 ---》返回移动端页面或者是PC页面

    package cn.sxt;
    
    import java.io.IOException;
    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 lianxi3
     */
    @WebServlet("/lianxi3")
    public class lianxi3 extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public lianxi3() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.getWriter().append("Served at: ").append(request.getContextPath());
        
            //获取请求的编码
            response.getWriter().println(request.getCharacterEncoding()+"1
    ");
            //获取当前的项目地址
            response.getWriter().println(request.getContextPath()+"2
    ");
            //获取请求头具体的字段
            response.getWriter().println(request.getHeader("Host")+"3
    ");
            //判断是移动还是pc端
            response.getWriter().println(request.getHeader("User-Agent")+"4
    ");
            
            //获取请求的方法
            response.getWriter().println(request.getMethod()+"5
    ");
            //获取请求的参数
            response.getWriter().println(request.getParameter("username")+"6
    ");
            //获取路径信息
            response.getWriter().println(request.getPathInfo()+"7
    ");
            //response.getWriter().println(request.get+"
    ");
        String webname=request.getParameter("webname");
            //直接重新让客户端进行新的请求
            response.sendRedirect("http://www."+webname+".com");
            
            
    //获取请求的端口号
            response.getWriter().println(request.getLocalPort()+"
    ");
            
            
            //获取请求的所有数据放置的map(要等浏览器发来请求)
            Map<String, String[]> parameterMap = request.getParameterMap();
            for(String key:parameterMap.keySet()) {
                
                String [] arr=parameterMap.get(key);
                
                response.getWriter().println(key+"
    ");
                
                for (int i = 0; i < arr.length; i++) {
                    response.getWriter().println(arr[i]+"
    ");
                }
            }
            
    
        
        }
    
        /**
         * @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);
        }
    
    }
     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
            <form action="./lianxi4" method="GET">
            <h3>请选择你喜欢的明星</h3>
            
            <span>蔡徐坤</span>
            <input type="checkbox" name="star" value="cxk" />
            
            <span>郭敬明</span>
            <input type="checkbox" name="star" value="gjm" />
            
            <span>TFBOYS</span>
            <input type="checkbox" name="star" value="tfboys" />
            
            <input type="submit" value="提交" />
        </form>
    </body>
    </html>
    
    
    


    package
    cn.sxt; import java.io.IOException; 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 lianxi4 */ @WebServlet("/lianxi4") public class lianxi4 extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public lianxi4() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //设置请求和响应的编码 request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html"); response.getWriter().append("Served at: ").append(request.getContextPath()); //获取协议信息 response.getWriter().println("1 "+request.getProtocol()+" "); //获取路径中查询的字符串(一般获取不到) response.getWriter().println("2 "+request.getQueryString()+" "); //一般获取不到 response.getWriter().println("4 "+request.getRemoteAddr()+" "); //返回请求根路径后面的路径内容 response.getWriter().println("5 "+request.getRequestURI()+" "); //获取servlet路径 response.getWriter().println("66 "+request.getServletPath()+" "); //获取请求头字段的内容值是整数 response.getWriter().println("7 "+request.getIntHeader("Upgrade-Insecure-Requests")+" "); //response.getWriter().println("8 "+request.get+" "); //获取同一参数(name)的多个value(要等浏览器发来请求) String[] parameterValues = request.getParameterValues("star"); response.getWriter().println("你喜欢的明星是:"); for(int i=0;i<parameterValues.length;i++) { response.getWriter().println(parameterValues[i]+";"); } } /** * @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); } }

     

    Response 对象:

    问题:

    在使用 Request 对象获取了请求数据并进行处理后,处理的结果如何显示到浏览器中呢?

    解决:使用 Response 对象

    服务器在调用指定的 Servlet 进行请求处理的时候,会给 Servlet 的方法传递两个实参 request 和 response。其中 request 中封存了请求相关的

    请求数据,而 response 则是用来进行响应的一个对象。

    使用:

    设置响应头

    设置响应编码格式

    设置 HTTP 响应报头的方法

    下面的方法可用于在 Servlet 程序中设置 HTTP 响应报头。这些方法通过 HttpServletResponse 对象可用。

    方法 & 描述

    void addCookie(Cookie cookie)

    把指定的 cookie 添加到响应。

    void addHeader(String name, String value)

    添加一个带有给定的名称和值的响应报头。

    void sendRedirect(String location)

    使用指定的重定向位置 URL 发送临时重定向响应到客户端。

    void setCharacterEncoding(String charset)

    设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8。

    void setContentType(String type)

    如果响应还未被提交,设置被发送到客户端的响应的内容类型。

    void setHeader(String name, String value)

    设置一个带有给定的名称和值的响应报头。

    void setIntHeader(String name, int value)

    设置一个带有给定的名称和整数值的响应报头。

    void setStatus(int sc)

    为该响应设置状态码。

    设置响应实体

    请求乱码问题解决:

    使用 String 进行重新编码:

    uname=new String(uname.getBytes("iso8859-1"),"utf-8");

    Get 方式请求:

    service 方法中使用: req.setCharacterEncoding(“utf-8”);

    tomcat 服务器目录下的 conf 文件下找到 server.xml 文件,打开进行如下配置:

    Post 方式请求:

    service 方法中使用: req.setCharacterEncoding(“utf-8”);

    流程总结:

    Servlet 的使用流程:

    设置请求编码格式设置响应编码格式获取请求信息

    处理请求信息响应处理结果

    数据流转流程:

    浏览器------>服务器 >数据库

    浏览器<------服务器<数据库

    请求转发:

    问题:

    服务器在接收到浏览器的请求后, 仅仅使用一个

    Servlet 进行请求处理,会造成不同的 Servlet 逻辑代码冗余,Servlet 的职责不明确。

    解决:

    使用请求转发。特点:

    一次请求

    地址栏信息不改变。(重定向是叫浏览器重新发送一次请求,请求转发是本身已经有文件在了)

    Request 对象作用域

    问题:使用请求转发后,不同的 Servlet 之间怎么进行数据的共享呢?或者说数据怎么从一个servlet 流转给另外一个Servlet 呢?

    解决:使用request 对象的作用域使用:

    request.setAttribute(object name,Object value); request.getAttribute(Object obj)

    作用:解决了一次请求内的不同Servlet 的数据(请求数据+其他数据)共享问题

    作用域:基于请求转发,一次请求中的所有Servlet 共享。注意:

    使用Request 对象进行数据流转,数据只在一次请求内有效。特点:

    服务器创建

    每次请求都会创建生命周期一次请求

    重定向

    问题:

    如果当前的请求,Servlet 无法进行处理怎么办?

    如果使用请求转发,造成表单数据重复提交怎么办? 解决:

    使用重定向使用:

    response.sendRedirect(“路径”).

    本地路径为:uri

    网络路径为:定向资源的URL 信息特点:

    两次请求

    浏览器地址栏信息改变避免表单重复提交

    package cn.sxt;
    
    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;
    
    /**
     * Servlet implementation class lianxi2
     */
    @WebServlet("/lianxi2")
    public class lianxi2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public lianxi2() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            //设置请求和响应的编码
                    request.setCharacterEncoding("UTF-8");
                    response.setCharacterEncoding("UTF-8");
                    //设置响应类型
                    response.setContentType("text/html");
                    //设置响应头
                    //response.setHeader("Content-Type", "text/json");
                    
                    
            response.getWriter().append("Served at: ").append(request.getContextPath());
            
            //创建一个cookie
            Cookie cookie = new Cookie("userAuthid", "sfnsfjsoijfasosf");
            //响应给浏览器(添加进响应对象)
            response.addCookie(cookie);
            //获取浏览器请求的cookie的数据
            Cookie[] cookies = request.getCookies();
            for(int i=0;i<cookies.length;i++) {
            response.getWriter().println("
    "+cookies[i].getName()+":"+cookies[i].getValue()+"
    ");
                        
                    }
           //为该响应设置状态码。
            response.setStatus(403);
            
    }
        /**
         * @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);
        }
    
    }

    Servlet 表单数据

    很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序。浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法。

    GET方法

    GET 方法向页面请求发送已编码的用户信息。页面和已编码的信息中间用字符分隔,如下所示:

    http://www.test.comhellokey1=value1&key2=value2

    GET 方法是默认的从浏览器向 Web 服务器传递信息的方法,它会产生一个很长的字符串,出现在浏览器的地址栏中。

    如果您要向服务器传递的是密码或其他的敏感信息,请不要使用 GET 方法。

    GET 方法有大小限制:请求字符串中最多只能有 1024 个字符。

    POST 方法

    另一个向后台程序传递信息的比较可靠的方法是 POST 方法。POST 方法打包信息的方式与 GET 方法基本相同,但是 POST 方法不是把信息作为 URL 中字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息。消息以标准输出的形式传到后台程序,您可以解析和使用这些标准输出。

    Servlet 使用 doPost() 方法处理这种类型的请求。

    Servlet 读取表单数据

    Servlet 处理表单数据,这些数据会根据不同的情况使用不同的方法自动解析:

    getParameter():您可以调用 request.getParameter() 方法来获取表单参数的值。

    getParameterValues():如果参数出现一次以上,则调用该方法,并返回多个值,例如复选框。(上面列子)拿到全部的val值,但它是数组,所以要循环输出

    getParameterNames():如果您想要得到当前请求中的所有参数的完整列表,则调用该方法。

    读取所有的表单参数

    以下是通用的实例,使用 HttpServletRequest getParameterNames() 方法读取所有可用的表单参数。该方法返回一个枚举,其中包含未指定顺序的参数名。

    一旦我们有一个枚举,我们可以以标准方式循环枚举,使用 hasMoreElements() 方法来确定何时停止,使用 nextElement() 方法来获取每个参数的名称。

    
    
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <!-- GET/POST:都是以请求的方式提交数据 -
        url:提交服务器的地址什么
        Parameter:提交的数据
        form/ajax方式:form元素和ajax
        
        
        Form
        action:提交给服务器的地址
        input:元素的name属性一定要记得设置,不记得就连提交的机会都没有
        name:要前后端统一
        
        注意:如果需要有隐藏字段,记得可以在输入元素上设置hidden属性
        
        
    -->
    
     <form action="./lianxi2" method="GET">
        <input type="text" name="search"  value="" placeholder="请输入要搜索的内容"/>
        
        <input type="text" hidden="hidden" name="userType" value="student" />
        
        
        
        <input type="submit" value="提交" />
    
    </form>
    
    
    <form action="./lianxi2" method="POST">
        <input type="text" name="search"  value="" placeholder="请输入要搜索的内容"/>
        <!-- hidden用于放隐藏域,用于存放数据  也就是说上面的输入内容是在studeng类型中 -->
        <input type="text" hidden="hidden" name="userType" value="student" />
        
         <h3>你喜欢什么英雄?</h3>
        小鱼
        <input type="checkbox" name="hero" value="xiaoyu" />
        剑圣
        <input type="checkbox" name="hero" value="jiansheng" />
        亚索
        <input type="checkbox" name="hero" value="yasuo" /> 
        
        
        <!--  <select name="hero" id="" multiple="multiple">
            <option value="" disabled="disabled">请选择你喜欢的英雄</option>
            <option value="xiaoyu">小鱼</option>
            <option value="jiansheng">剑圣</option>
            <option value="yasuo">亚索</option>
        </select>-->
        
        <!--
            文本输入框,在里面可以直接写html,css
          -->
        <textarea name="article" id="" cols="30" rows="10"></textarea>
        
        <input type="submit" value="提交" /> 
    
    </form>
    
    
    
    
    </body>
    </html>
    
    
    

    package
    cn.sxt; 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; /** * Servlet implementation class lianxi2 */ @WebServlet("/lianxi2") public class lianxi2 extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public lianxi2() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //设置请求和响应的编码 request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); //设置响应类型 response.setContentType("text/html"); //设置响应头 //response.setHeader("Content-Type", "text/json"); response.getWriter().append("Served at: ").append(request.getContextPath()); //表单的请求方法 response.getWriter().println(" "+request.getMethod()); //表单的内容 response.getWriter().println(" "+request.getParameter("search")); //获得用户类型 response.getWriter().println(" "+request.getParameter("userType"));
             //获取同一参数(name)的多个value(要等浏览器发来请求)
            String[] parameterValues = request.getParameterValues("star");
            for(int i=0;i<parameterValues.length;i++) {
                response.getWriter().println(parameterValues[i]+";");
            }
     } /** * @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); } }

    AJAX

    允许跨域请求

    //允许所有IP地址和端口请求

    response.setHeader("Access-Control-Allow-Origin", "*");

    //允许所有的文档类型请求 

    response.setHeader("Access-Control-Content-Type", "*");

    
    
    package cn.sxt;
    import java.io.IOException;
    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 lianxi2
     */
    @WebServlet("/lianxi2")
    public class lianxi2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public lianxi2() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            
                    //允许所有IP地址和端口请求
                  response.setHeader("Access-Control-Allow-Origin", "*");
                    
    
                    //允许所有的文档类型请求 
                   response.setHeader("Access-Control-Content-Type", "*");
                    
            response.getWriter().append("Served at: ").append(request.getContextPath());
            
            
    }
        /**
         * @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);
        }
    
    }
    
    
    

    <!
    DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script src="js/jquery-1.11.0.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $.get("http://localhost:8080/hello3/lianxi2").then(function(e){ console.log(e) }) </script> </body> </html>
     
    package cn.sxt;
    import java.io.IOException;
    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 lianxi2
     */
    @WebServlet("/lianxi2")
    public class lianxi2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public lianxi2() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            
                    //允许所有IP地址和端口请求
                  response.setHeader("Access-Control-Allow-Origin", "*");
                    
    
                    //允许所有的文档类型请求 
                   response.setHeader("Access-Control-Content-Type", "*");
                    
            response.getWriter().append("Served at: ").append(request.getContextPath());
        //------------------------------------------------------
            response.getWriter().println(request.getParameter("city"));    
            
    }
        /**
         * @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);
        }
    
    }
    
    
    

    <!
    DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="text" name="city" id="city" placeholder="请输入你要搜索的城市" value="" /> <button>提交</button> <script src="js/jquery-1.11.0.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $("button").click(function(){ var data = { city:$("#city").val() } $.get("http://localhost:8080/hello3/lianxi2",data).then(function(e){ console.log(e) }) }) </script> </body> </html>
    jQuery设置多选项请求:
    
    $.ajax({
        url:"",
        method:"POST",
        data:{
            name:"abc",
            hero:["abc","cxk","666"]
        },complete:function(){
            console.log(123)
        }
    })
    注意:jQuery默认会给表单的key值多添加一个中括号,servlet获取内容是,就变为:request.getParameterValues("hero[]");

    目前大家对于浏览器和服务器的交互模式,以及请求的处理都有了理解,并且也能够进行请求的处理。本节课围绕整个流程再次进行技术优化,重点学习Cookie 技术,此技术的应用面是非常广的。

    Cookie学习

    问题:

    HTTP 协议是没有记忆功能的,一次请求结束后,相关数据会被销毁。如果第二次的请求需要使用相同的请求数据怎么办呢? 难道是让用户再次请求书写吗?

    解决:

    使用Cookie 技术解释:

    Cookie 技术其实是浏览器端的数据存储技术,解决了不同请求需要使用相同的请求数据的问题。我们把请求需要共享的请求数据,存储在浏览器端,避免用户进行重复的书写请求数据。但是哪些数据需要使用Cookie 技术存储起来是一个主观问题,需要在后台进行响应的时候来告诉浏览器,有些数据其他请求还会使用,需要存储起来。

    特点:

    浏览器端的数据存储技术

    适合少量数据键值对

    1次请求加响应

    请求:客户端 ---》  服务器

    响应:服务器 ---》响应内容包含(set-cookie:userType-》VIP)

    2次请求

    请求:客户端(浏览器判断是否有有效期内的cookie)将cookie发送给到 ---》 服务器

    响应:服务器获取cookie,判断是否是vip用户 ---》相应内容给到客户端(并且可以添加新cookie或者修改原来的cookie)

    Cookie 数据存储

    临时存储:

    不设置cookie 信息的存储时间,周期为一次会话, 存储在浏览器内存中

     

    定时存储:

    设置存储时间,周期为时间设置,存储在用户电脑中。

    Servlet Cookie 处理

    Cookie 是存储在客户端计算机上的文本文件,并保留了各种跟踪信息。Java Servlet 显然支持 HTTP Cookie。

    识别返回用户包括三个步骤:

    1、服务器脚本向浏览器发送一组 Cookie。例如:姓名、年龄或识别号码等。

    2、浏览器将这些信息存储在本地计算机上,以备将来使用。

    3、当下一次浏览器向 Web 服务器发送任何请求时,浏览器会把这些 Cookie 信息发送到服务器,服务器将使用这些信息来识别用户。

    Servlet Cookie 处理需要对中文进行编码与解码,方法如下:

    String  str   =   java.net.URLEncoder.encode("中文","UTF-8");        //编码

    String  str   =   java.net.URLDecoder.decode("编码后的字符串","UTF-8");// 解码

    Javascript

    encodeURI() //路径编码函数

    decodeURI() //路径解码函数

    Cookie 剖析

    Cookie 通常设置在 HTTP 头信息中(虽然 JavaScript 也可以直接在浏览器上设置一个 Cookie)。设置 Cookie 的 Servlet 会发送如下的头信息:

    HTTP/1.1 200 OK

    Date: Fri, 04 Feb 2000 21:03:38 GMT

    Server: Apache/1.3.9 (UNIX) PHP/4.0b3

    Set-Cookie: name=xyz; expires=Friday, 04-Feb-07 22:03:38 GMT;

                     path=/; domain=m.baidu.com

    Connection: close

    Content-Type: text/html

    Set-Cookie 头包含了一个名称值对、一个 GMT 日期、一个路径和一个域。名称和值会被 URL 编码。expires 字段是一个指令,告诉浏览器在给定的时间和日期之后"忘记"该 Cookie。

    如果浏览器被配置为存储 Cookie,它将会保留此信息直到到期日期。如果用户的浏览器指向任何匹配该 Cookie 的路径和域的页面,它会重新发送 Cookie 到服务器。浏览器的头信息可能如下所示:

    GET / HTTP/1.0

    Connection: Keep-Alive

    User-Agent: Mozilla/4.6 (X11; I; Linux 2.2.6-15apmac ppc)

    Host: zink.demon.co.uk:1126

    Accept: image/gif, */*

    Accept-Encoding: gzip

    Accept-Language: en

    Accept-Charset: iso-8859-1,*,utf-8

    Cookie: name=xyz

    Servlet 就能够通过请求方法 request.getCookies() 访问 Cookie,该方法将返回一个 Cookie 对象的数组。

    Servlet Cookie 方法

    以下是在 Servlet 中操作 Cookie 时可使用的有用的方法列表。

    方法 & 描述

    public void setMaxAge(int expiry)

    该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie 只会在当前 session 会话中持续有效。

    public int getMaxAge()

    该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示,没有设定值。

    public String getName()

    该方法返回 cookie 的名称。名称在创建后不能改变。

    public void setValue(String newValue)

    该方法设置与 cookie 关联的值。

    public String getValue()

    该方法获取与 cookie 关联的值。

    public void setSecure(boolean flag)

    该方法设置布尔值,表示 cookie 是否应该只在加密的(即 SSL)连接上发送。

    public void setComment(String purpose)

    设置cookie的注释。该注释在浏览器向用户呈现 cookie 时非常有用。

    public String getComment()

    获取 cookie 的注释,如果 cookie 没有注释则返回 null。

    通过 Servlet 设置 Cookie

    通过 Servlet 设置 Cookie 包括三个步骤:

    (1) 创建一个 Cookie 对象:您可以调用带有 cookie 名称和 cookie 值的 Cookie 构造函数,cookie 名称和 cookie 值都是字符串。

    Cookie cookie = new Cookie("key","value");

    请记住,无论是名字还是值,都不应该包含空格或以下任何字符:

    [ ] ( ) = , " / ? @ : ;

    (2) 设置最大生存周期:您可以使用 setMaxAge 方法来指定 cookie 能够保持有效的时间(以秒为单位)。下面将设置一个最长有效期为 24 小时的 cookie。

    cookie.setMaxAge(60*60*24);

    (3) 发送 Cookie 到 HTTP 响应头:您可以使用 response.addCookie 来添加 HTTP 响应头中的 Cookie,如下所示:

    response.addCookie(cookie);

    通过 Servlet 读取 Cookie

    要读取 Cookie,您需要通过调用 HttpServletRequest 的 getCookies( ) 方法创建一个 javax.servlet.http.Cookie 对象的数组。然后循环遍历数组,并使用 getName() 和 getValue() 方法来访问每个 cookie 和关联的值。

    通过 Servlet 删除 Cookie

    删除 Cookie 是非常简单的。如果您想删除一个 cookie,那么您只需要按照以下三个步骤进行:

    1、读取一个现有的 cookie,并把它存储在 Cookie 对象中。

    2、使用 setMaxAge() 方法设置 cookie 的年龄为零,来删除现有的 cookie。

    3、把这个 cookie 添加到响应头。

    package cn.sxt;
    
    import java.io.IOException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    
    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;
    
    /**
     * Servlet implementation class lianxi2
     */
    @WebServlet("/lianxi2")
    public class lianxi2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public lianxi2() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            //设置请求和响应的编码
                    request.setCharacterEncoding("UTF-8");
                    response.setCharacterEncoding("UTF-8");
                    //设置响应类型
                    response.setContentType("text/html");    
            response.getWriter().append("Served at: ").append(request.getContextPath());
            
            //编码
            String encode = URLEncoder.encode("张三", "UTF-8");
            Cookie cookie = new Cookie("user",encode);
            //设置60s有效
            cookie.setMaxAge(60);
            
            //响应给浏览器(添加进响应对象)
            response.addCookie(cookie);
            
            
            System.out.println(cookie.getMaxAge());
            //cookie.setDomain("localhost");
            Cookie[] cookies = request.getCookies();
        for(int i=0;i<cookies.length;i++) {
                response.getWriter().println(cookies[i].getName()+":"+URLDecoder.decode(cookies[i].getValue(), "UTF-8")  );
                response.getWriter().println(cookies[i].getMaxAge());
                
                response.addCookie(cookies[i]);
                
                
            }
            
            
    }
        /**
         * @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);
        }
    
    }
  • 相关阅读:
    求教——使用node做表单,刷新浏览器页面,浏览器为什么会重复提交上次所填的信息
    sublime 插件
    h5专题应该兼容那些浏览器?
    省市区县镇级联数据JS版
    使用 iscroll 实现焦点图无限循环
    DAO与DTO的区别
    Struts2的DMI的开启方法
    在JSP中的java代码中调用js代码
    Eclipse发布web项目时报错:Multiple Contexts have a path of "/xxx".
    记录:将MyEclipse的Dynamic Web Project项目部署到Eclipse的过程
  • 原文地址:https://www.cnblogs.com/406070989senlin/p/11016372.html
Copyright © 2011-2022 走看看