spring 接收_header 作为get请求的httpheader
今天项目遇到一个问题,我们项目用户验证和权限验证的信息(licence)是在http头中设置的,百度了一下,只有ajax才能设置头信息,form表单是无法设置的,但是我突然想起springMVC关于form表单解决put、delete提交方式的问题,我灵机一动,于是模仿springMVC实现了设置自定义header的功能。
起源
项目使用的是SSM框架,废话不多说,我们先看springMVC对于form表单提交put、delete请求问题的解决方案,springMVC是使用了一个过滤器,使之用用户只需在form表单增加一个隐藏域_method即可,比如下面这样:
- <form id="fm" method="post" >
- <input type="hidden" name="_method" value="put"/>
- <input type="hidden" name="_header" value="${licence }"/>
- <div class="fitem">
- <label>uNum:</label>
- <input name="uNum" class="easyui-validatebox" required="true">
- </div>
- <div class="fitem">
- <label>uPass:</label>
- <input name="uPass" class="easyui-validatebox" required="true">
- </div>
- <div class="fitem">
- <label>uName:</label>
- <input name="uName" class="easyui-validatebox" required="true">
- </div>
- <div class="fitem">
- <label>csId:</label>
- <input name="csId" class="easyui-validatebox" required="true">
- </div>
- <div class="fitem">
- <label>uJob:</label>
- <input name="uJob" class="easyui-validatebox" required="true">
- </div>
- <div class="fitem">
- <label>uStartTime:</label>
- <input name="uStartTime" class="easyui-validatebox" required="true">
- </div>
- <div class="fitem">
- <label>rId:</label>
- <input name="rId" class="easyui-validatebox" required="true">
- </div>
- <div class="fitem">
- <label>uMail:</label>
- <input name="uMail" class="easyui-validatebox" validType="email" required="true">
- </div>
- <div class="fitem">
- <label>uState:</label>
- <input name="uState" class="easyui-validatebox" required="true">
- </div>
- </form>
_method里的值就是你要提交方式,具体情况大家自己百度我就细说了。
实现
springmvc在web.xml中配置是这样的
- <filter>
- <filter-name>httpMethodFilter</filter-name>
- <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>httpMethodFilter</filter-name>
- <servlet-name>SpringMVC</servlet-name>
- </filter-mapping>
然后我们来看springMVC的源码:
- /*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.springframework.web.filter;
- import java.io.IOException;
- import java.util.Locale;
- import javax.servlet.FilterChain;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletRequestWrapper;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.util.Assert;
- import org.springframework.util.StringUtils;
- /**
- * {@link javax.servlet.Filter} that converts posted method parameters into HTTP methods,
- * retrievable via {@link HttpServletRequest#getMethod()}. Since browsers currently only
- * support GET and POST, a common technique - used by the Prototype library, for instance -
- * is to use a normal POST with an additional hidden form field ({@code _method})
- * to pass the "real" HTTP method along. This filter reads that parameter and changes
- * the {@link HttpServletRequestWrapper#getMethod()} return value accordingly.
- *
- * <p>The name of the request parameter defaults to {@code _method}, but can be
- * adapted via the {@link #setMethodParam(String) methodParam} property.
- *
- * <p><b>NOTE: This filter needs to run after multipart processing in case of a multipart
- * POST request, due to its inherent need for checking a POST body parameter.</b>
- * So typically, put a Spring {@link org.springframework.web.multipart.support.MultipartFilter}
- * <i>before</i> this HiddenHttpMethodFilter in your {@code web.xml} filter chain.
- *
- * @author Arjen Poutsma
- * @since 3.0
- */
- public class HiddenHttpMethodFilter extends OncePerRequestFilter {
- /** Default method parameter: {@code _method} */
- public static final String DEFAULT_METHOD_PARAM = "_method";
- private String methodParam = DEFAULT_METHOD_PARAM;
- /**
- * Set the parameter name to look for HTTP methods.
- * @see #DEFAULT_METHOD_PARAM
- */
- public void setMethodParam(String methodParam) {
- Assert.hasText(methodParam, "'methodParam' must not be empty");
- this.methodParam = methodParam;
- }
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
- String paramValue = request.getParameter(this.methodParam);
- if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
- String method = paramValue.toUpperCase(Locale.ENGLISH);
- HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
- filterChain.doFilter(wrapper, response);
- }
- else {
- filterChain.doFilter(request, response);
- }
- }
- /**
- * Simple {@link HttpServletRequest} wrapper that returns the supplied method for
- * {@link HttpServletRequest#getMethod()}.
- */
- private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
- private final String method;
- public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
- super(request);
- this.method = method;
- }
- @Override
- public String getMethod() {
- return this.method;
- }
- }
- }
重点我们来看他写的HttpMethodRequestWrapper这个内部类,这个类继承HttpServletRequestWrapper,而HttpServletRequestWrapper我进去看了下都是调用更上层的方法自己并没有做什么事情,再往上我就没去看了。我理解的他的原理是:request在得到method时时使用getMethod方法的,所以他重写了getMethod方法,从而可以把_method的值当做method。
那么既然这样,我也可以把_header的值当做header啊,而request获取header的方法是public String getHeader(String name),所以我就写了下面这样的过滤器:
- package com.zs.tools;
- import java.io.IOException;
- import javax.servlet.FilterChain;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletRequestWrapper;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.web.filter.HiddenHttpMethodFilter;
- /**
- * 张顺,2017-2-28
- * 处理form表单头的过滤器,
- * 如果表单有_header字段,可以自动将该字段转为request的header头信息(增加一条头)
- * @author it023
- */
- public class MyHiddenHttpMethodFilter extends HiddenHttpMethodFilter{
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
- String header=request.getParameter("_header");
- if (header!=null && !header.trim().equals("")) {
- HttpServletRequest wrapper = new HttpHeaderRequestWrapper(request,header);
- super.doFilterInternal(wrapper, response, filterChain);
- }else {
- super.doFilterInternal(request, response, filterChain);
- }
- }
- private static class HttpHeaderRequestWrapper extends HttpServletRequestWrapper{
- private final String header;
- public HttpHeaderRequestWrapper(HttpServletRequest request,String licence) {
- super(request);
- this.header=licence;
- }
- @Override
- public String getHeader(String name) {
- if (name!=null &&
- name.equals("licence") &&
- super.getHeader("licence")==null) {
- return header;
- }else {
- return super.getHeader(name);
- }
- }
- }
- }
然后,在web.xml中配置一下,我是放在HiddenHttpMethodFilter前面的。
- <filter>
- <filter-name>httpHeaderFilter</filter-name>
- <filter-class>com.zs.tools.MyHiddenHttpMethodFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>httpHeaderFilter</filter-name>
- <servlet-name>SpringMVC</servlet-name>
- </filter-mapping>
结果
结果很成功,具体的代码我不想贴了,请看日志,这一条表示获取到http头的licence(不要在意licence为什么这么简单,那是因为这是测试数据)。
转自http://blog.csdn.net/fe123rarwa14235pp/article/details/58607296
spring 接收_header 作为get请求的httpheader的更多相关文章
- Spring MVC体系结构和处理请求控制器
Spring MVC体系结构和处理请求控制器 一:MVC设计模式: (1.)数据访问接口:DAO层 (2.)处理业务逻辑层:Service层 (3.)数据实体:POJO (4.)负责前段请求接受并处理 ...
- Spring Boot中扩展XML请求和响应的支持
在Spring Boot中,我们大多时候都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一 ...
- spring接收json字符串的两种方式
一.前言 前几天遇到一个问题,前端H5调用我的springboot一个接口(post方式,@RequestParameter接收参数),传入的参数接收不到.自己测试接口时使用postman的form- ...
- Spring接收数据,传递数据
Spring接收数据,传递数据 前提配置 POM <dependency> <groupId>org.springframework</groupId> < ...
- Spring MVC 原理探秘 - 一个请求的旅行过程
1.简介 在前面的文章中,我较为详细的分析了 Spring IOC 和 AOP 部分的源码,并写成了文章.为了让我的 Spring 源码分析系列文章更为丰富一些,所以从本篇文章开始,我将来向大家介绍一 ...
- Spring MVC的handlermapping之请求分发如何找到正确的Handler(BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping)
本文讲的是Spring MVC如何找到正确的handler, 前面请求具体怎么进入到下面的方法,不再细说. 大概就是Spring mvc通过servlet拦截请求,实现doService方法,然后进入 ...
- 反向代理:是指以代理server来接收Internet上的请求,然后将请求转发到内部网络的server上,并将结果返回给Internet上连接的client,此时的代理server对外就表现为反向代理server。
Nginx安装好之后.開始使用它来简单实现反向代理与负载均衡的功能.在这之前.首先得脑补一下什么是反向代理和负载均衡. 反向代理:是指以代理server来接收Internet上的请求,然后将 ...
- Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理
Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理 本文链接:https://blog.csdn.net/puhaiyang/article/details/78146620 ...
- Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题
Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题 继实现动态修改请求 Body 以及重试带 Body 的请求之后,我们又遇到了一个小问题.最近很多接口,收到 ...
随机推荐
- PHP的发展史,功能与特点
web1.0时代:所有的代码都是在浏览器端执行的静态脚本,用户请求的也都是服务器上事先已经存在的静态网页,用户和服务器之间不能进行任何的交互!(不需要数据库的支持) web2.0时代:用户和服务器之间 ...
- 定时任务管理之python篇celery使用
一.为什么要用celery celery是一个简单.灵活.可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必须工具.他是一个专注于实时处理的任务队列,同时也支持任务调度. celery是异 ...
- JAVA Apache POI 之sax 解析10万级大数量数据
第一步让我们来看看我们的大量数据的excel 文件 好的下面第二步看一下代码: package com.chinait.utils; /** * 写这个东西主要是最近做了一个联通的数据迁移工作,他们就 ...
- Springboot 版本+ jdk 版本 + Maven 版本的匹配
Spring boot 版本 Spring Framework jdk 版本 maven 版本 1.2.0 版本之前 6 3.0 1.2.0 4.1.3+ 6 3.2+ 1.2.1 4.1.3+ 7 ...
- 如何从sql server导出到csv文件
如何从sql server导出到csv文件,具体代码如下: private static void WriteHeader(SqlDataReader reader, TextWriter outpu ...
- node总结--回调函数阻塞和非阻塞代码实例
阻塞代码实例: var fs = require("fs"); var data = fs.readFileSync('input.txt'); console.log(data. ...
- 写了一个可以个性化设置的仿<select>标签
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【Visual Studio】LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_
出现这个问题的原因:工程在转换过程中,发现有一些工程使用MD编译选项,有一些工程使用MTD编译选项,导致静态和动态连接MSVC的连接库有冲突.将全部工程改变MT或MTD编译,即可以解决. 工程 —&g ...
- 标准C程序设计七---106
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- ThinkPHP 5.1 基础知识
==========================================//模板中的默认标题{$title|default='默认标题'}========================= ...