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
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Deepak Agrawal
Deepak is an bright developer with experience in Groovy and Grails. He is well versed with AngularJS.