2017-06-06 72 views
3

在spring中有一个用于请求参数的bean对象:是否有一种方法可以为bean属性定义一个别名?如何在Spring-mvc中为请求参数设置别名?

@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不起作用,但是有没有类似的注释可以使用?

+0

您是否看过这篇文章? https://dzone.com/articles/customizing-parameter-names –

+0

不是开箱即用的。 –

回答

0

我相信你可以看看Spring文档为@RequestParam注释,这里是一个复制快照:

enter image description here

我标志着它在一个红色长方形你。

您可以清楚地看到@RequestParam注释中的value参数用于别名目的。

+0

“@ RequestParam”不适用于现场,只适用于方法! – membersound

0

您可以使用setters。鉴于您的例子:

@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}% 

更新

好吧,如果你要处理的连字符命名参数事情变得有点棘手。

基本上你可以:

  1. 让这将normalize带有分隔符的参数名称,以便弹簧能够成功地约束他们的过滤器。
  2. 接收所有请求参数作为您的控制器中的原始地图,normalize键,然后自行填充所有类型转换内容的对象。

带过滤器的选项可能是这样的:

@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)); 
     } 
    } 
} 

有了以前的例子应该工作的是

第二个选项可能是:

@RestController 
public static class MyServlet { 

    @GetMapping 
    public String test(@RequestParam Map<String, String> pvs) { 
     final MyReq req = new MyReq(); 
     final BeanWrapper beanWrapper = new HyphenAwareBeanWrapper(req); 
     beanWrapper.setPropertyValues(pvs); 
     return req.toString(); 
    } 
} 

和包装:

public static class HyphenAwareBeanWrapper extends BeanWrapperImpl { 
    public static final String HYPHEN = "-"; 

    public HyphenAwareBeanWrapper(Object object) { 
     super(object); 
    } 

    @Override 
    public void setPropertyValues(Map<?, ?> map) throws BeansException { 
     final ArrayList<PropertyValue> propertyValueList = new ArrayList<>(map.size()); 
     for (Map.Entry<?, ?> entry : map.entrySet()) { 
      final String key = entry.getKey().toString().contains(HYPHEN) 
        ? WordUtils.capitalizeFully(entry.getKey().toString(), HYPHEN.charAt(0)).replaceAll(HYPHEN, "") 
        : entry.getKey().toString(); 
      propertyValueList.add(new PropertyValue(key, entry.getValue())); 
     } 
     super.setPropertyValues(new MutablePropertyValues(propertyValueList)); 
    } 
} 

测试:

$ curl -XGET 'http://localhost:8000?name=John&age=42' 
{John42}% 
$ curl -XGET 'http://localhost:8000?different-name=John&age=42' 
{John42}% 
+0

好吧,但如果我重命名setter,我完全可以重命名属性+ getter + setter。但那不是我想要的。想象一下,输入参数应该作为“MY-INPUT”发送。像'my-input = test'这样的setter是一个无效的变量名。虽然我想提供一个功能,这些参数是可能的。 – membersound

+0

是的,你可以重命名字段和getter,但你不必。您可以根据需要为一个属性设置多个setter。至于hypen-separated参数名称 - 我已经更新了一个答案。 –

0

用以下方法也可以使用设置自定义名称注释:

请参阅Bozhos回答: How to customize parameter names when binding spring mvc command objects

因为我使用spring 4,所以可以按如下方式添加自定义解析器。

@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; 
} 

此外,由于我也喜欢搭配GET查询参数不区分大小写的,我用下面的类:

https://github.com/mdeinum/spring-utils/blob/master/src/main/java/biz/deinum/web/filter/CaseInsensitiveRequestFilter.java

它可以是有线的,如下所示:

@Bean 
public CaseInsensitiveRequestFilter caseInsensitiveFilter() { 
    return new CaseInsensitiveRequestFilter(); 
} 
相关问题