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;}@Overridepublic 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 {@Autowiredprivate RequestMappingHandlerAdapter requestMappingHandlerAdapter;//Rename cacheprivate final Map<Class<?>, Map<String, String>> replaceMap = new ConcurrentHashMap<Class<?>, Map<String, String>>();public RenamingProcessor(boolean annotationNotRequired) {super(annotationNotRequired);}@Overrideprotected 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;}@Overrideprotected 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{@Overridepublic 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
轉載于:https://www.cnblogs.com/davidwang456/p/6781731.html
總結
以上是生活随笔為你收集整理的spring mvc给参数起别名的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java开发中的Mutex vs Sem
- 下一篇: feign client传递对象