Java Servlet & JSP simple loginTomcat/JSP/servlets web-projectfile downloading using jsp but not readableA Java Web App with Servlets, JSP and Session: shopping cart exampleServlet and JSP for user registration, with CAPTCHA and error handlingOpen source Pastebin tool made in JSP and servletAuthorization token from servlet filter stores user nameJava login system using JSP and servletsThread Safe ServletSimple login with jspAsking data to a Servlet from jsp and send them back to the jsp

Averting Real Women Don’t Wear Dresses

Why isn’t the tax system continuous rather than bracketed?

Why does the A-4 Skyhawk sit nose-up when on ground?

Is this one of the engines from the 9/11 aircraft?

Why is C++ initial allocation so much larger than C's?

Should I include salary information on my CV?

Alphabet completion rate

Should I tell my insurance company I'm making payments on my new car?

Do French speakers not use the subjunctive informally?

Rvalues, lvalues and formal definitions

STM Microcontroller burns every time

How to perform Login Authentication at the client-side?

What is the line crossing the Pacific Ocean that is shown on maps?

Layout of complex table

What do you call the action of someone tackling a stronger person?

Should my manager be aware of private LinkedIn approaches I receive? How to politely have this happen?

MH370 blackbox - is it still possible to retrieve data from it?

Intuitively, why does putting capacitors in series decrease the equivalent capacitance?

How can I convince my reader that I will not use a certain trope?

How to determine what is the correct level of detail when modelling?

Are neural networks the wrong tool to solve this 2D platformer/shooter game? Is there a proven way to frame this problem to a neural network?

Ending: accusative or not?

Why would people reject a god's purely beneficial blessing?

How can I repair scratches on a painted French door?



Java Servlet & JSP simple login


Tomcat/JSP/servlets web-projectfile downloading using jsp but not readableA Java Web App with Servlets, JSP and Session: shopping cart exampleServlet and JSP for user registration, with CAPTCHA and error handlingOpen source Pastebin tool made in JSP and servletAuthorization token from servlet filter stores user nameJava login system using JSP and servletsThread Safe ServletSimple login with jspAsking data to a Servlet from jsp and send them back to the jsp






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








7












$begingroup$


I am currently learning Java Servlets and JSP at university. As a little practice I created a project where I want to be able to login into a protected area. Now, I got it working by using a RequestDispatcher. However, after I have been forwarded to the protected area, the URL in the browser shows http://localhost:8080/jspractice02/FrontController. I think it would make more sense to be http://localhost:8080/jspractice02/protected/dashboard.jsp. Should I use sendRedirect instead of a Dispatcher?
Another thing is that I don't know if my code structure is somewhat senseful, especially how I handle the login. I would love to get some feedback on that.



Directory Structure



+-- src
| +-- main
| +-- java
| | +-- de.practice.PresentationLayer
| | +-- FrontController.java
| +-- webapp
| | +-- home.jsp
| | +-- protected
| | +-- dashboard.jsp
| | +-- add-student.jsp


FrontController.java



package de.practice.Presentation;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
* Servlet implementation class FrontController
*/
@WebServlet("/FrontController")
public class FrontController extends HttpServlet
private static final long serialVersionUID = 1L;


private static String username = "";
private static String password = "";
private static String queryString = "";


/**
* Constructor
*/
public FrontController()
super();



/**
* doGet
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

String jsp = "";
queryString = request.getParameter("action");

if(queryString != null)

switch(queryString)
case "addStudent":
jsp = "protected/student.jsp";


RequestDispatcher rd = request.getRequestDispatcher(jsp);
rd.forward(request, response);





/**
* doPost
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

doGet(request, response);
login(request, response);





/**
* validPassword
* @param request
* @param response
* @param password
* @return
*/
private boolean validPassword(HttpServletRequest request, HttpServletResponse response, String password)

if(password.length() >= 3)
return true;

return false;



/**
* validUsername
* @param request
* @param response
* @param username
* @return
*/
private boolean validUsername(HttpServletRequest request, HttpServletResponse response, String username)

if(username.length() >= 3)
return true;

return false;



