spring 接收_header 作為get請求的httpheader


今天項目遇到一個問題,我們項目用戶驗證和權限驗證的信息(licence)是在http頭中設置的,百度了一下,只有ajax才能設置頭信息,form表單是無法設置的,但是我突然想起springMVC關於form表單解決put、delete提交方式的問題,我靈機一動,於是模仿springMVC實現了設置自定義header的功能。  

起源

項目使用的是SSM框架,廢話不多說,我們先看springMVC對於form表單提交put、delete請求問題的解決方案,springMVC是使用了一個過濾器,使之用用戶只需在form表單增加一個隱藏域_method即可,比如下面這樣:

[html] view plain copy
  1. <form id="fm" method="post" >  
  2.         <input type="hidden" name="_method" value="put"/>  
  3.         <input type="hidden" name="_header" value="${licence }"/>  
  4.         <div class="fitem">  
  5.             <label>uNum:</label>  
  6.             <input name="uNum" class="easyui-validatebox" required="true">  
  7.         </div>  
  8.         <div class="fitem">  
  9.             <label>uPass:</label>  
  10.             <input name="uPass" class="easyui-validatebox" required="true">  
  11.         </div>  
  12.         <div class="fitem">  
  13.             <label>uName:</label>  
  14.             <input name="uName" class="easyui-validatebox" required="true">  
  15.         </div>  
  16.         <div class="fitem">  
  17.             <label>csId:</label>  
  18.             <input name="csId" class="easyui-validatebox" required="true">  
  19.         </div>  
  20.         <div class="fitem">  
  21.             <label>uJob:</label>  
  22.             <input name="uJob" class="easyui-validatebox" required="true">  
  23.         </div>  
  24.         <div class="fitem">  
  25.             <label>uStartTime:</label>  
  26.             <input name="uStartTime" class="easyui-validatebox" required="true">  
  27.         </div>  
  28.         <div class="fitem">  
  29.             <label>rId:</label>  
  30.             <input name="rId" class="easyui-validatebox" required="true">  
  31.         </div>  
  32.         <div class="fitem">  
  33.             <label>uMail:</label>  
  34.             <input name="uMail" class="easyui-validatebox" validType="email" required="true">  
  35.         </div>  
  36.         <div class="fitem">  
  37.             <label>uState:</label>  
  38.             <input name="uState" class="easyui-validatebox" required="true">  
  39.         </div>  
  40.     </form>  

_method里的值就是你要提交方式,具體情況大家自己百度我就細說了。

實現

springmvc在web.xml中配置是這樣的

[html] view plain copy
  1. <filter>  
  2.         <filter-name>httpMethodFilter</filter-name>  
  3.         <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
  4.     </filter>  
  5.     <filter-mapping>  
  6.         <filter-name>httpMethodFilter</filter-name>  
  7.         <servlet-name>SpringMVC</servlet-name>  
  8.     </filter-mapping>  

然后我們來看springMVC的源碼:

[java] view plain copy
  1. /* 
  2.  * Copyright 2002-2012 the original author or authors. 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package org.springframework.web.filter;  
  18.   
  19. import java.io.IOException;  
  20. import java.util.Locale;  
  21. import javax.servlet.FilterChain;  
  22. import javax.servlet.ServletException;  
  23. import javax.servlet.http.HttpServletRequest;  
  24. import javax.servlet.http.HttpServletRequestWrapper;  
  25. import javax.servlet.http.HttpServletResponse;  
  26.   
  27. import org.springframework.util.Assert;  
  28. import org.springframework.util.StringUtils;  
  29.   
  30. /** 
  31.  * {@link javax.servlet.Filter} that converts posted method parameters into HTTP methods, 
  32.  * retrievable via {@link HttpServletRequest#getMethod()}. Since browsers currently only 
  33.  * support GET and POST, a common technique - used by the Prototype library, for instance - 
  34.  * is to use a normal POST with an additional hidden form field ({@code _method}) 
  35.  * to pass the "real" HTTP method along. This filter reads that parameter and changes 
  36.  * the {@link HttpServletRequestWrapper#getMethod()} return value accordingly. 
  37.  * 
  38.  * <p>The name of the request parameter defaults to {@code _method}, but can be 
  39.  * adapted via the {@link #setMethodParam(String) methodParam} property. 
  40.  * 
  41.  * <p><b>NOTE: This filter needs to run after multipart processing in case of a multipart 
  42.  * POST request, due to its inherent need for checking a POST body parameter.</b> 
  43.  * So typically, put a Spring {@link org.springframework.web.multipart.support.MultipartFilter} 
  44.  * <i>before</i> this HiddenHttpMethodFilter in your {@code web.xml} filter chain. 
  45.  * 
  46.  * @author Arjen Poutsma 
  47.  * @since 3.0 
  48.  */  
  49. public class HiddenHttpMethodFilter extends OncePerRequestFilter {  
  50.   
  51.     /** Default method parameter: {@code _method} */  
  52.     public static final String DEFAULT_METHOD_PARAM = "_method";  
  53.   
  54.     private String methodParam = DEFAULT_METHOD_PARAM;  
  55.   
  56.   
  57.     /** 
  58.      * Set the parameter name to look for HTTP methods. 
  59.      * @see #DEFAULT_METHOD_PARAM 
  60.      */  
  61.     public void setMethodParam(String methodParam) {  
  62.         Assert.hasText(methodParam, "'methodParam' must not be empty");  
  63.         this.methodParam = methodParam;  
  64.     }  
  65.   
  66.     @Override  
  67.     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  
  68.             throws ServletException, IOException {  
  69.   
  70.         String paramValue = request.getParameter(this.methodParam);  
  71.         if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {  
  72.             String method = paramValue.toUpperCase(Locale.ENGLISH);  
  73.             HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);  
  74.             filterChain.doFilter(wrapper, response);  
  75.         }  
  76.         else {  
  77.             filterChain.doFilter(request, response);  
  78.         }  
  79.     }  
  80.   
  81.   
  82.     /** 
  83.      * Simple {@link HttpServletRequest} wrapper that returns the supplied method for 
  84.      * {@link HttpServletRequest#getMethod()}. 
  85.      */  
  86.     private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {  
  87.   
  88.         private final String method;  
  89.   
  90.         public HttpMethodRequestWrapper(HttpServletRequest request, String method) {  
  91.             super(request);  
  92.             this.method = method;  
  93.         }  
  94.   
  95.         @Override  
  96.         public String getMethod() {  
  97.             return this.method;  
  98.         }  
  99.     }  
  100.   
  101. }  

