scwcd : handling exceptions : chap : 5

44
1 Handling Exceptions Helmi ben abdallah @rchitect JEE

Upload: oxia

Post on 08-Feb-2017

145 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: SCWCD : Handling exceptions : CHAP : 5

1

Handling Exceptions

Helmi ben abdallah @rchitect JEE

Page 2: SCWCD : Handling exceptions : CHAP : 5

2

THE FOLLOWING SUN CERTIFIED WEB COMPONENT DEVELOPER FOR J2EE PLATFORM EXAM OBJECTIVES COVERED IN THIS CHAPTER:

4.1 For each of the following cases, identify correctly constructed code for handling business logic exceptions, and match that code with correct statements about the code’s behavior:

• Return an HTTP error using the sendError response method • Return an HTTP error using the setStatus method

4.2 Given a set of business logic exceptions, identify the following: • The configuration that the deployment descriptor uses to handle each exception • How to use a RequestDispatcher to forward the request to an error page • Specify the handling declaratively in the deployment descriptor

4.3 Identify the method used for the following: • Write a message to the WebApp log• Write a message and an exception to the WebApp log

Page 3: SCWCD : Handling exceptions : CHAP : 5

3

Page 4: SCWCD : Handling exceptions : CHAP : 5

4

• developers must take a proactive approach toward error handling when developing code. The code must anticipate potential problems, notify the client, log the issue, limit damage, and offer recovery alternatives. In this chapter, we will discuss the various ways to handle common application errors. They include:

• How to notify the client of errors or status changes• How to use and create error pages• How to log messages• How to define servlet exceptions

Page 5: SCWCD : Handling exceptions : CHAP : 5

5

Problem Notification

• When a problem occurs within a servlet, the developer must decide how the application should proceed.• Should it return an error and continue? • Orshould it return an error page and stop the execution of

the application? • If an error page is returned, who will develop it—the

server or the application?• How will the application locate a custom error page?

These are the questions a developer must answer and consider when writing efficient servlets.

Page 6: SCWCD : Handling exceptions : CHAP : 5

6

Page 7: SCWCD : Handling exceptions : CHAP : 5

7

Page 8: SCWCD : Handling exceptions : CHAP : 5

8

Page 9: SCWCD : Handling exceptions : CHAP : 5

9

sendError

The HttpServletResponse class provides a sendError(…) method that gives the developer an opportunity to set an error status code for the response header and enables the servlet to replace the response body with a server-specific page explaining the error. • The method signature is as follows:public void sendError(int sc)public void sendError(int sc, String msg)

Page 10: SCWCD : Handling exceptions : CHAP : 5

10

• Back to our example: instead of writing to the output stream when an error occurs, you can now set the sendError(…) status and message to the response object, as shown here:…

try {theFile=getFile(filePath);} catch(FileNotFoundException e) {res.sendError(res.SC_NOT_FOUND,“The name of the file that could not be found is: “+ filePath);}…

Page 11: SCWCD : Handling exceptions : CHAP : 5

11

Page 12: SCWCD : Handling exceptions : CHAP : 5

12

When using the sendError(…) method, three things should happen:• An error response is sent to the client by using the

specified status code.• The servlet’s response body is replaced with an HTML-

formatted server error page containing the specified message.• The content type is set to text/html , leaving cookies and

other headers unmodified.• A response is committed after it is sent to the client. When

the sendError(…) method is used, the response is considered committed and should no longer be written to. If the response is already committed and sendError(…)Is called, an IllegalStateException should be thrown.

Page 13: SCWCD : Handling exceptions : CHAP : 5

13

If a condition occurs that is not a problem, but just a status notification,you can use the setStatus(int statusCode) method to modify the response header. This topic is covered next.

setStatus

Page 14: SCWCD : Handling exceptions : CHAP : 5

14

setStatus

• The HttpServletResponse class provides a setStatus(…) method that gives the developer an opportunity to set the status code to notify the client of the when there is no error for the response header. The method signature is as follows:• public void setStatus(int statusCode)• This method sets the status by using a

specified number or constant SC_XXX value defined in the HttpServletResponse class. The coding preference, however, is to use the constant value rather than hard-coding a number.

