首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Spring MVC矩阵变量仅检索一个参数值

Spring MVC矩阵变量仅检索一个参数值
EN

Stack Overflow用户
提问于 2018-05-31 16:29:16
回答 1查看 633关注 0票数 0

我正在构建一个spring-mvc rest API应用程序,并且打算对我的一些端点使用矩阵变量。不幸的是,我不能检索每个使用的矩阵变量的一个以上的值。

我的spring-mvc版本是spring-webmvc:4.3.12.RELEASE

我遵循了这个实现示例中显示的步骤:http://www.baeldung.com/spring-mvc-matrix-variables

我已经启用了Spring MVC矩阵变量:

代码语言:javascript
复制
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);
    }
}

所以我创建了两个测试端点:

代码语言:javascript
复制
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;
    }
}

当我打电话的时候

代码语言:javascript
复制
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请求,status=400)。字符串类型的方法参数缺少矩阵变量“v2”

但是当我打电话给

代码语言:javascript
复制
GET http://[...]/my_awesome_project/matrix_test_one/v2=titi
OR
GET http://[...]/my_awesome_project/matrix_test_one/[anything except "v1=*"]

我有以下相同的错误消息:

出现意外错误(type=Bad请求,status=400)。字符串类型的方法参数缺少矩阵变量“v1”

所以Spring似乎可以获取矩阵变量的第一个元素,但到此为止。

所以我继续尝试第二个测试函数:

代码语言:javascript
复制
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

返回:

代码语言:javascript
复制
{
    "v1": "toto"
}

-

代码语言:javascript
复制
GET http://[...]/my_awesome_project/matrix_test_two/v2=titi;v1=toto;v3=tata

返回:

代码语言:javascript
复制
{
    "v2": "titi"
}

因此,这种行为似乎证实了我的恐惧。

你看到我为了启用矩阵变量支持(可能与分号有关)而遗漏了什么吗?

EN

回答 1

Stack Overflow用户

发布于 2018-05-31 17:13:49

上面提到的例子是使用Spring Boot。通过Spring Boot启动exmaple的工作方式与预期一致。如果没有Spring Boot,它不会像这个Q&A中解释的那样开箱即用。原因是从@Configuration注入的UrlPathHelper (示例中的第2点)未用于处理请求。使用UrlPathHelper的默认实例,因此urlPathHelper.shouldRemoveSemicolonContent()返回true。这将从请求中删除矩阵变量。

编辑:

我对它进行了调试,结果发现有两个RequestMappingHandlerMapping类型的bean。

所以我尝试了这个配置:

代码语言:javascript
复制
@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的状态:

代码语言:javascript
复制
@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;
    }

}

这对我来说就够了。矩阵变量已映射。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50619903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档