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?
–
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}%
–
–
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