Thursday, December 22, 2016

How to redirect to error page when exception occurs from servlet?

Servlet is thrown ServletException and IOException. If you want to handle each exception seperately then you can handle multiple handler in web.xml file.

For example: you've to use exception-type or error-code and location in error-page to handle specific exception or error code.



        <error-page>
           
<exception-type>java.io.IOException</exception-type>                           
            <location>/Handler1</location>        
        </error-page>
   



       
<error-page>         
                 <exception-type>javax.servlet.ServletException</exception-type>         
                 <location>/Handler2</location>        
         </error-page>
   




        
<error-page>          
               <error-code>404</error-code>          
               <location>/invalidRequest</location>        
          </error-page>
   


If you want to handle runtime exceptions and all other exceptions in a single exception handler, you can provide exception-type as Throwable.

Only way to handle it in a generic way is to use web.xml like below:


        <error-page> 

                      <exception-type>java.lang.Throwable</exception-type>                      
                      <location>/Handler</location>        
        </error-page>   

Example:

We handle the error in /Handler  servlet and forward / redirect the error to errorPage.jsp.

/Handler:

@WebServlet("/Handler")
public class ExceptionHandler extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Process(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Process(req, resp);
    }
   
    public void Process(HttpServletRequest req, HttpServletResponse resp)  throws ServletException, IOException
    {
        Throwable throwable = (Throwable) req.getAttribute("javax.servlet.error.exception");
        int status_code = (Integer) req.getAttribute("javax.servlet.error.status_code");
        String servlet_name = (String) req.getAttribute(" javax.servlet.error.servlet_name");
       
        if(servlet_name==null)
        {
            servlet_name = "unknown";
        }
        String uri = (String) req.getAttribute("javax.servlet.error.request_uri");  
       
        if(uri==null)
        {
            uri = "unknown";
        }
       
        req.setAttribute("error", "Servlet: " + servlet_name + " has thrown an exception "
                + throwable.getClass().getName() + ": " + throwable.getMessage());
        req.getRequestDispatcher("/errorPage.jsp").forward(req, resp);
    }
   

errorPage.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Error Occurred</title>
    </head>
    <body>
        <h1>${error}</h1>
    </body>
</html>




Monday, December 19, 2016

Create Java Servlet Using @annotation

Web applications are configured by means of web.xml. That means you have to configure web components like WebServlet, WebListener, WebFilter, WebInitParam etc in deployment descriptor i.e. web.xml.

From Servlet 3.0, Web components can be deployed by using annotations. This will be easier for quick development. But if both web.xml and annotation present for a component, then the deployment descriptor (web.xml) configurations will be executed because it'll override the annotation declaration.

The @WebServlet annotation is used to declare a servlet. The annotated class must extend the javax.servlet.http.HttpServlet class.

Min. App. Servers requirements: Tomcat7, GlassFish, WebLogic Server, JBoss

Syntax

@WebServlet(
    attribute1=value1,
    attribute2=value2,
    ...
)
public class TheServlet extends javax.servlet.http.HttpServlet {
    // servlet code...
}
 

Attributes of @WebServlet

Name
Type
Required
Description
value
or
urlPatterns
String[]
Required
Specify one or more URL patterns of the servlet. Either of attribute can be used, but not both.
name
String
Optional
Name of the servlet
displayName
String
Optional
Display name of the servlet
description
String
Optional
Description of the servlet
asyncSupported
boolean
Optional
Specify whether the servlet supports asynchronous operation mode. Default is false.
initParams
WebInitParam[]
Optional
Specify one or more initialization parameters of the servlet. Each parameter is specified by @WebInitParam annotation type.
loadOnStartup
int
Optional
Specify load-on-startup order of the servlet.
smallIcon
String
Optional
Specify name of the small icon of the servlet.
largeIcon
String
Optional
Specify name of the large icon of the servlet.
NOTE: the attributes displayName, description, smallIcon and largeIcon are primarily used by tools, IDEs or servlet containers, they do not affect operation of the servlet.
 

Examples

A servlet is annotated with only the URL pattern:

@WebServlet("/myServlet")
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("Hello");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       
        super.service(req, resp);
       
    }
}
Here the servlet MyServlet is mapped to the URL pattern /myServlet. When accessing this servlet by Get method [accessing by only the URL], it will return a “Hello” message.

A servlet is annotated with multiple URL patterns:

@WebServlet(urlPatterns={"/sendFile", "/uploadFile"})
 
public class UploadServlet extends HttpServlet{
 
   @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,   IOException {
        PrintWriter writer = resp.getWriter();
        writer.print("<html>");

        writer.print("<body>");
        writer.print("<h1>Sample HTML Respose</h1>");
        writer.print("
</body>");
        writer.print("
</html>");
    }

   @Override

   protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);
    }
  
}
Here the servlet UploadServlet is mapped to the two URL pattern /sendFile and /uploadFile. When accessing this servlet by Get method [accessing by only the URL], it will return HTML output.

Declare a servlet with additional information:


@WebServlet(
        name="MyOwnServlet",
        description="This is my annotated servlet",
        urlPatterns="/MyOwnServlet"
        )

public class OwnServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);
    }
    
}
Here the servlet OwnServlet is mapped to  URL pattern /MyOwnSerlet. When accessing this servlet by Get method [accessing by only the URL], it will return BLANK page.

Declare a servlet with some init parameters:


