关于servlet的重定向在有nginx反向代理时出错的解决方法

最近在做web开发的时候遇到这么一件事情,明明在servlet重定向中用的是相对地址,但是在页面上依旧跳转到了根目录的绝对地址下去了。但是在本地运行的时候并没有这个问题,和服务器唯一的区别在于服务器上使用了nginx的反向代理机制。

上代码:

@WebServlet(name = "Logout",urlPatterns = "/logoutServlet")
public class LogoutServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getSession().invalidate();
        response.sendRedirect("./index.jsp");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

这是出问题的代码,可以看到,这个地方的重定向我是用了sendRedirect,这个方法在一般情况下是没有问题的。然后查询了sendRedirect的工作原理:
客户发送一个请求到服务器,服务器匹配servlet,这都和请求转发一样,servlet处理完之后调用了sendRedirect()这个方法,这个方法是response的方法,所以,当这个servlet处理完之后,看到response.senRedirect()方法,立即向客户端返回这个响应,响应行告诉客户端你必须要再发送一个请求,去访问test.jsp,紧接着客户端受到这个请求后,立刻发出一个新的请求,去请求test.jsp,这里两个请求互不干扰,相互独立,在前面request里面setAttribute()的任何东西,在后面的request里面都获得不了。可见,在sendRedirect()里面是两个请求,两个响应。
可以看出,用了sendRedirect实际上是浏览器重新向服务器发出访问新页面的请求,这个新请求在经过nginx时被解读成了绝对地址,所以无法访问到正确的资源,解决方法是采用请求转发(RequestDispatcher)。因为请求转发的整个转发流程都在服务器内完成,不再经过前端页面,所以能够正确读取到页面。代码如下:

@WebServlet(name = "Logout",urlPatterns = "/logoutServlet")
public class LogoutServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getSession().invalidate();
        request.getRequestDispatcher("./index.jsp").forward(request,response);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

你可能感兴趣的:(软件工程)