【问题标题】:Java Servlets - Forward to url instead of ServletName.do [duplicate]Java Servlets - 转发到 url 而不是 ServletName.do [重复]
【发布时间】:2016-10-13 03:14:04
【问题描述】:

我有一个 Java Servlet Web 应用程序,一切正常。 然而,有一件小事困扰着我。

当一个人登录时,表单被转发到验证信息的 LoginServlet。验证信息后,用户将被重定向到dashboard.jsp。困扰我的是浏览器中的 URL 显示“http://localhost:8080/LoginServlet.do”而不是“http://localhost:8080/dashboard.jsp”。我正在转发请求和响应对象,所以我需要使用 RequestDispatcher,对吗?

如何确保 URL 读取的是“dashboard.jsp”而不是“LoginServlet.do”?

登录小服务程序:

public class LoginServlet extends HttpServlet{

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        /*
        * Information that has arrived here, has been checked by the login filter.
        * This servlet takes the parameters from the form, calls the UserService and tries to login.
        * If it succeeds: put the User object in the session scope, and redirect to welcome.jsp with a message 'login successful'
        * If it fails: redirect back to index.jsp with a message 'Login failed'
        */

        RequestDispatcher rd;
        String email = req.getParameter("loginEmail");
        String password = req.getParameter("loginPassword");

        UserService us = ServiceProvider.getUserService();
        User u = us.loginUser(email, password);
        if(u != null) {
            // User information was correct, login successful.
            req.getSession().removeAttribute("loggedUser");
            req.getSession().setAttribute("loggedUser", u);
            req.setAttribute("message", "Login successful");
            u.getAllPomodoros();
            rd = req.getRequestDispatcher("dashboard.jsp");
            rd.forward(req, resp);
        } else {
            // Login failed. Redirect to index.jsp
            req.setAttribute("message", "Login failed");
            rd = req.getRequestDispatcher("index.jsp");
            rd.forward(req, resp);
        }
    }
}

我的 Web.xml(不确定是否相关):

--SNIP--
    <servlet>
        <servlet-name>Login Servlet</servlet-name>
        <servlet-class>controller.LoginServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Login Servlet</servlet-name>
        <url-pattern>/LoginServlet.do</url-pattern>
    </servlet-mapping>
--SNIP--

【问题讨论】:

    标签: java jsp servlets


    【解决方案1】:

    转发告诉服务器使用给定的 JSP 来显示结果数据。这里没有与客户端交互来向 JSP 发送新的 HTTP 请求。如果您正在查看地址栏中的 JSP,那么您需要告诉客户端每次都发送一个新的 HTTP 请求。这意味着你使用发送重定向,所以它会是

    response.sendRedirect(request.getContextPath() + "/index.jsp");
    

    【讨论】:

    • 感谢您的回答。你能告诉我request.getContextPath() 的用途是什么吗?
    • getContextPath() 返回应用程序的名称,如您的 URl 中所示。因此,如果您的 URL 类似于 'localhost:8080/App/index.jsp,您的上下文路径将是 App
    • 明白了。您是否建议在每个链接上都使用它?感谢您的回答。
    • 我真的不建议 sendRedirect,它比转发慢得多,除非你真的有需求,你需要跟踪 JSP
    【解决方案2】:

    关于 sendRedirect() 的更多信息

    -为目标资源创建新请求。

    -消耗两个请求和响应调用。

    -我们可以看到重定向的地址,它不是透明的。

    -sendRedirect() 方法较慢(然后是 forward() ),因为当创建新请求时,旧请求对象会丢失。

    -在HttpServletResponse中声明。

    【讨论】:

    • 感谢您抽出宝贵时间发帖!确实有用的信息,正是我想要的。
    【解决方案3】:

    您应该使用response.sendRedirect(URLYouWantThemToBeSentTo),因为转发是在服务器上完成的,客户端/导航器不知道它发生了。

    【讨论】:

    • 如果我使用sendRedirect,Reponse和Request对象还会被转发吗?因为我依赖我的 Dashboard.jsp 可以访问会话范围内的“loggedUser”。
    • @Cake 你不必担心它是否在会话范围内,只要它不在请求范围内就可以了。这不会让您退出会话。
    • 嗯,有道理。在我使用 sendRedirect 后,请求范围得到了破坏者。将消息“并排”发送到下一页(带有“成功登录”)的最优雅的方式是什么?我是否必须将该消息放入 SessionScope,然后显示该消息并再次从 SessionScope 中删除该消息?
    • @Cake 我猜你可以将消息保存为会话属性。因为你不再使用请求了。不要忘记删除它之后的消息。相关:stackoverflow.com/questions/17001185/…
    【解决方案4】:

    我会稍微“重构”您的解决方案:

    • 解决方案基于重定向。为什么 ?因为负责身份验证的组件不必托管在运行应用程序的服务器上(大多数情况下它不是,它是一个专门的组件)。

    • 用户打开dashboard.jsp。

    • servlet 过滤器负责检查是否存在身份验证cookie(使用专用软件组件)。如果 cookie 不存在,则用户将被重定向到负责对用户进行身份验证的软件组件(看起来像您的 LoginServlet),诀窍是添加 &goto=dashboard.jsp(您来自哪里,您要打开的页面) .

    • LoginServlet 确实对用户进行身份验证(任何类型的身份验证:用户名和密码、eid、...)。如果身份验证正常,则创建 cookie 并重定向用户(使用 goto=URL)。例如到dashboard.jsp。

    • 重定向到dashboard.jsp之后,这次过滤器会让你打开dashboard.jsp或者任何因为cookie被过滤器保护的页面。

    这是实现现代身份验证的某种方式。当然你也可以使用框架(Spring Security)、应用程序(openAM)来实现相同的功能。希望我已经足够清楚了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-28
      • 2015-10-28
      • 2012-10-13
      • 1970-01-01
      相关资源
      最近更新 更多