You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

validateToken接口测试异常:ID变为%7Bid%7D致查询失败排查

问题分析与解决方案

核心问题

你的代码在服务层构建远程请求时,错误地处理了路径变量{id},导致远程接口收到的不是你传入的c8r1p15dv5lr0on,而是URL编码后的%7Bid%7D(也就是{id}的编码结果),这才会触发"Token '%7Bid%7D' not found"的错误,最终返回false。

为什么会出现%7Bid%7D?

%7B是字符{的URL编码,%7D是字符}的URL编码。你的Service层定义了带路径变量的URI:"/SSOServiceToken/validateToken/{id}",但在executeFilteredRequest方法中,处理GET请求时,你没有替换这个{id}占位符,反而把id作为查询参数附加到URL后面。最终构建出的URL是:

http://localhost:8180/SSOServiceToken/validateToken/{id}?id=c8r1p15dv5lr0on

当这个URL被发送到远程服务时,{id}会被自动URL编码成%7Bid%7D,远程服务读取路径中的这个值,自然找不到对应的Token,返回false。

至于Postman测试正常,大概率是你直接调用了远程服务的正确路径(比如/SSOServiceToken/validateToken/c8r1p15dv5lr0on),绕过了服务层的错误逻辑。

修复方案

你需要修改executeFilteredRequest方法,先替换URI中的路径变量,再处理查询参数(如果有的话)。这里提供两种优化思路:

方案1:区分路径变量与查询参数(推荐)

重构方法,将路径变量和查询参数分开处理,逻辑更清晰:

private <T> T executeFilteredRequest(Map<String, Object> pathVariables, 
                                     Map<String, Object> queryParameters, 
                                     String uri, 
                                     Class<T> type, 
                                     HttpMethod httpMethod) throws JsonProcessingException {
    RestTemplate restTemplate = restTemplateBuilder.build();
    HttpHeaders headers = new HttpHeaders();
    headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
    headers.setContentType(MediaType.APPLICATION_JSON);

    // 第一步:替换URI中的路径变量
    String expandedUri = UriComponentsBuilder.fromUriString(uri)
            .buildAndExpand(pathVariables)
            .toUriString();

    // 第二步:构建完整URL并添加查询参数(如果有)
    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:8180" + expandedUri);
    if (queryParameters != null && !queryParameters.isEmpty()) {
        queryParameters.forEach(builder::queryParam);
    }

    // 处理POST请求体
    String jsonBody = "";
    if (HttpMethod.POST.equals(httpMethod)) {
        ObjectMapper objectMapper = new ObjectMapper();
        jsonBody = objectMapper.writeValueAsString(pathVariables); // 根据实际需求调整请求体内容
    }

    HttpEntity<?> entity = new HttpEntity<>(jsonBody, headers);
    ResponseEntity<T> response = restTemplate.exchange(builder.toUriString(), httpMethod, entity, type);
    return response.getBody();
}

然后修改validateToken方法的调用:

@Override
public boolean validateToken(String id) throws JsonProcessingException {
    Map<String, Object> pathVariables = new HashMap<>();
    pathVariables.put("id", id);
    String uri = "/SSOServiceToken/validateToken/{id}";
    HttpMethod httpMethod = HttpMethod.GET;
    // 这里没有查询参数,传入null即可
    return executeFilteredRequest(pathVariables, null, uri, Boolean.class, httpMethod);
}

方案2:快速修复现有逻辑

如果不想大改方法,也可以直接在现有方法中先替换路径变量:

private <T> T executeFilteredRequest(Map<String,Object> parameters, String uri, Class<T> type, HttpMethod httpMethod) throws JsonProcessingException {
    RestTemplate restTemplate = restTemplateBuilder.build();
    HttpHeaders headers = new HttpHeaders();
    headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
    headers.setContentType(MediaType.APPLICATION_JSON);

    // 先替换路径变量
    String expandedUri = UriComponentsBuilder.fromUriString(uri)
            .buildAndExpand(parameters)
            .toUriString();
    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:8180" + expandedUri);

    String jsonBody="";
    if (httpMethod == HttpMethod.POST){
        ObjectMapper objectMapper=new ObjectMapper();
        jsonBody=objectMapper.writeValueAsString(parameters);
    }
    // 注意:如果parameters里有查询参数,这里需要单独处理,避免重复添加

    HttpEntity<?> entity = new HttpEntity<>(jsonBody,headers);
    ResponseEntity<T> response = restTemplate.exchange(builder.toUriString(), httpMethod, entity, type);
    return response.getBody();
}

验证修复

修改后,你的测试用例调用Controller时,服务层会正确生成URL:

http://localhost:8180/SSOServiceToken/validateToken/c8r1p15dv5lr0on

远程服务能找到对应的Token,返回true,Controller也就会返回200 OK和true的结果,符合你的预期。

内容的提问来源于stack exchange,提问作者Nivel23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 12:12:32