Page 15: SCWCD : Handling exceptions : CHAP : 5

15

There is a fine difference between the setStatus(int statusCode) method and the sendError(int errorCode) method:• the setStatus(…) method does not generate an automatic

error response page, whereas sendError(…) does.• In fact, if you use setStatus(…) to define an error, then the

servlet is completely responsible for generating the response. The body can be text based, a generated image, or anything else appropriate. If an error page is not configured, a server-dependent Page Not Found message will appear.• Stylistically, setStatus(…) should be used for non-errors,

such as SC_OK or SC_MOVED_TEMPORARILY, whereas sendError(…) should be used for errors that are a part of the 400 and 500 series. A non-error is a flag that does not indicate a critical problem.

Page 16: SCWCD : Handling exceptions : CHAP : 5

16

• When setStatus(…) is called to define a non-error, the status code is set and the servlet code continues to process. • When setStatus(…) is called to define an error, the status

code is set and an error page is sought in response.• If one is not found, a server-dependent Page Not Found

message will appear.

Page 17: SCWCD : Handling exceptions : CHAP : 5

17

• A call to the setStatus(…) method does not commit the response, but it does cause the container to clear the response buffer (causing any previous response body information to be erased). As a result, this method should be called early in the development of a response. I• n addition to erasing the response body, the container will

also set the Location header but preserves cookies and other headers.• If the response is already committed, calls to

setStatus(…) are ignored.

The setStatus(…) method is also useful when you have a servlet that takes a long time to process. If written correctly, the servlet can be designed to provide the client with intermittent updates on the state of the activity. If, for example, a reload is required, a message notifying the client could be sent.

Page 18: SCWCD : Handling exceptions : CHAP : 5

18

Error Pages

• Until now, we have relied on default error pages or raw text sent to the output stream Writer as means of conveying problems to the client.• There are a few more error page options worth iscussing.

There are three types of error pages:1. Server-generated pages2. Static custom pages3. Dynamic custom pages• The default behavior of setStatus(…) and sendError(…)

generates an error page formatted by the server.

Page 19: SCWCD : Handling exceptions : CHAP : 5

19

Static Error Page• A static error page is usually an HTML-formatted page that contains a

response to the occurring problem. Its information explains the problem, but does not change. A status code is associated to the page through the deployment descriptor.

• For example, imagine that you created an error page called 404.html. It could be as simple as the following:

<HTML><BODY>This is my error page for code: 404</BODY></HTML>

Page 20: SCWCD : Handling exceptions : CHAP : 5

20

By using the error-page tag, you could cause the status code value of 404 to display your page 404.html.<web-app><error-page><error-code> 404</error-code><location> /errors/404.html </location></error-page></web-app>• The error-code tag defines the status code for the problem.

The location tag defines the error file and its path. The value for the location tag must begin with a forward slash (/) and it must refer to a resource within the context. The following image shows the custom error-page output.

Page 21: SCWCD : Handling exceptions : CHAP : 5

21

• It is important to know that entries in the web.xml file will override the default server configuration error pages.• If either sendError(404) or setStatus(404) is called, the

file 404.html located in the errors directory of the context directory will appear. • The benefit of static error pages is that they provide

standardized error responses for the entire application.

Page 22: SCWCD : Handling exceptions : CHAP : 5

22

Dynamic Error Page

For a more flexible page response, you can create a dynamic error page.

Dynamic pages enable the message, the page, or the data to change depending on the set error code. Instead of using HTML pages, a servlet could be written to handle errors. The server provides two servlet attributes to help accomplish this task:

javax.servlet.error.status_code returns an Integer object defining the error status code.

javax.servlet.error.message returns a String message, usually defined by the second argument passed to the sendError(…) method.

Page 23: SCWCD : Handling exceptions : CHAP : 5

23

Instinctively, you might have thought to reference the ErrorServlet by using the following path: /contextDir/WEB-INF/classes/ErrorServlet. This, however,will not work because of permissions. Remember, you cannot directly reference files within the /WEB-INF directory. For Tomcat, servlet classes can be accessed from the /servlet directory.

