2017-09-25 129 views
2

我正在编写一段简单的Java代码,它调用一个REST API来模仿我用curl做的相同的代码。卷曲命令发送POST请求到登录终点:应用程序的内容类型包括字符集

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' 

当这个成功,则得到一个204 HTTP响应代码和令牌作为HTTP标头。

现在,用下面的代码,我没有得到相同的结果,而是得到了一个HTTP 200,没有令牌,也没有正文。

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(); 

在试图理解我在做什么错的过程中,我遇到过一个反向代理(我使用“查尔斯”)的要求,实现了内容类型由okhttp3设置了包括字符集应用程序/ 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} 

我验证了匹配卷曲声明还未能

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' 

这是一个已知的问题? (这是我的理解,RFC的内容类型只允许字符集的文本/ *内容类型,但我不是那方面的专家!)

我该怎么做才能覆盖内容类型以删除charset部分?

回答

1

您正在使用Java String将您的JSON数据传递到RequestBody.create()。每OkHttp文档:

 
public static RequestBody create(@Nullable 
           MediaType contentType, 
           String content) 

返回传送内容的新请求主体。 如果contentType非空并且缺少字符集,则将使用UTF-8。

所以,你正在使用故意方法强制UTF-8,所以它很可能添加charset属性相匹配。

尝试使用其他create()方法中的一个将byte[]okio.ByteString作为输入,而不是Java String。他们没有记录为强制UTF-8,因为他们正在采取原始字节作为输入,所以它是调用者的责任,指定charset只有一个实际需要:

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}")); 
+0

我确认使用带'byte []'输入的'create()'工作。我不喜欢使用解决方法,但在这一点上对我来说已经足够了! :) –

相关问题