本文来自
get 请求想使用对象接受参数,但有需要使用别名,目前没有注解支持,需要自行实现
新增注解
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author kangpt
* @date 2022-12-08 19:06
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParamName {
/**
* The name of the request parameter to bind to.
*/
String value();
}
使用ServletRequestDataBinder给真实的Filed赋值
import org.springframework.beans.MutablePropertyValues;
import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;
import javax.servlet.ServletRequest;
import java.util.Map;
/**
* 将{@link ParamName}注释的field加入MutablePropertyValues,是spring能够注入该值
* @author kangpt
*/
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());
}
}
}
}
处理Field和别名的映射关系
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
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 java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Method processor supports {@link ParamName} parameters renaming
*
* @author kangpt
*/
public class RenamingProcessor extends ServletModelAttributeMethodProcessor {
@Lazy
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
/**
* A map caching annotation definitions of command objects (@ParamName-to-fieldname mappings)
*/
private final Map<Class<?>, Map<String, String>> replaceMap = new ConcurrentHashMap<>();
public RenamingProcessor(boolean annotationNotRequired) {
super(annotationNotRequired);
}
@Override
protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest nativeWebRequest) {
Object target = binder.getTarget();
Map<String, String> mapping = getFieldMapping(target.getClass());
ParamNameDataBinder paramNameDataBinder = new ParamNameDataBinder(target, binder.getObjectName(), mapping);
requestMappingHandlerAdapter.getWebBindingInitializer().initBinder(paramNameDataBinder, nativeWebRequest);
super.bindRequestParameters(paramNameDataBinder, nativeWebRequest);
}
private Map<String, String> getFieldMapping(Class<?> targetClass) {
if (targetClass == Object.class) {
return Collections.emptyMap();
}
if (replaceMap.containsKey(targetClass)) {
return replaceMap.get(targetClass);
}
Map<String, String> renameMap = new HashMap<>();
Field[] fields = targetClass.getDeclaredFields();
for (Field field : fields) {
ParamName paramNameAnnotation = field.getAnnotation(ParamName.class);
if (paramNameAnnotation != null && !paramNameAnnotation.value().isEmpty()) {
renameMap.put(paramNameAnnotation.value(), field.getName());
}
}
// 递归获取全部Field
renameMap.putAll(getFieldMapping(targetClass.getSuperclass()));
if (renameMap.isEmpty()) {
renameMap = Collections.emptyMap();
}
replaceMap.put(targetClass, renameMap);
return renameMap;
}
}
配置WebMvcConfigurationSupport生效
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
/**
* @author kangpt
* @date 2022-12-08 19:11
*/
@Configuration
public class WebContextConfiguration extends WebMvcConfigurationSupport {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(renamingProcessor());
}
@Bean
protected RenamingProcessor renamingProcessor() {
return new RenamingProcessor(true);
}
}
感谢
文章参考 https://blog.csdn.net/caodongfang126/article/details/92791829/
https://www.jianshu.com/p/1d167eac801e?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
https://stackoverflow.com/questions/8986593/how-to-customize-parameter-names-when-binding-spring-mvc-command-objects/16520399