Page 24: SCWCD : Handling exceptions : CHAP : 5

24

Page 25: SCWCD : Handling exceptions : CHAP : 5

25

• The current servlet would need to create the message by extracting the file name using req.getParameter(“inventoryList”) and then using the ServletContext’s getResourceAsStream(String path) method to read the path/filename value assigned to the parameter. If the servlet invokes the following method:• res.setError(res.SC_NOT_FOUND, msg); • the output will result in a servlet-generated page.

Page 26: SCWCD : Handling exceptions : CHAP : 5

26

Passing the Error

• A dynamic page uses the web.xml file to locate an error servlet associated to a defined error-code.• If, however, your servlet would like to pass an error to a

specific servlet to handle, given a situation rather than an error code type, you would need to use a RequestDispatcher. We will discuss this technique next.

Page 27: SCWCD : Handling exceptions : CHAP : 5

27

Passing the Error

• A servlet can handle its own errors or it can pass off the responsibility to another servlet to handle. The RequestDispatcher can be used to forward a request to an error page:

try {theFile=getFile(filePath);} catch(FileNotFoundException e) {String display = “/servlet/ErrorServlet”;RequestDispatcher dispatcher =req.getRequestDispatcher(display);dispatcher.forward(req, res); }

Page 28: SCWCD : Handling exceptions : CHAP : 5

28

• When a call to sendError(…) is made, the system sets the values for the variables:• javax.servlet.error.status_code• javax.servlet.error.message

Page 29: SCWCD : Handling exceptions : CHAP : 5

29

• After the code is changed to define the error attribute values, the output will display the expected information, as shown after the following code snippet.

try {theFile=getFile(filePath);} catch(FileNotFoundException e) {req.setAttribute("javax.servlet.error.status_code" ,new Integer(405));req.setAttribute("javax.servlet.error.message","Custom message: The file was not found");String display = "/servlet/ErrorServlet";RequestDispatcher dispatcher = req.getRequestDispatcher(display);dispatcher.forward(req, res); }

Page 30: SCWCD : Handling exceptions : CHAP : 5

30

Logging Messages

• In summary, errors can be passed off to other servlets by use of the RequestDispatcher. Because the web.xml file is not used by the processing servlet, the error attributes must be set prior to forwarding the request. • Next we will address how to track these errors by logging

messages.

Page 31: SCWCD : Handling exceptions : CHAP : 5

31

• The GenericServlet class offers two methods that enable the servlet to write its errors to a log file for further inspection:• public void log(String msg) writes an error message to the

servlet log file.• public void log(String msg, Throwable t) writes an error

message and Throwable object, which contains a stack trace of the exception, to the servlet log file.

Page 32: SCWCD : Handling exceptions : CHAP : 5

32

• Reporting a stack trace message to the client is a bit more difficult than simply executing a System.out.println(e.printStackTrace()) statement. • In fact, that statement won’t compile, because the

printStackTrace() method returns a void. To pass an error message to a client, the sendError(…) method must be called. But before it can be passed a message, you must• capture the trace and write it to a PrintStream or PrintWriter. The

Throwable class provides methods that extract the trace; they include:• void printStackTrace() prints a Throwable object to a

standard output stream.• void printStackTrace(PrintStream p) prints a Throwable

object to a specified print stream.• void printStackTrace(PrintWriter p) prints a Throwable

object to a specified print writer.

Page 33: SCWCD : Handling exceptions : CHAP : 5

33

Servlet Exceptions

• When a method throws an exception, the developer has two choices:• the servlet can either catch the exception or throw it to the

server to handle.• When a server catches an exception, it has complete freedom

to handle the problem in the way it deems appropriate. It could automatically log the exception,it could pass the client a message, it could call destroy() on the servlet and reload it, or it could do something else completely different.• The server cannot be expected to catch all exceptions.

Specifically, the specification states that those exceptions handled by the server must subclass IOException, ServletException, or RuntimeException.

Page 34: SCWCD : Handling exceptions : CHAP : 5

34

ServletException• A javax.servlet.ServletException is thrown by a servlet to indicate a

general servlet problem has occurred. The ServletException class subclasses the Exception class and has four constructors:• ServletException() is the default constructor that creates a