@WebServlet(urlPatterns="/paramTest",
        initParams={
                        @WebInitParam(name="dir",value="d:/test"),
                        @WebInitParam(name="types", value="pdf,doc,docx")
                    }
        )

public class InitParamTestServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String dir = getInitParameter("dir");
        String types = getInitParameter("types");
      
        PrintWriter writer = resp.getWriter();
        writer.write(dir);
        writer.write(types);
    }
  
}
Here the servlet InitParamTestServlet is mapped to  URL pattern /paramTest. When accessing this servlet by Get method [accessing by only the URL], it will print the values of initialization parameters.

Declare a servlet with asynchronous operation mode and load-on-startup order:


@WebServlet(
            urlPatterns="/taskController",
            loadOnStartup=1,
            asyncSupported= true
        )

public class BackgroundProcess extends HttpServlet{

    @Override
    public void init() throws ServletException {
        System.out.println("Background Process started.....");
    }
  
}
The servlet BackgroundProcess is mapped to  URL pattern /taskController. Here loadOnStartup=1 means that the servlet is initialized by the container when it starts up or when the application is deployed. Value 1 means that the priority level of the servlet is 1 [most] for the application server or container. The app server or container calls the init() method of the servlet when the server being started or the application being deployed.

You can starts multiple servlet of a web application by the server using this annotation with a specific order. If the value of this annotation  is same for multiple servlets, then the container will decide the initialization orders of them[ i.e. sometimes initialized by order of names].

We also specify the servlet supports asynchronous mode by using asyncSupported= true.
 




Thursday, December 8, 2016

Checked vs Unchecked Exceptions in Java

In Java, there are two types of exceptions:

1. Checked Exception

2. Unchecked Exception

1. Checked Exception

These exceptions are check at compile time.  If a method throws a checked exception, then the caller have to either caught by throws or try/catch block.

Example 1:

The java.io.IOException is a checked exception. The method1() throws this exception.

void method1() throws IOException 
{
         
}
  
 
The following  method2() gives compile error because it calls method1() but doesn't throws  IOException or doesn't caught it within try/catch block.


void method2()
    {
        method1();
    }
 
Error when compile:    
 unreported exception IOException; must be caught or declared to be thrown method1();

Example 2:

If some code throws a checked exception within a method, then it must be caught within try/catch or throws keyword.

The following 2 implementations of method2() will compile.

Using try/catch block.

void method2()
    {
        try
        {
            method1();
        }
        catch(IOException e)
        {
           
        }
    }
 
 
 
Declaring throws keyword.

void method2() throws IOException
    {
       
            method1();
       
    }
 
 
Example 3:

The following will not compile because checked exception not handled in either try/catch block or throws keyword.

public void ioOperation(boolean isResourceAvailable) 
{

       if (!isResourceAvailable) {

                 throw new IOException();

       }

}
 
 
The following 2 implementations of ioOperation() will compile.

Using try/catch block.



public void ioOperation(boolean isResourceAvailable) 
{
            try {

                        if (!isResourceAvailable) {

                                        throw new IOException();

                       }

            } catch(IOException e) {


             }

}
 
 

Declaring throws keyword


public void ioOperation(boolean isResourceAvailable) throws IOException
{

      if (!isResourceAvailable) {

            throw new IOException();

      }

}

2. Unchecked Exception

These exceptions are not checked at compile time. In java, Under Error and RunimeException classes are unchecked exceptions, everything else under throwable classes are checked exceptions.

                   +-----------+
                    | Throwable|
                   +----------- +

                    /            \
                  /                \
          +-------+         +-----------  +
          | Error   |         | Exception |
          +-------+          +----------- +
          /     |       \              /     |        \
         \______/           \_____/      \
       
unchecked         checked         \                             
                                                   
+----------------------  +
                                                     | RuntimeException |                                        
                                                    +----------------------  + 
                                                                /   |    |      \                                               
                                                     \_________________/                                                                                    
                                                              unchecked
 


Example 4:
Consider the following Java program. It compiles fine, but it throws ArithmeticException when run. The compiler allows it to compile, because ArithmeticException is an unchecked exception.

class Main {
   public static void main(String args[]) {
      int x = 0;
      int y = 10;
      int z = y/x;
  }
}
 
 Example 5:
 The method3() throw RuntimeException. But doesn't require to caught within try/catch or throws keyword. It'll compile fine.

void method3()
    {
       
            throw new RuntimeException();
       
    }
 
 
 
As for the particular questions:
  1. Is the NumberFormatException consider a checked exception?
    No. NumberFormatException is unchecked (= is subclass of RuntimeException). Why? I don't know. (but there should have been a method isValidInteger(..))
  2. Is RuntimeException an unchecked exception?
    Yes, exactly.
  3. What should I do here?
    It depends on where this code is and what you want to happen. If it is in the UI layer - catch it and show a warning; if it's in the service layer - don't catch it at all - let it bubble. Just don't swallow the exception. If an exception occurs in most of the cases you should choose one of these:
    • log it and return
    • rethrow it (declare it to be thrown by the method)
    • construct a new exception by passing the current one in constructor
  4. Now, couldn't the above code also be a checked exception? I can try to recover the situation like this? Can I?
    It could've been. But nothing stops you from catching the unchecked exception as well
  5. Why do people add class Exception in the throws clause?
    Most often because people are lazy to consider what to catch and what to rethrow. Throwing Exception is a bad practice and should be avoided.