当参数值形似模板时UriBuilder无法工作,如何解决?
解决UriBuilder误将查询参数值识别为模板的问题
问题场景
使用UriBuilder创建HTTP客户端端点时,若查询参数值包含{}格式内容(如示例中的b4o3h4{g}fghg3),会被UriBuilder误判为模板变量,抛出如下错误:
The template variable 'g' has no value java.lang.IllegalArgumentException: The template variable 'g' has no value at org.glassfish.jersey.uri.UriTemplate$1ValuesFromArrayStrategy.valueFor(UriTemplate.java:996) at org.glassfish.jersey.uri.UriTemplate.resolveTemplate(UriTemplate.java:682) at org.glassfish.jersey.uri.UriTemplate.createUriComponent(UriTemplate.java:1006) at org.glassfish.jersey.uri.UriTemplate.createURIWithStringValues(UriTemplate.java:946) at org.glassfish.jersey.uri.UriTemplate.createURIWithStringValues(UriTemplate.java:882) at org.glassfish.jersey.uri.UriTemplate.createURI(UriTemplate.java:847) at org.glassfish.jersey.uri.internal.JerseyUriBuilder._build(JerseyUriBuilder.java:890) at org.glassfish.jersey.uri.internal.JerseyUriBuilder.build(JerseyUriBuilder.java:807)
原代码示例:
String key = "b4o3h4{g}fghg3"; String uri = UriBuilder.fromUri(getUriForName(name)) .queryParam("name", name) .queryParam("key", key) .build();
解决方案
方法1:提前对参数值进行URL编码
将包含{}的参数值先做URL编码,再传入queryParam,避免被识别为模板:
import java.net.URLEncoder; import java.nio.charset.StandardCharsets; String key = "b4o3h4{g}fghg3"; // 对key进行URL编码,转义特殊字符 String encodedKey = URLEncoder.encode(key, StandardCharsets.UTF_8.name()); String uri = UriBuilder.fromUri(getUriForName(name)) .queryParam("name", name) .queryParam("key", encodedKey) .build();
编码后{}会被转为%7B和%7D,UriBuilder不会再将其识别为模板变量,同时符合URL规范。
方法2:手动转义参数中的特殊字符
如果仅需处理{},可以直接替换字符串中的{}为对应的URL转义字符:
String key = "b4o3h4{g}fghg3"; // 手动转义{和} String escapedKey = key.replace("{", "%7B").replace("}", "%7D"); String uri = UriBuilder.fromUri(getUriForName(name)) .queryParam("name", name) .queryParam("key", escapedKey) .build();
这种方式针对性强,但如果参数包含其他URL特殊字符(如&、=等),建议使用方法1的通用编码方式。
内容的提问来源于stack exchange,提问作者gurdingering
相关产品推荐
相关产品推荐

