Java - Servlet

java

getServletContext()

// Servlet

javax.servlet.http;

// Passing values from servlet to JSP:
HashMap pageValues = dao.getInfo(entitiesID, mode);
pageValues.put("ENVIRONMENT", environment);
req.setAttribute("pageValues", pageValues);
request.setAttribute("errorMessage", "Invalid Credentials!!");

<%
String attributeValue = request.getAttribute("attributeName");
%>
<%= attributeValue %>

// Sending content directly to the browser:
PrintWriter out = response.getWriter();
out.println("<html><head></head><body>Hellow</body></html>");

// Forward to JSP page:
request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);

// Redirect:
response.sendRedirect("/someUrl");

// Get a form parameter
String v = request.getParameter('v');

doGet
doPost
service

// The parameters that we typically pass to a servlet method:
HttpServletRequest
HttpServletResponse

// Set a session attribute
request.getSession().setAttribute(“name”, name);

// Get a session attribute
String name = request.getSession().getAttribute(“name”);

// Set the content-type for the response:
response.setContentType("text/html");

// Set HTTP response headers:
File file = new File(fileName);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\""+ file.getName() + "\"");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control","private, must-revalidate, max-age=300, post-check=0, pre-check=0");
//response.setHeader("Pragma", "no-cache");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition","attachment; filename=\"" + fileName + "\"");
response.setHeader("Content-Length", String.valueOf(badFile.length()));

Setting a request attribute before forwarding to a JSP page makes sense. However, 
setting a request attribute before sending a redirect does not make sense.  Setting a 
session attribute before sending a redirect does make sense.  If you need to persist 
some information before sending a redirect, set a session attribute.

The init method is invoked only once when the server starts. The service 
method is invoke once for each request. We typically do not need to implement 
these methods, but they are there from the base class. If we have special 
logic that need to happen when the server initialize the servlet, we can 
implement the init method, but we probably need to call the init method of 
the base class, and we need to keep in mind that this logic get executed 
only once. Likewise, we can override the service method, and the logic get 
executed once for each request. This means that the servlet exists from the 
time that the server is started to the time that the server is shutdown. If 
we need to do something special, we can override both the init method and the 
service method if needed.  When the server is shutdown, the destroy method of 
the servlet is invoked.

The init method is invoked once when the server starts or the thread is 
started. The service method is invoked once for each request. The shutdown 
method is invoked when the server is shutdown.

If you want to handle all request types from a single method, your servlet can simply 
implement the service() method. If you choose to implement the service() method, 
you cannot implement the doPost() or doGet() methods, unless you call 
super.service() at the beginning of the service() method.

public void service(HttpServletRequest req, HttpServletResponse res) throws IOException {
}

package webapp;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = "/login.do")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Yahoo!!!!!!!!</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("My First Servlet");
        out.println("</body>");
        out.println("</html>");
    }
}

<!-- webapp/WEB-INF/web.xml -->
<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>To do List</display-name>
    <welcome-file-list>
        <welcome-file>login.do</welcome-file>
    </welcome-file-list>
</web-app>

// A simple servlet that redirect to a JSP for rendering:

package webapp;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = "/login.do")
public class LoginServlet extends HttpServlet {

    private LoginService service = new LoginService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        String name = request.getParameter("name");
        String password = request.getParameter("password");

        boolean isValidUser = service.validateUser(name, password);

        if (isValidUser) {
            request.setAttribute("name", name);
            request.getRequestDispatcher("/WEB-INF/views/welcome.jsp").forward(request, response);
        } else {
            request.setAttribute("errorMessage", "Invalid Credentials!!");
            request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);
        }
    }

}

// webapp\WEB-INF\views\login.jsp
<%@ page language=“java” contentType=“text/html; charset=UTF-8” pageEncoding=“UTF-8”%>
<!DOCTYPE html>
<html>
<head>
<title>Yahoo!!</title>
</head>
<body>
    <p><font color="red">${errorMessage}</font></p>
    <form action="/login.do" method="POST">
      Name : <input name="name" type="text" /> Password : 
      <input name="password" type="password" /> <input type="submit" />
    </form>
</body>
</html>

// The above code demonstrate:
1.  implementing the doGet and doPost methods.
2.  using getRequestDispatcher to forward the request to a JSP page.
3.  using request.getParameter to obtain a form parameter.
3.  using request.setAttribute to set attributes before forwarding the request to a JSP page.

