简体   繁体   English

如何在Spring Rest @PathVariable中正确转义'/'

[英]How to correctly escape '/' in Spring Rest @PathVariable

In Spring Boot 1.5.4 I have a request mapping like this: 在Spring Boot 1.5.4中,我有一个如下的请求映射:

@RequestMapping(value = "/graph/{graphId}/details/{iri:.+}", 
                method = RequestMethod.GET,
                produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public JSONObject getGraph(@PathVariable Long graphId, 
                           @PathVariable String iri) {
    log.debug("Details called for graph ID {} for IRI {}", graphId, iri);
    return detailsService.getDetails(graphId, iri);
}

Accessing 访问

http://localhost:9000/api/v1/graph/2/details/http%3Anthnth33 HTTP://本地主机:9000 / API / V1 /图形/ 2 /信息/ HTTP%3Anthnth33

works fine and the server maps the request correctly and the code returns the expected result 工作正常,服务器正确映射了请求,代码返回了预期的结果

But accessing 但是访问

http://localhost:9000/api/v1/graph/2/details/http%3A%2F%2Fserverurl.net%2Fv1%2Fus%2Fh.schumacher%408tsch.net%2Fn%2FLouSchumacher HTTP://本地主机:9000 / API / V1 /图形/ 2 /信息/ HTTP%3A%2F%2Fserverurl.net%2Fv1%2Fus%2Fh.schumacher%408tsch.net%2Fn%2FLouSchumacher

gives a bad server request (Failed to load resource: the server responded with a status of 400 (Bad Request)). 给出错误的服务器请求 (无法加载资源:服务器以400(错误请求)的状态响应)。 The request mapping to the end point isn't even done in that case. 在这种情况下,甚至没有完成映射到端点的请求。

Obviously the slash '/' encoded as %2F (using encodeURIComponent()) causes trouble. 显然,编码为%2F的斜杠“ /”(使用encodeURIComponent())会引起麻烦。 Why? 为什么? What am I missing? 我想念什么? How should uri parameter then be encoded? uri参数应该如何编码?

The question is not only about how to extract PathVariables but more on how to force String to recognize the correct mapping. 问题不仅在于如何提取PathVariables,还在于如何强制String识别正确的映射。

The issue with your example is how Spring is doing path matching. 您的示例的问题是Spring如何进行路径匹配。 The URL you have provided as example 您提供的URL作为示例

http://localhost:9000/api/v1/graph/2/details/http%3A%2F%2Fserverurl.net%2Fv1%2Fus%2Fh.schumacher%408tsch.net%2Fn%2FLouSchumacher

will be decoded into by container 将被容器解码为

http://localhost:9000/api/v1/graph/2/details/http://serverurl.net/v1/us/h.schumacher@8tsch.net/n/LouSchumacher HTTP://本地主机:9000 / API / V1 /图形/ 2 /信息/ HTTP://serverurl.net/v1/us/h.schumacher@8tsch.net/n/LouSchumacher

before processing by Spring matcher. 在由Spring Matcher处理之前。 This makes matche think that this only http: corresponds {iri:.+} and as later goes / so it is some longer path you don't have a mapping for. 这使得matche认为这只是http:对应{iri:.+}和后来去/所以这是你没有一个映射一些较长的路径。

The approach described here should work for you: Spring 3 RequestMapping: Get path value 这里描述的方法应该对您有用:Spring 3 RequestMapping:获取路径值

@RequestMapping(value = "/graph/{graphId}/details/**", 
                method = RequestMethod.GET,
                produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public JSONObject getGraph(@PathVariable Long graphId, 
                           HttpServletRequest request) {
    String iri = (String) request.getAttribute(
        HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
    log.debug("Details called for graph ID {} for IRI {}", graphId, iri);
    return detailsService.getDetails(graphId, iri);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM