重定向与请求转发与过滤器

重定向与请求转发的区别

重定向Redirect的原理

重定向方法

    //下列代码中涉及路径问题,在后文讨论
    response.sendRedirect("index.jsp");
    response.sendRedirect("/index.jsp");

重定向的处理流程

  • 接受客户端的http请求
  • 在接受请求的Servlet中调用sendRedirect()方法
  • 服务器发回包含3xx状态码和目标资源URL的response
  • 客户端浏览器读取到3xx状态码,再次发送新的请求到目标URL

p.s. 有关重定向3xx状态码和重定向种类请参阅MDN


请求转发RequestDispatch的原理

请求转发方法

    request.getRequestDispatcher("index.jsp").forward(request, response);

请求转发的处理流程

  • 接受客户端的http请求
  • 在Servlet中调用forward()方法将请求转发到另一个URL(jsp/servlet)
  • jsp/servlet处理请求,并将响应发给客户端(此时请求路径依然是上一个Servlet)

比较

  1. 重定向在客户端生效,而请求转发作用在服务器
  2. 重定向中客户端发送两次Request请求,第一次发送给目标Sevlet,目标Servlet发回3xx状态码和重定向URL,第二次发送给重定向URL
  3. 请求转发中客户端发送一次Request请求,目标Servlet将该请求转发给另一个jsp/servlet,另一个servlet/jsp发回响应报文
  4. 重定向时客户端地址栏的请求路径会发生变化,而请求转发不会,因为客户端并不知道响应报文是由另一个jsp/servlet发回的

重定向与请求转发的路径问题

区分绝对路径与相对路径

C:/Windows/System32/cmd.exe 就是cmd.exe的绝对路径,假设当前处于C:/Windows路径下,那么cmd.exe的相对路径就是./System32/cmd.exe,其中 . 代表当前目录( … 代表当前目录的上一级目录)

假定当前项目的结构是这样的

    |---web
      |---admin
      | |--loginFail.jsp
      | |--loginSuccess.jsp
      |---index.jsp
      |---test.jsp
      |---WEB-INF  
    |---LoginServlet.java

    需要理清的问题是localhost:port代表的是**服务器地址*,在讨论路径问题时不需要讨论它,其后的路径才是真正的访问路径。

重定向路径问题

    //假定当前地址处于module_name/test.jsp

    //这代表着 [localhost:port]/module_name/index.jsp
    response.sendRedirect("index.jsp");
    //这代表着 [localhost:port]/index.jsp, 发回状态码404
    response.sendRedirect("/index.jsp");
    //正确的绝对路径应该是
    response.sendRedirect("/module_name/index.jsp");
    //你也可以使用,附带了服务器地址及协议,更加“绝对”
    response.sendRedirect("http://localhost:port/module_name/index.jsp");
    //那么,同理你也可以转到其他服务器,例如百度
    response.sendRedirect("http://www.baidu.com/");


    //使用 “/” 的路径代表绝对路径
    //不使用 "/" 的路径代表相对路径,module_name代表项目名

请求转发路径问题

    //假定当前地址处于module_name/index.jsp

    //这代表着 [localhost:port]/module_name/admin/loginSuccess.jsp
    request.getRequestDispatcher("admin/loginSuccess.jsp").forward();
    //这代表着[localhost:port]/module_name/admin/loginSuccess.jsp
    request.getRequestDispatcher("/admin/loginSuccess.jsp").forward();
    //这代表着[localhost:port]/module_name/module_name/admin/loginSuccess.jsp,发回状态码404
    request.getRequestDispatcher("/module_name/admin/loginSuccess.jsp").forward();

    /*
     *可以发现使用绝对路径时,加上项目名反而404了
     *这是因为请求转发是在服务器上进行的
     *所以绝对路径前置地址是 [domain/ip]:port/module_name
     */

    /*
     *到这里就可以看出来了
     *使用绝对路径时前置地址即服务器地址
     *即[domain/ip]:port/[AbsoluteURL]
     *使用相对地址时则前置地址为当前所在目录
     *即 :[domain/ip]:port/./[URL]
     *
     *例如当前处于localhost:port/module_name/admin/loginSuccess.jsp
     *那么重定向或者请求转发回localhost:port/module_name/index.jsp
     *相对路径为: ../index.jsp
     *绝对路径为: /module_name/index.jsp(重定向)
     *           /index.jsp(请求转发)
     */

使用过滤器Filter拦截未登录请求

Filter是什么

Filter意指过滤器,用于处理用户的非法请求,比如上文中,如果没有过滤器,那么用户在地址栏中输入[domain/ip]:port/module_name/admin/loginSuccess.jsp,就能直接未登录访问loginSuccess.jsp。

Filter是怎么起作用的

Filter需要过滤的路径在DD(web.xml)文件中进行配置。当客户端要访问admin/loginSuccess.jsp时会先执行LoginFilter中的doFilter()方法对请求进行验证。下面实现一个简单的过滤器当用户通过修改地址栏路径访问loginSuccess.jsp时将用户重定向回index.jsp

实现LoginFilter类

    @WebFilter(filterName = "LoginFilter")
    public class LoginFilter implements Filter {
        public void destroy() {
        }

        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {

            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
            //请求路径 localhost:port/module_name/admin/*.jsp
            String currentURL = request.getRequestURI();
            //项目路径 localhost:port/module_name
            String contextURL = request.getContextPath();
            //访问路径 = 请求路径 - 项目路径 = /admin/*.jsp
            String targetURL = currentURL.substring(contextURL.length());
            if(targetURL.equals("/login")){
                System.out.println("Login is legal. Your currentURL is " + currentURL);
                chain.doFilter(request, response);
            }else{
                System.out.println("Login is illegal. Your currentURL is " + targetURL);
                //因为请求路径是[localhost:port]/module_name/admin/*.jsp
                //所以当前所处目录是 module_name/admin,重定向使用相对路径为../index.jsp
                response.sendRedirect("../index.jsp");
            }
        }

        public void init(FilterConfig config) throws ServletException {
        }

    }

DD中Filter的设置

    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>com.web.filter.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值