Thursday 28 November 2013

HttpServletRequestWrapper class usage or Modify HttpServletRequest Object including header information

Recently i came across a requirement where for time being I need to send some information in header of HttpServletRequest object. Setting it in browser level was not a option as we cant setup the header information everytime and in every system.

So did browsing little bit and found a solution. Also came to know many people are looking for it so would like to share the code for doing a work around using HttpServletRequestWrapper.

In the below project, going to insert value in the HttpServletRequest object as parameter and later modifying the object in the java code to get the value using method getHeader() of HttpServletRequest object.

Project Name : EditHeaderVariable 

First create a dynamic web project with the name you would like to give and put necessary jar files. I have made it as spring mvc project using maven. Giving below the dependency requirements in pom.xml file.

pom.xml

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  <modelVersion>4.0.0</modelVersion>  
  <groupId>EditHeaderVariable</groupId>  
  <artifactId>EditHeaderVariable</artifactId>  
  <version>0.0.1-SNAPSHOT</version>  
  <name>EditHeaderVariable</name>  
  <description>EditHeaderVariable</description>  
  <dependencies>  
       <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-core</artifactId>  
            <version>3.2.4.RELEASE</version>  
            <type>jar</type>  
            <scope>compile</scope>  
       </dependency>  
       <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-web</artifactId>  
            <version>3.2.4.RELEASE</version>  
            <type>jar</type>  
            <scope>compile</scope>  
       </dependency>  
       <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-webmvc</artifactId>  
            <version>3.2.4.RELEASE</version>  
            <type>jar</type>  
            <scope>compile</scope>  
       </dependency>  
  </dependencies>  
 </project>  

web.xml

