java.lang.IllegalArgumentException: Not enough variable values available to expand 'phone'
at org.springframework.web.util.UriComponents$VarArgsTemplateVariables.getValue(UriComponents.java:367)
at org.springframework.web.util.HierarchicalUriComponents$QueryUriTemplateVariables.getValue(HierarchicalUriComponents.java:1055)
at org.springframework.web.util.UriComponents.expandUriComponent(UriComponents.java:262)
at org.springframework.web.util.HierarchicalUriComponents.lambda$expandQueryParams$5(HierarchicalUriComponents.java:443)
at java.util.Map.forEach(Map.java:630)
at org.springframework.web.util.HierarchicalUriComponents.expandQueryParams(HierarchicalUriComponents.java:439)
at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:429)
at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:51)
at org.springframework.web.util.UriComponents.expand(UriComponents.java:172)
at org.springframework.web.util.DefaultUriBuilderFactory$DefaultUriBuilder.build(DefaultUriBuilderFactory.java:376)
at org.springframework.web.util.DefaultUriBuilderFactory.expand(DefaultUriBuilderFactory.java:202)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:669)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:414)
这是个占位符的问题。
RestTemplate
在请求的 url 中存在{phone}
这个值,默认到参数中找对应的值做替换。
解析 url 中存在的特殊值
正则表达式"\\{([^/]+?)\\}"
命中了{phone}
,那么程序回去寻找参数中的phone
进行替换。
private static final Pattern NAMES_PATTERN = Pattern.compile("\\{([^/]+?)\\}")
@Nullable
static String expandUriComponent(@Nullable String source, UriTemplateVariables uriVariables,
@Nullable UnaryOperator<String> encoder) {
if (source == null) {
return null
if (source.indexOf('{') == -1) {
return source
if (source.indexOf(':') != -1) {
source = sanitizeSource(source)
Matcher matcher = NAMES_PATTERN.matcher(source)
StringBuffer sb = new StringBuffer()
while (matcher.find()) {
String match = matcher.group(1)
String varName = getVariableName(match)
Object varValue = uriVariables.getValue(varName)
if (UriTemplateVariables.SKIP_VALUE.equals(varValue)) {
continue
String formatted = getVariableValueAsString(varValue)
formatted = encoder != null ? encoder.apply(formatted) : Matcher.quoteReplacement(formatted)
matcher.appendReplacement(sb, formatted)
matcher.appendTail(sb)
return sb.toString()
从 uriVariables 中寻值
如果找不到 phone,则会提示异常IllegalArgumentException
* URI template variables backed by a variable argument array.
private static class VarArgsTemplateVariables implements UriTemplateVariables {
private final Iterator<Object> valueIterator;
public VarArgsTemplateVariables(Object... uriVariableValues) {
this.valueIterator = Arrays.asList(uriVariableValues).iterator();
@Override
@Nullable
public Object getValue(@Nullable String name) {
if (!this.valueIterator.hasNext()) {
throw new IllegalArgumentException("Not enough variable values available to expand '" + name + "'");
return this.valueIterator.next();
我们这边抛出异常,是因为有部分历史数据中用户的手机号中设置成138${phone}
这种值,在写入的时候没有做合法性校验。
URL
把花括号{}
中的内容当成了占位符,而又没有传入占位符对应的值,才导致报错。