230 likes | 329 Views
Tips re: errors. Obviously, the best approach to reducing bugs is to code to a design and perform testing at incremental stages. However when you don’t know what the problem is then…
E N D
j.c.westlake@staffs.ac.uk Tips re: errors • Obviously, the best approach to reducing bugs is to code to a design and perform testing at incremental stages. • However when you don’t know what the problem is then… • Whenever you come across an error in your JSP application, you need a mental checklist to help you track down the problem.
j.c.westlake@staffs.ac.uk Files and Folders - locations • Your .htm, .jsp and database files should be placed in the following folder: • At University: \\fcet11.staffs.ac.uk\studentID\ • At Home: /tomcat/webapps/ROOT/myJSPfolder/
j.c.westlake@staffs.ac.uk HTML Checklist • At home ensure the server is installed correctly and has been started. • At Uni the server should be running automatically but you always test by running http://fcet11:8080/index.jsp • Are you using the correct URL? (should start with http://fcet11:8080 at uni or http://localhost:8080 at home) • Are your .htm or .html files appearing ok? • Do any of your HTML forms contain reserved Java keywords as names (e.g. not String, int etc.) • Do any of your HTML forms contain reserved SQL keywords (e.g. name, description, password etc.) http://www.xlinesoft.com/asprunnerpro/articles/sql_access_odbc_reserved_keywords.htm
j.c.westlake@staffs.ac.uk JSP Checklist • Remember that using GET you are restricted to (usually less than) 1024 chars. • You should use POST – but GET is good for debugging as you can see it in the url string in the browser – that is the recommendation for your early use of JSP • Use the error page – see later in module
j.c.westlake@staffs.ac.uk Database Problems • Remember we are using DSN-less connections – you can use a DSN at home if you wish to – available through the ODBC utility in control panel • Your connection object must have the following structure: • At University: Connection conn = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb,*.accdb)};DBQ=C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/studentid/databasefilename"); However it is best to use the provided helper DBConnection.JSP which has the line: String sMyDatabase = getServletContext().getRealPath(sDatapath); to work out the path dynamically.
j.c.westlake@staffs.ac.uk Database Problems • At Home: Connection conn = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb,*.accdb)};DBQ=C:/tomcat/webapps/ROOT/studentid/databasefilename;"); OR, you can use the IP address of your machine (127.0.1.2 in this example) Connection conn = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=//127.0.1.2/databasefilename;");
j.c.westlake@staffs.ac.uk Database Problems • Be very careful with your SQL statements! • Remember that you cannot put a record into a database that has the same primary key value as another record – you will get a nasty message • We can gracefully handle this eventually • You only put apostrophes around values that are string-based and your database field is expecting Text values. E.g. INSERT INTO MyTable (4157, ‘Consummated Ferrets’, ‘B157’); Note the first field in the table is numeric INSERT INTO MyTable (‘4157’, ‘Consummated Ferrets’, ‘B157’); // error!
j.c.westlake@staffs.ac.uk Database Problems • Be very careful with your SQL statements! • Date values have a pair of # around them, but avoid using DATE types. • If you have a problem with currency fields, use number, set it’s field size to Decimal and set the format to Currency, then set the number of decimal places and scale to 2 – see next slide
j.c.westlake@staffs.ac.uk Autosequence datatype • The autosequence column name does not need to be named in your insert sql statement when writing to a database. • We recommend you be careful if you use autosequence fields – they can be more trouble than they are worth • Can be nasty when get out of sequence • Your mileage may vary – some people do not experience many problems with autonumbering keyfields • For example, Nic Shulver always uses them, without issues
j.c.westlake@staffs.ac.uk Try…Catch • In Java (and JSP) we can use a try…catch block around any piece of code that may cause an exception. <% try { // Code which can throw can exception } catch(Exception e) // only catch it if the code fails above { // Exception handler code here } %>
j.c.westlake@staffs.ac.uk Exceptions • For very practical reasons, Java enforces the use of try…catch blocks around any piece of code that can cause an exception to be thrown. • By ‘thrown’, it is meant that the exception has occurred. • When an exception is thrown, one of several things can happen depending on what you want your web application to do at that point.
j.c.westlake@staffs.ac.uk Exception Handling • Do nothing… let your program fall over and read the error message that Java produces on the server. • You could handle the exception locally (i.e. in your code at the point where the exception occurred) within your catch block. • Or, you could redirect the user to an error page and do something there.
j.c.westlake@staffs.ac.uk Form.htm <html> <head></head> <body> <form action="FormHandler.jsp" method="post"> Enter your age ( in years ) : <input type="text" name="age" /> <input type="submit" value="Submit" /> </form> </body> </html>
j.c.westlake@staffs.ac.uk FormHandler.jsp <html> <head></head> <body> <% int age; age = Integer.parseInt(request.getParameter("age")); %> <p>Your age is : <%= age %> years.</p> <p><a href="Form.htm">Back</a>.</p> </body> </html>
j.c.westlake@staffs.ac.uk But…….. • This code works fine until a user enters something other than an integer via the form.
j.c.westlake@staffs.ac.uk Simple Fix - Local Try…Catch <% int age; try { age = Integer.parseInt(request.getParameter("age")); out.print("Your age is : " + age + "years. <br>"); } catch(NumberFormatException e) { out.print("You must enter a number! <br>"); } %>
j.c.westlake@staffs.ac.uk User-Defined Error Page <%@ page errorPage="ExceptionHandler.jsp" %> <html> <head></head> <body> <% int age; age = Integer.parseInt(request.getParameter("age")); %> <p>Your age is : <%=age %> years.</p> <p><a href="Form.html">Back</a>.</p> </body> </html>
j.c.westlake@staffs.ac.uk User-Defined Error Page <%@ page isErrorPage="true" import="java.io.*" %> <html><head></head> <body> <font color="red"><%= exception.toString() %><br></font> <% out.println("<!--"); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); exception.printStackTrace(pw); out.print(sw); sw.close(); pw.close(); out.println("-->"); %> </body> </html>
j.c.westlake@staffs.ac.uk Ok, Good, Better! • This works well but we can do better! • Currently, the error message that is displayed is a standard Java message. • These can be difficult to understand so instead we’ll pass our own message to our error page for it to display…
j.c.westlake@staffs.ac.uk Combined Version <% int age; try { age = Integer.parseInt(request.getParameter("age")); } catch (NumberFormatException e) { throw new JspException("Please enter a valid integer value!"); } %>
j.c.westlake@staffs.ac.uk Combined Version • This time we catch the NumberFormatException locally and throw a new JspException with our own exception message. • JspException is a JSP special exception class which extends java.lang.Exception. • We need to change the error page code to this: <font color="red"> <%= exception.getMessage() %> <br> </font>
j.c.westlake@staffs.ac.uk Recap • Error investigation does improve with experience • JSP errors at run time and can be a combination of <% or } problems • Validation to catch errors from say user input can be improved by the use of exception JSPs