Multiple read requests data in Request

Source: Internet
Author: User

If the request is a get method, the specified parameters can be read directly through the GetParameter (String param) method, which can be read multiple times;

The parameters of the post method are stored in the input stream, read only once, and cannot be read multiple times.

Sometimes it is necessary to print the request parameters in the filter, so the input stream in the POST request is read in the filter, which causes the request parameter not to be taken from the controller.

Workaround:

    • Using Threadlocal, the read post parameter is stored in the filter in Threadlocal, and the controller can then read the request parameter from the threadlocal.
    • The ability to implement multiple reads using the Httpservletrequestwrapper class provided by the servlet, overriding the related ServletRequest method

1.ThreadLocal method

Threadlocal implementation:

 Public classThreadcache {
The Threadlocal store only simple string objects, and you can define your own objects to store more complex parameters.Private StaticThreadlocal<string> ThreadLocal =NewThreadlocal<string>(); Public StaticString getpostrequestparams{returnThreadlocal.get (); } Public Static voidsetpostrequestparams (String postrequestparams) {threadlocal.set (postrequestparams); } Public Static voidRemovepostrequestparams () {threadlocal.remove (); }}

A simple filter:

Importorg.apache.commons.io.IOUtils;ImportOrg.slf4j.Logger;Importorg.slf4j.LoggerFactory;Importjavax.servlet.*;ImportJavax.servlet.annotation.WebFilter;Importjavax.servlet.http.HttpServletRequest;ImportJavax.servlet.http.HttpServletResponse;Importjava.io.IOException;/*** Created by EndStart on 16/12/19.*/@WebFilter (Value= {"/test/threadlocal/*"}) Public classSimplefilterImplementsFilter {Private StaticLogger log = Loggerfactory.getlogger (simplefilter.class); @Override Public voidInit (Filterconfig filterconfig)throwsservletexception {} @Override Public voidDoFilter (ServletRequest request, servletresponse response, Filterchain chain)throwsIOException, servletexception {httpservletrequest req=(httpservletrequest) request; HttpServletResponse Res=(httpservletresponse) response; Try {            if("POST". Equals (Req.getmethod (). toUpperCase ())) {
Get Request Parametersbyte[] bytes =Ioutils.tobytearray (Request.getinputstream ()); String params=NewString (bytes, req.getcharacterencoding ()); Threadcache.setpostrequestparams (params); Log.info ("Filer-post request parameter: [params={}]", params); } Else{log.info ("Non-POST request"); } chain.dofilter (request, response); } Catch(Exception e) {log.error (E.getmessage (), E); }} @Override Public voiddestroy () {}}

A simple test controller:

ImportCom.sankuai.xm.ems.auth.filter.ThreadCache;ImportOrg.slf4j.Logger;Importorg.slf4j.LoggerFactory;ImportOrg.springframework.stereotype.Controller;Importorg.springframework.web.bind.annotation.RequestMapping;ImportOrg.springframework.web.bind.annotation.RequestMethod;ImportOrg.springframework.web.bind.annotation.ResponseBody;/*** Created by EndStart on 16/12/19.*/@Controller @requestmapping ("/test") Public classTestController {Private StaticLogger log = Loggerfactory.getlogger (TestController.class); @RequestMapping (Value= "/threadlocal/getpostrequestparams", method =requestmethod.post) @ResponseBody Public voidGetpostrequestparams () {String params=Threadcache.getpostrequestparams (); Log.info ("Controller-post request parameter: [params={}]", params); }}

Here we only save the post parameters, read from the threadlocal repeatedly, and the Get method needs to be obtained from the request;

2.HttpServletRequestWrapper method

Implement a Httpservletrequestwrapper subclass:

