Tag:spring
Category:spring
Article From:https://www.cnblogs.com/yucongblog/p/9122342.html

 Due to the recent use of spring+jersey development, servlet based filter should be set up. Read JSON parameters in body in filter through request.getReader or getInputStream.When processing, the bottom of the rest style Jersey framework is also based on the same principle to read the parameters in the post request body. Because of request’s own principles: getReader or getInputStream can only call one and only one time.The content of body can be obtained normally, resulting in the first reading of the parameters in the body through the getReader in the filter, and when the controller is executed in Jersey, an exception occurs.

java.lang.IllegalStateException: getReader() has already been called for this request。

 

############################

###           Running system: windows8

###          JDKVersion: JDK1.7

###          Framework: spring3x + jersey2.x

###          Developing IDE:MyEclipse

############################

1.0 Configure spring filter filter in web.xml to integrate custom filter

 

[html] view plain copy

 
  1. <filter>  
  2.         <filter-name>DelegateFilter</filter-name>  
  3.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  4.         <init-param>  
  5.             <param-name>targetBeanName</param-name>  
  6.             <param-value>myFilter</param-value<!– Custom interceptor –&gt
  7.         </init-param>  
  8.         <init-param>  
  9.             <param-name>targetFilterLifecycle</param-name>  
  10.             <param-value>true</param-value>  
  11.         </init-param>  
  12.     </filter>  
  13.     <filter-mapping>  
  14.         <filter-name>DelegateFilter</filter-name>  
  15.         <url-pattern>/*</url-pattern>  
  16.     </filter-mapping>  

2.0Define custom filterbean in spring configuration file application.xml.

 

 

[html] view plain copy

 
  1. <bean id=“myFilter” class=“com.cybbj.action.filter.FilterPost”></bean>  
[html] view plain copy

 
  1. PS:If you want to use other bean. in the springIOC container in filter, such as other service classes. It can be configured in this bean. Such
  2. For example, in filter, you need to inject common commonSerivce
  3. public class myFilter implements Filter{  
  4.     private CommonService commonService;  
  5.   
  6. //Need setter
  7.    …….  
  8. }  
[plain] view plain copy

 
  1. If you want to use commonService instead of throwing null pointer exceptions, you need to configure dependencies in bean:
  2. <bean id=”myFilter” class=”com.cybbj.action.filter.FilterPost”>  
  3. <property name=”commonService”> <ref bean=”commonService”/> <!– Among them, commonService is configured by annotations or XML to class –&gt in IOC container; < /property> < /bean>

 

[plain] view plain copy

 
  1. 3.0 Custom filter
  2. The original code and the running results are as follows:

 

[java] view plain copy

 
  1. public class FilterPost implements Filter{  
  2.       
  3.     private Log log = LogFactory.getLog(FilterPost.class);  
  4.   
  5.     String param = “”;  
  6.       
  7.     public void destroy() {  
  8.         // TODO Auto-generated method stub  
  9.           
  10.     }  
  11.   
  12.     public void doFilter(ServletRequest req, ServletResponse res,  
  13.             FilterChain chain) throws IOException, ServletException {  
  14.            HttpServletRequest request = null;  
  15.             if(req instanceof HttpServletRequest) {   
  16.                request = (HttpServletRequest)req;  
  17.             }  
  18.               
  19.             if(“POST”.equalsIgnoreCase(request.getMethod())){  
  20.                 param = this.getBodyString(request.getReader());  
  21.                 log.info(“filterRead the parameters in body: > > > > > > > > > “+param”;
  22.                 chain.doFilter(request, res);  
  23.     }  
  24.           
  25.     }  
  26.   
  27.     public void init(FilterConfig config) throws ServletException {  
  28.           
  29.     }  
[java] view plain copy

 
  1.     //Get the parameter of the parameter in the request request body
  2. lic static String getBodyString(BufferedReader br) {  
  3. String inputLine;  
  4.      String str = “”;  
  5.    try {  
  6.      while ((inputLine = br.readLine()) != null) {  
  7.       str += inputLine;  
  8.      }  
  9.      br.close();  
  10.    } catch (IOException e) {  
  11.      System.out.println(“IOException: ” + e);  
  12.    }  
  13.    return str;  

 

4.0Post request processing in controller based on Jersey

 

[html] view plain copy

 
  1. @POST  
  2. @Path(“/postJson”)  
  3. @Produces(MediaType.APPLICATION_JSON)  
  4. @Consumes(MediaType.APPLICATION_JSON)  
  5. public Map<String, String> postByJson(Map<String, Object> jsonParam) {  
  6.   
  7.     JSONObject jo = new JSONObject(jsonParam);  
  8.     System.out.println(jsonParam);  
  9.     Map<String, Stringparam = new HashMap<String, String>();  
  10.     param.put(“name”, jo.getString(“name”).length()==0? “” : jo.getString(“name”));  
  11.     param.put(“age”, jo.getString(“age”).length()==0  ? “” :jo.getString(“age”));  
  12.     param.put(“status”, “200”);  
  13.     param.put(“Msg”, “ok,success”);  
  14.     return param;  
  15. }  

 

 

[html] view plain copy

 
  1. 5. Abnormity
  2. java.lang.IllegalStateException: getReader() has already been called for this request  
  3.     at org.apache.catalina.connector.Request.getInputStream(Request.java:1085)  

Resolvent:

 

[html] view plain copy

 
  1. This problem is solved by combining JODD open source framework and replacing ServletRequest with ServletRequestWrapper in Filter. Such

 

 

A:Add jodd support:

Add a dependency on jodd in pom.xml:

 

[html] view plain copy

 
  1. <!– https://mvnrepository.com/artifact/org.jodd/jodd-core –>  
  2. <dependency>  
  3. </span><groupId>org.jodd</groupId>  
  4. </span><artifactId>jodd-core</artifactId>  
  5. </span><version>3.4.8</version>  
  6. </dependency>  

 

 

B:Create custom ServletRequestWrapper with jodd

 

[html] view plain copy

 
  1. public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{  
  2.   
  3.      private final byte[] body; //To save the data from the read body
  4.        
  5.         public BodyReaderHttpServletRequestWrapper(HttpServletRequest request)     
  6.     throws IOException {    
  7.             super(request);    
  8.             body = StreamUtil.readBytes(request.getReader(), “UTF-8”);    
  9.         }    
  10.         
  11.         @Override    
  12.         public BufferedReader getReader() throws IOException {    
  13.             return new BufferedReader(new InputStreamReader(getInputStream()));    
  14.         }    
  15.         
  16.         @Override    
  17.         public ServletInputStream getInputStream() throws IOException {    
  18.             final ByteArrayInputStream bais = new ByteArrayInputStream(body);    
  19.             return new ServletInputStream() {    
  20.         
  21.                 @Override    
  22.                 public int read() throws IOException {    
  23.                     return bais.read();    
  24.                 }  
  25.   
  26.                 @Override  
  27.                 public boolean isFinished() {  
  28.                     // TODO Auto-generated method stub  
  29.                     return false;  
  30.                 }  
  31.   
  32.                 @Override  
  33.                 public boolean isReady() {  
  34.                     // TODO Auto-generated method stub  
  35.                     return false;  
  36.                 }  
  37.   
  38.                 @Override  
  39.                 public void setReadListener(ReadListener arg0) {  
  40.                     // TODO Auto-generated method stub  
  41.                       
  42.                 }    
  43.             };    
  44.         }    
  45. }  


C:Replacing request with wrapper to modify filter

 

 

[html] view plain copy

 
  1. public void doFilter(ServletRequest req, ServletResponse res,  
  2.             FilterChain chain) throws IOException, ServletException {  
  3.           String method = “GET”;  
  4.            ServletRequest requestWrapper = null;    
  5.             if(req instanceof HttpServletRequest) {    
  6.                 method = ((HttpServletRequest) req).getMethod();  
  7.                 requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) req);  //Replacement
  8.             }    
  9.               
  10.             if(“POST”.equalsIgnoreCase(method)){  
  11.                 param = this.getBodyString(requestWrapper.getReader());  
  12.                 log.info(“filterRead the parameters in body>>>>>>>>>”+param);  
  13.                 chain.doFilter(requestWrapper, res);  
  14.     }  
  15.           

D:Request test

 

Ask for success…

 

Reference article: http://liwx2000.iteye.com/blog/1542431

 

Original address: https://blog.csdn.net/xiansky2015/article/details/52013690

Leave a Reply

Your email address will not be published. Required fields are marked *