我正在构建一个spring-mvc rest API应用程序,我打算在我的某些端点上使用矩阵变量。不幸的是,我无法为每个使用的矩阵变量检索多个值。
我的spring-mvc版本是spring-webmvc:4.3.12.RELEASE
我按照此实施示例中显示的步骤进行操作:http://www.baeldung.com/spring-mvc-matrix-variables。
我已启用Spring MVC矩阵变量:
package fr.compagny.project.configuration;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.util.UrlPathHelper;
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
所以我创建了2个测试端点:
package fr.compagny.project.webservice;
import [...]
@Api
@RefreshScope
@RestController
@RequestMapping(value = "/my_awesome_project")
public class ProjectWS {
//Services
private ProjectService projectService;
//Validator
private ValidatorService validator;
@ApiOperation(value = "Matrix Variable Test 1.")
@GetMapping(value = "/matrix_test_one/{vars}", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public String getMatrixTestOne (@MatrixVariable(pathVar = "vars", required = true) String v1,
@MatrixVariable(pathVar = "vars", required = true) String v2,
@MatrixVariable(pathVar = "vars", required = true) String v3) {
return v1 + v2 + v3;
}
@ApiOperation(value = "Matrix Variable Test 2.")
@GetMapping(value = "/matrix_test_two/{vars}", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public Map<String, String> getMatrixTestTwo (@MatrixVariable Map<String, String> vars) {
return vars;
}
@Autowired
public void setProjectService(ProjectService projectService) {
this.projectService = projectService;
}
@Autowired
public void setValidatorService(ValidatorService validatorService) {
this.validator = validatorService;
}
}
当我打电话
GET http://[...]/my_awesome_project/matrix_test_one/v1=toto;v2=titi;v3=tata
OR
GET http://[...]/my_awesome_project/matrix_test_one/v1=toto
我有以下相同的错误消息:
出现意外错误(type = Bad Request,status = 400)。失踪 矩阵变量&#39; v2&#39;对于String
类型的方法参数
但是当我打电话时
GET http://[...]/my_awesome_project/matrix_test_one/v2=titi
OR
GET http://[...]/my_awesome_project/matrix_test_one/[anything except "v1=*"]
我有以下相同的错误消息:
出现意外错误(type = Bad Request,status = 400)。 缺少矩阵变量&#39; v1&#39;对于String
类型的方法参数
所以Spring似乎可以获得矩阵变量的第一个元素,但那时就停止了。
所以我继续尝试第二个测试功能:
GET http://[...]/my_awesome_project/matrix_test_two/v1=toto;v2=titi;v3=tata
OR
GET http://[...]/my_awesome_project/matrix_test_two/v1=toto
返回:
{
"v1": "toto"
}
-
GET http://[...]/my_awesome_project/matrix_test_two/v2=titi;v1=toto;v3=tata
返回:
{
"v2": "titi"
}
所以这种行为似乎证实了我的恐惧。
为了启用矩阵变量支持(可能与分号有关),您是否看到了我遗漏的内容?
答案 0 :(得分:0)
上面提到的例子是使用Spring Boot。通过Spring Boot启动exmaple按预期工作。如果没有Spring Boot,它就不会开箱即用,正如Q&A中所解释的那样。原因是从UrlPathHelper
注入的@Configuration
(示例中的第2点)并不用于处理请求。使用了UrlPathHelper
的默认实例,因此urlPathHelper.shouldRemoveSemicolonContent()
返回true
。这将从请求中删除矩阵变量。
编辑:
我调试了它,结果发现有两个类型为RequestMappingHandlerMapping
的bean。
所以我尝试了这个配置:
@Configuration
@ComponentScan(basePackageClasses = { WebMvcConfiguration.class })
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Bean("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping")
@Qualifier("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping")
public RequestMappingHandlerMapping fullyQualifiedRequestMappingHandlerMapping() {
return requestMappingHandlerMapping();
}
@Bean
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping requestMappingHandlerMapping = super.requestMappingHandlerMapping();
requestMappingHandlerMapping.getUrlPathHelper().setRemoveSemicolonContent(false);
return requestMappingHandlerMapping;
}
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = configurer.getUrlPathHelper();
if (urlPathHelper == null) {
urlPathHelper = new UrlPathHelper();
}
urlPathHelper.setRemoveSemicolonContent(false);
}
}
但是第一种方法并没有创建完全限定的bean。这个bean正在处理请求。所以矩阵变量仍然被删除。
由于我无法为bean提供工厂方法,我试图修改bean的状态:
@Component
public class Initializer {
@Autowired
private ApplicationContext appContext;
@PostConstruct
protected void init() {
initUrlPathHelper("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping");
initUrlPathHelper("requestMappingHandlerMapping");
}
protected void initUrlPathHelper(String beanName) {
AbstractHandlerMapping b = (AbstractHandlerMapping) appContext.getBean(beanName);
b.setUrlPathHelper(urlPathHelper());
}
public UrlPathHelper urlPathHelper() {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
return urlPathHelper;
}
}
这对我有用。矩阵变量已经映射。