重點我們來看他寫的HttpMethodRequestWrapper這個內部類,這個類繼承HttpServletRequestWrapper,而HttpServletRequestWrapper我進去看了下都是調用更上層的方法自己並沒有做什么事情,再往上我就沒去看了。我理解的他的原理是:request在得到method時時使用getMethod方法的,所以他重寫了getMethod方法,從而可以把_method的值當做method。

那么既然這樣,我也可以把_header的值當做header啊,而request獲取header的方法是public String getHeader(String name),所以我就寫了下面這樣的過濾器:

[java] view plain copy
  1. package com.zs.tools;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.FilterChain;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletRequestWrapper;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import org.springframework.web.filter.HiddenHttpMethodFilter;  
  11.   
  12.   
  13. /** 
  14.  * 張順,2017-2-28 
  15.  * 處理form表單頭的過濾器, 
  16.  * 如果表單有_header字段,可以自動將該字段轉為request的header頭信息(增加一條頭) 
  17.  * @author it023 
  18.  */  
  19. public class MyHiddenHttpMethodFilter extends HiddenHttpMethodFilter{  
  20.   
  21.       
  22.     @Override  
  23.     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  
  24.             throws ServletException, IOException {  
  25.         String header=request.getParameter("_header");  
  26.         if (header!=null && !header.trim().equals("")) {  
  27.             HttpServletRequest wrapper = new HttpHeaderRequestWrapper(request,header);  
  28.             super.doFilterInternal(wrapper, response, filterChain);  
  29.         }else {  
  30.             super.doFilterInternal(request, response, filterChain);  
  31.         }  
  32.     }  
  33.       
  34.     private static class HttpHeaderRequestWrapper extends HttpServletRequestWrapper{  
  35.   
  36.         private final String header;  
  37.           
  38.         public HttpHeaderRequestWrapper(HttpServletRequest request,String licence) {  
  39.             super(request);  
  40.             this.header=licence;  
  41.         }  
  42.   
  43.         @Override  
  44.         public String getHeader(String name) {  
  45.             if (name!=null &&   
  46.                     name.equals("licence") &&   
  47.                     super.getHeader("licence")==null) {  
  48.                 return header;  
  49.             }else {  
  50.                 return super.getHeader(name);  
  51.             }  
  52.         }  
  53.           
  54.     }  
  55.       
  56.       
  57. }  

然后,在web.xml中配置一下,我是放在HiddenHttpMethodFilter前面的。

[html] view plain copy
  1. <filter>  
  2.         <filter-name>httpHeaderFilter</filter-name>  
  3.         <filter-class>com.zs.tools.MyHiddenHttpMethodFilter</filter-class>  
  4.     </filter>  
  5.     <filter-mapping>  
  6.         <filter-name>httpHeaderFilter</filter-name>  
  7.         <servlet-name>SpringMVC</servlet-name>  
  8.     </filter-mapping>  

結果

結果很成功,具體的代碼我不想貼了,請看日志,這一條表示獲取到http頭的licence(不要在意licence為什么這么簡單,那是因為這是測試數據)。

 

轉自http://blog.csdn.net/fe123rarwa14235pp/article/details/58607296


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM