今天项目遇到一个问题,我们项目用户验证和权限验证的信息(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. package org.springframework.web.filter;
  17. import java.io.IOException;
  18. import java.util.Locale;
  19. import javax.servlet.FilterChain;
  20. import javax.servlet.ServletException;
  21. import javax.servlet.http.HttpServletRequest;
  22. import javax.servlet.http.HttpServletRequestWrapper;
  23. import javax.servlet.http.HttpServletResponse;
  24. import org.springframework.util.Assert;
  25. import org.springframework.util.StringUtils;
  26. /**
  27. * {@link javax.servlet.Filter} that converts posted method parameters into HTTP methods,
  28. * retrievable via {@link HttpServletRequest#getMethod()}. Since browsers currently only
  29. * support GET and POST, a common technique - used by the Prototype library, for instance -
  30. * is to use a normal POST with an additional hidden form field ({@code _method})
  31. * to pass the "real" HTTP method along. This filter reads that parameter and changes
  32. * the {@link HttpServletRequestWrapper#getMethod()} return value accordingly.
  33. *
  34. * <p>The name of the request parameter defaults to {@code _method}, but can be
  35. * adapted via the {@link #setMethodParam(String) methodParam} property.
  36. *
  37. * <p><b>NOTE: This filter needs to run after multipart processing in case of a multipart
  38. * POST request, due to its inherent need for checking a POST body parameter.</b>
  39. * So typically, put a Spring {@link org.springframework.web.multipart.support.MultipartFilter}
  40. * <i>before</i> this HiddenHttpMethodFilter in your {@code web.xml} filter chain.
  41. *
  42. * @author Arjen Poutsma
  43. * @since 3.0
  44. */
  45. public class HiddenHttpMethodFilter extends OncePerRequestFilter {
  46. /** Default method parameter: {@code _method} */
  47. public static final String DEFAULT_METHOD_PARAM = "_method";
  48. private String methodParam = DEFAULT_METHOD_PARAM;
  49. /**
  50. * Set the parameter name to look for HTTP methods.
  51. * @see #DEFAULT_METHOD_PARAM
  52. */
  53. public void setMethodParam(String methodParam) {
  54. Assert.hasText(methodParam, "'methodParam' must not be empty");
  55. this.methodParam = methodParam;
  56. }
  57. @Override
  58. protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  59. throws ServletException, IOException {
  60. String paramValue = request.getParameter(this.methodParam);
  61. if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
  62. String method = paramValue.toUpperCase(Locale.ENGLISH);
  63. HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
  64. filterChain.doFilter(wrapper, response);
  65. }
  66. else {
  67. filterChain.doFilter(request, response);
  68. }
  69. }
  70. /**
  71. * Simple {@link HttpServletRequest} wrapper that returns the supplied method for
  72. * {@link HttpServletRequest#getMethod()}.
  73. */
  74. private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
  75. private final String method;
  76. public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
  77. super(request);
  78. this.method = method;
  79. }
  80. @Override
  81. public String getMethod() {
  82. return this.method;
  83. }
  84. }
  85. }

重点我们来看他写的HttpMethodRequestWrapper这个内部类,这个类继承HttpServletRequestWrapper,而HttpServletRequestWrapper我进去看了下都是调用更上层的方法自己并没有做什么事情,再往上我就没去看了。我理解的他的原理是:request在得到method时时使用getMethod方法的,所以他重写了getMethod方法,从而可以把_method的值当做method。

那么既然这样,我也可以把_header的值当做header啊,而request获取header的方法是public String getHeader(String name),所以我就写了下面这样的过滤器:

  1. package com.zs.tools;
  2. import java.io.IOException;
  3. import javax.servlet.FilterChain;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletRequestWrapper;
  7. import javax.servlet.http.HttpServletResponse;
  8. import org.springframework.web.filter.HiddenHttpMethodFilter;
  9. /**
  10. * 张顺,2017-2-28
  11. * 处理form表单头的过滤器,
  12. * 如果表单有_header字段,可以自动将该字段转为request的header头信息(增加一条头)
  13. * @author it023
  14. */
  15. public class MyHiddenHttpMethodFilter extends HiddenHttpMethodFilter{
  16. @Override
  17. protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  18. throws ServletException, IOException {
  19. String header=request.getParameter("_header");
  20. if (header!=null && !header.trim().equals("")) {
  21. HttpServletRequest wrapper = new HttpHeaderRequestWrapper(request,header);
  22. super.doFilterInternal(wrapper, response, filterChain);
  23. }else {
  24. super.doFilterInternal(request, response, filterChain);
  25. }
  26. }
  27. private static class HttpHeaderRequestWrapper extends HttpServletRequestWrapper{
  28. private final String header;
  29. public HttpHeaderRequestWrapper(HttpServletRequest request,String licence) {
  30. super(request);
  31. this.header=licence;
  32. }
  33. @Override
  34. public String getHeader(String name) {
  35. if (name!=null &&
  36. name.equals("licence") &&
  37. super.getHeader("licence")==null) {
  38. return header;
  39. }else {
  40. return super.getHeader(name);
  41. }
  42. }
  43. }
  44. }

然后,在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

spring 接收_header 作为get请求的httpheader的更多相关文章

  1. Spring MVC体系结构和处理请求控制器

    Spring MVC体系结构和处理请求控制器 一:MVC设计模式: (1.)数据访问接口:DAO层 (2.)处理业务逻辑层:Service层 (3.)数据实体:POJO (4.)负责前段请求接受并处理 ...

  2. Spring Boot中扩展XML请求和响应的支持

    在Spring Boot中,我们大多时候都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一 ...

  3. spring接收json字符串的两种方式

    一.前言 前几天遇到一个问题,前端H5调用我的springboot一个接口(post方式,@RequestParameter接收参数),传入的参数接收不到.自己测试接口时使用postman的form- ...

  4. Spring接收数据,传递数据

    Spring接收数据,传递数据 前提配置 POM   <dependency> <groupId>org.springframework</groupId> < ...

  5. Spring MVC 原理探秘 - 一个请求的旅行过程

    1.简介 在前面的文章中,我较为详细的分析了 Spring IOC 和 AOP 部分的源码,并写成了文章.为了让我的 Spring 源码分析系列文章更为丰富一些,所以从本篇文章开始,我将来向大家介绍一 ...

  6. Spring MVC的handlermapping之请求分发如何找到正确的Handler(BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping)

    本文讲的是Spring MVC如何找到正确的handler, 前面请求具体怎么进入到下面的方法,不再细说. 大概就是Spring mvc通过servlet拦截请求,实现doService方法,然后进入 ...

  7. 反向代理:是指以代理server来接收Internet上的请求,然后将请求转发到内部网络的server上,并将结果返回给Internet上连接的client,此时的代理server对外就表现为反向代理server。

       Nginx安装好之后.開始使用它来简单实现反向代理与负载均衡的功能.在这之前.首先得脑补一下什么是反向代理和负载均衡.   反向代理:是指以代理server来接收Internet上的请求,然后将 ...

  8. Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理

    Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理   本文链接:https://blog.csdn.net/puhaiyang/article/details/78146620 ...

  9. Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题

    Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题 继实现动态修改请求 Body 以及重试带 Body 的请求之后,我们又遇到了一个小问题.最近很多接口,收到 ...

随机推荐

  1. kb-01-e<取余操作,宽搜,巧妙>;

    题目描述: n属于1到200,找到对应的一个数只含有0和1,并且是n的倍数: 分析: 本题有几个数会是大数:所以要考虑大数: 用到余数的性质:例如n=6,1%6=1: 1*10%6=4:       ...

  2. ACM程序设计选修课——1044: (ds:队列)打印队列(queue模拟)

    问题 A: (ds:队列)打印队列 时间限制: 1 Sec  内存限制: 128 MB 提交: 25  解决: 4 [提交][状态][讨论版] 题目描述 网络工程实验室只有一台打印机,它承担了非常繁重 ...

  3. P3919 (模板)可持久化数组 (主席树)

    题目链接 Solution 主席树水题,连差分的部分都不需要用到. 直接用主席树的结构去存一下就好了. Code #include<bits/stdc++.h> #define mid ( ...

  4. 【bzoj2301】[HAOI2011]Problem b 莫比乌斯反演

    Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数 ...

  5. 移动web端使用rem实现自适应原理

    1.先获取到物理像素和实际像素的像素比 var pixclPatio = 1 / window.devicePixelRatio; 2.viewport视口设置为像素比大小 document.writ ...

  6. jrebel 激活

    jrebel idea插件激活,亲测可用: 在jrebel server处,写上: http://139.199.89.239:1008/88414687-3b91-4286-89ba-2dc813b ...

  7. 标准C程序设计七---50

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  8. CSS3自定义滚动条

    webkit支持拥有overflow属性的区域,列表框,下拉菜单,textarea的滚动条自定义样式,不过由于用到了CSS3的属性,兼容性不好 看下滚动条demo:demo1(纯CSS3版) 滚动条的 ...

  9. Vijos 1323: 化工厂装箱员

    题形:DP 题意:A,B,C三种物品,一共N个,顺序摆放,按顺序拿.每次手上最多能拿10个物品,然后可以将某个类别的物品分类放好,再从剩下的拿,补全10个.问最少放几次,可以把所有物品分类好. 思路: ...

  10. 拖拽排序插件 ---- Dragula

    相关链接:  https://github.com/bevacqua/react-dragula https://github.com/bevacqua/react-dragula demo:  ht ...