views:

211

answers:

2

Since this not really answers my question, I'm gonna clarify.

3 .jsp pages, index.jsp, calculator.jsp and error.jsp.

index.jsp contains (withoug html and body tags):

<p><b>Enter the Number you want to know the square root of:</b></p>
<form action="calculator.jsp" method="post">
<div><input type="text" name="number_textfield" size="40" /> <input type="submit" value="Send" /></div>
</form>

error.jsp contains (without html body tags):

<%@page isErrorPage="true" import="java.io.*" %>
<%
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
exception.printStackTrace(pw);
String exceptionstack = sw.toString();
%>
<p>Path to File causing this error:
<span class="errortext"><%= request.getAttribute("javax.servlet.error.request_uri") %></span><br />
Error Message: <span class="errortext"><%= exception %></span><br />
The Error is: <span class="errortext"><%= exception.getMessage() %></span><br /></p>
<hr />
<p>Exception stack:</p>
<pre class="errortext"><%= exceptionstack %></pre>
<p><a href="../index.jsp">Index Page</a></p>

Now in calculator.jsp....

1) If I leave the textfield empty in index.jsp, I'm gettin displayed the error according to error.jsp.

2) If I enter a number smaller than 0, nothing happens. Now I've tried various methods from there. None of them works.

The calculator.jsp (without body and html tag):

<%@ page errorPage="../WEB-INF/sqrterror.jsp" %>

 <%
    String number_string = request.getParameter("number_textfield");
    double number = Double.parseDouble(number_string);
    if (number < 0){
     //THAT'S WHAT I'M MISSING HERE :(
 %>

 <%
    }

    else{
                 double sqrt = Math.sqrt(number);            
  %>
        <p>Square Root of <%= number %> is <%= sqrt %> .</p>
        <p><a href="../A03/sqrtcalculator.jsp">Back to Index Page</a></p>
  <%
    }
 %>
A: 

Just add

  throw new IllegalArgumentException("Number must be non-negative");
ZZ Coder
I only hope that he will see the error page anyway since the response is almost already committed with all of those scriptlets ..
BalusC
+4  A: 

You've one big problem here: if you throw an Exception halfway a JSP file, then the chance is big that it will never reach the error.jsp, simply because the response is already committed. The response headers are already set, the response writer is already obtained, the response content is already sent to the client (even if only partly), all only because of the fact that the JSP does that by nature as being a pure view technology. This is a point of no return. The enduser may end up with a blank page and you may end up with an IllegalStateException in the server logs.

If you are very, very lucky, everything is still in the buffer which is not flushed yet, then the webcontainer can still manage to reset it all and forward the request to error.jsp. But I wouldn't rely on that. Writing raw Java code in JSP files is considered bad practice.

Better use a Servlet class. I'll give you a kickoff example. Change your index.jsp as follows:

<h4>Enter the Number you want to know the square root of:</h4>
<form action="calculator" method="post">
    <input type="text" name="number" size="40" />
    <input type="submit" value="Send" />
    ${error}
</form>

The ${error} should display the error message, if any. The servlet can set it as a request attribute.

Change your result.jsp as follows:

<p>Square Root of ${param.number} is ${result}.</p>

The ${param.number} should display the "number" request parameter. The ${result} should display the result, if any. The servlet can set it as a request attribute.

Create a Servlet class CalculatorServlet:

public class CalculatorServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String number = request.getParameter("number");

        // Check if number is set and if it is valid, with little help of regex.
        // Those are valid: "12" and "12.34", but those not: "-1" or "" or null.
        if (number != null && number.matches("^\\d+(\\.\\d+)?$")) {
            request.setAttribute("result", Math.sqrt(Double.parseDouble(number)));
            request.getRequestDispatcher("result.jsp").forward(request, response);
        } else {
            request.setAttribute("error", "Please enter valid number.");
            request.getRequestDispatcher("index.jsp").forward(request, response);
        }

    }
}

Note that I don't throw exceptions, but just validate the values and set an user-friendly error message for the case that the input is wrong. You should expect that the user can enter wrong values. Never trust user input, always validate it in a proper manner. Your application should not look like to "drastically break" on wrong user input. Exceptions are only affordable if for example the backend DB is down and more of those kind of unrecoverable matters.

Now map this servlet in web.xml as follows (oh, ensure that you're using Servlet 2.4 or newer to get EL (Expression Language, the ${} things) to work in template text):

<servlet>
    <servlet-name>calculator</servlet-name>
    <servlet-class>com.example.CalculatorServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>calculator</servlet-name>
    <url-pattern>/calculator</url-pattern>
</servlet-mapping>

The url-pattern should cover the action url as you're going to use in the <form action>.

That should be it. Much nicer separation of business logic and the presentation logic. That's a good start of the MVC way.

BalusC
+1 Yes, very helpful, thank you, that is if I were interested in Servlets. I'm not. I want to stay with Scriptlets. Still very helpful examples, thanks again!
NoCanDo