Spring MVC @PathVariable给出404错误

时间:2017-02-01 22:46:31

标签: spring spring-mvc character-encoding path-variables

我一直在寻找答案,尽管他们解决了非常类似的问题但很多答案并没有解决我的问题。

所以我的问题是:我有一个路径变量,可能包含字符“/”。相同的值还包含其他特殊字符,例如“。” “+”“=”等基本上都是有效的Base64字符。

但Spring MVC抛出404日志,说没有找到处理程序。我尝试在路径变量中使用正则表达式,但无济于事。所以下面是我的代码片段:

http://localhost:8080/sale/public/viewSaleDetails/b91a03730a746a2b27e1c7bbbd94ddf6a9df593301cd96c606348df5eed235da.FkJJbOqEM8Xvhffe6FwUdQ8/mMCD4+fxpY7w5L9kbJ8=

是我的网址。如果你看到它有/ in path变量值。随着 ”。”和“+”和“=”。如果我删除/在字符“m”和“8”之间,Spring会正确映射这个。但是/有价值它只是不起作用。我尝试了很多东西,包括字符编码过滤器,路径变量等正则表达式。请帮忙。

此外,我不想尽可能使用请求参数。

@RequestMapping(value = "/public/viewSaleDetails/{id}", method = RequestMethod.GET)

是我的映射。此外,网址是从浏览器中点击的,因为它没有任何URL编码。我在浏览器网络栏上跟踪它,它没有按预期编码。我使用Spring 4.2.8 RELEASE版本与java 8和tomcat 8

1 个答案:

答案 0 :(得分:0)

路径中有匹配斜杠的open issue in spring Jira。由于讨论,在框架级别上改变mathing策略是不合理的。问题是由this stackoverflow post创建的,我建议根据the answer创建价值解析器。

以下是此类解析器的示例代码:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

@SpringBootApplication
public class SampleSpringApp {
    public static void main(String[] args) {
        SpringApplication.run(SampleSpringApp.class, args);
    }
}

@RestController
class SampleController {
    @RequestMapping("/records/**")
    public String getId(Id id) {
        return id.id;
    }
}

@Configuration
@EnableWebMvc
class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new IdResolver());
    }
}

class IdResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return Id.class.isAssignableFrom(parameter.getParameterType());
    }

    @Override
    public Object resolveArgument(MethodParameter parameter,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) throws Exception {    
        String basePath = ((String) webRequest.getAttribute(
                HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE,
                RequestAttributes.SCOPE_REQUEST
        )).replace("**", "");
        String id = ((String) webRequest.getAttribute(
                HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE,
                RequestAttributes.SCOPE_REQUEST
        )).replace(basePath, "");
        return new Id(id);
    }
}

class Id {
    public final String id;

    Id(String id) {
        this.id = id;
    }
}