zoukankan      html  css  js  c++  java
  • Servlet为主理解cookie,session,filter

    servlet

    首先Servlet是继承HttpServlet实现方法,一般是init,doget,dopost,service,destroy等

    由JVM的垃圾回收器对servlet进行垃圾回收

    配置Servlet

    1.Servlet的声明

    2.Servlet访问方式声明

    <servlet>
            <servlet-name>ShowServlet</servlet-name>
            <servlet-class>yang.control.ShowServlet</servlet-class> 
    </servlet>
    <servlet-mapping>
      <servlet-name>ShowServlet</servlet-name>
       <url-pattern>/yang.control/ShowServlet</url-pattern>
    </servlet-mapping>

    Servlet需要处理基于Http的请求

    http请求头如下

    三大部分,1请求行,2请求头部,3请求包体

     请求行:请求行由方法字段、URL 字段 和HTTP 协议版本字段 3 个部分组成,他们之间使用空格隔开。常用的 HTTP 请求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT;

    请求头部:里面有Date Cookies等

    当然你肯定有疑问,我们的一般的请求数据呢,请求数据不在GET方法中 使用,而是在POST方法中使用也就是我们的请求行里的请求方法之一。

    那么我们看一个平常用到的servlet基于Http的操作

    package com.yang.Servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class ShowServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.getWriter().write("乱码");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    }

     因为write():仅支持输出字符类型数据,字符、字符数组、字符串等所以中文肯定会乱码,

    当然我们可以这样

            resp.setCharacterEncoding("utf-8");
            resp.getWriter().write("乱码");

    但是不可能每一个都这样设置所以需要过滤器(见下面)

    看完了上面的代码和讲解你也许知道一点点servler和http的联系,

    但是你也许奇怪resp的getwriter怎么来的

    那我们来看看resp即HttpServletResponse的源码

     点金源码一看,这不很多熟悉的方法吗还有常见的sendRedirect重定向啊什么方法但是没有getwriter

    但是我们发现

     他继承ServletResponse,那我们再进去看看ServletResponse它的源码

    就找到我们的getwriter

    getWriter()返回一个PrintWriter object。并且是返回的PrintWriter类型!

    我们知道PrintWriter可以直接调用write()或print()方法,把字符串作为参数写入

    write():仅支持输出字符类型数据,字符、字符数组、字符串等

    print():可以将各种类型(包括Object)的数据通过默认编码转换成bytes字节形式,这些字节都通过write(int c)方法被输出

    因此传输数据时,write,print都可以使用,print可以写入对象,而write不行

    所以我们就知道了上面就是在写入字符串并通过response返回响应给客户端

     通过上面也大致了解点了servler与http的关系了

    即我们的客户端发送请求过去,服务器返回响应回来

    而这个发送一般也就是我们的请求头,看上图,发送的方法也很多比如post,get

    而servlet就针对这些写定可一些方法接口实现他们,比如我们常用的

    public void doGet(HttpServletRequest request, HttpServletResponse response)

    所以基本的请求就是request,响应回来的就是response,方法就是get

    同理下面不就是post方法去请求吗

    public void doPost(HttpServletRequest request, HttpServletResponse response)

    所以再看上面的代码

     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.getWriter().write("乱码");
        }
     @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    }
     

    理解起来就是我们客服端发送请求,而这个请求不管是get还是post都会到get里面,然后即我们客户端发送一个get方法的req(Request)请求出去,而返回回来的是resp,再加上resp执行了下面的

    resp.getWriter().write("乱码");

    所以返回出一个乱码字符。

    同理的requset

    理解了这些之后加上前面的讲解

    我们就能更好理解cookie和session

    如cookie我们前面讲过被包含在请求头里所以我们肯定先去req即请求里面去找找

    那么cookie是怎么运作的

    我理解为

    发起请求时,浏览器会检查所有存蓄的cookie,如果这个cookie的作用域即路径和域这些大于或等于请求的资源的位置就会吧cookie放进http请求头里面发送给服务器也就是上面说的

    处理请求时 服务器对cookie检查,比如登录。如果通过,直接进行业务逻辑等,比如跳转,不需要再次登录等操作

    并且在响应回来时,服务器会把cookie再次发送回来,一般是浏览器保存到硬盘等,所以这里也可以看出resq也会有cookie的函数等操作

    res里面很容易找到了getCookies() 方法。

    那我们来一个实例

    了解cookie

    删除第i个cookies

    Cookie cookie  = req.getCookies()[i]   //先拿到第i个cookie
    cookie.setMaxage=0 //通过设置最多年龄为0即清空
    resp.addCookies(cookie) //放进resp即响应里面,所以返回回来的cookie就是0了所以就成功删除了第i个cooike

    同理分析session

    只不过Session是保存在服务器的

    所以我们就可以通过request发送请求去得到服务器的session

    HttpSession session = res.getSession();

    还很多session的操作看源码

    Filter 

    Filter是实现Filter接口,重写方法

    package com.yang.Filter;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class EncodingFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("初始化");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
                servletRequest.setCharacterEncoding("utf-8");
                servletResponse.setCharacterEncoding("utf-8");
                servletResponse.setContentType("text/html;charset=UTF-8");
    
                //chain链
                System.out.println("执行前");
                filterChain.doFilter(servletRequest,servletResponse);//让我们的请求继续走,如果不写,程序到这里就被拦截停止这就是链下去,链
                System.out.println("执行后");
        }
    
        @Override
        public void destroy() {
            System.out.println("销毁");
        }
    }

    可以看到程序开始之前就初始化了

     web.xml如下

    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app>
      <display-name>Archetype Created Web Application</display-name>
      <servlet>
        <servlet-name>ShowServlet</servlet-name>
        <servlet-class>com.yang.Servlet.ShowServlet</servlet-class>
      </servlet>
    <!--  //开启两个这样在servlet下就有过滤器,-->
      <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/servlet/show</url-pattern>
      </servlet-mapping>
    
      <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/show</url-pattern>
      </servlet-mapping>
    
      <filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>com.yang.Filter.EncodingFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
    <!--    只要是servlet下的请求就会被过滤-->
        <url-pattern>/servlet/*</url-pattern>
      </filter-mapping>
    </web-app>

    可以看到servlet路径下就会被过滤

    但是没有在过滤器下就不会。

     那么下面来看一个实际例子

  • 相关阅读:
    关于Handler中Message的创建问题
    Android的组件化和模块化
    Android 和 JS交互方法初探
    synchronized相关用法简述
    关于导入高德地图 java.lang.UnsatisfiedLinkError: Couldn't load XXXfrom loader dalvik.system.PathClassLoader[DexPathLis
    圆的变化(自定义动画,及自定义UI)
    依赖注入
    PHP错误代号列表
    windows 系统错误码总结
    composer
  • 原文地址:https://www.cnblogs.com/yangj-Blog/p/12972054.html
Copyright © 2011-2022 走看看