如何在Spring Rest @PathVariable

时间:2017-10-21 07:18:09

标签: java spring rest

在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);
}

访问

http://localhost:9000/api/v1/graph/2/details/http%3Anthnth33

工作正常,服务器正确映射请求,代码返回预期结果

但访问

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

提供错误的服务器请求(无法加载资源:服务器响应状态为400(错误请求))。在这种情况下,甚至没有映射到终点的请求。

显然斜杠'/'编码为%2F(使用encodeURIComponent())会导致麻烦。为什么?我错过了什么?如何对uri参数进行编码?

问题不仅在于如何提取PathVariables,还在于如何强制String识别正确的映射。

1 个答案:

答案 0 :(得分:1)

您的示例的问题是Spring如何进行路径匹配。您提供的URL

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

将被容器

解码

http://localhost:9000/api/v1/graph/2/details/http://serverurl.net/v1/us/h.schumacher@8tsch.net/n/LouSchumacher

在由Spring匹配器处理之前。这使得matche认为只有http:对应{iri:.+},后来才会/,所以它是一个较长的路径,你没有映射。

此处描述的方法适用于您:Spring 3 RequestMapping: Get path value

@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);
}