• 过虑器


    1.实现一个最基本的过虑器

    1:过虑器只对url(路径)进行过虑。
    2:过虑器开发人员来实现。
    3:过虑器由于是web的核心组,所以这个filter的实现者也必须要配置到web.xml中。
    4:三个生命周期方法:init,destory,doFilter(执行过虑任务)。用户的每次请求,都会执行doFIlter方法,而Init,destory只会执行一次。Init方法执行的时间:在项目启动时,直接初始化Filter的对象,所以会在tomcat启动时执行init方法。

    第一步:书写一个类实现Filter接口:

    @WebFilter("/OneServlet")
    public class OneFilter implements Filter {
    
        public void destroy() {
            System.err.println("destroy"+this);
        }
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.err.println("正在过滤"+this+":"+request);    
            chain.doFilter(request, response);
            System.err.println("执行完成"+this+":"+request);    
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
            System.err.println("init"+this);
        }
    
    }

    第二步:在web.xml中配置这个过虑器

    第三步:测试执行

    package cn.servlet;
    
    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;
    
    @WebServlet("/OneServlet")
    public class OneServlet extends HttpServlet {
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            
            System.err.println("这是doGet 方法");
            response.getWriter().write("你好 OneServlet"+this+":"+request);
        }
    
    }

    2.filter的filter-mapping中的url-pattern的设置

    url-pattern的设置:

    /* = 对所有url都请求这个servlet。| 都被这个filter过虑.

    / = 只可以给servlet。 - 所有其他的servlet不处理的url都由这个url所指定的servlet处理。默认servlet。

    *.jspx = 所有以jspx结束都请求到这个Servlet或是被某个Filter拦截。如http://local:8080/proj/abc.jspx

    /jsps/* = 所有路径中以/jsps/开头的都请求到这个servlet或是被某个filter拦截到。

    /jsps/*.jspx 错误的:SUN规定*两边不可以同时出现字符。

    3.过虑器中的其他配置

    如果有jsps/abc.jsp这个页面,则显示这个页面有两种方式:

    1:在地址栏请求:http://local:8080/project/jsps/abc.jsp -- 可以被拦截到的,因为:路径符合/jsp/abc.jsp

    2:req.getRequestDispathcer(“/jsps/abc.jsp”).forward(req,resp); -

    Dipatcher属性:

    Request – 默认值,只拦截用户的新的请求。

    Forward – 对转发进行拦截。

    Include – 对include拦截。

    Error - 对错误进行拦截。

    <!-- 设置对转发拦截 -->

    <dispatcher>REQUEST</dispatcher>

    <dispatcher>FORWARD</dispatcher>

    默认情况下,不用配置就是request.

    4.配置过虑器的初始化参数

    在filter类中有一个方法:init(FilterConfig config); 而filtetrConfig中包含了从web.xml中读取初始化参数值。

    <filter>
          <filter-name>one</filter-name>
          <filter-class>cn.itcast.filter.OneFilter</filter-class>
          <init-param>
              <param-name>name</param-name>
              <param-value>张三Jack</param-value>
          </init-param>
          <init-param>
              <param-name>age</param-name>
              <param-value>88</param-value>
          </init-param>
      </filter>

    5.过虑器链FilterChain

    在filter的配置当中,有两个配置:filter,filter-mapping.Filter-mapping在前,则先执行,在后则后执行。

    <filter>
            <filter-name>first</filter-name>
            <filter-class>cn.filter.FirstFilter</filter-class>
        </filter>
        <filter>
            <filter-name>second</filter-name>
            <filter-class>cn.filter.SecondFilter</filter-class>
        </filter>
    
        <filter-mapping>
            <filter-name>first</filter-name>
            <url-pattern>/ForServlet</url-pattern>
        </filter-mapping>
        <filter-mapping>
            <filter-name>second</filter-name>
            <url-pattern>/ForServlet</url-pattern>
        </filter-mapping>

    6.过虑器应用之1-设置request编码

    写一个过虑器,对所有url全部过虑,/*.在doFilter方法中,设置request的编码为utf-8。一般情况下,这个过虑器永远是第一个要执行的过虑器。最好是通过配置设置编码。<filter><init-param>…

    第一步:实现Filter接口,在doFilter中接收初始化参数,设置编码

    public class charFilter implements Filter {
    
        private String encoding;
    
        public charFilter() {
        }
    
        public void destroy() {
        }
    
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            System.err.println("---");
            request.setCharacterEncoding(encoding);
            response.setContentType("text/html;charset=utf-8");
            chain.doFilter(request, response);
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
            this.encoding=fConfig.getInitParameter("bm");
        }
    }

    第二步:将上面的类配置到web.xml

    <filter>
          <filter-name>char</filter-name>
          <filter-class>cn.itcast.filter.CharFilter</filter-class>
          <init-param>
              <!-- 为了便于配置,在配置文件中设置编码 -->
              <param-name>bm</param-name>
              <param-value>UTF-8</param-value>
          </init-param>
      </filter>
    <filter-mapping>
        <filter-name>char</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    对get可以处理中文

    在CharFilter中对reuqest进行包装。目的:修改增强getParameter方法,如果是get转码。

    第一步:声明包装类:

    class MyRequest extends HttpServletRequestWrapper {
        public MyRequest(HttpServletRequest request) {
            super(request);
        }
    
        // 增强getParamter
        @Override
        public String getParameter(String name) {
            String val = super.getParameter(name);
            if (super.getMethod().equals("GET")) {
                try {
                    val = new String(val.getBytes("ISO-8859-1"),
                            super.getCharacterEncoding());
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
            return val;
        }
    }

    第二步:在doFilter方法中,声明包装类的实例

    public class CharFilter implements Filter {
        // 声明编码的成员变量
        private String encoding;
    
        public void init(FilterConfig config) throws ServletException {
            encoding = config.getInitParameter("bm");
        }
    
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            request.setCharacterEncoding(encoding);
            response.setContentType("text/html;charset=" + encoding);
            // 判断是否需要包装
            HttpServletRequest req = (HttpServletRequest) request;
            if (req.getMethod().equals("GET")) {
                request = new MyRequest(req);
            }
            // 声明包装类的实例
            // 放行
            chain.doFilter(request, response);
        }
        public void destroy() {
        }
    }

    7.设置某些页面缓存或是不缓存

    <%
        response.setHeader("expires","-1");
        response.setHeader("pragma","no-cache");
        response.setHeader("cache-control","no-cache");
    %>

    第一步:实现过虑器接口

    package cn.filter;public class CacheFilter implements Filter {
        public void destroy() {
        }
    
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
    
            HttpServletResponse resp = (HttpServletResponse) response;
            resp.setHeader("expires", "-1");
            resp.setHeader("pragma", "no-cache");
            resp.setHeader("cache-control", "no-cache");
            System.err.println("---");
            chain.doFilter(request, response);
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
        }
    
    }

    第二步:配置过虑器,url-pattern=*.jsp

    <!-- 配置控制缓存的filter -->
        <filter>
            <filter-name>cache</filter-name>
            <filter-class>cn.filter.CacheFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>cache</filter-name>
            <url-pattern>*.jsp</url-pattern>
        </filter-mapping>

    第三步:设置对某些页面缓存N天

    public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
    
            HttpServletResponse resp = (HttpServletResponse) response;
            // 计算2天以后的毫秒值
            // 日历
            Calendar cl = Calendar.getInstance();
            // 日历上加2天
            cl.add(Calendar.DATE, 2);
            long time = cl.getTimeInMillis();
            resp.setDateHeader("expires", time);
    
    //        resp.setHeader("expires", "-1");
    //        resp.setHeader("pragma", "no-cache");
    //        resp.setHeader("cache-control", "no-cache");
            System.err.println("---");
            chain.doFilter(request, resp);
        }

    8.生成验证码

    @WebServlet("/ImageServlet")
    public class ImageServlet extends HttpServlet {
        protected void doGet(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            // 设置响应类型
            response.setContentType("image/jpeg");
            int width = 60;
            int height = 30;
            BufferedImage img = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = img.getGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, width, height);
            g.setFont(new Font("宋体", Font.BOLD, 18));
            Random r = new Random();
            for (int i = 0; i < 4; i++) {
                Color c = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
                int code = r.nextInt(10);
                g.setColor(c);
                g.drawString("" + code, i * 15, 10 + r.nextInt(20));
            }
            for (int i = 0; i < 10; i++) {
                Color c = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
                g.setColor(c);
                g.drawLine(r.nextInt(60), r.nextInt(30), r.nextInt(60),
                        r.nextInt(30));
            }
            // 图片生效
            g.dispose();
            // 写到
            ImageIO.write(img, "JPEG", response.getOutputStream());
    
        }
    }

    方法一:欺骗浏览器

    <img id="img" src="<c:url value='/ImageServlet'/>"></img>
        <a href="javascript:_chg();">看不清</a>
    <script type="text/javascript">
        function _chg() {
            var img = document.getElementById("img");
            var time = new Date().getTime();
            img.src = "<c:url value='/ImageServlet?'/>"+time;
        }
    </script>

    方法二:图片不缓存

    11、验证用户是否已经登录

    package cn.itcast.filter;
    
    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    public class LoginFilter implements Filter{
        public void init(FilterConfig filterConfig) throws ServletException {
        }
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            //将request强转成htt...
            HttpServletRequest req = (HttpServletRequest) request;
            //获取session
            HttpSession ss = req.getSession();
            //从session中获取user
            if(ss.getAttribute("user")==null){
                System.err.println("你还没有登录");
                req.getSession().setAttribute("msg", "请你先登录");
                //重定向到登录
                HttpServletResponse resp = (HttpServletResponse) response;
                resp.sendRedirect(req.getContextPath()+"/index.jsp");
            }else{
                //放行
                chain.doFilter(request, response);
            }
        }
        public void destroy() {
        }
    }

    配置到web.xml中且对jsps/*进行过虑:

    <filter>
          <filter-name>login</filter-name>
          <filter-class>cn.itcast.filter.LoginFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>login</filter-name>
          <url-pattern>/jsps/*</url-pattern>
          <url-pattern>/views/*</url-pattern>
      </filter-mapping>

    12、实现自动登录

    自动登录,是为了帮助用户多次使用这个网页时,不用再次输入用户名和密码就可以登录。

    是指用户将用户的登录信息,人,保存到本地的文件中Cookie中。

    Name,value – 声明时 new Cookie(key,value);

    Path - 默认值,即为当前保存cookie的这个serlvet所在的路径。

    如果Cookie在这样的路径:http://loclhost:8080/project/abc/AServlet

    则Cookie的路径为: http://loclhost/project/abc

    则说明:

    所在在http://loclhost/project/abc目录下的servlet才可以读取这个cookie的值。

    如果:

    保存Cookie类:http://loclhost:8080/project/a/b/AServlet

    则Cookie的默认path为;

    http://loclhost/project/a/b

    对于path这个值可以手工设置:

    如果设置为: http://loclhost/project/ 即到项目名。

    则所有这个项目中的所有Serlvet|jsp都可以读取到这个 cookie.

    Cookie.setPath(requst.getContextPath());

    如果将path设置为 /

    即:cookie.setpath(“/”); - http://localhost/

    则所有在tomcat中运行的项目都可以读取这个到cookie.

    如果path设置为/必须要与domain共同使用才有意义。

    Age - 默认值-1,在浏览器中存在。 0:删除文件中的cookie和浏览器中的cookie。

    Domain - 域 -

    www.sina.com - login

    www.bbs.sina.com

    www.news.sina.com

    删除时,必须要设置的与之前设置的信息完全一样:

    Name

    Age = 0(文件和缓存),-1(只删除文件)

    Path 一样。

    Domain :null

    下一次用户再打开这个网页时,应该读取cookie中的信息,实现自动登录。

    13、实现用户自动登录:

    第一步:开发一个登录页面

    <c:choose>
            <c:when test="${empty sessionScope.name}">
                <form name="x" method="post" action="<c:url value='/LoginServlet'/>">
                    Name:<input type="text" name="name"/><br/>
                    auto:
                    <input type="radio" name="auto" value="-1">不自动登录
                    <br/>
                    <input type="radio" name="auto" value="1">1天<br/>
                    <input type="radio" name="auto" value="7">1周<br/>
                    <input type="submit"/>
                </form>
            </c:when>
            <c:otherwise>
                你已经登录了:${name}<br/>
                <a href="<c:url value='/LoginServlet'/>">退出</a>
            </c:otherwise>
    </c:choose>

    第二步:成功保存cookie

    public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //接收用户姓名
            String name = request.getParameter("name");
            String auto = request.getParameter("auto");
            //将用户信息放到session
            request.getSession().setAttribute("name",name);
            //判断auto是否是-1
            if(!auto.equals("-1")){
                int day = Integer.parseInt(auto);//1|7
                int seconds = 60*60*24*day;
                //声明cookie
                Cookie c = new Cookie("autoLogin",name);
                c.setMaxAge(seconds);
                c.setPath(request.getContextPath());
                //保存cookie
                response.addCookie(c);
                
            }
        }

    第三步:要求访问本网点中任何一个页面都应该实现自动登录

    写一个过虑器,对所有url=/*进行过虑。在doFilter中读取所有cookie。是否存在名称为autoLogin的名称cookie。永远都放行。

    public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            //在这儿读取cookie
            HttpServletRequest req = (HttpServletRequest) request;
            //获取所的有cookie
            Cookie[] cs = req.getCookies();
            if(cs!=null){
                for(Cookie c:cs){
                    if(c.getName().equals("autoLogin")){//如果存在自动登录的cookie
                        String value = c.getValue();//用户名称
                        //登录成功是指
                        req.getSession().setAttribute("name", value);
                        break;
                    }
                }
            }
            //不管是否自动登录成
            chain.doFilter(request, response);
        }

    第四涉:配置到web.xml中对所有url=/*

    <filter>
         <filter-name>auto</filter-name>
         <filter-class>cn.itcast.filter.AutoFilter</filter-class>
     </filter>
     <filter-mapping>
         <filter-name>auto</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>

    第五步:开发退出

    System.err.println("用户退出");
            //删除整个session
            request.getSession().invalidate();
            Cookie c = new Cookie("autoLogin", "ddd");
            c.setMaxAge(0);
            c.setPath(request.getContextPath());
            response.addCookie(c);
    //        request.getSession().removeAttribute("name");
            response.sendRedirect(request.getContextPath()+"/index.jsp");

    第六步:优化代码

    由于用户在做手工登录时,也会进入AutoFiilter的doFilter方法,且读取所有Cookie遍历一次。而这次遍历对用户来说是多余。所以应该将LoginServet这个url在doFiler中不过过虑。且对退出也不能自动登录。

  • 相关阅读:
    java代码---------常用的方法indexOf()和substring()方法的小结、主要是下标都是从0开始,很重要,错了就那个差远了啊
    java代码-----indexOf()方法--从字符串的某个字符的第一次出现的位子开始
    java代码----substring()方法是按索引截取字符串。。。下标0开始
    java代码啊==indexOf()方法返回字符第一次出现的位置
    java代码------实现从控制台输入整型,
    java代码----I/O流从控制台输入信息判断并抛出异常
    (转)pip和easy_install使用方式
    小小粉丝度度熊
    P1613 跑路
    P3819 松江1843路
  • 原文地址:https://www.cnblogs.com/sunhan/p/3542130.html
Copyright © 2020-2023  润新知