Adding spring DispatcherServlet and other filter as required.

 <?xml version="1.0" encoding="UTF-8"?>  
 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
  <display-name>EditHeaderVariable</display-name>  
  <welcome-file-list>  
   <welcome-file>index.jsp</welcome-file>  
  </welcome-file-list>  
  <servlet>  
   <servlet-name>editHeader</servlet-name>  
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--  
   <init-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>  
   </init-param>  
   --><load-on-startup>1</load-on-startup>  
  </servlet>  
   <context-param>  
      <param-name>contextConfigLocation</param-name>  
      <param-value>/WEB-INF/editHeader-servlet.xml</param-value>  
  </context-param>  
  <servlet-mapping>  
   <servlet-name>editHeader</servlet-name>  
   <url-pattern>*.html</url-pattern>  
  </servlet-mapping>  
  <listener>  
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  </listener>  
  <filter>  
       <filter-name>modifyRequestObjectFilter</filter-name>  
       <filter-class>com.prajith.filter.ModifyRequestObjectFilter</filter-class>  
  </filter>  
  <filter-mapping>  
       <filter-name>modifyRequestObjectFilter</filter-name>  
       <url-pattern>/*</url-pattern>  
  </filter-mapping>  
 </web-app>  

editHeader-servlet.xml

enabling autoscan feature of the spring.

 <beans xmlns="http://www.springframework.org/schema/beans"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xmlns:context="http://www.springframework.org/schema/context"  
      xsi:schemaLocation="http://www.springframework.org/schema/beans   
      http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
      http://www.springframework.org/schema/context  
      http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
      <context:component-scan base-package="com.prajith" />  
      <bean id="viewResolver"  
           class="org.springframework.web.servlet.view.InternalResourceViewResolver" >  
       <property name="prefix">  
        <value>jsp/</value>  
       </property>  
       <property name="suffix">  
        <value>.jsp</value>  
       </property>  
     </bean>  
 </beans>  

index.jsp

welcome page for the application where we are giving option to enter some value in the form which we want to get in the header of the HttpServletRequest object created on submission.

 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"  
   pageEncoding="ISO-8859-1"%>  
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
 <html>  
 <head>  
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
 <title>Insert title here</title>  
 </head>  
 <body>  
      <form method="post" action="testheader.html">  
           write the header value to get : <input id="headerTest" name="headerTest" type="text" />  
           <input type="submit" value="submit"/>  
      </form>  
 </body>  
 </html>  

result.jsp

This jsp is just to redirect 2 time without wasting time on again clicking and redirecting. This jsp is also to show that the second  HttpServletRequest object does't contain any information passed in earlier HttpServletRequest object but still we are able to get the value of the earlier submitted request in the getHeader() method of the new HttpServletRequest object.

 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"  
   pageEncoding="ISO-8859-1"%>  
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
 <html>  
 <head>  
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
 <title>Insert title here</title>  
 </head>  
 <body>  
 <%response.sendRedirect("/EditHeaderVariable/resultCheck.html");%>  
 </body>  
 </html>  

result2.jsp

This jsp shows the value which we submitted in the first request from the index.jsp by getting the value from the getHeader() method of the HttpServletRequest object from session so that we need not submit the header information every time we need.

 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"  
   pageEncoding="ISO-8859-1"%>  
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
 <html>  
 <head>  
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
 <title>Insert title here</title>  
 </head>  
 <body>  
 ${message}  
 </body>  
 </html>  

HeaderController.java

This controller is for just printing and redirecting to the correct jsp resource. 
 
 package com.prajith.httpservlet;  
 import javax.servlet.http.HttpServletRequest;  
 import javax.servlet.http.HttpServletResponse;  
 import org.springframework.stereotype.Controller;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.servlet.ModelAndView;  
 @Controller  
 public class HeaderController {  
      @RequestMapping("/testheader")  
      public ModelAndView testHeader(HttpServletRequest request, HttpServletResponse response){  
           System.out.println("testheader");  
           System.out.println(request.getHeader("headerTest"));  
           return new ModelAndView("result");  
      }  
      @RequestMapping("/resultCheck")  
      public ModelAndView resultCheck(HttpServletRequest request, HttpServletResponse response){  
           System.out.println("resultCheck");  
           System.out.println(request.getHeader("headerTest"));  
           return new ModelAndView("result2","message",request.getHeader("headerTest"));  
      }  
 }  

ModifyRequestObjectFilter.java 

 This filter has been created so that we can modify the request object before reaching the controller. On reaching the controller, the controller gets modified HttpServletRequest object. In the below code you can see we have overridden the dofilter method of the filter interface and changed the ServletRequest object by casting the new class ModifyRequest which extends to HttpServletRequestWrapper class to ServletRequest object

 package com.prajith.filter;  
 import java.io.IOException;  
 import javax.servlet.Filter;  
 import javax.servlet.FilterChain;  
 import javax.servlet.FilterConfig;  
 import javax.servlet.ServletException;  
 import javax.servlet.ServletRequest;  
 import javax.servlet.ServletResponse;  
 import javax.servlet.annotation.WebFilter;  
 import javax.servlet.http.HttpServletRequest;  
 /**  
  * Servlet Filter implementation class ModifyRequestObjectFilter  
  */  
 @WebFilter("/ModifyRequestObjectFilter")  
 public class ModifyRequestObjectFilter implements Filter {  
   /**  
    * Default constructor.   
    */  
   public ModifyRequestObjectFilter() {  
     // TODO Auto-generated constructor stub  
   }  
      /**  
       * @see Filter#destroy()  
       */  
      public void destroy() {  
           // TODO Auto-generated method stub  
      }  
      /**  
       * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)  
       */  
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
           // TODO Auto-generated method stub  
           // place your code here  
           // pass the request along the filter chain  
           try{  
                request=(ServletRequest)new ModifyRequest((HttpServletRequest)request);  
                chain.doFilter(request, response);  
           }catch(Exception e){  
                System.out.println("error "+e);  
           }  
      }  
      /**  
       * @see Filter#init(FilterConfig)  
       */  
      public void init(FilterConfig fConfig) throws ServletException {  
           // TODO Auto-generated method stub  
      }  
 }  

ModifyRequest.java

This class extends to HttpServletRequestWrapper class and overrides getHeader method. In this method we don't want to loose the originality of the method so we have coded as super.getHeader() which calls the parent class method and returns the value accordingly. In case the returned value is null then we are modifying the value to be returned as per our need.
This is not only to modity the getHeader() method but also can be used to modify other method of the HttpServletRequest as per our need.
 
 package com.prajith.filter;  
 import javax.servlet.http.HttpServletRequest;  
 import javax.servlet.http.HttpServletRequestWrapper;  
 public class ModifyRequest extends HttpServletRequestWrapper {  
      private HttpServletRequest req;  
      private String value=null;  
      public ModifyRequest(HttpServletRequest request) {  
           super(request);  
           req=request;  
           // TODO Auto-generated constructor stub  
      }  
      @Override  
      public String getHeader(String name){  
           value=super.getHeader(name);  
           if(value==null){  
                value=req.getParameter(name);  
                if(req.getParameter(name) !=null)  
                req.getSession().setAttribute(name, req.getParameter(name));  
           }  
           if(req.getParameter(name)==null){  
                value=(String)req.getSession().getAttribute(name);  
           }  
           return value;  
      }  
 }  

project structure image :


maven library dependency: