Spring MVC 实现 GET 请求下划线风格参数映射至驼峰风格的类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring MVC 实现 GET 请求下划线风格参数映射至驼峰风格的类相关的知识,希望对你有一定的参考价值。

参考技术A 这里是 Wrapper 的具体实现

主要内容是修改了getParameterNames和getParameterValues的返回值。

继续往里面 Debug 观察mpvs是如何得到的。

发现调用的是WebUtils的getParametersStartingWith方法,继续观察里面的实现。

这里最终发现了可以 hook 的点就是修改getParameterNames和getParameterValues的返回值。这个方法返回的Map的 key 将会用来寻找映射对象的属性来赋值,如果是下划线风格的毫无疑问将会无法匹配而导致赋值失败。所以加 Wrapper 修改getParameterNames的返回值,让获取到的 key 都是驼峰风格的,同步的还要修改getParameterValues保证传入驼峰风格的 key 时也能正常的获取到 value。

Spring MVC过滤器-HiddenHttpMethodFilter

Spring MVC过滤器-HiddenHttpMethodFilter

浏览器form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求,该过滤器为HiddenHttpMethodFilter。

HiddenHttpMethodFilter的父类是OncePerRequestFilter,它继承了父类的doFilterInternal方法,工作原理是将jsp页面的form表单的method属性值在doFilterInternal方法中转化为标准的Http方法,即GET,、POST、 HEAD、OPTIONS、PUT、DELETE、TRACE,然后到Controller中找到对应的方法。例如,在使用注解时我们可能会在Controller中用于@RequestMapping(value = "list", method = RequestMethod.PUT),所以如果你的表单中使用的是

,那么这个表单会被提交到标了Method="PUT"的方法中。

需要注意的是,由于doFilterInternal方法只对method为post的表单进行过滤,所以在页面中必须如下设置:

<form action="..." method="post">
    <input type="hidden" name="_method" value="put" />
        ......
</form>

而不是使用:

<form action="..." method="put">
        ......
</form>

同时,HiddenHttpMethodFilter必须作用于dispatcher前,所以在web.xml中配置HiddenHttpMethodFilter时,需参照如下代码:

        <filter>  
                <filter-name>HiddenHttpMethodFilter</filter-name>  
                <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
        </filter>  
        <filter-mapping>  
                <filter-name>HiddenHttpMethodFilter</filter-name>  
                <servlet-name>spring</servlet-name>  
        </filter-mapping>
        <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:dispatcher.xml</param-value>
        </init-param>
    </servlet>
        <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

下面是一个示例:

<form th:action="@/emp" method="post">  
<!--发送put请求修改员工数据-->
    <!--
1、SpringMVC中配置HiddenHttpMethodFilter;(SpringBoot自动配置好的)
2、页面创建一个post表单
3、创建一个input项,name="_method";值就是我们指定的请求方式
-->
    <input type="hidden" name="_method" value="put" th:if="$emp!=null"/>
    <input type="hidden" name="id" th:if="$emp!=null" th:value="$emp.id">
    <div class="form-group">
        <label>LastName</label>
        <input name="lastName" type="text" class="form-control" placeholder="zhangsan" th:value="$emp!=null?$emp.lastName">
    </div>
    <div class="form-group">
        <label>Email</label>
        <input name="email" type="email" class="form-control" placeholder="[email protected]" th:value="$emp!=null?$emp.email">
    </div>
    <div class="form-group">
        <label>Gender</label><br/>
        <div class="form-check form-check-inline">
            <input class="form-check-input" type="radio" name="gender" value="1" th:checked="$emp!=null?$emp.gender==1">
            <label class="form-check-label">男</label>
        </div>
        <div class="form-check form-check-inline">
            <input class="form-check-input" type="radio" name="gender" value="0" th:checked="$emp!=null?$emp.gender==0">
            <label class="form-check-label">女</label>
        </div>
    </div>
    <div class="form-group">
        <label>department</label>
        <!--提交的是部门的id-->
        <select class="form-control" name="department.id">
            <option th:selected="$emp!=null?$dept.id == emp.department.id" th:value="$dept.id" th:each="dept:$depts" th:text="$dept.departmentName">1</option>
        </select>
    </div>
    <div class="form-group">
        <label>Birth</label>
        <input name="birth" type="text" class="form-control" placeholder="zhangsan" th:value="$emp!=null?$#dates.format(emp.birth, 'yyyy-MM-dd HH:mm')">
    </div>
    <button type="submit" class="btn btn-primary" th:text="$emp!=null?'修改':'添加'">添加</button>
</form>

以上是关于Spring MVC 实现 GET 请求下划线风格参数映射至驼峰风格的类的主要内容,如果未能解决你的问题,请参考以下文章

spring mvc的几种使用方式1

Spring MVC 使用HiddenHttpMethodFilter配置Rest风格的URL

spring MVC实践

restful风格接口和spring的运用

如何在对 Spring MVC 控制器的 GET 请求中接受日期参数?

405 在客户端请求命中 Spring MVC 中的拦截器之前不支持请求方法“GET”