How can I set an alias for request parameters in Spring-mvc?

With bean for request parameters in spring: is there a way to define an alias for 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 it @RequestParam

doesn't work, but is there a similar annotation I could use?

+3


source to share


3 answers


I believe you can take a look at the Spring Documentation for annotation @RequestParam

, here is the copied snapshot:

enter image description here



I marked it in a red box for you.

You can clearly see that the parameter value

in the annotation @RequestParam

is for the purpose of the alias.

0


source


You can use setters for this. Considering your example:

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

      

And the caller can 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 hyphenated parameters, things get a little more complicated.

Basically you can:

  • Create a filter that will be normalize

    hyphenated parameter names so spring can bind them successfully.
  • Get all the request parameters as a source map in the controller, normalize

    and then populate the object with all the type conversions yourself.

A filter option 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));
        }
    }
}

      

So the previous example should work as it is.

The second option could 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}%

      

0


source


With the following approach, custom names can be defined using annotation:

See Bozho's answer: How to customize parameter names when binding spring mvc objects

When I am using spring 4, a custom transformer 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 can then be used in a get bean request like this:

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

      

Also, since I also like to match query query parameters in a case insensitive manner, I use the following class:

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

It can be connected like this:

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

      

0


source







All Articles