basic servlet exception used to provide a more descriptive name of the problem.• ServletException(String message) constructs a servlet

exception with the specified message.• ServletException(Throwable rootCause) constructs a servlet

exception with a Throwable object containing a stack trace of the root problem.• ServletException(String message, Throwable rootCause)

constructs a servlet exception with a specified message and a Throwable object containing a stack trace of the root problem.

Page 35: SCWCD : Handling exceptions : CHAP : 5

35

• When an exception occurs, the developer might want to catch the exception and throw it back to the calling thread with a different name. For example:

try {is.read();} catch (IOException e) {throw new ServletException(e);}• The ServletException acts as a wrapper to provide a more relevant

exception name to the caller. Now, after the ServletException is caught, the getRootCause() method can be called to return the Throwable object.

• This method returns the Throwable object that contains a trace identifying the original problem and source. If the exception was created without a Throwable object, null is returned.

Page 36: SCWCD : Handling exceptions : CHAP : 5

36

UnavailableException• The javax.servlet.UnavailableException is a subclass of the

Servlet Exception class. An UnavailableException is thrown to indicate a servlet is either temporarily or permanently unavailable:• Permanently unavailable The servlet throwing the

exception cannot recover from the error until some action is taken. Usually, the servlet is corrupt in some way or not configured properly. Generally, the servlet should log both the error and the actions needed to correct the problem.• Temporarily unavailable A servlet cannot handle the

request for a period of time due to some system-wide problem. For example, there might not be sufficient memory or disk storage to handle requests, or a third-tier server might not be accessible. Some of these problems are self-correcting, and others might require a system administrator to take corrective action.

Page 37: SCWCD : Handling exceptions : CHAP : 5

37

• A servlet that throws an UnavailableException that is permanent is removed from service, and a new servlet instance is created to handle further requests.• If a new instance cannot be created, an error will be sent to the

client.• When a servlet is unavailable, the server will return a response

containing an SC_SERVICE_UNAVAILABLE(503) status code to notify the client of the situation. The response will also include a Retry-After header with an estimated time of unavailability.• If either a temporary or permanent UnavailableException is

thrown during the init(…) method, the service(…) method will never be reached.• Instead, the server will try to initialize a new instance either

immediately or after the defined period of time

Page 38: SCWCD : Handling exceptions : CHAP : 5

38

The UnavailableException class has two constructors:• UnavailableException(String msg) constructs an exception

with a descriptive message indicating the servlet is permanently unavailable.

• UnavailableException(String msg, int seconds) constructs an exception with a descriptive message indicating the servlet is temporarily unavailable for an estimated amount of time.

Page 39: SCWCD : Handling exceptions : CHAP : 5

39

• When the exception is temporary and an estimated time cannot be provided,the specification encourages developers to provide a negative value for the second argument. Do keep in mind that the time is only an estimate.• After the exception is thrown, the component catching the

exception can use the following methods to learn more about the problem:• int getUnavailableSeconds() returns the number of

seconds the servlet expects to be temporarily unavailable.

• boolean isPermanent() returns a boolean indicating whether the servlet is permanently unavailable.

Page 40: SCWCD : Handling exceptions : CHAP : 5

40

Exception Pages• This sample code from the DTD shows how a static or

servlet page can be used when a specific exception is thrown:

…<error-page><exception-type>javax.servlet.UnavailableException</exception-type><location>/servlet/DynamicErrorDisplay</location></error-page>

When the UnavailableException is thrown, the server will locate the DynamicErrorServlet and display its contents to the client.

The exception-type must include the fully qualifying package name. Otherwise,the exception will be handled in its default manner.

Page 41: SCWCD : Handling exceptions : CHAP : 5

41

• By using error attributes, you can construct a dynamic servlet to handle various exception types.• Although the system might provide default values for

some of these attributes, the developer can also set their definitions at some point within the application and share them with other servlets depending on the definition scope.

Page 42: SCWCD : Handling exceptions : CHAP : 5

42

Page 43: SCWCD : Handling exceptions : CHAP : 5

43

Page 44: SCWCD : Handling exceptions : CHAP : 5

44