Importorg.apache.commons.io.IOUtils;ImportJavax.servlet.ReadListener;ImportJavax.servlet.ServletInputStream;Importjavax.servlet.http.HttpServletRequest;ImportJavax.servlet.http.HttpServletRequestWrapper;ImportJava.io.*;/*** Created by EndStart on 16/11/30.*/ Public classWrappedhttpservletrequestextendsHttpservletrequestwrapper {Private byte[] bytes; PrivateWrappedservletinputstream Wrappedservletinputstream;  PublicWrappedhttpservletrequest (HttpServletRequest request)throwsIOException {Super(Request); //read the request parameters in the input stream and save them in the bytes .bytes =Ioutils.tobytearray (Request.getinputstream ()); Bytearrayinputstream Bytearrayinputstream=Newbytearrayinputstream (bytes);  This. Wrappedservletinputstream =NewWrappedservletinputstream (Bytearrayinputstream);

It is important to write back the post parameters to the request streamRewriteinputstream (); } /*** Re-write the parameters into the request.*/ Public voidRewriteinputstream () {Wrappedservletinputstream.setstream (NewBytearrayinputstream (Bytes! =NULL? Bytes:New byte[0])); } @Override PublicServletInputStream getInputStream ()throwsIOException {returnWrappedservletinputstream; } @Override PublicBufferedReader Getreader ()throwsIOException {return NewBufferedReader (NewInputStreamReader (Wrappedservletinputstream)); } /*** Get post parameters, you can convert to the appropriate format*/ PublicString Getrequestparams ()throwsIOException {return NewString (Bytes, This. getcharacterencoding ()); } Private classWrappedservletinputstreamextendsServletInputStream { Public voidSetStream (InputStream stream) { This. Stream =stream; } PrivateInputStream Stream; PublicWrappedservletinputstream (InputStream stream) { This. Stream =stream; } @Override Public intRead ()throwsIOException {returnStream.read (); } @Override Public Booleanisfinished () {return true; } @Override Public BooleanIsReady () {return true; } @Override Public voidSetreadlistener (Readlistener readlistener) {}}}

Implement another filter:

Importcom.sankuai.xm.ems.utils.wrap.WrappedHttpServletRequest;ImportOrg.slf4j.Logger;Importorg.slf4j.LoggerFactory;Importjavax.servlet.*;ImportJavax.servlet.annotation.WebFilter;Importjavax.servlet.http.HttpServletRequest;Importjava.io.IOException;/*** Created by EndStart on 16/12/19.*/@WebFilter (Value= {"/test/wrapped/*"}) Public classSimplewrappedfilterImplementsFilter {Private StaticLogger log = Loggerfactory.getlogger (simplewrappedfilter.class); @Override Public voidInit (Filterconfig filterconfig)throwsservletexception {} @Override Public voidDoFilter (ServletRequest request, servletresponse response, Filterchain chain)throwsIOException, servletexception {Try{wrappedhttpservletrequest Requestwrapper=Newwrappedhttpservletrequest ((httpservletrequest) request); if("POST". Equals (Requestwrapper.getmethod (). toUpperCase ())) {
Get request parameter String params=Requestwrapper.getrequestparams (); Log.info ("Filer-post request parameter: [params={}]", params); } Else{log.info ("Non-POST request"); } //here Dofilter passed in the subclass we implementedChain.dofilter (requestwrapper, response); } Catch(Exception e) {log.error (E.getmessage (), E); }} @Override Public voiddestroy () {}}

We add a new approach to the above TestController:

 @RequestMapping (value = "/wrapped/getpostrequestparams", Method = //  public void Getpostrequestparams (@RequestBody String params) { public  " Span style= "COLOR: #0000ff" >void  getpostrequestparams (httpservletrequest request) throws   exception{ byte  [] bytes = Ioutils.tobytearray (Request.getinputstream ()); string params  = new   String (bytes,                Request.getcharacterencoding ());    Log.info ( controller-post request parameter: [params={}] "

In this method, we have implemented the Wrappedhttpservletrequest class in Simplewrappedfilter, whose constructor automatically reads the input stream in the ServletRequest and saves the data. Finally, the data is re-written to ServletRequest, allowing Cotroller to read the input parameters again from the request.

Multiple read requests data in Request

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.