When having a bean object for request params in spring: is there a way to define an alias for a bean properties?

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

Of course @RequestParam does not work, but is there a similar annotation I could use?

Have you looked through this article? dzone.com/articles/customizing-parameter-names – Vasiliy Vlasov Jun 6 '17 at 12:52 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 + '}';

And caller might use:

$so44390404 curl -XGET 'http://localhost:8000?name=adam&age=42'          
{adam42}%
$so44390404 curl -XGET 'http://localhost:8000?Different_Name=John&age=23'
{John23}% 

Update

Well, if you're dealing with hyphen-named parameters things become a little bit trickier.

Basically you can:

  • Make a filter which will normalize hyphened parameter names, so spring can bind them successfully.
  • Receive all request params as a raw map in your controller, normalize keys and then populate object with all type conversion stuff by yourself.
  • An option with filter might look like this:

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

    With that previous example should work as is.

    The second option might be:

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

    And the wrapper:

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

    Testing:

    $ curl -XGET 'http://localhost:8000?name=John&age=42'
    {John42}%
    $ curl -XGET 'http://localhost:8000?different-name=John&age=42'
    {John42}%
                    Well but if I rename the setter, I could as well rename the property + getter + setter completely. But that's not what I want. Imagine the input parameter should be send as "MY-INPUT". A setter like my-input=test is an invalid variable name. Though I want to provide a feature where such params are possible.
                        – membersound
                    Jun 7 '17 at 6:56
                    Yes, you can rename field and getter as well, but you don't have to. You can have as many setters for one property as you want. As for the hypen-separated parameter names - I have updated an answer.
                        – Bohdan Levchenko
                    Jun 7 '17 at 12:34
    

    With the following approach it is possible to set custom names using an annotation:

    See Bozhos answer: How to customize parameter names when binding spring mvc command objects

    As I'm using spring 4, the custom resolver can be added as follows.

    @Configuration
    public class AdapterConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
            super.addArgumentResolvers(argumentResolvers);
            argumentResolvers.add(new AnnotationServletModelAttributeResolver(false));
    

    It then can be used on the get query bean as follows:

    @SupportsCustomizedBinding
    public class MyReq {
       @CommandParameter("different-name") //this is valid now!
       private String name;
    

    Further, as I also like to match the get query parameters case insensitive, I'm using the following class:

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

    It can be wired as follows:

    @Bean
    public CaseInsensitiveRequestFilter caseInsensitiveFilter() {
        return new CaseInsensitiveRequestFilter();
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

    site design / logo © 2019 Stack Exchange Inc; user contributions licensed under cc by-sa 4.0 with attribution required. rev 2019.10.23.35228