spring mvc给参数起别名
需求:
将http报文请求(保护body和url)中的参数传递给Controller时支持使用别名。
举例:
下面两条请求报文的结果是一致的。
http://example.com/foo?jobType=permanent&location=Stockholm
http://example.com/foo?jt=permanent&loc=Stockholm
返回响应
解决方法
Spring MVC3 提供了丰富的参数映射机制, 详细信息可以参见这里
同时对于Spring MVC默认的提供的映射机制不能涵盖的对象,我们可以通过扩展HandlerMethodArgumentResolver和HttpMessageConverter的机制来实现。
HandlerMethodArgumentResolver对应输入, HttpMessageConverter对应输出
1.预备代码
- package com.davidwang456.web.model;
- import com.davidwang456.web.annotation.ParamName;
- public class Job {
- @ParamName("jt")
- private String jobType;
- @ParamName("loc")
- private String location;
- public String getJobType() {
- return jobType;
- }
- public void setJobType(String jobType) {
- this.jobType = jobType;
- }
- public String getLocation() {
- return location;
- }
- public void setLocation(String location) {
- this.location = location;
- }
- @Override
- public String toString(){
- return "jobType="+jobType+",location="+location;
- }
- }
2.注解
- package com.davidwang456.web.annotation;
- import java.lang.annotation.Documented;
- import java.lang.annotation.Retention;
- import java.lang.annotation.Target;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.RetentionPolicy;
- /**
- * Overrides parameter name
- */
- @Target(ElementType.FIELD)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface ParamName {
- /**
- * The name of the request parameter to bind to.
- */
- String value();
- }
3.注解处理器
- package com.davidwang456.web.processor;
- import java.lang.reflect.Field;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.WebDataBinder;
- import org.springframework.web.context.request.NativeWebRequest;
- import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
- import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;
- import com.davidwang456.web.annotation.ParamName;
- /**
- * Method processor supports {@link ParamName} parameters renaming
- *
- */
- public class RenamingProcessor extends ServletModelAttributeMethodProcessor {
- @Autowired
- private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
- //Rename cache
- private final Map<Class<?>, Map<String, String>> replaceMap = new ConcurrentHashMap<Class<?>, Map<String, String>>();
- public RenamingProcessor(boolean annotationNotRequired) {
- super(annotationNotRequired);
- }
- @Override
- protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest nativeWebRequest) {
- Object target = binder.getTarget();
- Class<?> targetClass = target.getClass();
- if (!replaceMap.containsKey(targetClass)) {
- Map<String, String> mapping = analyzeClass(targetClass);
- replaceMap.put(targetClass, mapping);
- }
- Map<String, String> mapping = replaceMap.get(targetClass);
- ParamNameDataBinder paramNameDataBinder = new ParamNameDataBinder(target, binder.getObjectName(), mapping);
- requestMappingHandlerAdapter.getWebBindingInitializer().initBinder(paramNameDataBinder, nativeWebRequest);
- super.bindRequestParameters(paramNameDataBinder, nativeWebRequest);
- }
- private static Map<String, String> analyzeClass(Class<?> targetClass) {
- Field[] fields = targetClass.getDeclaredFields();
- Map<String, String> renameMap = new HashMap<String, String>();
- for (Field field : fields) {
- ParamName paramNameAnnotation = field.getAnnotation(ParamName.class);
- if (paramNameAnnotation != null && !paramNameAnnotation.value().isEmpty()) {
- renameMap.put(paramNameAnnotation.value(), field.getName());
- }
- }
- if (renameMap.isEmpty()) return Collections.emptyMap();
- return renameMap;
- }
- }
4.数据绑定
- package com.davidwang456.web.processor;
- import java.util.Map;
- import javax.servlet.ServletRequest;
- import org.springframework.beans.MutablePropertyValues;
- import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;
- /**
- * ServletRequestDataBinder which supports fields renaming using {@link ParamName}
- *
- */
- public class ParamNameDataBinder extends ExtendedServletRequestDataBinder {
- private final Map<String, String> renameMapping;
- public ParamNameDataBinder(Object target, String objectName, Map<String, String> renameMapping) {
- super(target, objectName);
- this.renameMapping = renameMapping;
- }
- @Override
- protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
- super.addBindValues(mpvs, request);
- for (Map.Entry<String, String> entry : renameMapping.entrySet()) {
- String from = entry.getKey();
- String to = entry.getValue();
- if (mpvs.contains(from)) {
- mpvs.add(to, mpvs.getPropertyValue(from).getValue());
- }
- }
- }
- }
5.注册处理器
- <mvc:annotation-driven>
- <mvc:argument-resolvers>
- <bean class="com.davidwang456.web.processor.RenamingProcessor">
- <constructor-arg name="annotationNotRequired" value="true"/>
- </bean>
- </mvc:argument-resolvers>
- </mvc:annotation-driven>
或者java config模式
- package com.davidwang456.web.configurer;
- import java.util.List;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.method.support.HandlerMethodArgumentResolver;
- import org.springframework.web.servlet.config.annotation.EnableWebMvc;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
- import com.davidwang456.web.processor.RenamingProcessor;
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter{
- @Override
- public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
- RenamingProcessor renameResolver = new RenamingProcessor(true);
- argumentResolvers.add(renameResolver);
- }
- }
参考文献:
【1】http://stackoverflow.com/questions/8986593/how-to-customize-parameter-names-when-binding-spring-mvc-command-objects
【2】http://geekabyte.blogspot.tw/2014/08/how-to-inject-objects-into-spring-mvc.html
【3】http://www.cnblogs.com/daxin/p/3296493.html
spring mvc给参数起别名的更多相关文章
- spring mvc绑定参数之 类型转换 有三种方式:
spring mvc绑定参数之类型转换有三种方式: 1.实体类中加日期格式化注解(上次做项目使用的这种.简单,但有缺点,是一种局部的处理方式,只能在本实体类中使用.方法三是全局的.) @DateTim ...
- Spring MVC接收参数(Map,List,JSON,Date,2个Bean)(记录一次面试惨状)
题目Spring MVC 接收参数 MapListDate2个BeanJSON Spring MVC接收参数 -Map Spring MVC接收参数 -List Spring MVC接收参数 -dat ...
- spring mvc 复杂参数注入
过了这么久,又重新把博客拾起来了 来上海工作也已经有将近两周的时间了, 今天在整理项目的时候,遇到了一个关于参数注入的问题 背景: 我的开发前台用的是extjs4,在对后台spring mvc提交表单 ...
- Spring MVC温故而知新 – 参数绑定、转发与重定向、异常处理、拦截器
请求参数绑定 当用户发送请求时,根据Spring MVC的请求处理流程,前端控制器会请求处理器映射器返回一个处理器,然后请求处理器适配器之心相应的处理器,此时处理器映射器会调用Spring Mvc 提 ...
- Spring MVC请求参数绑定
所谓请求参数绑定,就是在控制器方法中,将请求参数绑定到方法参数上 @RequestParam 绑定单个请求参数到方法参数上 @RequestParam("id") Integer ...
- Spring MVC处理参数Convert
Springmvc.xml 配置convert,xml中配置多个相同的泛型时,xml里配置的convert会从上到下挨个执行. <!-- 配置注解驱动,并配置convert --> < ...
- Spring MVC Action参数类型 List集合类型(简单案例)
题目:定义一个员工实体(Employee),实现批量添加员工功能,在表单中可以一次添加多个员工,数据可以不持久化 1,新建一个项目 2, 然后选择Maven框架选择 maven-archetype-w ...
- Spring MVC请求参数绑定 自定义类型转化 和获取原声带额servlet request response信息
首先还在我们的框架的基础上建立文件 在domian下建立Account实体类 import org.springframework.stereotype.Controller; import org. ...
- Spring MVC初始化参数绑定
初始化参数绑定与类型转换很类似,初始化绑定时,主要是参数类型 ---单日期 在处理器类中配置绑定方法 使用@InitBinder注解 在这里首先注册一个用户编辑器 参数一为目标类型 proper ...
随机推荐
- poj 3259 bellman最短路推断有无负权回路
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 36717 Accepted: 13438 Descr ...
- 基础数位DP小结
HDU 3555 Bomb dp[i][0] 表示含 i 位数的方案总和. sp[i][0] 表示对于位数为len 的 num 在区间[ 10^(i-1) , num/(10^(len-i)) ] 内 ...
- Android Studio 修改注释模板中的${USER}变量以及修改默认的头部注释
引言 通常我们创建类文件都会自动生成一段头部注释. 有时候这不是我们想要的效果. 它默认是Created By XXX. 而我们要的是@author XXX. 而且这里面的XXX是系统的的用户名,不一 ...
- m_Orchestrate learning system---十三、thinkphp的验证器支持多语言么
m_Orchestrate learning system---十三.thinkphp的验证器支持多语言么 一.总结 一句话总结:支持,不仅验证器支持,其它的插件应该都支持 不仅thinkphp支持多 ...
- ES API 备忘
本文所列的所有API在ElasticSearch文档是有详尽的说明,但它的结构组织的不太好. 这篇文章把ElasticSearch API用表格的形式供大家参考. https://www.iteblo ...
- MySQL学习(五)——使用JDBC完成用户表CRUD的操作
通过案例我们发现“获得连接”和“释放资源”两次代码将在之后的增删改查所有功能中都存在,开发中遇到此种情况,将采用工具类的方法进行抽取,从而达到代码的重复利用. 1.使用properties配置文件 开 ...
- swift语言点评八-枚举
总结:swift中的枚举可以看作变量可以作为case匹配参数的类 Enumerations 枚举的作用:状态列举与匹配 枚举值与类型 If a value (known as a “raw” valu ...
- 使用dispatch_group来进行线程同步
我的上篇文章iOS中多个网络请求的同步问题总结中用到了dispatch_group来进行线程同步,对用法不是特别熟悉所以整理这篇文章来加深记忆(闲着也是闲着). 一.简单介绍下将会用到的一些东西 英语 ...
- Calling Mojo from Blink
Variants Let's assume we have a mojom file such as this: module example.mojom; interface Foo { ...
- 路飞学城Python-Day4
29.二进制转换计算机使用的语言就是二进制古时候,人们使用信鸽.书信.千里马等方式.但是这样的方式是不可靠的,时间也长.古时候的军方,通过烽火狼烟进行简单的信息交流 30.二进制的转换(II)8 4 ...