/**
*
* @param request
* @param response
* @param password
* @param username
* @throws IOException
* @throws ServletException
*/
private void login(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
// Get username and password
username = request.getParameter("username");
password = request.getParameter("password");


// check if they are valid
if(validUsername(request, response, username) && validPassword(request, response, password))

// If valid create session
HttpSession session = request.getSession();
session.setAttribute("username", username);

// and redirect to protected area
RequestDispatcher rd = request.getRequestDispatcher("protected/dashboard.jsp");
rd.forward(request, response);

else
// Code for invalid login
RequestDispatcher rd = request.getRequestDispatcher("login-failed.jsp");
rd.forward(request, response);












<%@ include file="partials/header.jsp"%>

<section id="start" class="panel">
<div class="container">
<h1>Home</h1>

<form class="form" method="post" action="FrontController">
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" class="form-control">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" class="form-control">
</div>

<input type="submit" name="submitBtn" class="btn btn-primary">
</form>

</div>
</section>

<%@ include file="partials/footer.jsp"%>









share|improve this question











$endgroup$


















    7












    $begingroup$


    I am currently learning Java Servlets and JSP at university. As a little practice I created a project where I want to be able to login into a protected area. Now, I got it working by using a RequestDispatcher. However, after I have been forwarded to the protected area, the URL in the browser shows http://localhost:8080/jspractice02/FrontController. I think it would make more sense to be http://localhost:8080/jspractice02/protected/dashboard.jsp. Should I use sendRedirect instead of a Dispatcher?
    Another thing is that I don't know if my code structure is somewhat senseful, especially how I handle the login. I would love to get some feedback on that.



    Directory Structure



    +-- src
    | +-- main
    | +-- java
    | | +-- de.practice.PresentationLayer
    | | +-- FrontController.java
    | +-- webapp
    | | +-- home.jsp
    | | +-- protected
    | | +-- dashboard.jsp
    | | +-- add-student.jsp


    FrontController.java



    package de.practice.Presentation;

    import java.io.IOException;
    import java.util.ArrayList;

    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;

    /**
    * Servlet implementation class FrontController
    */
    @WebServlet("/FrontController")
    public class FrontController extends HttpServlet
    private static final long serialVersionUID = 1L;


    private static String username = "";
    private static String password = "";
    private static String queryString = "";


    /**
    * Constructor
    */
    public FrontController()
    super();



    /**
    * doGet
    */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

    String jsp = "";
    queryString = request.getParameter("action");

    if(queryString != null)

    switch(queryString)
    case "addStudent":
    jsp = "protected/student.jsp";


    RequestDispatcher rd = request.getRequestDispatcher(jsp);
    rd.forward(request, response);





    /**
    * doPost
    */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

    doGet(request, response);
    login(request, response);





    /**
    * validPassword
    * @param request
    * @param response
    * @param password
    * @return
    */
    private boolean validPassword(HttpServletRequest request, HttpServletResponse response, String password)

    if(password.length() >= 3)
    return true;

    return false;



    /**
    * validUsername
    * @param request
    * @param response
    * @param username
    * @return
    */
    private boolean validUsername(HttpServletRequest request, HttpServletResponse response, String username)

    if(username.length() >= 3)
    return true;

    return false;



    /**
    *
    * @param request
    * @param response
    * @param password
    * @param username
    * @throws IOException
    * @throws ServletException
    */
    private void login(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    // Get username and password
    username = request.getParameter("username");
    password = request.getParameter("password");


    // check if they are valid
    if(validUsername(request, response, username) && validPassword(request, response, password))

    // If valid create session
    HttpSession session = request.getSession();
    session.setAttribute("username", username);

    // and redirect to protected area
    RequestDispatcher rd = request.getRequestDispatcher("protected/dashboard.jsp");
    rd.forward(request, response);

    else
    // Code for invalid login
    RequestDispatcher rd = request.getRequestDispatcher("login-failed.jsp");
    rd.forward(request, response);












    <%@ include file="partials/header.jsp"%>

    <section id="start" class="panel">
    <div class="container">
    <h1>Home</h1>

    <form class="form" method="post" action="FrontController">
    <div class="form-group">
    <label for="username">Username</label>
    <input type="text" name="username" class="form-control">
    </div>
    <div class="form-group">
    <label for="password">Password</label>
    <input type="password" name="password" class="form-control">
    </div>

    <input type="submit" name="submitBtn" class="btn btn-primary">
    </form>

    </div>
    </section>

    <%@ include file="partials/footer.jsp"%>









    share|improve this question











    $endgroup$














      7












      7








      7





      $begingroup$


      I am currently learning Java Servlets and JSP at university. As a little practice I created a project where I want to be able to login into a protected area. Now, I got it working by using a RequestDispatcher. However, after I have been forwarded to the protected area, the URL in the browser shows http://localhost:8080/jspractice02/FrontController. I think it would make more sense to be http://localhost:8080/jspractice02/protected/dashboard.jsp. Should I use sendRedirect instead of a Dispatcher?
      Another thing is that I don't know if my code structure is somewhat senseful, especially how I handle the login. I would love to get some feedback on that.



      Directory Structure



      +-- src
      | +-- main
      | +-- java
      | | +-- de.practice.PresentationLayer
      | | +-- FrontController.java
      | +-- webapp
      | | +-- home.jsp
      | | +-- protected
      | | +-- dashboard.jsp
      | | +-- add-student.jsp


      FrontController.java



      package de.practice.Presentation;

      import java.io.IOException;
      import java.util.ArrayList;

      import javax.servlet.RequestDispatcher;
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import javax.servlet.http.HttpSession;

      /**
      * Servlet implementation class FrontController
      */
      @WebServlet("/FrontController")
      public class FrontController extends HttpServlet
      private static final long serialVersionUID = 1L;


      private static String username = "";
      private static String password = "";
      private static String queryString = "";


      /**
      * Constructor
      */
      public FrontController()
      super();



      /**
      * doGet
      */
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

      String jsp = "";
      queryString = request.getParameter("action");

      if(queryString != null)

      switch(queryString)
      case "addStudent":
      jsp = "protected/student.jsp";


      RequestDispatcher rd = request.getRequestDispatcher(jsp);
      rd.forward(request, response);





      /**
      * doPost
      */
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

      doGet(request, response);
      login(request, response);





      /**
      * validPassword
      * @param request
      * @param response
      * @param password
      * @return
      */
      private boolean validPassword(HttpServletRequest request, HttpServletResponse response, String password)

      if(password.length() >= 3)
      return true;

      return false;



      /**
      * validUsername
      * @param request
      * @param response
      * @param username
      * @return
      */
      private boolean validUsername(HttpServletRequest request, HttpServletResponse response, String username)

      if(username.length() >= 3)
      return true;

      return false;



      /**
      *
      * @param request
      * @param response
      * @param password
      * @param username
      * @throws IOException
      * @throws ServletException
      */
      private void login(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
      // Get username and password
      username = request.getParameter("username");
      password = request.getParameter("password");


      // check if they are valid
      if(validUsername(request, response, username) && validPassword(request, response, password))

      // If valid create session
      HttpSession session = request.getSession();
      session.setAttribute("username", username);

      // and redirect to protected area
      RequestDispatcher rd = request.getRequestDispatcher("protected/dashboard.jsp");
      rd.forward(request, response);

      else
      // Code for invalid login
      RequestDispatcher rd = request.getRequestDispatcher("login-failed.jsp");
      rd.forward(request, response);












      <%@ include file="partials/header.jsp"%>

      <section id="start" class="panel">
      <div class="container">
      <h1>Home</h1>

      <form class="form" method="post" action="FrontController">
      <div class="form-group">
      <label for="username">Username</label>
      <input type="text" name="username" class="form-control">
      </div>
      <div class="form-group">
      <label for="password">Password</label>
      <input type="password" name="password" class="form-control">
      </div>

      <input type="submit" name="submitBtn" class="btn btn-primary">
      </form>

      </div>
      </section>

      <%@ include file="partials/footer.jsp"%>









      share|improve this question











      $endgroup$




      I am currently learning Java Servlets and JSP at university. As a little practice I created a project where I want to be able to login into a protected area. Now, I got it working by using a RequestDispatcher. However, after I have been forwarded to the protected area, the URL in the browser shows http://localhost:8080/jspractice02/FrontController. I think it would make more sense to be http://localhost:8080/jspractice02/protected/dashboard.jsp. Should I use sendRedirect instead of a Dispatcher?
      Another thing is that I don't know if my code structure is somewhat senseful, especially how I handle the login. I would love to get some feedback on that.



      Directory Structure



      +-- src
      | +-- main
      | +-- java
      | | +-- de.practice.PresentationLayer
      | | +-- FrontController.java
      | +-- webapp
      | | +-- home.jsp
      | | +-- protected
      | | +-- dashboard.jsp
      | | +-- add-student.jsp


      FrontController.java



      package de.practice.Presentation;

      import java.io.IOException;
      import java.util.ArrayList;

      import javax.servlet.RequestDispatcher;
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import javax.servlet.http.HttpSession;

      /**
      * Servlet implementation class FrontController
      */
      @WebServlet("/FrontController")
      public class FrontController extends HttpServlet
      private static final long serialVersionUID = 1L;


      private static String username = "";
      private static String password = "";
      private static String queryString = "";


      /**
      * Constructor
      */
      public FrontController()
      super();



      /**
      * doGet
      */
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

      String jsp = "";
      queryString = request.getParameter("action");

      if(queryString != null)

      switch(queryString)
      case "addStudent":
      jsp = "protected/student.jsp";


      RequestDispatcher rd = request.getRequestDispatcher(jsp);
      rd.forward(request, response);





      /**
      * doPost
      */
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

      doGet(request, response);
      login(request, response);





      /**
      * validPassword
      * @param request
      * @param response
      * @param password
      * @return
      */
      private boolean validPassword(HttpServletRequest request, HttpServletResponse response, String password)

      if(password.length() >= 3)
      return true;

      return false;



      /**
      * validUsername
      * @param request
      * @param response
      * @param username
      * @return
      */
      private boolean validUsername(HttpServletRequest request, HttpServletResponse response, String username)

      if(username.length() >= 3)
      return true;

      return false;



      /**
      *
      * @param request
      * @param response
      * @param password
      * @param username
      * @throws IOException
      * @throws ServletException
      */
      private void login(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
      // Get username and password
      username = request.getParameter("username");
      password = request.getParameter("password");


      // check if they are valid
      if(validUsername(request, response, username) && validPassword(request, response, password))

      // If valid create session
      HttpSession session = request.getSession();
      session.setAttribute("username", username);

      // and redirect to protected area
      RequestDispatcher rd = request.getRequestDispatcher("protected/dashboard.jsp");
      rd.forward(request, response);

      else
      // Code for invalid login
      RequestDispatcher rd = request.getRequestDispatcher("login-failed.jsp");
      rd.forward(request, response);












      <%@ include file="partials/header.jsp"%>

      <section id="start" class="panel">
      <div class="container">
      <h1>Home</h1>

      <form class="form" method="post" action="FrontController">
      <div class="form-group">
      <label for="username">Username</label>
      <input type="text" name="username" class="form-control">
      </div>
      <div class="form-group">
      <label for="password">Password</label>
      <input type="password" name="password" class="form-control">
      </div>

      <input type="submit" name="submitBtn" class="btn btn-primary">
      </form>

      </div>
      </section>

      <%@ include file="partials/footer.jsp"%>






      java authentication servlets jsp






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jun 8 at 17:13









      200_success

      134k21 gold badges169 silver badges440 bronze badges




      134k21 gold badges169 silver badges440 bronze badges










      asked Jun 8 at 13:22









      Dennis FinkDennis Fink

      1738 bronze badges




      1738 bronze badges




















          3 Answers
          3






          active

          oldest

          votes


















          7












          $begingroup$

          Critical error



          private static String username = "";
          private static String password = "";
          private static String queryString = "";


          You should never keep request-scoped data in a field in a servlet. Servlet is created only once during application startup, and shared among all requests. So if several clients connect to your servlet at the same time, they might not reach the protected page, even if they provide correct password. It will also lead to setting wrong username attribute in the session object. If you had customized pages for each user, this could also lead to people seeing protected pages of other people.



          Solution - extract the sensitive request-scoped data in doGet method only. Also, simply removing the static keyword will not resolve the issue.



          Code style



          1. Get rid of empty JavaDoc that only makes the code harder to read

          2. Get rid of obvious comments that only make the code harder to read, like // Get username and password

          3. Do not introduce redunant code (constructor that only calls super())

          4. Improve method ordering. When you call validUsername() in login(), then validUsername() should be below login() in the class. this improves readability.

          5. Get rid of redundant logic. For example, the validUsername() method body can be elegantly expressed in one line - return username.length() >= 3. By the way, I think this method should be named isUsernameValid() in my opinion.

          6. Do not pass unnecessary arguments to methods. For example, validUsername() does not need request and response.

          Other



          The browser shows http://localhost:8080/jspractice02/FrontController because you've annotated the class with @WebServlet("/FrontController"). Please read the documentation on how that works.



          I'm not sure if calling doGet() from doPost() is necessary (and I'm not sure if it's best practice). Your doPost() should just login the user and redirect them if the credentials provided are valid.






          share|improve this answer











          $endgroup$












          • $begingroup$
            "Do not introduce redunant code (constructor that only calls super())" Keep in mind that there are instances when declaring default constructors is required, for example when the binary is being obfuscated (obfuscator strips the default ones, but leaves user defined ones intact).
            $endgroup$
            – Bobby
            Jun 9 at 8:32










          • $begingroup$
            "Can you think how?" We're doing a code review here, not playing guessing games. Just tell the people.
            $endgroup$
            – Bobby
            Jun 9 at 8:33


















          5












          $begingroup$

          package de.practice.Presentation


          That's not a valid package name under the Java convention. Packages are all lowercase with maybe underscores.




          private static String username = "";


          You don't want these static, actually, you don't want them as fields at all. When dealing with requests, you have to consider that one instance of the same class might handle multiple requests simultaneously. Having a state in the class (f.e. fields) has to be carefully considered.




          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 

          String jsp = "";
          queryString = request.getParameter("action");

          if(queryString != null)

          switch(queryString)
          case "addStudent":
          jsp = "protected/student.jsp";


          RequestDispatcher rd = request.getRequestDispatcher(jsp);
          rd.forward(request, response);




          Consider mapping your requests and actions in a way which allows you to refer to locations directly without having to resort to a big switch statement.




          private boolean validPassword(HttpServletRequest request, HttpServletResponse response, String password) 

          if(password.length() >= 3)
          return true;

          return false;



          We all know that's just a placeholder, but you could return directly:



          return password.length() >= 3;



          RequestDispatcher rd = request.getRequestDispatcher("login-failed.jsp");
          rd.forward(request, response);


          You're repeating this action multiple times, consider a helper function. But you could also write that in one line.




          /**
          * Constructor
          */


          You might as well omit the Javadoc if it's not going to be useful.








          share|improve this answer









          $endgroup$




















            1












            $begingroup$

            You've received some good comments on the detailed coding, so I'll focus on the design.



            • Follow the single responsibility principle in your controller, it should do one thing, dispatch the commands it receives.

            • The SRP will make it unnecessary to change the controller to add new commands. Replace your switch with a command mapping, see the Command Pattern. A good approach to this is to load the commands from a property file into a Hashmap; so Command=ClassName that maps the command-name to a class name.

            • Use the Class.forName(className).newInstance() idiom to construct new instances of the commands on demand.

            • Create a hierarchy of the access controlled commands to minimise the risk of a security/access holes. So all the controlled commands must inherit from an access controlled command.

            See this answer for a more elaborate explanation : https://softwareengineering.stackexchange.com/a/345714/241947






            share|improve this answer











            $endgroup$












            • $begingroup$
              "Use the Class.forName(className).newInstance() idiom to make the commands" Could you iterate on that?
              $endgroup$
              – Bobby
              Jun 10 at 17:52










            • $begingroup$
              @Bobby It is factory method that constructs a new instance of a class using a variable name rather than a hard coded class name. The className value needs to be fully qualified with the package but is really simple to use and extremely powerful factory method. I've added a link to the JavaDoc.
              $endgroup$
              – Martin Spamer
              Jun 13 at 17:35






            • 1




              $begingroup$
              Oh, className is not a placeholder but an actual variable, then I get what you mean.
              $endgroup$
              – Bobby
              Jun 13 at 19:11













            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f221929%2fjava-servlet-jsp-simple-login%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            7












            $begingroup$

            Critical error



            private static String username = "";
            private static String password = "";
            private static String queryString = "";


            You should never keep request-scoped data in a field in a servlet. Servlet is created only once during application startup, and shared among all requests. So if several clients connect to your servlet at the same time, they might not reach the protected page, even if they provide correct password. It will also lead to setting wrong username attribute in the session object. If you had customized pages for each user, this could also lead to people seeing protected pages of other people.



            Solution - extract the sensitive request-scoped data in doGet method only. Also, simply removing the static keyword will not resolve the issue.



            Code style



            1. Get rid of empty JavaDoc that only makes the code harder to read

            2. Get rid of obvious comments that only make the code harder to read, like // Get username and password

            3. Do not introduce redunant code (constructor that only calls super())

            4. Improve method ordering. When you call validUsername() in login(), then validUsername() should be below login() in the class. this improves readability.

            5. Get rid of redundant logic. For example, the validUsername() method body can be elegantly expressed in one line - return username.length() >= 3. By the way, I think this method should be named isUsernameValid() in my opinion.

            6. Do not pass unnecessary arguments to methods. For example, validUsername() does not need request and response.

            Other



            The browser shows http://localhost:8080/jspractice02/FrontController because you've annotated the class with @WebServlet("/FrontController"). Please read the documentation on how that works.



            I'm not sure if calling doGet() from doPost() is necessary (and I'm not sure if it's best practice). Your doPost() should just login the user and redirect them if the credentials provided are valid.






            share|improve this answer











            $endgroup$












            • $begingroup$
              "Do not introduce redunant code (constructor that only calls super())" Keep in mind that there are instances when declaring default constructors is required, for example when the binary is being obfuscated (obfuscator strips the default ones, but leaves user defined ones intact).
              $endgroup$
              – Bobby
              Jun 9 at 8:32










            • $begingroup$
              "Can you think how?" We're doing a code review here, not playing guessing games. Just tell the people.
              $endgroup$
              – Bobby
              Jun 9 at 8:33















            7












            $begingroup$

            Critical error



            private static String username = "";
            private static String password = "";
            private static String queryString = "";


            You should never keep request-scoped data in a field in a servlet. Servlet is created only once during application startup, and shared among all requests. So if several clients connect to your servlet at the same time, they might not reach the protected page, even if they provide correct password. It will also lead to setting wrong username attribute in the session object. If you had customized pages for each user, this could also lead to people seeing protected pages of other people.



            Solution - extract the sensitive request-scoped data in doGet method only. Also, simply removing the static keyword will not resolve the issue.



            Code style



            1. Get rid of empty JavaDoc that only makes the code harder to read

            2. Get rid of obvious comments that only make the code harder to read, like // Get username and password

            3. Do not introduce redunant code (constructor that only calls super())

            4. Improve method ordering. When you call validUsername() in login(), then validUsername() should be below login() in the class. this improves readability.

            5. Get rid of redundant logic. For example, the validUsername() method body can be elegantly expressed in one line - return username.length() >= 3. By the way, I think this method should be named isUsernameValid() in my opinion.

            6. Do not pass unnecessary arguments to methods. For example, validUsername() does not need request and response.

            Other



            The browser shows http://localhost:8080/jspractice02/FrontController because you've annotated the class with @WebServlet("/FrontController"). Please read the documentation on how that works.



            I'm not sure if calling doGet() from doPost() is necessary (and I'm not sure if it's best practice). Your doPost() should just login the user and redirect them if the credentials provided are valid.






            share|improve this answer











            $endgroup$












            • $begingroup$
              "Do not introduce redunant code (constructor that only calls super())" Keep in mind that there are instances when declaring default constructors is required, for example when the binary is being obfuscated (obfuscator strips the default ones, but leaves user defined ones intact).
              $endgroup$
              – Bobby
              Jun 9 at 8:32










            • $begingroup$
              "Can you think how?" We're doing a code review here, not playing guessing games. Just tell the people.
              $endgroup$
              – Bobby
              Jun 9 at 8:33













            7












            7








            7





            $begingroup$

            Critical error



            private static String username = "";
            private static String password = "";
            private static String queryString = "";


            You should never keep request-scoped data in a field in a servlet. Servlet is created only once during application startup, and shared among all requests. So if several clients connect to your servlet at the same time, they might not reach the protected page, even if they provide correct password. It will also lead to setting wrong username attribute in the session object. If you had customized pages for each user, this could also lead to people seeing protected pages of other people.



            Solution - extract the sensitive request-scoped data in doGet method only. Also, simply removing the static keyword will not resolve the issue.



            Code style



            1. Get rid of empty JavaDoc that only makes the code harder to read

            2. Get rid of obvious comments that only make the code harder to read, like // Get username and password

            3. Do not introduce redunant code (constructor that only calls super())

            4. Improve method ordering. When you call validUsername() in login(), then validUsername() should be below login() in the class. this improves readability.

            5. Get rid of redundant logic. For example, the validUsername() method body can be elegantly expressed in one line - return username.length() >= 3. By the way, I think this method should be named isUsernameValid() in my opinion.

            6. Do not pass unnecessary arguments to methods. For example, validUsername() does not need request and response.

            Other



            The browser shows http://localhost:8080/jspractice02/FrontController because you've annotated the class with @WebServlet("/FrontController"). Please read the documentation on how that works.



            I'm not sure if calling doGet() from doPost() is necessary (and I'm not sure if it's best practice). Your doPost() should just login the user and redirect them if the credentials provided are valid.






            share|improve this answer











            $endgroup$



            Critical error



            private static String username = "";
            private static String password = "";
            private static String queryString = "";


            You should never keep request-scoped data in a field in a servlet. Servlet is created only once during application startup, and shared among all requests. So if several clients connect to your servlet at the same time, they might not reach the protected page, even if they provide correct password. It will also lead to setting wrong username attribute in the session object. If you had customized pages for each user, this could also lead to people seeing protected pages of other people.



            Solution - extract the sensitive request-scoped data in doGet method only. Also, simply removing the static keyword will not resolve the issue.



            Code style



            1. Get rid of empty JavaDoc that only makes the code harder to read

            2. Get rid of obvious comments that only make the code harder to read, like // Get username and password

            3. Do not introduce redunant code (constructor that only calls super())

            4. Improve method ordering. When you call validUsername() in login(), then validUsername() should be below login() in the class. this improves readability.

            5. Get rid of redundant logic. For example, the validUsername() method body can be elegantly expressed in one line - return username.length() >= 3. By the way, I think this method should be named isUsernameValid() in my opinion.

            6. Do not pass unnecessary arguments to methods. For example, validUsername() does not need request and response.

            Other



            The browser shows http://localhost:8080/jspractice02/FrontController because you've annotated the class with @WebServlet("/FrontController"). Please read the documentation on how that works.



            I'm not sure if calling doGet() from doPost() is necessary (and I'm not sure if it's best practice). Your doPost() should just login the user and redirect them if the credentials provided are valid.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jun 9 at 10:30

























            answered Jun 8 at 16:41









            RK1RK1

            3792 silver badges14 bronze badges




            3792 silver badges14 bronze badges











            • $begingroup$
              "Do not introduce redunant code (constructor that only calls super())" Keep in mind that there are instances when declaring default constructors is required, for example when the binary is being obfuscated (obfuscator strips the default ones, but leaves user defined ones intact).
              $endgroup$
              – Bobby
              Jun 9 at 8:32










            • $begingroup$
              "Can you think how?" We're doing a code review here, not playing guessing games. Just tell the people.
              $endgroup$
              – Bobby
              Jun 9 at 8:33
















            • $begingroup$
              "Do not introduce redunant code (constructor that only calls super())" Keep in mind that there are instances when declaring default constructors is required, for example when the binary is being obfuscated (obfuscator strips the default ones, but leaves user defined ones intact).
              $endgroup$
              – Bobby
              Jun 9 at 8:32










            • $begingroup$
              "Can you think how?" We're doing a code review here, not playing guessing games. Just tell the people.
              $endgroup$
              – Bobby
              Jun 9 at 8:33















            $begingroup$
            "Do not introduce redunant code (constructor that only calls super())" Keep in mind that there are instances when declaring default constructors is required, for example when the binary is being obfuscated (obfuscator strips the default ones, but leaves user defined ones intact).
            $endgroup$
            – Bobby
            Jun 9 at 8:32




            $begingroup$
            "Do not introduce redunant code (constructor that only calls super())" Keep in mind that there are instances when declaring default constructors is required, for example when the binary is being obfuscated (obfuscator strips the default ones, but leaves user defined ones intact).
            $endgroup$
            – Bobby
            Jun 9 at 8:32












            $begingroup$
            "Can you think how?" We're doing a code review here, not playing guessing games. Just tell the people.
            $endgroup$
            – Bobby
            Jun 9 at 8:33




            $begingroup$
            "Can you think how?" We're doing a code review here, not playing guessing games. Just tell the people.
            $endgroup$
            – Bobby
            Jun 9 at 8:33













            5












            $begingroup$

            package de.practice.Presentation


            That's not a valid package name under the Java convention. Packages are all lowercase with maybe underscores.




            private static String username = "";


            You don't want these static, actually, you don't want them as fields at all. When dealing with requests, you have to consider that one instance of the same class might handle multiple requests simultaneously. Having a state in the class (f.e. fields) has to be carefully considered.




            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 

            String jsp = "";
            queryString = request.getParameter("action");

            if(queryString != null)

            switch(queryString)
            case "addStudent":
            jsp = "protected/student.jsp";


            RequestDispatcher rd = request.getRequestDispatcher(jsp);
            rd.forward(request, response);




            Consider mapping your requests and actions in a way which allows you to refer to locations directly without having to resort to a big switch statement.




            private boolean validPassword(HttpServletRequest request, HttpServletResponse response, String password) 

            if(password.length() >= 3)
            return true;

            return false;



            We all know that's just a placeholder, but you could return directly:



            return password.length() >= 3;



            RequestDispatcher rd = request.getRequestDispatcher("login-failed.jsp");
            rd.forward(request, response);


            You're repeating this action multiple times, consider a helper function. But you could also write that in one line.




            /**
            * Constructor
            */


            You might as well omit the Javadoc if it's not going to be useful.








            share|improve this answer









            $endgroup$

















              5












              $begingroup$

              package de.practice.Presentation


              That's not a valid package name under the Java convention. Packages are all lowercase with maybe underscores.




              private static String username = "";


              You don't want these static, actually, you don't want them as fields at all. When dealing with requests, you have to consider that one instance of the same class might handle multiple requests simultaneously. Having a state in the class (f.e. fields) has to be carefully considered.




              protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 

              String jsp = "";
              queryString = request.getParameter("action");

              if(queryString != null)

              switch(queryString)
              case "addStudent":
              jsp = "protected/student.jsp";


              RequestDispatcher rd = request.getRequestDispatcher(jsp);
              rd.forward(request, response);




              Consider mapping your requests and actions in a way which allows you to refer to locations directly without having to resort to a big switch statement.




              private boolean validPassword(HttpServletRequest request, HttpServletResponse response, String password) 

              if(password.length() >= 3)
              return true;

              return false;



              We all know that's just a placeholder, but you could return directly:



              return password.length() >= 3;



              RequestDispatcher rd = request.getRequestDispatcher("login-failed.jsp");
              rd.forward(request, response);


              You're repeating this action multiple times, consider a helper function. But you could also write that in one line.




              /**
              * Constructor
              */


              You might as well omit the Javadoc if it's not going to be useful.








              share|improve this answer









              $endgroup$















                5












                5








                5





                $begingroup$

                package de.practice.Presentation


                That's not a valid package name under the Java convention. Packages are all lowercase with maybe underscores.




                private static String username = "";


                You don't want these static, actually, you don't want them as fields at all. When dealing with requests, you have to consider that one instance of the same class might handle multiple requests simultaneously. Having a state in the class (f.e. fields) has to be carefully considered.




                protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 

                String jsp = "";
                queryString = request.getParameter("action");

                if(queryString != null)

                switch(queryString)
                case "addStudent":
                jsp = "protected/student.jsp";


                RequestDispatcher rd = request.getRequestDispatcher(jsp);
                rd.forward(request, response);




                Consider mapping your requests and actions in a way which allows you to refer to locations directly without having to resort to a big switch statement.




                private boolean validPassword(HttpServletRequest request, HttpServletResponse response, String password) 

                if(password.length() >= 3)
                return true;

                return false;



                We all know that's just a placeholder, but you could return directly:



                return password.length() >= 3;



                RequestDispatcher rd = request.getRequestDispatcher("login-failed.jsp");
                rd.forward(request, response);


                You're repeating this action multiple times, consider a helper function. But you could also write that in one line.




                /**
                * Constructor
                */


                You might as well omit the Javadoc if it's not going to be useful.








                share|improve this answer









                $endgroup$



                package de.practice.Presentation


                That's not a valid package name under the Java convention. Packages are all lowercase with maybe underscores.




                private static String username = "";


                You don't want these static, actually, you don't want them as fields at all. When dealing with requests, you have to consider that one instance of the same class might handle multiple requests simultaneously. Having a state in the class (f.e. fields) has to be carefully considered.




                protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 

                String jsp = "";
                queryString = request.getParameter("action");

                if(queryString != null)

                switch(queryString)
                case "addStudent":
                jsp = "protected/student.jsp";


                RequestDispatcher rd = request.getRequestDispatcher(jsp);
                rd.forward(request, response);




                Consider mapping your requests and actions in a way which allows you to refer to locations directly without having to resort to a big switch statement.




                private boolean validPassword(HttpServletRequest request, HttpServletResponse response, String password) 

                if(password.length() >= 3)
                return true;

                return false;



                We all know that's just a placeholder, but you could return directly:



                return password.length() >= 3;



                RequestDispatcher rd = request.getRequestDispatcher("login-failed.jsp");
                rd.forward(request, response);


                You're repeating this action multiple times, consider a helper function. But you could also write that in one line.




                /**
                * Constructor
                */


                You might as well omit the Javadoc if it's not going to be useful.









                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jun 8 at 16:35









                BobbyBobby

                5,1881 gold badge23 silver badges41 bronze badges




                5,1881 gold badge23 silver badges41 bronze badges





















                    1












                    $begingroup$

                    You've received some good comments on the detailed coding, so I'll focus on the design.



                    • Follow the single responsibility principle in your controller, it should do one thing, dispatch the commands it receives.

                    • The SRP will make it unnecessary to change the controller to add new commands. Replace your switch with a command mapping, see the Command Pattern. A good approach to this is to load the commands from a property file into a Hashmap; so Command=ClassName that maps the command-name to a class name.

                    • Use the Class.forName(className).newInstance() idiom to construct new instances of the commands on demand.

                    • Create a hierarchy of the access controlled commands to minimise the risk of a security/access holes. So all the controlled commands must inherit from an access controlled command.

                    See this answer for a more elaborate explanation : https://softwareengineering.stackexchange.com/a/345714/241947






                    share|improve this answer











                    $endgroup$












                    • $begingroup$
                      "Use the Class.forName(className).newInstance() idiom to make the commands" Could you iterate on that?
                      $endgroup$
                      – Bobby
                      Jun 10 at 17:52










                    • $begingroup$
                      @Bobby It is factory method that constructs a new instance of a class using a variable name rather than a hard coded class name. The className value needs to be fully qualified with the package but is really simple to use and extremely powerful factory method. I've added a link to the JavaDoc.
                      $endgroup$
                      – Martin Spamer
                      Jun 13 at 17:35






                    • 1




                      $begingroup$
                      Oh, className is not a placeholder but an actual variable, then I get what you mean.
                      $endgroup$
                      – Bobby
                      Jun 13 at 19:11















                    1












                    $begingroup$

                    You've received some good comments on the detailed coding, so I'll focus on the design.



                    • Follow the single responsibility principle in your controller, it should do one thing, dispatch the commands it receives.

                    • The SRP will make it unnecessary to change the controller to add new commands. Replace your switch with a command mapping, see the Command Pattern. A good approach to this is to load the commands from a property file into a Hashmap; so Command=ClassName that maps the command-name to a class name.

                    • Use the Class.forName(className).newInstance() idiom to construct new instances of the commands on demand.

                    • Create a hierarchy of the access controlled commands to minimise the risk of a security/access holes. So all the controlled commands must inherit from an access controlled command.

                    See this answer for a more elaborate explanation : https://softwareengineering.stackexchange.com/a/345714/241947






                    share|improve this answer











                    $endgroup$












                    • $begingroup$
                      "Use the Class.forName(className).newInstance() idiom to make the commands" Could you iterate on that?
                      $endgroup$
                      – Bobby
                      Jun 10 at 17:52










                    • $begingroup$
                      @Bobby It is factory method that constructs a new instance of a class using a variable name rather than a hard coded class name. The className value needs to be fully qualified with the package but is really simple to use and extremely powerful factory method. I've added a link to the JavaDoc.
                      $endgroup$
                      – Martin Spamer
                      Jun 13 at 17:35






                    • 1




                      $begingroup$
                      Oh, className is not a placeholder but an actual variable, then I get what you mean.
                      $endgroup$
                      – Bobby
                      Jun 13 at 19:11













                    1












                    1








                    1





                    $begingroup$

                    You've received some good comments on the detailed coding, so I'll focus on the design.



                    • Follow the single responsibility principle in your controller, it should do one thing, dispatch the commands it receives.

                    • The SRP will make it unnecessary to change the controller to add new commands. Replace your switch with a command mapping, see the Command Pattern. A good approach to this is to load the commands from a property file into a Hashmap; so Command=ClassName that maps the command-name to a class name.

                    • Use the Class.forName(className).newInstance() idiom to construct new instances of the commands on demand.

                    • Create a hierarchy of the access controlled commands to minimise the risk of a security/access holes. So all the controlled commands must inherit from an access controlled command.

                    See this answer for a more elaborate explanation : https://softwareengineering.stackexchange.com/a/345714/241947






                    share|improve this answer











                    $endgroup$



                    You've received some good comments on the detailed coding, so I'll focus on the design.



                    • Follow the single responsibility principle in your controller, it should do one thing, dispatch the commands it receives.

                    • The SRP will make it unnecessary to change the controller to add new commands. Replace your switch with a command mapping, see the Command Pattern. A good approach to this is to load the commands from a property file into a Hashmap; so Command=ClassName that maps the command-name to a class name.

                    • Use the Class.forName(className).newInstance() idiom to construct new instances of the commands on demand.

                    • Create a hierarchy of the access controlled commands to minimise the risk of a security/access holes. So all the controlled commands must inherit from an access controlled command.

                    See this answer for a more elaborate explanation : https://softwareengineering.stackexchange.com/a/345714/241947







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jun 13 at 17:19

























                    answered Jun 10 at 9:31









                    Martin SpamerMartin Spamer

                    3852 silver badges12 bronze badges




                    3852 silver badges12 bronze badges











                    • $begingroup$
                      "Use the Class.forName(className).newInstance() idiom to make the commands" Could you iterate on that?
                      $endgroup$
                      – Bobby
                      Jun 10 at 17:52










                    • $begingroup$
                      @Bobby It is factory method that constructs a new instance of a class using a variable name rather than a hard coded class name. The className value needs to be fully qualified with the package but is really simple to use and extremely powerful factory method. I've added a link to the JavaDoc.
                      $endgroup$
                      – Martin Spamer
                      Jun 13 at 17:35






                    • 1




                      $begingroup$
                      Oh, className is not a placeholder but an actual variable, then I get what you mean.
                      $endgroup$
                      – Bobby
                      Jun 13 at 19:11
















                    • $begingroup$
                      "Use the Class.forName(className).newInstance() idiom to make the commands" Could you iterate on that?
                      $endgroup$
                      – Bobby
                      Jun 10 at 17:52










                    • $begingroup$
                      @Bobby It is factory method that constructs a new instance of a class using a variable name rather than a hard coded class name. The className value needs to be fully qualified with the package but is really simple to use and extremely powerful factory method. I've added a link to the JavaDoc.
                      $endgroup$
                      – Martin Spamer
                      Jun 13 at 17:35






                    • 1




                      $begingroup$
                      Oh, className is not a placeholder but an actual variable, then I get what you mean.
                      $endgroup$
                      – Bobby
                      Jun 13 at 19:11















                    $begingroup$
                    "Use the Class.forName(className).newInstance() idiom to make the commands" Could you iterate on that?
                    $endgroup$
                    – Bobby
                    Jun 10 at 17:52




                    $begingroup$
                    "Use the Class.forName(className).newInstance() idiom to make the commands" Could you iterate on that?
                    $endgroup$
                    – Bobby
                    Jun 10 at 17:52












                    $begingroup$
                    @Bobby It is factory method that constructs a new instance of a class using a variable name rather than a hard coded class name. The className value needs to be fully qualified with the package but is really simple to use and extremely powerful factory method. I've added a link to the JavaDoc.
                    $endgroup$
                    – Martin Spamer
                    Jun 13 at 17:35




                    $begingroup$
                    @Bobby It is factory method that constructs a new instance of a class using a variable name rather than a hard coded class name. The className value needs to be fully qualified with the package but is really simple to use and extremely powerful factory method. I've added a link to the JavaDoc.
                    $endgroup$
                    – Martin Spamer
                    Jun 13 at 17:35




                    1




                    1




                    $begingroup$
                    Oh, className is not a placeholder but an actual variable, then I get what you mean.
                    $endgroup$
                    – Bobby
                    Jun 13 at 19:11




                    $begingroup$
                    Oh, className is not a placeholder but an actual variable, then I get what you mean.
                    $endgroup$
                    – Bobby
                    Jun 13 at 19:11

















                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f221929%2fjava-servlet-jsp-simple-login%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Wikipedia:Vital articles Мазмуну Biography - Өмүр баян Philosophy and psychology - Философия жана психология Religion - Дин Social sciences - Коомдук илимдер Language and literature - Тил жана адабият Science - Илим Technology - Технология Arts and recreation - Искусство жана эс алуу History and geography - Тарых жана география Навигация менюсу

                    Bruxelas-Capital Índice Historia | Composición | Situación lingüística | Clima | Cidades irmandadas | Notas | Véxase tamén | Menú de navegacióneO uso das linguas en Bruxelas e a situación do neerlandés"Rexión de Bruxelas Capital"o orixinalSitio da rexiónPáxina de Bruselas no sitio da Oficina de Promoción Turística de Valonia e BruxelasMapa Interactivo da Rexión de Bruxelas-CapitaleeWorldCat332144929079854441105155190212ID28008674080552-90000 0001 0666 3698n94104302ID540940339365017018237

                    What should I write in an apology letter, since I have decided not to join a company after accepting an offer letterShould I keep looking after accepting a job offer?What should I do when I've been verbally told I would get an offer letter, but still haven't gotten one after 4 weeks?Do I accept an offer from a company that I am not likely to join?New job hasn't confirmed starting date and I want to give current employer as much notice as possibleHow should I address my manager in my resignation letter?HR delayed background verification, now jobless as resignedNo email communication after accepting a formal written offer. How should I phrase the call?What should I do if after receiving a verbal offer letter I am informed that my written job offer is put on hold due to some internal issues?Should I inform the current employer that I am about to resign within 1-2 weeks since I have signed the offer letter and waiting for visa?What company will do, if I send their offer letter to another company