zoukankan      html  css  js  c++  java
  • spring 接收_header 作为get请求的httpheader

    今天项目遇到一个问题,我们项目用户验证和权限验证的信息(licence)是在http头中设置的,百度了一下,只有ajax才能设置头信息,form表单是无法设置的,但是我突然想起springMVC关于form表单解决put、delete提交方式的问题,我灵机一动,于是模仿springMVC实现了设置自定义header的功能。  

    起源

    项目使用的是SSM框架,废话不多说,我们先看springMVC对于form表单提交put、delete请求问题的解决方案,springMVC是使用了一个过滤器,使之用用户只需在form表单增加一个隐藏域_method即可,比如下面这样:

    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中配置是这样的

    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的源码:

    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),所以我就写了下面这样的过滤器:

    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前面的。

    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

  • 相关阅读:
    javaScript
    CSS
    HTML
    折纸 (模拟)
    不等式(数学)
    周期串查询
    大集训模拟赛十一
    大假期集训模拟赛十
    P1631 序列合并
    KMP(烤馍片)算法
  • 原文地址:https://www.cnblogs.com/tiancai/p/8080372.html
Copyright © 2011-2022 走看看