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

使用Swagger/OpenAPI Codegen+RestTemplate时指标URI标签未模板化问题

解决RestTemplate生成代码的Micrometer URI标签模板化问题

方案1:调整OpenAPI Generator插件配置

针对openapi-generator-maven-plugin,添加配置项强制生成使用URI模板参数的代码,避免提前展开路径:

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>最新稳定版本</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <generatorName>java</generatorName>
                <library>resttemplate</library>
                <configOptions>
                    <!-- 关键配置:启用URI模板,让RestTemplate原生处理变量替换 -->
                    <useUriTemplates>true</useUriTemplates>
                    <!-- 可选:确保使用RestTemplate的uriTemplate参数重载方法 -->
                    <restTemplateUriTemplateHandler>true</restTemplateUriTemplateHandler>
                </configOptions>
            </configuration>
        </execution>
    </executions>
</plugin>

配置后生成的代码会直接调用restTemplate.exchange(String urlTemplate, HttpMethod method, ..., Object... uriVariables),Micrometer就能自动捕获模板化的uri标签。

方案2:自定义Micrometer标签提供者

如果插件配置无法生效,通过自定义RestTemplateExchangeTagsProvider手动注入原始URI模板:

  1. 添加请求拦截器传递模板信息
    通过ThreadLocal在调用生成的API方法时,把原始URI模板传递给RestTemplate:
    public class UriTemplateInterceptor implements ClientHttpRequestInterceptor {
        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
            // 从ThreadLocal获取提前存储的原始模板(可通过AOP在API方法调用前设置)
            String uriTemplate = UriTemplateHolder.get();
            if (uriTemplate != null) {
                request.getAttributes().put("uri_template", uriTemplate);
                UriTemplateHolder.clear();
            }
            return execution.execute(request, body);
        }
    }
    // 给RestTemplate注册拦截器
    restTemplate.getInterceptors().add(new UriTemplateInterceptor());
    
  2. 自定义标签提供者
    public class CustomRestTemplateExchangeTagsProvider extends DefaultRestTemplateExchangeTagsProvider {
        @Override
        public Tag uri(ClientHttpResponse response) {
            HttpRequest request = response.getRequest();
            String template = (String) request.getAttributes().get("uri_template");
            if (template != null) {
                return Tag.of("uri", template);
            }
            // 兜底使用默认逻辑
            return super.uri(response);
        }
    }
    
  3. 替换默认提供者
    在Spring配置中注册自定义提供者:
    @Bean
    public RestTemplateExchangeTagsProvider restTemplateExchangeTagsProvider() {
        return new CustomRestTemplateExchangeTagsProvider();
    }
    

方案3:定制代码生成模板

直接修改生成器的Freemarker模板,重构URI处理逻辑:

  • 对于openapi-generator,找到restTemplate.mustache模板文件(可从官方仓库获取),修改方法内的URI生成代码:
    原代码(提前展开路径):
    String url = UriComponentsBuilder.fromPath("{{path}}").buildAndExpand({{#pathParams}}{{paramName}}, {{/pathParams}}).toUriString();
    
    改为(直接传递模板):
    ResponseEntity<{{returnType}}> response = restTemplate.exchange("{{path}}", HttpMethod.{{httpMethod}}, requestEntity, {{returnType}}.class, {{#pathParams}}{{paramName}}, {{/pathParams}});
    
  • 对于swagger-codegen-maven-plugin,找到对应的api.mustache模板,做类似修改。

针对OpenAPI Generator的特殊问题处理

如果生成的代码看似使用了模板但urlTemplate仍为null,检查以下两点:

  • 确保RestTemplate使用DefaultUriBuilderFactory(Spring默认配置),而非自定义的UriTemplateHandler
  • 升级Micrometer到1.10+版本,新版本对RestTemplate的模板解析支持更完善

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:15:18