2016-06-12 6 views
1

Ich habe eine Java-Servlet-Webanwendung, alles funktioniert gut. Es gibt jedoch eine kleine Sache, die mich stört.Java-Servlets - Weiterleiten an URL anstelle von ServletName.do

Wenn sich eine Person anmeldet, wird das Formular an das LoginServlet weitergeleitet, das die Informationen überprüft. Wenn die Informationen verifiziert wurden, wird der Benutzer zu Dashboard.jsp weitergeleitet. Die Sache, die mich stört ist, dass die URL im Browser "http://localhost:8080/LoginServlet.do" anstelle von "http://localhost:8080/dashboard.jsp" sagt. Ich übergebe die Anfrage- und Antwortobjekte, also muss ich einen RequestDispatcher verwenden, richtig?

Wie kann ich sicherstellen, dass die URL 'dashboard.jsp' anstelle von 'LoginServlet.do' lautet?

Anmeldung Servlets:

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); 
     } 
    } 
} 

Mein Web.xml (nicht sicher, ob es relevant ist):

--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-- 

Antwort

1

Die Vorwärts teilt den Server mit dem angegebenen JSP zu verwenden, um die Ergebnisdaten zu zeigen. Hier gibt es keine Interaktion mit dem Client, um eine neue HTTP-Anfrage an die JSP zu senden. Wenn Sie die JSP in der Adressleiste sehen, müssen Sie dem Client mitteilen, dass er jedes Mal eine neue HTTP-Anforderung senden muss. Und das würde bedeuten, Sie die Send-Umleitung verwenden, so wäre es

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

Vielen Dank für Ihre Antwort. Können Sie mir sagen, was die Verwendung von 'request.getContextPath()' ist? – Cake

+0

getContextPath() gibt den Namen der App wie in Ihrem URl angezeigt zurück. Wenn Ihre URL etwa "http: // localhost: 8080/App/index.jsp" lautet, lautet Ihr Kontextpfad App –

+0

. Empfehlen Sie das auf jedem Link zu verwenden? Danke für die Antwort. – Cake

1

Sie sollten response.sendRedirect(URLYouWantThemToBeSentTo) verwenden, da die Weiterleitung auf dem Server und der Client/Navigator getan hat, ist keine Ahnung, es passiert ist.

+0

Wenn ich das sendRedirect verwende, werden das Antwort- und das Request-Objekt weitergeleitet? Weil ich darauf angewiesen bin, dass meine Dashboard.jsp Zugriff auf den 'eingeloggten Benutzer' im Sitzungsumfang hat. – Cake

+0

@Cake Sie müssen sich keine Sorgen machen, wenn es im Sitzungsumfang ist, solange es nicht im Anforderungsbereich ist, ist es in Ordnung. Dies wirft Sie nicht aus der Sitzung. –

+0

ah das macht Sinn. Der Anforderungsbereich wird zerstört, nachdem ich sendRedirect verwendet habe. Was wäre die eleganteste Art, eine Nachricht "mit" auf die nächste Seite zu senden (mit "Erfolgreich angemeldet")? Müsste ich diese Nachricht im SessionScope ablegen, dann die Nachricht anzeigen und die Nachricht erneut aus dem SessionScope entfernen? – Cake

1

Weitere Informationen über sendRedirect()

-New Anfrage wird für die Zielressource erstellt.

-Zwei Anforderungs- und Antwortanrufe werden verbraucht.

-Wir können umgeleitete Adresse sehen, es ist nicht transparent.

-Die Methode sendRedirect() ist langsamer (dann forward()), weil das neue Anfrageobjekt verloren geht, wenn eine neue Anfrage erstellt wird.

-Es ist in HttpServletResponse deklariert.

+1

Vielen Dank für die Zeit zu posten! Nützliche Informationen, genau das, was ich gesucht habe. – Cake

0

würde ich Ihre Lösung ein wenig ‚Refactoring‘:

  • Die Lösung auf Umleitungen basiert. Warum ? Da die für die Authentifizierung verantwortliche Komponente NICHT auf dem Server gehostet werden muss, auf dem die Anwendung ausgeführt wird (meistens nicht und es handelt sich um eine spezielle Komponente).

  • Der Benutzer öffnet das Dashboard.jsp.

  • Ein Servlet-Filter ist dafür verantwortlich zu prüfen, ob ein Authentifizierungs-Cookie vorhanden ist (unter Verwendung einer dedizierten Softwarekomponente). Wenn der Cookie nicht vorhanden ist, wird der Benutzer an eine Softwarekomponente weitergeleitet, die für die Authentifizierung des Benutzers zuständig ist (sieht wie Ihr LoginServlet aus). Der Trick besteht darin, & goto = dashboard.jsp hinzuzufügen (woher Sie kommen, die Seite, die Sie öffnen möchten)).

  • LoginServlet authentifiziert den Benutzer (jede Art von Authentifizierung: Benutzername und Passwort, eid, ...). Wenn die Authentifizierung in Ordnung ist, wird der Cookie erstellt und der Benutzer wird umgeleitet (mit der goto = URL). Zum Beispiel zu dashboard.jsp.

  • Nachdem die Umleitung zu dashboard.jsp stattgefunden hat, können Sie mit dem Filter diesmal das Dashboard.jsp oder eine Seite öffnen, die aufgrund des Cookies durch den Filter geschützt ist.

Das ist ein Weg, um eine moderne Authentifizierung zu erreichen. Natürlich können Sie auch Frameworks (Spring Security), Anwendungen (openAM) verwenden, um dasselbe zu erreichen. Hoffe ich war klar genug.

Verwandte Themen