博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring mvc给参数起别名
阅读量:6702 次
发布时间:2019-06-25

本文共 5951 字,大约阅读时间需要 19 分钟。

需求:

将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)@Documentedpublic @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
, Map
> replaceMap = new ConcurrentHashMap
, Map
>(); 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
mapping = analyzeClass(targetClass); replaceMap.put(targetClass, mapping); } Map
mapping = replaceMap.get(targetClass); ParamNameDataBinder paramNameDataBinder = new ParamNameDataBinder(target, binder.getObjectName(), mapping); requestMappingHandlerAdapter.getWebBindingInitializer().initBinder(paramNameDataBinder, nativeWebRequest); super.bindRequestParameters(paramNameDataBinder, nativeWebRequest); } private static Map
analyzeClass(Class
targetClass) { Field[] fields = targetClass.getDeclaredFields(); Map
renameMap = new HashMap
(); 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
renameMapping; public ParamNameDataBinder(Object target, String objectName, Map
renameMapping) { super(target, objectName); this.renameMapping = renameMapping; } @Override protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) { super.addBindValues(mpvs, request); for (Map.Entry
entry : renameMapping.entrySet()) { String from = entry.getKey(); String to = entry.getValue(); if (mpvs.contains(from)) { mpvs.add(to, mpvs.getPropertyValue(from).getValue()); } } }}

5.注册处理器

或者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@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter{      @Override      public void addArgumentResolvers(List
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

你可能感兴趣的文章
laravel框架——composer导入laravel
查看>>
Java---利用程序实现在控制台聊天
查看>>
Oracle监听器—静态注册
查看>>
java 程序中打开文件和文件夹
查看>>
书籍推荐-记这几年看的书
查看>>
ROS系统玩转自主移动机器人(3)-- 开源机器人结构介绍
查看>>
HIVE ORC 报错ClassCastException
查看>>
例题练习
查看>>
下拉框——把一个select框中选中内容移到另一个select框中遇到的问题
查看>>
游戏提高性能 游戏降帧处理
查看>>
将本地代码备份到Github public repository
查看>>
开源框架:CocoaPods 安装学习教程
查看>>
vue使用render渲染&jsx
查看>>
新闻发布项目——接口类(commentDao)
查看>>
Android的MVC框架
查看>>
Extracting Text From Image
查看>>
Ionic混合移动app框架学习
查看>>
Java中什么是匿名对象,空参构造方法输出创建了几个匿名对象,属性声明成static...
查看>>
数据存储和界面展示(二)
查看>>
修改 cmd 字体为 Consolas
查看>>