Your Web application will have errors, all software products do. No one can claim that they have developed a bug-free code. Well, if they do, they need to be frozen and displayed in the museum of extinct species. Jokes apart, any systems strength depends on how gracefully it can handle exceptions.
In this chapter, we are going to see how the deployment descriptor can be used to handle exceptions.
So, lets get started!!!
Web Application Exceptions
The servlet specification addresses the need to handle errors. The following snippet shows you how to use the error-page element, which defines which resource the container should use for a given exception.
< web-app >
< error-page >
< error-code > 404 < / error-code >
< location > /404.html < / location >
< / error-page >
< / web-app >
With this definition, the client will get the 404.html page if it requests a page that the container cannot find.
You can accomplish the same thing a little more dynamically with the RequestDispatcher. You can forward a request to an error page easily like so:
ServletContext context = getServletContext();
dispatcher = context.getRequestDispatcher("/errors/error.jsp");
dispatcher.forward(request,response);
Although this is more dynamic, it ignores all kinds of rules for good practice. It would be better to use the error-page element most of the time but forward to an error page with the RequestDispatcher on occasion.
You can also specify the exception handling declaratively in the deployment descriptor. You do this with the error-page element and the exception-type subelement like so:
< web-app >
< error-page >
< exception-type > javax.servlet.ServletException < / exception-type >
< location > /servlet/ErrorDisplay < / location >
< / error-page >
< / web-app >
This is a good practice as it makes the intention explicit for your Web application as opposed to relying on defaults.
Previous Chapter: Chapter 48 - Elements of the Deployment Descriptor
Next Chapter: Chapter 50 - Web Application Security
Topics Covered in the Blog - Synopsis
Showing posts with label servlet exception handling. Show all posts
Showing posts with label servlet exception handling. Show all posts
Friday, April 29, 2011
Monday, April 4, 2011
Quick Recap: Chapters 25 to 29
Let us now quickly recap what we learnt in the previous few chapters on Servlet Exception Handling…
Introduction to Servlet Exception Handling:
• Exception Handling is a powerful feature of the J2EE Technology and we can use it to handle unexpected behavior in our code
• There are categories of error codes that give us a fair idea of what went wrong. For ex: error codes 5XX signifies that something was wrong on the server side
The sendError Method:
• You can use the sendError method of the HttpResponse to send error messages to the browser
• It takes two parameters – the error code and a error message
• You can override the default behavior of the method and have custom code to handle exceptional cases
• The sendError method will set the appropriate headers and content body for an error message to return to the client.
• Using this method will commit the response (if not already committed) and terminate it. The data stacked in the output stream to the client before calling sendError() method is ignored
The setStatus Method:
• The setStatus method sets the status code for a given response
• Use this method, instead of sendError, when there is no exception or serious error
• If there is a serious error, the sendError method should be used; otherwise use setStatus.
The WebApp Log:
• Log files get written with the sequence of events handled by the Servlet
• You can write custom content into the log file in order to help us handle exceptional situations better
Key Terms we learnt in this section are:
• exception
• sendError()
• setStatus()
• Logging
• Status codes
• Error codes
Previous Chapter: Chapter 29 - WebApp Log
Next Chapter: Self Test - Chapters 25 to 29
Introduction to Servlet Exception Handling:
• Exception Handling is a powerful feature of the J2EE Technology and we can use it to handle unexpected behavior in our code
• There are categories of error codes that give us a fair idea of what went wrong. For ex: error codes 5XX signifies that something was wrong on the server side
The sendError Method:
• You can use the sendError method of the HttpResponse to send error messages to the browser
• It takes two parameters – the error code and a error message
• You can override the default behavior of the method and have custom code to handle exceptional cases
• The sendError method will set the appropriate headers and content body for an error message to return to the client.
• Using this method will commit the response (if not already committed) and terminate it. The data stacked in the output stream to the client before calling sendError() method is ignored
The setStatus Method:
• The setStatus method sets the status code for a given response
• Use this method, instead of sendError, when there is no exception or serious error
• If there is a serious error, the sendError method should be used; otherwise use setStatus.
The WebApp Log:
• Log files get written with the sequence of events handled by the Servlet
• You can write custom content into the log file in order to help us handle exceptional situations better
Key Terms we learnt in this section are:
• exception
• sendError()
• setStatus()
• Logging
• Status codes
• Error codes
Previous Chapter: Chapter 29 - WebApp Log
Next Chapter: Self Test - Chapters 25 to 29
Chapter 29: WebApp Log
One of the most important requirements for any error handling mechanism is the presence of a Log File. The log file is used to capture all the events that happen in the application and it helps the developer debug his application in case anything doesn't work as expected. In this chapter, we are going to take a look at the WebApp Log and see how it is useful in the debugging part of Exception Handling.
So, lets get started!!!
The WebApp Log:
The Server Configuration File defines the component elements that comprise the “Server,” a singleton element that represents the entire JVM. Two of these elements are the Access log and the Activity log. These are simple text files to which the container appends messages. While containers differ, Tomcat implements the specification very closely, except for just a few things. Since Tomcat is our server of choice for this series on SCWCD Certification, lets now take a look at how Tomcat uses logs.
By default, log files are created in the “logs” directory relative to the home directory of Tomcat installation ($CATALINA_HOME). You can specify a different directory, using either a relative (to $CATALINA_HOME) or absolute path, with the “directory” attribute in the server.xml file. Different containers handle this in various ways, but Tomcat creates two new files, access and activity, every time you start the server.
Tomcat implements several log files. One of them is the Global log file (for example, catalina_log.2011-04-04.txt). Its contents look like this after starting, stopping, and starting again:
2011-04-04 13:52:29 HttpConnector Opening server socket ...
2011-04-04 13:52:34 HttpConnector[8080] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][0] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][1] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][2] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][3] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][4] Starting ...
2011-04-04 14:33:36 HttpProcessor[8080][4] Stopping ...
2011-04-04 14:33:36 HttpProcessor[8080][3] Stopping ...
2011-04-04 14:33:36 HttpProcessor[8080][2] Stopping ...
2011-04-04 14:33:36 HttpProcessor[8080][1] Stopping ...
2011-04-04 14:33:36 HttpProcessor[8080][0] Stopping ...
2011-04-04 14:33:36 HttpConnector[8080] Stopping ...
2011-04-04 14:34:52 HttpConnector Opening server ...
2011-04-04 14:34:55 HttpConnector[8080] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][0] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][1] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][2] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][3] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][4] Starting ...
When something breaks, this log is somewhat helpful in that you can see what thread is broken. A more helpful log is Tomcat's access log (such as localhost_access_log.2011-04-04.txt), which appends the following line after I request the previous servlet above with
http://localhost:8080/examples/servlet/ErrorServlet:
127.0.0.1 - - [25/Dec/2011:14:23:53 -0800]
"GET /examples/servlet/ErrorServlet HTTP/1.1" 200 75
The log which is most interesting to us is the file localhost_examples_log.2011-04-04.txt. This is the one that is written to when you use the logging functionality in the servlet environment.
Writing Stuff into the Log File:
Now that we know what the log files are and the types of log files that get created, let us take a look at a sample program that is going to write out stuff into the log file.
Code:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.util.Enumeration;
import java.sql.Timestamp;
import java.io.PrintWriter;
import java.io.IOException;
public class LoggingServlet extends HttpServlet
{
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("< html >");
out.println("< head > < title >Servlet Exception Handling " +
"Example < / title > < / head >");
out.println("< body >");
String logMessage = getSbuf(request);
out.println(" We are Logging this request.");
ServletContext context = getServletContext();
context.log(logMessage);
out.println(logMessage);
out.println(" < / body > ");
out.println("< / html >");
}
public String getSbuf(HttpServletRequest request)
throws ServletException
{
// get generic servlet request properties
StringBuffer sbuf = new StringBuffer();
sbuf.append("Activity occurred at " + (new Timestamp(System.currentTimeMillis())) + '\n');
sbuf.append(" characterEncoding=" + request.getCharacterEncoding() + '\n');
sbuf.append(" contentLength=" + request.getContentLength() + '\n');
sbuf.append(" contentType=" + request.getContentType() + '\n');
sbuf.append("locale=" +request.getLocale() + '\n');
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
sbuf.append(" parameter=" + name + "=");
String values[] = request.getParameterValues(name);
for (int i = 0; i < values.length; i++) { if (i > 0)
sbuf.append(", ");
sbuf.append(values[i]);
}
sbuf.append('\n');
}
sbuf.append(" protocol=" + request.getProtocol() + '\n');
sbuf.append(" remoteAddr=" + request.getRemoteAddr() + '\n');
sbuf.append(" remoteHost=" + request.getRemoteHost() + '\n');
sbuf.append(" scheme=" + request.getScheme() + '\n');
sbuf.append(" serverName=" + request.getServerName() + '\n');
sbuf.append(" serverPort=" + request.getServerPort() + '\n');
sbuf.append(" isSecure=" + request.isSecure() + '\n');
// Render the HTTP servlet request properties
if (request instanceof HttpServletRequest) {
sbuf.append("********************************");
HttpServletRequest reqObj = (HttpServletRequest) request;
sbuf.append(" contextPath=" + reqObj.getContextPath() + '\n');
Cookie cookies[] = reqObj.getCookies();
if (cookies == null)
cookies = new Cookie[0];
for (int i = 0; i < cookies.length; i++) {
sbuf.append(" cookie=" + cookies[i].getName() + "=" + cookies[i].getValue());
}
names = reqObj.getHeaderNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
String value = reqObj.getHeader(name);
sbuf.append(" header=" + name + "=" + value + '\n');
}
sbuf.append(" method=" + reqObj.getMethod() + '\n');
sbuf.append(" pathInfo=" + reqObj.getPathInfo() + '\n');
sbuf.append(" queryString=" + reqObj.getQueryString() + '\n');
sbuf.append(" remoteUser=" + reqObj.getRemoteUser() + '\n');
sbuf.append("requestedSessionId=" + reqObj.getRequestedSessionId());
sbuf.append(" requestURI=" + reqObj.getRequestURI() + '\n');
sbuf.append(" servletPath=" + reqObj.getServletPath() + '\n');
}
sbuf.append("*****************************" +'\n');
// return the information
return sbuf.toString();
}
}
The above code is just a wrapper on the Logger. It creates a string buffer of the request parameters and then prints them all into the log file using the ServletContext.log(String) method. You may not actually need all of this information but it's a good place to start. It is just an example to tell you how to write contents into the log. You can alter it in anyway to print out stuff into your log file for debugging your application effectively.
Contents of the Log File:
If you execute the above sample servlet, your log file will be loaded with a lot of information that may not make much sense from the debugging point of view. But, nonetheless, lets take a look at what got written into our log file localhost_examples_log.2011-012-04.txt:
2011-04-04 16:09:15 Activity occurred at 2011-04-04 16:09:15
characterEncoding=null
contentLength=-1
contentType=null
locale=en_US
protocol=HTTP/1.1
remoteAddr=127.0.0.1
remoteHost=127.0.0.1
scheme=http
serverName=localhost
serverPort=8080
isSecure=false
contextPath=/examples
header=accept=*/*
header=accept-language=en-us
header=accept-encoding=gzip, deflate
header=user-agent=Mozilla/4.0 (compatible;
MSIE 5.01; Windows 7)
header=host=localhost:8080
header=connection=Keep-Alive
method=GET
pathInfo=null
queryString=null
remoteUser=null
requestedSessionId=null
requestURI=/examples/servlet/LoggingServlet
servletPath=/servlet/LoggingServlet
*********************************************
2011-04-04 16:09:15 InvokerFilter(ApplicationFilterConfig
[name=Path Mapped Filter,
filterClass=filters.ExampleFilter]): 10 milliseconds
The contents of the log file were altered a bit to fit to the blogger page but this is almost everything you will see in your log file. I repeat, what you see in your log file might be slightly different than what you see above.
There is one more wrinkle to the log feature that you need to know for the exam. You can pass an exception object to the log method. If you add the following code to the preceding LoggingServlet code:
try
{
int zero = 0;
int problem = 10/zero;
} catch (Exception e)
{
log("Oops, You cannot divide by zero.", e);
throw new ServletException(e);
}
The logger will add the following to the log file (localhost_examples_log.2011-012-04.txt):
2011-04-04 22:00:09 org.apache.catalina.INVOKER.LoggingServlet:
Oops, You cannot divide by zero.
java.lang.ArithmeticException: / by zero
at LoggingServlet.service(LoggingServlet.java:38)
at javax.servlet.http.HttpServlet.service(...)
//33 more lines of error messages removed for space
at java.lang.Thread.run(Thread.java:536)
Previous Chapter: Chapter 28 - The setStatus Method
Next Chapter: Quick Recap - Chapters 25 to 29
So, lets get started!!!
The WebApp Log:
The Server Configuration File defines the component elements that comprise the “Server,” a singleton element that represents the entire JVM. Two of these elements are the Access log and the Activity log. These are simple text files to which the container appends messages. While containers differ, Tomcat implements the specification very closely, except for just a few things. Since Tomcat is our server of choice for this series on SCWCD Certification, lets now take a look at how Tomcat uses logs.
By default, log files are created in the “logs” directory relative to the home directory of Tomcat installation ($CATALINA_HOME). You can specify a different directory, using either a relative (to $CATALINA_HOME) or absolute path, with the “directory” attribute in the server.xml file. Different containers handle this in various ways, but Tomcat creates two new files, access and activity, every time you start the server.
Tomcat implements several log files. One of them is the Global log file (for example, catalina_log.2011-04-04.txt). Its contents look like this after starting, stopping, and starting again:
2011-04-04 13:52:29 HttpConnector Opening server socket ...
2011-04-04 13:52:34 HttpConnector[8080] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][0] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][1] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][2] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][3] Starting ...
2011-04-04 13:52:34 HttpProcessor[8080][4] Starting ...
2011-04-04 14:33:36 HttpProcessor[8080][4] Stopping ...
2011-04-04 14:33:36 HttpProcessor[8080][3] Stopping ...
2011-04-04 14:33:36 HttpProcessor[8080][2] Stopping ...
2011-04-04 14:33:36 HttpProcessor[8080][1] Stopping ...
2011-04-04 14:33:36 HttpProcessor[8080][0] Stopping ...
2011-04-04 14:33:36 HttpConnector[8080] Stopping ...
2011-04-04 14:34:52 HttpConnector Opening server ...
2011-04-04 14:34:55 HttpConnector[8080] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][0] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][1] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][2] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][3] Starting ...
2011-04-04 14:34:56 HttpProcessor[8080][4] Starting ...
When something breaks, this log is somewhat helpful in that you can see what thread is broken. A more helpful log is Tomcat's access log (such as localhost_access_log.2011-04-04.txt), which appends the following line after I request the previous servlet above with
http://localhost:8080/examples/servlet/ErrorServlet:
127.0.0.1 - - [25/Dec/2011:14:23:53 -0800]
"GET /examples/servlet/ErrorServlet HTTP/1.1" 200 75
The log which is most interesting to us is the file localhost_examples_log.2011-04-04.txt. This is the one that is written to when you use the logging functionality in the servlet environment.
Writing Stuff into the Log File:
Now that we know what the log files are and the types of log files that get created, let us take a look at a sample program that is going to write out stuff into the log file.
Code:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.util.Enumeration;
import java.sql.Timestamp;
import java.io.PrintWriter;
import java.io.IOException;
public class LoggingServlet extends HttpServlet
{
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("< html >");
out.println("< head > < title >Servlet Exception Handling " +
"Example < / title > < / head >");
out.println("< body >");
String logMessage = getSbuf(request);
out.println(" We are Logging this request.");
ServletContext context = getServletContext();
context.log(logMessage);
out.println(logMessage);
out.println(" < / body > ");
out.println("< / html >");
}
public String getSbuf(HttpServletRequest request)
throws ServletException
{
// get generic servlet request properties
StringBuffer sbuf = new StringBuffer();
sbuf.append("Activity occurred at " + (new Timestamp(System.currentTimeMillis())) + '\n');
sbuf.append(" characterEncoding=" + request.getCharacterEncoding() + '\n');
sbuf.append(" contentLength=" + request.getContentLength() + '\n');
sbuf.append(" contentType=" + request.getContentType() + '\n');
sbuf.append("locale=" +request.getLocale() + '\n');
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
sbuf.append(" parameter=" + name + "=");
String values[] = request.getParameterValues(name);
for (int i = 0; i < values.length; i++) { if (i > 0)
sbuf.append(", ");
sbuf.append(values[i]);
}
sbuf.append('\n');
}
sbuf.append(" protocol=" + request.getProtocol() + '\n');
sbuf.append(" remoteAddr=" + request.getRemoteAddr() + '\n');
sbuf.append(" remoteHost=" + request.getRemoteHost() + '\n');
sbuf.append(" scheme=" + request.getScheme() + '\n');
sbuf.append(" serverName=" + request.getServerName() + '\n');
sbuf.append(" serverPort=" + request.getServerPort() + '\n');
sbuf.append(" isSecure=" + request.isSecure() + '\n');
// Render the HTTP servlet request properties
if (request instanceof HttpServletRequest) {
sbuf.append("********************************");
HttpServletRequest reqObj = (HttpServletRequest) request;
sbuf.append(" contextPath=" + reqObj.getContextPath() + '\n');
Cookie cookies[] = reqObj.getCookies();
if (cookies == null)
cookies = new Cookie[0];
for (int i = 0; i < cookies.length; i++) {
sbuf.append(" cookie=" + cookies[i].getName() + "=" + cookies[i].getValue());
}
names = reqObj.getHeaderNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
String value = reqObj.getHeader(name);
sbuf.append(" header=" + name + "=" + value + '\n');
}
sbuf.append(" method=" + reqObj.getMethod() + '\n');
sbuf.append(" pathInfo=" + reqObj.getPathInfo() + '\n');
sbuf.append(" queryString=" + reqObj.getQueryString() + '\n');
sbuf.append(" remoteUser=" + reqObj.getRemoteUser() + '\n');
sbuf.append("requestedSessionId=" + reqObj.getRequestedSessionId());
sbuf.append(" requestURI=" + reqObj.getRequestURI() + '\n');
sbuf.append(" servletPath=" + reqObj.getServletPath() + '\n');
}
sbuf.append("*****************************" +'\n');
// return the information
return sbuf.toString();
}
}
The above code is just a wrapper on the Logger. It creates a string buffer of the request parameters and then prints them all into the log file using the ServletContext.log(String) method. You may not actually need all of this information but it's a good place to start. It is just an example to tell you how to write contents into the log. You can alter it in anyway to print out stuff into your log file for debugging your application effectively.
Contents of the Log File:
If you execute the above sample servlet, your log file will be loaded with a lot of information that may not make much sense from the debugging point of view. But, nonetheless, lets take a look at what got written into our log file localhost_examples_log.2011-012-04.txt:
2011-04-04 16:09:15 Activity occurred at 2011-04-04 16:09:15
characterEncoding=null
contentLength=-1
contentType=null
locale=en_US
protocol=HTTP/1.1
remoteAddr=127.0.0.1
remoteHost=127.0.0.1
scheme=http
serverName=localhost
serverPort=8080
isSecure=false
contextPath=/examples
header=accept=*/*
header=accept-language=en-us
header=accept-encoding=gzip, deflate
header=user-agent=Mozilla/4.0 (compatible;
MSIE 5.01; Windows 7)
header=host=localhost:8080
header=connection=Keep-Alive
method=GET
pathInfo=null
queryString=null
remoteUser=null
requestedSessionId=null
requestURI=/examples/servlet/LoggingServlet
servletPath=/servlet/LoggingServlet
*********************************************
2011-04-04 16:09:15 InvokerFilter(ApplicationFilterConfig
[name=Path Mapped Filter,
filterClass=filters.ExampleFilter]): 10 milliseconds
The contents of the log file were altered a bit to fit to the blogger page but this is almost everything you will see in your log file. I repeat, what you see in your log file might be slightly different than what you see above.
There is one more wrinkle to the log feature that you need to know for the exam. You can pass an exception object to the log method. If you add the following code to the preceding LoggingServlet code:
try
{
int zero = 0;
int problem = 10/zero;
} catch (Exception e)
{
log("Oops, You cannot divide by zero.", e);
throw new ServletException(e);
}
The logger will add the following to the log file (localhost_examples_log.2011-012-04.txt):
2011-04-04 22:00:09 org.apache.catalina.INVOKER.LoggingServlet:
Oops, You cannot divide by zero.
java.lang.ArithmeticException: / by zero
at LoggingServlet.service(LoggingServlet.java:38)
at javax.servlet.http.HttpServlet.service(...)
//33 more lines of error messages removed for space
at java.lang.Thread.run(Thread.java:536)
Exam Trivia:
GenericServlet has log method! The abstract GenericServlet class has a log method, log(String), which writes the specified message to a servlet log file, prefixed by the servlet's name.
Previous Chapter: Chapter 28 - The setStatus Method
Next Chapter: Quick Recap - Chapters 25 to 29
Labels:
debugging,
exception handling in servlets,
log,
logging,
logging errors,
servlet exception handling,
webapp log
| Reactions: |
Tuesday, March 29, 2011
Chapter 28: The setStatus Method
In the previous chapter, we saw the sendError method. We saw how Tomcat implements it and we saw a wrapper method that used it but did some handling for custom error messages. Well, in this chapter, we are going to see the twin brother of the sendError method, the setStatus method.
So, lets get started…
The setStatus Method
The setStatus method sets the status code for a given response. Use this method, instead of sendError, when there is no exception or serious error (such as a blocked or a page inaccessible to the user). If there is a serious error, the sendError method should be used; otherwise use setStatus. Like the sendError method, using this method clears the buffer, but leaves cookies and other headers unmodified.
Let us now take a look at how Tomcat has implemented the setStatus method.
Code:
/**
* Set the HTTP status and message to be returned
* with this response.
*
* @param status The new HTTP status
* @param message The associated text message
*
* @deprecated As of Version 2.1 of the Java Servlet
* API, this method has been deprecated due to the
* ambiguous meaning of the message
* parameter.
*/
public void setStatus(int status, String message) {
if (included)
return; //Ignore any call from included servlet
this.status = status;
this.message = message;
}
As you can see in the code above, this method has been deprecated because the message functionality isn't reliable. The setStatus method will remain (the one taking only a status code), but without a message parameter in a future version, Maybe.
However, you can always write a wrapper to use the setStatus method effectively. (Just like we did for the sendError method)
Code:
/**
* statusManager Method.
*/
void checkCarStatus(HttpServletResponse response)
throws ServletException
{
if( !isValid(carName) )
{
response.setStatus(response.SC_BAD_REQUEST);
} else if( !isValid(carModel) )
{
response.setStatus(response.SC_BAD_REQUEST);
} else if( !isValid(carMakeYear) )
{
response.setStatus(response.SC_BAD_REQUEST);
} else if( !isValid(creditCardNumber) )
{
response.setStatus(response.SC_BAD_REQUEST);
} else
{
response.setStatus(response.SC_OK);
}
}
The code above is pretty straight forward. I suppose this can be used in a car repair garage. We first check if the cars name is valid and then check if the cars model is valid and then check its manufacture year. We also check the credit card number of the customer (because we need to get paid right) and if all these are valid, we set a OK response, else we set a bad request response. It's a simple implementation and you can alter it anyway you want, as long as it serves your purpose and uses the setStatus method, we are good…
The same status codes that are used for the sendError method can be used for the setStatus method, too. The primary difference is that the former prevents any further response to the client and throws an exception if you try. This is not so for the latter. There is one point of confusion with the setStatus method. The specification says the buffer is cleared when called. In other words, you should set this first before you send anything back to the client. However, I looked in Tomcat and did not observe the buffer being cleared. The following snippet:
out.println("pre setStatus message.");
response.setStatus(HttpServletResponse.SC_OK);
out.println("post setStatus message.");
produced this:
pre setStatus message.
post setStatus message.
Previous Chapter: Chapter 27 - sendError Method
Next Chapter: Chapter 29 - WebApp Log
So, lets get started…
The setStatus Method
The setStatus method sets the status code for a given response. Use this method, instead of sendError, when there is no exception or serious error (such as a blocked or a page inaccessible to the user). If there is a serious error, the sendError method should be used; otherwise use setStatus. Like the sendError method, using this method clears the buffer, but leaves cookies and other headers unmodified.
Let us now take a look at how Tomcat has implemented the setStatus method.
Code:
/**
* Set the HTTP status and message to be returned
* with this response.
*
* @param status The new HTTP status
* @param message The associated text message
*
* @deprecated As of Version 2.1 of the Java Servlet
* API, this method has been deprecated due to the
* ambiguous meaning of the message
* parameter.
*/
public void setStatus(int status, String message) {
if (included)
return; //Ignore any call from included servlet
this.status = status;
this.message = message;
}
As you can see in the code above, this method has been deprecated because the message functionality isn't reliable. The setStatus method will remain (the one taking only a status code), but without a message parameter in a future version, Maybe.
However, you can always write a wrapper to use the setStatus method effectively. (Just like we did for the sendError method)
Code:
/**
* statusManager Method.
*/
void checkCarStatus(HttpServletResponse response)
throws ServletException
{
if( !isValid(carName) )
{
response.setStatus(response.SC_BAD_REQUEST);
} else if( !isValid(carModel) )
{
response.setStatus(response.SC_BAD_REQUEST);
} else if( !isValid(carMakeYear) )
{
response.setStatus(response.SC_BAD_REQUEST);
} else if( !isValid(creditCardNumber) )
{
response.setStatus(response.SC_BAD_REQUEST);
} else
{
response.setStatus(response.SC_OK);
}
}
The code above is pretty straight forward. I suppose this can be used in a car repair garage. We first check if the cars name is valid and then check if the cars model is valid and then check its manufacture year. We also check the credit card number of the customer (because we need to get paid right) and if all these are valid, we set a OK response, else we set a bad request response. It's a simple implementation and you can alter it anyway you want, as long as it serves your purpose and uses the setStatus method, we are good…
The same status codes that are used for the sendError method can be used for the setStatus method, too. The primary difference is that the former prevents any further response to the client and throws an exception if you try. This is not so for the latter. There is one point of confusion with the setStatus method. The specification says the buffer is cleared when called. In other words, you should set this first before you send anything back to the client. However, I looked in Tomcat and did not observe the buffer being cleared. The following snippet:
out.println("pre setStatus message.");
response.setStatus(HttpServletResponse.SC_OK);
out.println("post setStatus message.");
produced this:
pre setStatus message.
post setStatus message.
Exam Trivia:
Containers don't always follow the specifications! As you can see, Tomcat does not clear the buffer as the specification says. The specification doesn't make sense as of this moment because, the way Tomcat implemented it is better. However, since other containers may follow the specification here and the exam will be based on the specification, assume that is how it actually works.
Previous Chapter: Chapter 27 - sendError Method
Next Chapter: Chapter 29 - WebApp Log
Chapter 27: The sendError Method
In the chapter on introduction to Servlet Exception Handling, we have used the term, use the sendError method and in the previous chapter, we saw an example that actually used this method. This chapter is dedicated solely for the purpose of explaining the features of this method and how to use it effectively.
So, lets get started!!!
The sendError Method
The sendError method sends an error response to the client using the specified status (Remember the bunch of status codes we saw in one of the previous chapters?). Using this method clears the buffer. The server creates an HTML-formatted server error page. This page contains a default, or the message you provide, as an argument. It also sets the content type to “text/html”, even if you changed this, but leaves cookies and other headers unmodified.
The sendError method will set the appropriate headers and content body for an error message to return to the client. An optional String argument can be provided to the sendError method, which can be used in the content body of the error. Using this method will commit the response (if not already committed) and terminate it. The data stacked in the output stream to the client before calling sendError() method is ignored.
Internally, the servlet base classes prevent you from writing to the output stream after calling sendError(). In the write-to-stream methods there is a test for a previous error in the servlet that looks like this:
//suspended is a flag set once output is committed
if (suspended)//true if sendError has been called
throw new IOException
(sm.getString("responseBase.write.suspended"));
That is why you can't add to the outputstream after calling sendError().
The best way to understand the sendError() method is to look at it directly. Lets take a look at some sample code that will help us do just that.
Code: This is the actual code implementation of how Tomcat implements the sendError method.
/**
* Send an error response with the status and message.
*
* @param status HTTP status code to send
* @param message Corresponding message to send
*
* @exception IllegalStateException if this response has
* already been committed
* @exception IOException if an input/output error occurs
*/
public void sendError(int status, String message)
throws IOException
{
if (isCommitted())
throw new IllegalStateException
(sm.getString("httpResponseBase.sendError.ise"));
if (included)
return; //Ignore any call from an included servlet
setError();
// Record the status code and message.
this.status = status;
this.message = message;
// Clear any data content that has been buffered
resetBuffer();
// Cause the response to be finished
// (from the application perspective)
setSuspended(true);
}
If you observe the code above, the first thing it does is, throw an IllegalStateException if the response was already committed. Then it returns from the method if it is not invoked by the outermost servlet. The next thing it does is, call the setError method which updates an internal flag. Then it updates the status and message fields. These two fields are of most importance to us. Then it clears the buffer and finally suspends any further output stream access.
You can make better use of this method if you create a wrapper for it. You might want to do this if you care to send custom messages to the client rather than accept the default ones provided by the container.
Below is code for a sample wrapper that can be used for sending custom messages instead of using the default one.
Code:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.PrintWriter;
import java.io.IOException;
public class ErrorHandlingServlet extends HttpServlet
{
//your own custom flag:
static final int SC_CUSTOM_ERROR_FIRST_NAME = 3229;
public void sendError(HttpServletResponse response,
int code)
throws ServletException, IOException
{
// Message sent by sendError().
String message = getErrorMessage(code);
if(message.equals("NONE"))
{
response.sendError(HttpServletResponse.SC_ FORBIDDEN);
} else
{
response.sendError(HttpServletResponse.SC_ FORBIDDEN,
message);
}
//update your own log
//logError(code, message);
}
public String getErrorMessage(int code)
{
String message = "NONE";
switch (code)
{
case HttpServletResponse.SC_OK:
return ("OK");
case HttpServletResponse.SC_ACCEPTED:
return ("Accepted");
case HttpServletResponse.SC_BAD_GATEWAY:
return ("Bad Gateway");
case HttpServletResponse.SC_BAD_REQUEST:
return ("Bad Request");
case HttpServletResponse.SC_CONFLICT:
return ("Conflict");
//There are a lot more codes.
//Just put a few for example
//first custom message; overrides the default message
case HttpServletResponse.SC_GONE:
return ("Sorry, this resource +
"is not available any more.");
case
HttpServletResponse.SC_HTTP_VERSION_NOT_ SUPPORTED:
return ("Hey! You are doing something Hinky" +
" and we do not support it.");
case HttpServletResponse.SC_INTERNAL_SERVER_ERROR:
return ("I Have no clue as to what happened, but it "
"was a bad server error");
case HttpServletResponse.SC_MOVED_PERMANENTLY:
return ("This Page has moved For good"
"permanently!");
// You can add a lot more custom error messages and provide
// handling for it.
default:
return ("NONE");
}
}
}
Previous Chapter: Chapter 26 - Returning an Error Code to the Client
Next Chapter: Chapter 27 - setStatus Method
So, lets get started!!!
The sendError Method
The sendError method sends an error response to the client using the specified status (Remember the bunch of status codes we saw in one of the previous chapters?). Using this method clears the buffer. The server creates an HTML-formatted server error page. This page contains a default, or the message you provide, as an argument. It also sets the content type to “text/html”, even if you changed this, but leaves cookies and other headers unmodified.
Exam Trivia:
We cannot or rather should not send data to a client after the sendError() method is invoked. Once this method is invoked, all the buffered output will be discarded. If data has been written to the response buffer but not yet returned to the client (i.e., response not committed), the data is cleared and replaced with the data sent by the sendError() method. Data written to the response after the sendError() is called is ignored. However, if you write data to the response buffer and try to commit it after the sendError is invoked, an IllegalStateException will be thrown.
Be cautious and watch out for code that does exactly this in the exam question. It may look legit but it will throw an exception and you may overlook the exception choice in the answer.
The sendError method will set the appropriate headers and content body for an error message to return to the client. An optional String argument can be provided to the sendError method, which can be used in the content body of the error. Using this method will commit the response (if not already committed) and terminate it. The data stacked in the output stream to the client before calling sendError() method is ignored.
Internally, the servlet base classes prevent you from writing to the output stream after calling sendError(). In the write-to-stream methods there is a test for a previous error in the servlet that looks like this:
//suspended is a flag set once output is committed
if (suspended)//true if sendError has been called
throw new IOException
(sm.getString("responseBase.write.suspended"));
That is why you can't add to the outputstream after calling sendError().
The best way to understand the sendError() method is to look at it directly. Lets take a look at some sample code that will help us do just that.
Code: This is the actual code implementation of how Tomcat implements the sendError method.
/**
* Send an error response with the status and message.
*
* @param status HTTP status code to send
* @param message Corresponding message to send
*
* @exception IllegalStateException if this response has
* already been committed
* @exception IOException if an input/output error occurs
*/
public void sendError(int status, String message)
throws IOException
{
if (isCommitted())
throw new IllegalStateException
(sm.getString("httpResponseBase.sendError.ise"));
if (included)
return; //Ignore any call from an included servlet
setError();
// Record the status code and message.
this.status = status;
this.message = message;
// Clear any data content that has been buffered
resetBuffer();
// Cause the response to be finished
// (from the application perspective)
setSuspended(true);
}
If you observe the code above, the first thing it does is, throw an IllegalStateException if the response was already committed. Then it returns from the method if it is not invoked by the outermost servlet. The next thing it does is, call the setError method which updates an internal flag. Then it updates the status and message fields. These two fields are of most importance to us. Then it clears the buffer and finally suspends any further output stream access.
You can make better use of this method if you create a wrapper for it. You might want to do this if you care to send custom messages to the client rather than accept the default ones provided by the container.
Below is code for a sample wrapper that can be used for sending custom messages instead of using the default one.
Code:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.PrintWriter;
import java.io.IOException;
public class ErrorHandlingServlet extends HttpServlet
{
//your own custom flag:
static final int SC_CUSTOM_ERROR_FIRST_NAME = 3229;
public void sendError(HttpServletResponse response,
int code)
throws ServletException, IOException
{
// Message sent by sendError().
String message = getErrorMessage(code);
if(message.equals("NONE"))
{
response.sendError(HttpServletResponse.SC_ FORBIDDEN);
} else
{
response.sendError(HttpServletResponse.SC_ FORBIDDEN,
message);
}
//update your own log
//logError(code, message);
}
public String getErrorMessage(int code)
{
String message = "NONE";
switch (code)
{
case HttpServletResponse.SC_OK:
return ("OK");
case HttpServletResponse.SC_ACCEPTED:
return ("Accepted");
case HttpServletResponse.SC_BAD_GATEWAY:
return ("Bad Gateway");
case HttpServletResponse.SC_BAD_REQUEST:
return ("Bad Request");
case HttpServletResponse.SC_CONFLICT:
return ("Conflict");
//There are a lot more codes.
//Just put a few for example
//first custom message; overrides the default message
case HttpServletResponse.SC_GONE:
return ("Sorry, this resource +
"is not available any more.");
case
HttpServletResponse.SC_HTTP_VERSION_NOT_ SUPPORTED:
return ("Hey! You are doing something Hinky" +
" and we do not support it.");
case HttpServletResponse.SC_INTERNAL_SERVER_ERROR:
return ("I Have no clue as to what happened, but it "
"was a bad server error");
case HttpServletResponse.SC_MOVED_PERMANENTLY:
return ("This Page has moved For good"
"permanently!");
// You can add a lot more custom error messages and provide
// handling for it.
default:
return ("NONE");
}
}
}
Previous Chapter: Chapter 26 - Returning an Error Code to the Client
Next Chapter: Chapter 27 - setStatus Method
Monday, March 28, 2011
Chapter 26: Returning an Error Code to the Client
In the previous chapter, we learnt what the error codes are and what they signify. We also saw an introduction to servlet exception handling. Before we get any further on this topic of exception handling, we need to know how to send error codes to the browser. That is exactly what we are going to learn now.
So, lets get started!!!
Returning an Error Code to the Client
The servlet is just as prone to logic errors and bugs as standalone applications. Java has a smart facility for handling them in both environments. Let's look at a very simple example of how you might handle an error in a servlet. The TestErrorServlet servlet illustrates the use of the sendError() method. It takes an error code as a parameter and an optional custom message associated with that error
Source Code:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletException;
import java.io.PrintWriter;
import java.io.IOException;
public class TestErrorServlet extends HttpServlet {
public void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.sendError(HttpServletResponse.SC_FORBIDDEN,
"Sorry, restricted to Authorized Personnel.");
}
}
Compile the TestErrorServlet file and hit the servlet with your browser.
The container will send an error message to the client. You should see a page that looks like below.
Previous Chapter: Chapter 25 - Introduction to Servlet Exception Handling
Next Chapter: Chapter 27 - sendError Method
So, lets get started!!!
Returning an Error Code to the Client
The servlet is just as prone to logic errors and bugs as standalone applications. Java has a smart facility for handling them in both environments. Let's look at a very simple example of how you might handle an error in a servlet. The TestErrorServlet servlet illustrates the use of the sendError() method. It takes an error code as a parameter and an optional custom message associated with that error
Source Code:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletException;
import java.io.PrintWriter;
import java.io.IOException;
public class TestErrorServlet extends HttpServlet {
public void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.sendError(HttpServletResponse.SC_FORBIDDEN,
"Sorry, restricted to Authorized Personnel.");
}
}
Compile the TestErrorServlet file and hit the servlet with your browser.
The container will send an error message to the client. You should see a page that looks like below.
Previous Chapter: Chapter 25 - Introduction to Servlet Exception Handling
Next Chapter: Chapter 27 - sendError Method
Chapter 25: Introduction to Servlet Exception Handling
Any technology, any programming language you learn, exception handling is an integral part of it. And the SCWCD exam covers topics related to Exception Handling in the Servlet Technology as well. Though, there are numerous ways of customized error handling available with servlets, the exam covers two main topics. Using the SENDERROR and SETSTATUS.
That is exactly what we are going to learn in this chapter and the next few chapters too.
So, lets get started!!!
Introduction to Servlet Exception Handling:
The way in which you create and manage exceptions in servlets is slightly different from how you do this with standalone applications.
We always use the response object (HttpServletResponse) and not the request object, to tell the browser that there is a problem.
The exam includes both exceptions (The ones caused by the Servlet) and HTTP Error Codes (Those you send back to the client).
Before we jump into the world of exceptions, lets quickly review the HTTP Protocol standards. This is essential because, the servlets communicate with clients using HTTP and it is helpful to know a little about this protocol.
The HTTP Protocol:
The HTTP protocol is a request/response scheme where a client sends a request to the server. There are four major portions of this request, which include, a request method (GET, POST…), URI (such as www.abc.com), protocol version (HTTP/1.1), and finally a MIME-like message. This message can be any size, and normally includes request modifiers, client information, and body content.
In this series of chapters, we will learn how we can send error information to the client using the sendError method, which sends a status line with the protocol version and a success or error code. It also returns a MIME like message containing server information, entity meta information and body content. You must remember that both the severity and type of error to properly tell the client what went wrong. Your error handling logic needs to determine the most appropriate severity for a particular error.
After receiving a request, the server responds. It returns an HTTP response message. The first line of this response message is called the status line. The status line has three parts. They are, in this order, protocol version, numeric status code, and status textual phrase. This status code is what you are setting when you use sendError and setStatus methods.
The Error Codes:
If you have been using the internet and J2EE applications for a while, you are sure to have encountered the 404: PAGE NOT FOUND message at some websites. This tells you that the URL is bad. i.e., if you try login to www.thisissurelyanincorrectwebsite.com you will probably get this message. The emphasis is on the number 404, this is the status code, a 3 digit integer number. The first digit defines the class of response, while the last two digits do not have any categories; they give an indication of what the problem is.
Let us now take a look at all the error codes that we can encounter in a HTTP based J2EE system. This list just contains the broad categorization based on the 1st digit.
While, the above table describes five set of status codes, we will primarily focus on the Server Error Category – the 5XX codes.
As mentioned previously, the HTTP protocol is a request/response scheme where a client sends a request to the server. When you need to inform the client of a problem at the server end, you call the sendError method. This causes the server to respond with a status line, with protocol version and a success or error code (this is what sendError affects directly). Of course, it also returns a MIME-like message containing server information, entity meta information, and body content.
Actually, the sendError() and setStatus are closely related. In fact, they both set the error message to be displayed by the client and the status code used by the client. The default status code is HttpServletResponse.SC_OK ="OK"; however, there are a few other standard codes as well.
That being said, lets take a look at the list of status codes available. These codes were defined by the W3C and are sanctioned by the Internet Society (ISOC). The constant names, quoted messages that get displayed in the browser, and code descriptions are a combination of the servlet specification and Tomcat's implementation of that specification. The exam will not test your memory of these directly. However, taking five minutes to study this table will help you understand what these codes do and figure out which ones you need to use with the sendError and setStatus methods. Notice that the RFC column provides the Request For Comment document and section, the Internet's way of documenting standards. Also, some browsers allow the user to hide “friendly” error messages. If they do that, they will not see many of these errors, even if they occur.
Let me repeat, you need not memorize these status codes but knowing them would be useful to understand the servlet exception handling concepts.
Previous Chapter: Self Test - Chapters 20 to 24
Next Chapter: Chapter 26 - Returning Error Codes
That is exactly what we are going to learn in this chapter and the next few chapters too.
So, lets get started!!!
Introduction to Servlet Exception Handling:
The way in which you create and manage exceptions in servlets is slightly different from how you do this with standalone applications.
We always use the response object (HttpServletResponse) and not the request object, to tell the browser that there is a problem.
The exam includes both exceptions (The ones caused by the Servlet) and HTTP Error Codes (Those you send back to the client).
Before we jump into the world of exceptions, lets quickly review the HTTP Protocol standards. This is essential because, the servlets communicate with clients using HTTP and it is helpful to know a little about this protocol.
The HTTP Protocol:
The HTTP protocol is a request/response scheme where a client sends a request to the server. There are four major portions of this request, which include, a request method (GET, POST…), URI (such as www.abc.com), protocol version (HTTP/1.1), and finally a MIME-like message. This message can be any size, and normally includes request modifiers, client information, and body content.
In this series of chapters, we will learn how we can send error information to the client using the sendError method, which sends a status line with the protocol version and a success or error code. It also returns a MIME like message containing server information, entity meta information and body content. You must remember that both the severity and type of error to properly tell the client what went wrong. Your error handling logic needs to determine the most appropriate severity for a particular error.
After receiving a request, the server responds. It returns an HTTP response message. The first line of this response message is called the status line. The status line has three parts. They are, in this order, protocol version, numeric status code, and status textual phrase. This status code is what you are setting when you use sendError and setStatus methods.
The Error Codes:
If you have been using the internet and J2EE applications for a while, you are sure to have encountered the 404: PAGE NOT FOUND message at some websites. This tells you that the URL is bad. i.e., if you try login to www.thisissurelyanincorrectwebsite.com you will probably get this message. The emphasis is on the number 404, this is the status code, a 3 digit integer number. The first digit defines the class of response, while the last two digits do not have any categories; they give an indication of what the problem is.
Let us now take a look at all the error codes that we can encounter in a HTTP based J2EE system. This list just contains the broad categorization based on the 1st digit.
| Number | Type | Description |
|---|---|---|
| 1XX | Informational | Request received, continuing to process. |
| 2XX | Success | The action was successfully received, understood, and accepted. |
| 3XX | Redirection | Further action must be taken in order to complete the request. |
| 4XX | Client Error | The request contains bad syntax or cannot be fulfilled. |
| 5XX | Server Error | The server failed to fulfill an apparently valid request. |
As mentioned previously, the HTTP protocol is a request/response scheme where a client sends a request to the server. When you need to inform the client of a problem at the server end, you call the sendError method. This causes the server to respond with a status line, with protocol version and a success or error code (this is what sendError affects directly). Of course, it also returns a MIME-like message containing server information, entity meta information, and body content.
Actually, the sendError() and setStatus are closely related. In fact, they both set the error message to be displayed by the client and the status code used by the client. The default status code is HttpServletResponse.SC_OK ="OK"; however, there are a few other standard codes as well.
That being said, lets take a look at the list of status codes available. These codes were defined by the W3C and are sanctioned by the Internet Society (ISOC). The constant names, quoted messages that get displayed in the browser, and code descriptions are a combination of the servlet specification and Tomcat's implementation of that specification. The exam will not test your memory of these directly. However, taking five minutes to study this table will help you understand what these codes do and figure out which ones you need to use with the sendError and setStatus methods. Notice that the RFC column provides the Request For Comment document and section, the Internet's way of documenting standards. Also, some browsers allow the user to hide “friendly” error messages. If they do that, they will not see many of these errors, even if they occur.
| Code | Constant | RFC | Message | Description |
|---|---|---|---|---|
| 100 | SC_CONTINUE | 10.1.1 | “Continue” | Client can continue. |
| 101 | SC_SWITCHING_PROTOCOLS | 10.1.2 | “Switching Protocols” | Server is switching protocols according to Upgrade header. |
| 200 | SC_OK | 10.2.1 | “OK” | Request succeeded normally. |
| 201 | SC_CREATED | 10.2.2 | “Created” | Request succeeded and created a new resource on the server. |
| 202 | SC_ACCEPTED | 10.2.3 | “Accepted” | Request was accepted for processing but was not completed. |
| 203 | SC_NON_AUTHORITATIVE_INFORMATION | 10.2.4 | “Non-Authoritative Information” | Meta information presented by the client did not originate from the server. |
| 204 | SC_NO_CONTENT | 10.2.5 | “No Content” | Request succeeded but there was no new information to return. |
| 205 | SC_RESET_CONTENT | 10.2.6 | “Reset Content” | Agent should reset the document view which caused the request to be sent. |
| 206 | SC_PARTIAL_CONTENT | 10.2.7 | “Partial Content” | Server has fulfilled the partial GET request for the resource. |
| 300 | SC_MULTIPLE_CHOICES | 10.3.1 | “Multiple Choices” | Requested resource corresponds to any one of a set of representations with each with its own specific location. |
| 301 | SC_MOVED_PERMANENTLY | 10.3.2 | “Moved Permanently” | Resource has permanently moved to a new location and future references should use a new URI with their requests. |
| 302 | SC_MOVED_TEMPORARILY | 10.3.3 | “Moved Temporarily” | Resource has temporarily moved to another location but future references should still use the original URI to access the resource. |
| 303 | SC_SEE_OTHER | 10.3.4 | “See Other” | Response to the request can be found under a different URI. |
| 304 | SC_NOT_MODIFIED | 10.3.5 | “Not Modified” | Conditional GET operation found that the resource was available and not modified. |
| 305 | SC_USE_PROXY | 10.3.6 | “Use Proxy” | Requested resource must be accessed through the proxy given by the Location field. |
| 307 | SC_TEMPORARY_REDIRECT | 10.3.8 | N/A | Requested resource resides temporarily under a different URI. The temporary URI should be given by the Location field in the response. |
| 400 | SC_BAD_REQUEST | 10.4.1 | “Bad Request” | Request sent by the client was syntactically incorrect. |
| 401 | SC_UNAUTHORIZED | 10.4.2 | “Unauthorized” | Request requires HTTP authentication. |
| 402 | SC_PAYMENT_REQUIRED | 10.4.3 | “Payment Required” | Reserved for future use. |
| 403 | SC_FORBIDDEN | 10.4.4 | “Forbidden” | Server understood the request but refused to fulfill it. |
| 404 | SC_NOT_FOUND | 10.4.5 | “Not Found” | Requested resource is not available. |
| 405 | SC_METHOD_NOT_ALLOWED | 10.4.6 | “Method Not Allowed” | Method specified in the Request-Line is not allowed for the resource identified by the Request-URI. |
| 406 | SC_NOT_ACCEPTABLE | 10.4.7 | “Not Acceptable” | Resource identified by the request is only capable of generating response entities that have content characteristics not acceptable according to the accept headers sent in the request. |
| 407 | SC_PROXY_AUTHENTICATION_REQUIRED | 10.4.8 | “Proxy Authentication Required” | Client must first authenticate itself with the proxy. |
| 408 | SC_REQUEST_TIMEOUT | 10.4.9 | “Request Timeout” | Client did not produce a request within the time that the server was prepared to wait. |
| 409 | SC_CONFLICT | 10.4.10 | “Conflict” | Request could not be completed due to a conflict with the current state of the resource. |
| 410 | SC_GONE | 10.4.11 | “Gone” | Resource is no longer available at the server and no forwarding address is known. This condition should be considered permanent. |
| 411 | SC_LENGTH_REQUIRED | 10.4.12 | “Length Required” | Request cannot be handled without a defined Content-Length. |
| 412 | SC_PRECONDITION_FAILED | 10.4.13 | “Precondition Failed” | A precondition given in one or more of the request-header fields evaluated to false when it was tested on the server. |
| 413 | SC_REQUEST_ENTITY_TOO_LARGE | 10.4.14 | “Request Entity Too Large” | Server is refusing to process the request because the request entity is larger than the server is willing or able to process. |
| 414 | SC_REQUEST_URI_TOO_LONG | 10.4.15 | “Request URI Too Long” | Server is refusing to service the request because the Request-URI is longer than the server is willing to interpret. |
| 415 | SC_UNSUPPORTED_MEDIA_TYPE | 10.4.16 | “Unsupported Media Type” | Server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method. |
| 416 | SC_REQUESTED_RANGE_NOT_SATISFIABLE | 10.4.17 | “Requested Range Not Satisfiable” | Server cannot serve the requested byte range. |
| 417 | SC_EXPECTATION_FAILED | 10.4.18 | “Expectation Failed” | Server could not meet the expectation given in the Expect request header. |
| 500 | SC_INTERNAL_SERVER_ERROR | 10.5.1 | “Internal Server Error” | Error inside the server which prevented it from fulfilling the request. This error represents many server problems such as exceptions or perhaps a database hiccup. |
| 501 | SC_NOT_IMPLEMENTED | 10.5.2 | “Not Implemented” | Server does not support the functionality needed to fulfill the request. |
| 502 | SC_BAD_GATEWAY | 10.5.3 | “Bad Gateway” | Server received an invalid response from a server it consulted when acting as a proxy or gateway. |
| 503 | SC_SERVICE_UNAVAILABLE | 10.5.4 | “Service Unavailable” | Server is temporarily overloaded and unable to handle the request. |
| 504 | SC_GATEWAY_TIMEOUT | 10.5.5 | “Gateway Timeout” | Server did not receive a timely response from the upstream server while acting as a gateway or proxy. |
| 505 | SC_HTTP_VERSION_NOT_SUPPORTED | 10.5.6 | “HTTP Version Not Supported” | Server does not support or refuses to support the HTTP protocol version that was used in the request message. |
Previous Chapter: Self Test - Chapters 20 to 24
Next Chapter: Chapter 26 - Returning Error Codes
Subscribe to:
Posts (Atom)
© 2013 by www.inheritingjava.blogspot.com. All rights reserved. No part of this blog or its contents may be reproduced or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Author.

