Spring MVC Missing matrix variable
Asked Answered
A

3

2

I'm trying to add a matrix parameter (or matrix variable) to my Rest Controller using SpringMVC (from Spring boot 1.2.3.RELEASE) Here is my code :

@RestController
public class SubAgentsController {

    @RequestMapping(value = "/{subagents}", method = RequestMethod.GET)
    public SubAgent subAgents(@MatrixVariable(value="agentName", pathVar="subagents") String agentName) {
        System.out.println(agentName);
    }
}

Unfortunately, when I try to get : http://localhost:8080/subagents;agentName=hello

that is the answer I receive :

There was an unexpected error (type=Bad Request, status=400).

Missing matrix variable 'agentName' for method parameter of type String

What did I do wrong ? According to http://docs.spring.io/spring-framework/docs/3.2.0.M2/reference/html/mvc.html that should work :-(

Thanks for your answers!

Amends answered 29/5, 2015 at 22:4 Comment(0)
H
2

As the documentation you linked to states,

Note that to enable the use of matrix variables, you must set the removeSemicolonContent property of RequestMappingHandlerMapping to false. By default it is set to true with the exception of the MVC namespace and the MVC Java config both of which automatically enable the use of matrix variables.

If you're configuring your application by extending WebMvcConfigurationSupport, then override the requestMappingHandlerMapping method which prepares the RequestMappingHandlerMapping and set its appropriate property.

@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
    final RequestMappingHandlerMapping requestMappingHandlerMapping = super.requestMappingHandlerMapping();
    requestMappingHandlerMapping.setRemoveSemicolonContent(false); // <<< this
    return requestMappingHandlerMapping;
}

You'll then be all set.


With Spring Boot, I think all you need is to declare a @Bean method with the above, ie. that returns a RequestMappingHandlerMapping instance.

Holotype answered 29/5, 2015 at 22:25 Comment(4)
right, thanks for your answer, that was it ! I would also add that for Spring Boot, you need to mark the class holding the RequestMapperHandling to to be annotated with @Configuration (not @Bean)Amends
@AnthonyDahanne I'm saying the method needs to be annotated with @Bean.Holotype
I did not need to add this @Bean annotation to the method. Just the method you provided, in a class annotated with @Configuration was necessary with Spring boot 1.2.3 - this is what I'm using : gist.github.com/anthonydahanne/82915d8123eea9ff60b7 and it's working greatAmends
@AnthonyDahanne Oh, because you're overriding WebMvcConfigurationSupport#requestMappingHandlerMapping which is the typical solution I suggested. In Spring boot, I don't believe it's necessary. You can simply provide a @Bean method in a registered @Configuration class.Holotype
R
4

In SpringBoot Application In order to enable Matrix variables you need to define below override code

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setRemoveSemicolonContent(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

Otherwise, they’re disabled by default

Rollet answered 16/2, 2017 at 17:58 Comment(0)
H
2

As the documentation you linked to states,

Note that to enable the use of matrix variables, you must set the removeSemicolonContent property of RequestMappingHandlerMapping to false. By default it is set to true with the exception of the MVC namespace and the MVC Java config both of which automatically enable the use of matrix variables.

If you're configuring your application by extending WebMvcConfigurationSupport, then override the requestMappingHandlerMapping method which prepares the RequestMappingHandlerMapping and set its appropriate property.

@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
    final RequestMappingHandlerMapping requestMappingHandlerMapping = super.requestMappingHandlerMapping();
    requestMappingHandlerMapping.setRemoveSemicolonContent(false); // <<< this
    return requestMappingHandlerMapping;
}

You'll then be all set.


With Spring Boot, I think all you need is to declare a @Bean method with the above, ie. that returns a RequestMappingHandlerMapping instance.

Holotype answered 29/5, 2015 at 22:25 Comment(4)
right, thanks for your answer, that was it ! I would also add that for Spring Boot, you need to mark the class holding the RequestMapperHandling to to be annotated with @Configuration (not @Bean)Amends
@AnthonyDahanne I'm saying the method needs to be annotated with @Bean.Holotype
I did not need to add this @Bean annotation to the method. Just the method you provided, in a class annotated with @Configuration was necessary with Spring boot 1.2.3 - this is what I'm using : gist.github.com/anthonydahanne/82915d8123eea9ff60b7 and it's working greatAmends
@AnthonyDahanne Oh, because you're overriding WebMvcConfigurationSupport#requestMappingHandlerMapping which is the typical solution I suggested. In Spring boot, I don't believe it's necessary. You can simply provide a @Bean method in a registered @Configuration class.Holotype
L
0

If you are using Spring Data and its controller mapping, try something like this also

@Configuration
public class DataMvcConfig extends RepositoryRestMvcConfiguration {

    @Override
    public DelegatingHandlerMapping restHandlerMapping() {
        final DelegatingHandlerMapping delegatingHandlerMapping = super.restHandlerMapping();
        for (HandlerMapping delegate : delegatingHandlerMapping.getDelegates()) {
            if (delegate instanceof AbstractHandlerMapping) {
                ((AbstractHandlerMapping)delegate).setRemoveSemicolonContent(false);
            }
        }
        return delegatingHandlerMapping;
    }
}
Lansquenet answered 2/11, 2022 at 1:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.