How to create duplicate object of httpServletRequest object

Posted By : Deepak Agrawal | 16-Dec-2014

This blog helps to create duplicate object or proxy of httpServletRequest using HttpServletRequestWrapper class provided by apache.

So that you can call getInputStream() and getReader() several times withOut getting IllegalStateException: errors.GrailsExceptionResolver - getInputStream() has already been called for this request and solve the bug https://jira.grails.org/browse/GRAILS-6372 on JIRA.

 

So first we have to create a class RequestWrapper that must implement HttpServletRequestWrapper. And in this class we have to read input data from httpServletRequest object. And by overriding getInputStream() and getReader() methods, we can call these methods infinite times.

package com.dcx.secured;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 *
 * @author deepak agrawal
 *
 *         this class stops reading the request payload twice causing an
 *         exception
 */

public class RequestWrapper extends HttpServletRequestWrapper {
	
	private String _body;

	public RequestWrapper(HttpServletRequest request) throws IOException {
		super(request);
		_body = "";
		BufferedReader bufferedReader = request.getReader();			
		String line;
		while ((line = bufferedReader.readLine()) != null){
			_body += line;
		}
	}

	@Override
	public ServletInputStream getInputStream() throws IOException {
		final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(_body.getBytes());
		return new ServletInputStream() {
			public int read() throws IOException {
				return byteArrayInputStream.read();
			}
		};
	}

	@Override
	public BufferedReader getReader() throws IOException {
		return new BufferedReader(new InputStreamReader(this.getInputStream()));
	}
}


 

Now we can create object of these object as we require by passing httpServletRequest object in constructore.

Example in my case I have to call getInputStream() on request object first in filtor and again in controllers.

Ex:-

@Override
	public void doFilter(ServletRequest request, ServletResponse response,FilterChain filterChain) throws IOException, ServletException {
		try {
			HttpServletRequest properRequest = ((HttpServletRequest) request);
			RequestWrapper wrappedRequest = new RequestWrapper(properRequest);
			request = wrappedRequest;
			
			JSONObject object=(JSONObject)JSON.parse(request.getReader()); 
			Object username=object.get("username"); 
			if(username!=null){ 
				 UserService userService=(UserService)SpringUtils.getSpringBean("userService"); 
				 String naame=(String)username;
				 if(!userService.isUserActive(naame)){ 
					 ((HttpServletResponse)response).setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
					 return;
				 }	 
			}
			filterChain.doFilter(request, response);
		} catch (Exception exception) {
			((HttpServletResponse) response).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "ERROR");
			System.out.println("LoginFilter.doFilter() exception: "+exception.getMessage());
		}
	}

 

Thank You

About Author

Author Image
Deepak Agrawal

Deepak is an bright developer with experience in Groovy and Grails. He is well versed with AngularJS.

Request for Proposal

Name is required

Comment is required

Sending message..