views:

590

answers:

3

Is it possible to have the same servlet perform validation? It seems that one might have to utilize some sort of recursion here, but when I type in something in the e-mail box and click submit the e-mail parameter is still blank. After I click submit, the URL changes to: http://localhost/servlet/EmailServlet?Email=test

The page shows Email: null and the text box, but I was expecting it to go through the validation function (i.e. not be null). Is it possible to achieve this type of recursive behavior?

public class EmailServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, 
            HttpServletResponse response) throws ServletException, IOException 
    {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        String theForm =
            "<FORM METHOD=\"GET\" ACTION=\"EmailServlet\">\n<INPUT TYPE=\"TEXT\" NAME=\"Email\"><P>\n" 
            + "<INPUT TYPE=\"SUBMIT\">\n</FORM>";
        String email = (String) request.<strike>getAttribute("Email");</strike>getParameter("Email");

        // Bogus email validation...
        if( email == null )
        {
            out.println("Email: " + email + "\n" + theForm);
        }
        else if(emailAddressNotBogous(email))
        {
            out.println("Thank you!");
        }
        else
        {
            out.println("“Invalid input. Please try again:\n" + theForm);
        }
        out.flush();        
    }
}

Update: as the accepted answer pointed out, there was an error in the code. Changing the getAttribute to getParameter fixes the "problem" :).

String email = (String) request.getAttributegetParameter("Email");

+1  A: 

you could have the form's method set to POST and then implement a doPost() method in your servlet. the doGet() will get called to display the form and the doPost() will get called to process the form submission.

alternatively you could have the doGet() method test for the presence of any parameters. if there aren't any then just display the form. if there are then process the submission...

emh
Is it possible to do it without changing the method to POST?
Lirik
+1  A: 

To get a form parameter in a servlet you use:

  request.getParameter("Email");

And yes you can use the same servlet but it would be way easier to use two different servlets to do this.

Vincent Ramdhanie
@Vincent DOH! I can't believe I did that... thanks for pointing out my error, everything works fine now.
Lirik
+2  A: 

Although the answer is already given, request parameters are to obtained by the obvious HttpServletRequest#getParameter() method, I would only comment on your way of using servlets which was a bit astonishing.

I strongly suggest you to use JSP for template text (HTML/CSS/JS), not a servlet. That's the normal practice. You also normally use doGet() to preprocess a request for display and doPost() to postprocess a request after form submit, but as you insist in using GET for this, it's okay then.

Change your servlet to something like this:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String email = request.getParameter("email");
    Map<String, String> messages = new HashMap<String, String>();

    if (email != null) {
        // Email is specified as request parameter, do the business logic here.
        if (email.trim().isEmpty()) {
            messages.put("error", "Please enter email");
        } else if (!email.matches("([^.@]+)(\\.[^.@]+)*@([^.@]+\\.)+([^.@]+)")) {
            messages.put("error", "Invalid email, please try again.");
        } else {
            // Do something with email here?
            messages.put("success", "Thank you!");
        }
    }

    // Put messages in request scope so that it's accessible in EL by ${messages}.        
    request.setAttribute("messages", messages);

    // Forward request to JSP for display.
    request.getRequestDispatcher("/WEB-INF/email.jsp").forward(request, response);
}

Map this servlet in web.xml on an url-pattern of /email so that you can access it by http://example.com/context/email. The JSP is placed in /WEB-INF/email.jsp so that users cannot access it directly without using the servlet.

Then, in the JSP just have something like:

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 2292260</title>
        <style>
            .error { color: red; }
            .success { color: green; }
        </style>
    </head>
    <body>
        <form>
            <label for="email">Email</label>
            <input id="email" name="email" value="${param.email}">
            <span class="error">${messages.error}</span>
            <br>
            <input type="submit">
            <span class="success">${messages.success}</span>
        </form>
    </body>
</html>

You see that the form action is omitted, this will let submit the form "recursively" to self as you asked in your question. If you have specified method="post" here, the doPost() would be called instead (which is a better practice). The ${param.email} will redisplay the submitted value by doing request.getParameter("email") under the hoods (not sure if you want this, but OK it's good to know). The ${messages.error} will show any associated error message by roughly doing pageContext.findAttribute("messages").get("error") under the hoods.

Much more clear and concise, isn't it? No template text clutter in servlet code anymore and using the EL powers in JSP to access "backend data". It's a good separation of view and controller. This must get you started in the right direction :) Good luck.

BalusC
@BalusC, you know my homewokrs are crazy :)! This problem is straight out of my assignment... my teacher requested that we perform the validation in the doPost() and a form with a GET method right inside the servlet. Of course your solution is amazing (as always), but in school they want to teach us things that are obscure, irrational and impractical. LOL +1 for always giving me answers that make sense in the REAL WORLD! :)
Lirik
Oh, it's homework. In future questions, please tag `homework` as well :) Then I'll take this into account and try to push the real work a bit less hard through your throat ;) You're welcome though.
BalusC
@BalusC Clearly I'm dyslexic too: "homewokrs" LOL... BTW, I added the 'homework' tag. Thanks again.
Lirik