提交 4c381475 编写于 作者: D Dima Gerasimov 提交者: Jake Wharton

Optional @Field/@FieldMap URL-encoding.

上级 9b0cc00c
......@@ -272,26 +272,32 @@ final class RequestBuilder implements RequestInterceptor.RequestFacade {
}
} else if (annotationType == Field.class) {
if (value != null) { // Skip null values.
String name = ((Field) annotation).value();
Field field = (Field) annotation;
String name = field.value();
boolean encodeName = field.encodeName();
boolean encodeValue = field.encodeValue();
if (value instanceof Iterable) {
for (Object iterableValue : (Iterable<?>) value) {
if (iterableValue != null) { // Skip null values.
formBody.addField(name, iterableValue.toString());
formBody.addField(name, encodeName, iterableValue.toString(), encodeValue);
}
}
} else if (value.getClass().isArray()) {
for (int x = 0, arrayLength = Array.getLength(value); x < arrayLength; x++) {
Object arrayValue = Array.get(value, x);
if (arrayValue != null) { // Skip null values.
formBody.addField(name, arrayValue.toString());
formBody.addField(name, encodeName, arrayValue.toString(), encodeValue);
}
}
} else {
formBody.addField(name, value.toString());
formBody.addField(name, encodeName, value.toString(), encodeValue);
}
}
} else if (annotationType == FieldMap.class) {
if (value != null) { // Skip null values.
FieldMap fieldMap = (FieldMap) annotation;
boolean encodeNames = fieldMap.encodeNames();
boolean encodeValues = fieldMap.encodeValues();
for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
Object entryKey = entry.getKey();
if (entryKey == null) {
......@@ -300,7 +306,8 @@ final class RequestBuilder implements RequestInterceptor.RequestFacade {
}
Object entryValue = entry.getValue();
if (entryValue != null) { // Skip null values.
formBody.addField(entryKey.toString(), entryValue.toString());
formBody.addField(entryKey.toString(), encodeNames, entryValue.toString(),
encodeValues);
}
}
}
......
......@@ -56,4 +56,10 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
public @interface Field {
String value();
/** Specifies whether {@link #value()} is URL encoded. */
boolean encodeName() default true;
/** Specifies whether the argument value to the annotated method parameter is URL encoded. */
boolean encodeValue() default true;
}
......@@ -44,4 +44,9 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface FieldMap {
/** Specifies whether parameter names (keys in the map) are URL encoded. */
boolean encodeNames() default true;
/** Specifies whether parameter values (values in the map) are URL encoded. */
boolean encodeValues() default true;
}
......@@ -24,6 +24,10 @@ public final class FormUrlEncodedTypedOutput implements TypedOutput {
final ByteArrayOutputStream content = new ByteArrayOutputStream();
public void addField(String name, String value) {
addField(name, true, value, true);
}
public void addField(String name, boolean encodeName, String value, boolean encodeValue) {
if (name == null) {
throw new NullPointerException("name");
}
......@@ -34,8 +38,12 @@ public final class FormUrlEncodedTypedOutput implements TypedOutput {
content.write('&');
}
try {
name = URLEncoder.encode(name, "UTF-8");
value = URLEncoder.encode(value, "UTF-8");
if (encodeName) {
name = URLEncoder.encode(name, "UTF-8");
}
if (encodeValue) {
value = URLEncoder.encode(value, "UTF-8");
}
content.write(name.getBytes("UTF-8"));
content.write('=');
......
......@@ -1456,6 +1456,30 @@ public class RequestBuilderTest {
assertTypedBytes(request.getBody(), "foo=bar&ping=pong");
}
@Test public void formEncodedWithEncodedNameFieldParam() {
class Example {
@FormUrlEncoded //
@POST("/foo") //
Response method(@Field(value = "na+me", encodeName = false) String foo) {
return null;
}
}
Request request = buildRequest(Example.class, "ba r");
assertTypedBytes(request.getBody(), "na+me=ba+r");
}
@Test public void formEncodedWithEncodedValueFieldParam() {
class Example {
@FormUrlEncoded //
@POST("/foo") //
Response method(@Field(value = "na me", encodeValue = false) String foo) {
return null;
}
}
Request request = buildRequest(Example.class, "ba+r");
assertTypedBytes(request.getBody(), "na+me=ba+r");
}
@Test public void formEncodedFieldOptional() {
class Example {
@FormUrlEncoded //
......@@ -1511,6 +1535,40 @@ public class RequestBuilderTest {
assertTypedBytes(request.getBody(), "foo=1&foo=2&foo=3&kit=kat");
}
@Test public void formEncodedWithEncodedNameFieldParamMap() {
class Example {
@FormUrlEncoded //
@POST("/foo") //
Response method(@FieldMap(encodeNames = false) Map<String, Object> fieldMap) {
return null;
}
}
Map<String, Object> fieldMap = new LinkedHashMap<String, Object>();
fieldMap.put("k+it", "k at");
fieldMap.put("pin+g", "po ng");
Request request = buildRequest(Example.class, fieldMap);
assertTypedBytes(request.getBody(), "k+it=k+at&pin+g=po+ng");
}
@Test public void formEncodedWithEncodedValueFieldParamMap() {
class Example {
@FormUrlEncoded //
@POST("/foo") //
Response method(@FieldMap(encodeValues = false) Map<String, Object> fieldMap) {
return null;
}
}
Map<String, Object> fieldMap = new LinkedHashMap<String, Object>();
fieldMap.put("k it", "k+at");
fieldMap.put("pin g", "po+ng");
Request request = buildRequest(Example.class, fieldMap);
assertTypedBytes(request.getBody(), "k+it=k+at&pin+g=po+ng");
}
@Test public void formEncodedFieldMap() {
class Example {
@FormUrlEncoded //
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册