// web.xml for servlet mapping:
<servlet>
    <servlet-name>springDispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/todo-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springDispatcher</servlet-name>
    <url-pattern>/spring-mvc/*</url-pattern>
</servlet-mapping>

// todo-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <context:component-scan base-package="com.companyName" />
    <mvc:annotation-driven />
</beans>

// Spring MVC Controller:
package com.companyName.springmvc.login;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class LoginController {
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String showLoginPage() {
        return "login";
    }
}

In the above code, we use the @Controller annotation to import and extends the 
Spring MVC Controller class. We also use the @RequestMapping annotation to 
define the servlet mapping URL. The @RequestMapping annotation is associated 
with the showLoginPage method.

// View Resolver:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/views/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
</bean>

// Read everything from getInputStream:
//Using Apache Commons
import org.apache.commons.io.IOUtils;

String file = servctxt.getRealPath("/qsrmsupport/misc/template.sql");
FileInputStream is = new FileInputStream(new File(file));
String sql = IOUtils.toString(is, "UTF-8");

InputStream jsonResponseIn = req.getInputStream();
String jsonResponse = IOUtils.toString(jsonResponseIn);
JSONArray jsonArray = new JSONArray(jsonResponse);

// Using native Java 7:
new String(Files.readAllBytes(Paths.get(filePath)));

// Get access to the servlet context
import javax.servlet.ServletContext;
ServletContext servctxt = getServletContext();

Just invoke the getServletContext() method. All servlets are implemented by 
extending the HttpServlet class. It is the responsibility of the application 
container (Tomcat, WebLogic, etc) to provide the getServletContext() method.

// Determine the path of your web application dynamically:
getServletContext().getRealPath("/");

// Other alternatives:
this.getClass().getProtectionDomain().getCodeSource().getLocation();
new File(".").getAbsolutePath();
System.getProperty("user.dir");
this.getClass().getClassLoader().getResource("").getPath();

// Display a different JSP pages based on different conditions:
RequestDispatcher dispatcher = request.getRequestDispatcher(pageName);
dispatcher.include(request, response);

In the above code the variable pageName is just the path to the JSP file. 
There may be some problem if the JSP files use relative path for some of 
its resources. To get around this problem, make sure that the JSP files 
use absolute paths for its resources.

// Obtain the URI of the current request:
String uri = (String) req.getAttribute("javax.servlet.error.request_uri");

// Servlet
public class FileServlet extends HttpServlet {
    private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String requestedFile = request.getPathInfo();
        if (requestedFile == null) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        String contentType = getServletContext().getMimeType(file.getName());

        response.reset();
        response.setBufferSize(DEFAULT_BUFFER_SIZE);
        response.setContentType(contentType);
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
        try {
            // Open streams.
            input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
            output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

            // Write file contents to response.
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            int length;
            while ((length = input.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
        } finally {
            // Gently close streams.
            input.close();
            output.close();
        }
    }
}

How to read everything from getInputStream?

//Using Apache Commons
import org.apache.commons.io.IOUtils;

String file = servctxt.getRealPath("/qsrmsupport/misc/template.sql");
FileInputStream is = new FileInputStream(new File(file));
String sql = IOUtils.toString(is, "UTF-8");

InputStream jsonResponseIn = req.getInputStream();
String jsonResponse = IOUtils.toString(jsonResponseIn);
JSONArray jsonArray = new JSONArray(jsonResponse);

// Using native Java 7:
new String(Files.readAllBytes(Paths.get(filePath)));

How can we get access to the servlet context?

import javax.servlet.ServletContext;
ServletContext servctxt = getServletContext();

Just invoke the getServletContext() method. All servlets are implemented by extending the HttpServlet class. It is the responsibility of the application container (Tomcat, WebLogic, etc) to provide the getServletContext() method.

How to write a servlet?

public class FileServlet extends HttpServlet {
    private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String requestedFile = request.getPathInfo();
        if (requestedFile == null) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        String contentType = getServletContext().getMimeType(file.getName());

        response.reset();
        response.setBufferSize(DEFAULT_BUFFER_SIZE);
        response.setContentType(contentType);
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
        try {
            // Open streams.
            input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
            output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

            // Write file contents to response.
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            int length;
            while ((length = input.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
        } finally {
            // Gently close streams.
            input.close();
            output.close();
        }
    }
}

How to determine the path of your web application dynamically?

If you have a servlet:

getServletContext().getRealPath("/");

Other alternatives:

this.getClass().getProtectionDomain().getCodeSource().getLocation();
new File(".").getAbsolutePath();
System.getProperty("user.dir");
this.getClass().getClassLoader().getResource("").getPath();

How to displays a JSP page inside a servlet?

I have a servlet, which needs to display different JSP pages based on different conditions:

    protected void beautifulMethodName(HttpServletRequest request, HttpServletResponse response, String pageName) 
    throws IOException, ServletException {
        RequestDispatcher dispatcher = request.getRequestDispatcher(pageName);
        dispatcher.include(request, response);
    }

The beautifulMethodName method is given the HttpServletRequest object, the HttpServletResponse object and the variable pageName. The variable pageName is just the path to the JSP file. There may be some problem if the JSP files use relative path for some of its resources. To get around this problem, make sure that the JSP files use absolute paths for its resources.

How to obtain the URI of the current request?

String uri = (String) req.getAttribute("javax.servlet.error.request_uri");

If we have a servlet which perform some logic and then delegate the rendering of the result to a JSP file, how can we pass information from the servlet to the JSP file?

String environment = Globals.splusInfo.myProps.getProperty("QSUPPORT_URL").toString();
HashMap pageValues = dao.getInfo(entitiesID, mode);
pageValues.put("ENVIRONMENT", environment);
req.setAttribute("pageValues", pageValues);

<%
String attributeValue = request.getAttribute("attributeName");
%>

<%= attributeValue %>

How can our servlet send content directly to the browser?

Use response.getWriter():

PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Yahoo!!!!!!!!</title>");
out.println("</head>");
out.println("<body>");
out.println("My First Servlet");
out.println("</body>");
out.println("</html>");

How can our servlet redirect to a JSP page?

request.getRequestDispatcher:

request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);

How can our servlet retrieve a GET parameter?

Use request.getParameter:

String v = request.getParameter('v');

How can our servlet retrieve a POST parameter?

Use request.getParameter:

String v = request.getParameter('v');

How can our servlet pass an attribute to our JSP?

Use request.setAttribute:

request.setAttribute("errorMessage", "Invalid Credentials!!");

What is the base class of a servlet?

HttpServlet. All the servlets must extends the HttpServlet class or one of its sub-classes if there is such sub-classes.

What are the typical methods that we must implement inside a servlet?

doGet, doPost

How can we define the URL for a servlet?

We can register it in the web.xml file using the servlet-mapping directive, or we can use the @WebServlet annotation if we are using Spring.

What are the parameters that we typically pass to the methods inside a servlet?

HttpServletRequest, HttpServletResponse

What package does the HttpServlet class belong to?

javax.servlet.http

What class the the HttpServlet class inherit from?

It inherits from the GenericServlet. ( javax.servlet.GenericServlet )

What is the difference between the HttpServlet class and the GenericServlet class?

The HttpServlet class is intended for applications that use HTTP. The GenericServlet class is intended as the base class for all protocol. IN NEED TO COME BACK TO THIS.

How can our servlet methods send a redirect?

Using the sendRedirect method of the response object:

response.sendRedirect("/someUrl");

How can our servlet forward the request to a JSP file?

Use the getRequestDispatcher method of the request object:

request.getRequestDispatcher(“/WEB-INF/views/add-todo.jsp”).forward(request, response)

What is the difference between the init method and the service method of a servlet?

The init method is invoked only once when the server starts. The service method is invoke once for each request. We typically do not need to implement these methods, but they are there from the base class. If we have special logic that need to happen when the server initialize the servlet, we can implement the init method, but we probably need to call the init method of the base class, and we need to keep in mind that this logic get executed only once. Likewise, we can override the service method, and the logic get executed once for each request. This means that the servlet exists from the time that the server is started to the time that the server is shutdown. If we need to do something special, we can override both the init method and the service method if needed.

When the server is shutdown, the destroy method of the servlet is invoked.

What is the lifecycle of a servlet?

The init method is invoked once when the server starts or the thread is started. The service method is invoked once for each request. The shutdown method is invoked when the server is shutdown.

What are the differences between a GET request and a POST request?

The GET request is less secure because all the parameters are visible in the URL. When dealing with sensitive data, we should always use https, and use a GET request if it does not change anything in the database, and use a POST request if it change data inside the database.

How can our servlet methods set a session attribute?

request.getSession.setAttribute(“name”, name);

How can our servlet methods get a session attribute?

String name = request.getSession.getAttribute(“name”);

How can our servlet methods set a request attribute before forwarding to a JSP?

request.setAttribute(“errorMessage”,”Invalid credentials”)

Should we set a request attribute before we redirect?

No. It does not make sense to set a request attribute and then do a redirect, when the browser follow the redirect, it is a new request. It only make sense to set a request attribute and do a forward, because it is an internal forward on the server side and it does not create a new request.

Why should we keep the size of the session as small as possible?

We should keep the size of the session as small as possible because session data persist for the life of the session which is typically 30 minutes or more, and information is typically kept inside the server memory (RAM) instead of on disk or database for performance reason. Even if session data is kept on disk or in the database, the size of the session data still imply performance penalty, so be careful with what you put into the session.

How can our servlet methods retrieve a request parameter?

String bookName = request.getParamter("bookName");

How can our servlet methods set the content type for the response?

Use the setContentType method of the response object:

response.setContentType("text/html");

How can our servlet methods send custom response header?

Use the setHeader method of the response object:

File file = new File(fileName);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\""+ file.getName() + "\"");

response.setHeader("Expires", "0");
response.setHeader("Cache-Control","private, must-revalidate, max-age=300, post-check=0, pre-check=0");
//response.setHeader("Pragma", "no-cache");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition","attachment; filename=\"" + fileName + "\"");
response.setHeader("Content-Length", String.valueOf(badFile.length()));
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License