【问题标题】:Spring MVC @PathVariable gives 404 errorSpring MVC @PathVariable 给出 404 错误
【发布时间】:2017-06-18 21:04:55
【问题描述】:

我一直在寻找答案,许多答案都没有解决我的问题,即使他们解决了非常相似的问题。

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

但是 Spring MVC 抛出 404 并显示未找到处理程序的日志。我也尝试在路径变量中使用正则表达式,但无济于事。所以下面是我的代码 sn-ps :

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

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

另外我尽量不要使用请求参数。

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

是我的映射。此外,该 url 是从浏览器中命中的,因为它没有任何 URL 编码。我在浏览器网络栏上跟踪它,它没有按预期对其进行编码。我正在使用带有 java 8 和 tomcat 8 的 Spring 4.2.8 RELEASE 版本

【问题讨论】:

  • 我不确定 Spring 是否可以处理 PathVariables 中的“/”,我认为它不起作用,但是您可以使用一些 url 重写器从 public/viewSaleDetails/{id 转换您的 PathVariable } 到 RequestParam public/viewSaleDetails?id=xx 在到达您的控制器之前。

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


【解决方案1】:

open issue in spring Jira 对应路径中的斜杠。并且由于讨论,在框架级别更改数学策略是不合理的。该问题是由于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;
    }
}

【讨论】:

    猜你喜欢
    • 2019-03-20
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 2016-05-09
    • 2013-11-17
    • 2012-08-03
    • 1970-01-01
    相关资源
    最近更新 更多