Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent retrofit from encoding my http request body

I'm trying to pass a string of the format below as the body of a http post request.

param1=PARAM1&param2=PARAM2&param3=PARAM3

But retrofit encodes my body so that = becomes \u003d and & becomes \u0026. And I end up with a string which actually looks like this:

param1\u003dPARAM1\u0026param2\u003dPARAM2\u0026param3\u003dPARAM3

How can I prevent that?

My retrofit rest api is defined as follows.

public interface RestAPI {
    @POST("/oauth/token")
    public void getAccessToken(@Body String requestBody, Callback<Response> response);
}
like image 283
user672009 Avatar asked Oct 29 '14 17:10

user672009


People also ask

How do I send a body in post request in retrofit?

Request Body@POST("users/new") Call<User> createUser(@Body User user); The object will also be converted using a converter specified on the Retrofit instance. If no converter is added, only RequestBody can be used.

What is retrofit HTTP client?

Retrofit is a type-safe REST client for Android, Java and Kotlin developed by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.

What is @body in retrofit?

The @Body annotation defines a single request body. interface Foo { @POST("/jayson") FooResponse postJson(@Body FooRequest body); } Since Retrofit uses Gson by default, the FooRequest instances will be serialized as JSON as the sole body of the request.

Is retrofit RESTful?

Retrofit is a REST Client for Java and Android allowing to retrieve and upload JSON (or other structured data) via a REST based You can configure which converters are used for the data serialization, example GSON for JSON.


2 Answers

If you have a serialized class (like a HashMap) in the request body and you want to prevent encoding that (like in vezikon's and my problem), you can create a custom Gson with disabled escaping using:

Gson gson = new GsonBuilder().disableHtmlEscaping().create();

Pass this converter to your rest adapter:

yourRestAdapter  = new RestAdapter.Builder()
    .setEndpoint(.....)
    .setClient(.....)
    .setConverter(new GsonConverter(gson))
    .build();

This way the "=" characters in the post body stay intact while submitting.

like image 146
Murat Ögat Avatar answered Sep 20 '22 09:09

Murat Ögat


To answer the question directly, you can use TypedString as the method parameter type. The reason the value is being changed is because Retrofit is handing the String to Gson in order to encode as JSON. Using TypedString or any TypedOutput subclass will prevent this behavior, basically telling Retrofit you will handle creating the direct request body yourself.

However, that format of payload is called form URL encoding. Retrofit has native support for it. Your method declaration should actually look like this:

@FormUrlEncoded
@POST("/oauth/token")
void getAccessToken(
    @Field("param1") String param1,
    @Field("param2") String param2,
    @Field("param3") String param3,
    Callback<Response> callback);
like image 29
Jake Wharton Avatar answered Sep 21 '22 09:09

Jake Wharton