I was writing a piece of simple Java code that calls a REST API to mimic the same I did with curl. The curl command sends a POST request to a login end-point:
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
"username": "MicroStrategy",
"password": "MyPassword",
"loginMode": 1
}' 'https://env-792.customer.cloud.microstrategy.com/MicroStrategyLibrary/api/auth/login'
When this succeeds, you get back a 204 HTTP response code and a token as an HTTP Header.
Now, with the following code, I did not get the same result and instead got a HTTP 200 and no token and no body.
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"username\": \"MicroStrategy\", \"password\": \"MyPassword\", \"loginMode\": 1}");
Request urlrequest = new Request.Builder()
.url("https://env-792.customer.cloud.microstrategy.com/MicroStrategyLibrary/api/auth/login")
.addHeader("accept", "application/json")
.post(body)
.build();
OkHttpClient client = new OkHttpClient();
Response urlresponse = client.newCall(urlrequest).execute();
In the process of trying to understand what I was doing wrong, I ran the request through a reverse proxy (I used "Charles") and realized that the content-type set by okhttp3 was including the charset for application/json:
POST /MicroStrategyLibrary/api/auth/login HTTP/1.1
accept: application/json
Content-Type: application/json; charset=utf-8
Content-Length: 63
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.8.0
Host: env-792.customer.cloud.microstrategy.com
{"username": "MicroStrategy", "password": "MyPassword", "loginMode": 1}
I verified that the matching curl statement also fails
curl -X POST --header 'Content-Type: application/json; charset=utf-8' --header 'Accept: application/json' -d '{
"username": "MicroStrategy",
"password": "MyPassword",
"loginMode": 1
}' 'https://env-792.customer.cloud.microstrategy.com/MicroStrategyLibrary/api/auth/login'
Is this a known issue? (it is my understanding that the RFC for content type only allows charset for the text/* content-types; but I'm no expert in that area!)
What can I do to overwrite the Content-Type to remove the charset part?
You are passing your JSON data to RequestBody.create()
using a Java String
. Per the OkHttp documentation:
\npublic static RequestBody create(@Nullable\n MediaType contentType,\n String content)\nReturns a new request body that transmits content. If contentType is non-null and lacks a charset, this will use UTF-8.
So, the method you are using intentionally forces UTF-8, so it is likely adding the charset
attribute to match.
Try using one of the other create()
methods that takes a byte[]
or okio.ByteString
as input instead of a Java String
. They are not documented as forcing UTF-8, since they are taking raw bytes as input, so it is the caller's responsibility to specify a charset
only if one is actually needed:
RequestBody body = RequestBody.create(mediaType, "{\"username\": \"MicroStrategy\", \"password\": \"MyPassword\", \"loginMode\": 1}".getBytes(StandardCharsets.UTF_8));
RequestBody body = RequestBody.create(mediaType, okio.ByteString.encodeUtf8("{\"username\": \"MicroStrategy\", \"password\": \"MyPassword\", \"loginMode\": 1}"));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.