Java 如何在Spring mvc中为请求参数设置别名?
在spring中为请求参数使用bean对象时:有没有办法为bean属性定义别名Java 如何在Spring mvc中为请求参数设置别名?,java,spring,spring-mvc,Java,Spring,Spring Mvc,在spring中为请求参数使用bean对象时:有没有办法为bean属性定义别名 @RestController public class MyServlet { @GetMapping public void test(MyReq req) { } } public class MyReq { @RequestParam("different-name") //this is invalid private String name; private int
@RestController
public class MyServlet {
@GetMapping
public void test(MyReq req) {
}
}
public class MyReq {
@RequestParam("different-name") //this is invalid
private String name;
private int age;
}
当然,
@RequestParam
不起作用,但是我可以使用类似的注释吗?您可以使用setter。举个例子:
@SpringBootApplication
public class So44390404Application {
public static void main(String[] args) {
SpringApplication.run(So44390404Application.class, args);
}
@RestController
public static class MyServlet {
@GetMapping
public String test(MyReq req) {
return req.toString();
}
}
public static class MyReq {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setDifferent_Name(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "{" + name + age + '}';
}
}
}
调用方可能会使用:
$so44390404 curl -XGET 'http://localhost:8000?name=adam&age=42'
{adam42}%
$so44390404 curl -XGET 'http://localhost:8000?Different_Name=John&age=23'
{John23}%
更新
如果你处理连字符命名的参数,事情会变得有点棘手
基本上你可以:
规范化
键,然后自己用所有类型转换内容填充对象@Component
public static class CustomRequestParametersFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
filterChain.doFilter(new RequestParameterNormalizerWrapper(request), response);
}
public static class RequestParameterNormalizerWrapper extends HttpServletRequestWrapper {
public static final String HYPHEN = "-";
private final Map<String, String[]> parameterMap = new HashMap<>();
public RequestParameterNormalizerWrapper(HttpServletRequest request) {
super(request);
for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
if (entry.getKey().contains(HYPHEN)) {
parameterMap.put(normalize(entry.getKey()), entry.getValue());
}
else {
parameterMap.put(entry.getKey(), entry.getValue());
}
}
}
private String normalize(final String key) {
if (key.contains(HYPHEN)) {
return WordUtils.capitalizeFully(key, HYPHEN.charAt(0)).replaceAll(HYPHEN, "");
}
return key;
}
@Override
public Map<String, String[]> getParameterMap() {
return Collections.unmodifiableMap(this.parameterMap);
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(this.parameterMap.keySet());
}
@Override
public String getParameter(String name) {
return super.getParameter(normalize(name));
}
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(normalize(name));
}
}
}
通过以下方法,可以使用注释设置自定义名称: 见Bozhos的回答: 在使用Spring4时,可以按如下方式添加自定义解析器
@Configuration
public class AdapterConfig extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new AnnotationServletModelAttributeResolver(false));
}
}
此外,由于我还喜欢匹配get查询参数(不区分大小写),因此我使用以下类:
其接线方式如下:
@SupportsCustomizedBinding
public class MyReq {
@CommandParameter("different-name") //this is valid now!
private String name;
}
@Bean
public CaseInsensitiveRequestFilter caseInsensitiveFilter() {
return new CaseInsensitiveRequestFilter();
}
请求参数由setter绑定。可以使用原始参数名称添加额外的setter。比如:
public class MyReq {
private String name;
private int age;
public void setDifferentName(String differentName) {
this.name=differentName;
}
}
@GetMapping(value = "/do-something")
public ResponseEntity<String> handleDoSomething(@Valid MyReq myReq) {
...
}
注意:仅当您的参数是类似于
differentName=abc
的驼峰大小写时,它才起作用。与Sergiy Dakhniy/Bohdan Levchenko注释类似,将不适用于different name=abc
。请求参数由setter绑定。您可以从传入请求中添加一个具有参数名称的额外setter。比如:
public class MyReq {
private String name;
private int age;
public void setDifferentName(String differentName) {
this.name=differentName;
}
}
@GetMapping(value = "/do-something")
public ResponseEntity<String> handleDoSomething(@Valid MyReq myReq) {
...
}
例如:
http://www.example.com/do-something?different_name=Joe
你看过这篇文章了吗?不是开箱即用的。但是如果我重命名setter,我还可以完全重命名属性+getter+setter。但那不是我想要的。假设输入参数应该作为“MY-input”发送。像myinput=test
这样的setter是无效的变量名。虽然我想提供一个可以使用此类参数的特性。是的,您也可以重命名字段和getter,但您不必这样做。一个属性可以有任意多个setter。至于hypen分离的参数名称,我已经更新了答案。
@GetMapping(value = "/do-something")
public ResponseEntity<String> handleDoSomething(@Valid MyReq myReq) {
...
}
public class MyReq {
private String name;
public void setDifferent_name(String name) {
this.name = name;
}
}