values) {
if (values != null)
return header(configKey, toArray(values, String.class));
return header(configKey, (String[]) null);
}
/**
* Replaces all existing headers with the newly supplied headers.
*
*
relationship to JAXRS 2.0
*
* Like {@code Invocation.Builder.headers(MultivaluedMap)}, except the
* values can be templatized.
*
* ex.
*
*
* template.headers(ImmutableMultimap.of("X-Application-Version", "{version}"));
*
*
* @param headers if null, remove all headers. else value to replace all headers
* with.
* @see #headers()
*/
public RequestTemplate headers(Map> headers) {
if (headers == null || headers.isEmpty())
this.headers.clear();
else
this.headers.putAll(headers);
return this;
}
/**
* Returns an immutable copy of the current headers.
*
* @see Request#headers()
*/
public Map> headers() {
return Collections.unmodifiableMap(headers);
}
/**
* replaces the {@link feign.Util#CONTENT_LENGTH} header.
*
* Usually populated by an {@link feign.codec.Encoder}.
*
* @see Request#body()
*/
public RequestTemplate body(String body) {
this.body = body;
if (this.body != null) {
byte[] contentLength = body.getBytes(UTF_8);
header(CONTENT_LENGTH, String.valueOf(contentLength.length));
}
this.bodyTemplate = null;
return this;
}
/* @see Request#body() */
public String body() {
return body;
}
/**
* populated by {@link Body}
*
* @see Request#body()
*/
public RequestTemplate bodyTemplate(String bodyTemplate) {
this.bodyTemplate = bodyTemplate;
this.body = null;
return this;
}
/**
* @see Request#body()
* @see #expand(String, Map)
*/
public String bodyTemplate() {
return bodyTemplate;
}
/**
* if there are any query params in the {@link #body()}, this will extract
* them out.
*
* @return
*/
private StringBuilder pullAnyQueriesOutOfUrl(StringBuilder url) {
// parse out queries
int queryIndex = url.indexOf("?");
if (queryIndex != -1) {
String queryLine = url.substring(queryIndex + 1);
Map> firstQueries = parseAndDecodeQueries(queryLine);
if (!queries.isEmpty()) {
firstQueries.putAll(queries);
queries.clear();
}
queries.putAll(firstQueries);
return new StringBuilder(url.substring(0, queryIndex));
}
return url;
}
private static Map> parseAndDecodeQueries(String queryLine) {
Map> map = new LinkedHashMap>();
if (emptyToNull(queryLine) == null)
return map;
if (queryLine.indexOf('&') == -1) {
if (queryLine.indexOf('=') != -1)
putKV(queryLine, map);
else
map.put(queryLine, null);
} else {
char[] chars = queryLine.toCharArray();
int start = 0;
int i = 0;
for (; i < chars.length; i++) {
if (chars[i] == '&') {
putKV(queryLine.substring(start, i), map);
start = i + 1;
}
}
putKV(queryLine.substring(start, i), map);
}
return map;
}
private static void putKV(String stringToParse, Map> map) {
String key;
String value;
// note that '=' can be a valid part of the value
int firstEq = stringToParse.indexOf('=');
if (firstEq == -1) {
key = urlDecode(stringToParse);
value = null;
} else {
key = urlDecode(stringToParse.substring(0, firstEq));
value = urlDecode(stringToParse.substring(firstEq + 1));
}
Collection values = map.containsKey(key) ? map.get(key) : new ArrayList();
values.add(value);
map.put(key, values);
}
@Override public String toString() {
return request().toString();
}
/**
* Replaces query values which are templated with corresponding values from the {@code unencoded} map.
* Any unresolved queries are removed.
*/
public void replaceQueryValues(Map unencoded) {
Iterator>> iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Entry> entry = iterator.next();
if (entry.getValue() == null) {
continue;
}
Collection values = new ArrayList();
for (String value : entry.getValue()) {
if (value.indexOf('{') == 0 && value.indexOf('}') == value.length() - 1) {
Object variableValue = unencoded.get(value.substring(1, value.length() - 1));
// only add non-null expressions
if (variableValue == null) {
continue;
}
if (variableValue instanceof Iterable) {
for (Object val : Iterable.class.cast(variableValue)) {
values.add(urlEncode(String.valueOf(val)));
}
} else {
values.add(urlEncode(String.valueOf(variableValue)));
}
} else {
values.add(value);
}
}
if (values.isEmpty()) {
iterator.remove();
} else {
entry.setValue(values);
}
}
}
public String queryLine() {
if (queries.isEmpty())
return "";
StringBuilder queryBuilder = new StringBuilder();
for (String field : queries.keySet()) {
for (String value : valuesOrEmpty(queries, field)) {
queryBuilder.append('&');
queryBuilder.append(field);
if (value != null) {
queryBuilder.append('=');
if (!value.isEmpty())
queryBuilder.append(value);
}
}
}
queryBuilder.deleteCharAt(0);
return queryBuilder.insert(0, '?').toString();
}
private static final long serialVersionUID = 1L;
}