使用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模板:
- 添加请求拦截器传递模板信息
通过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()); - 自定义标签提供者
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); } } - 替换默认提供者
在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
相关产品推荐
相关产品推荐

