我正在开发一个Android项目,它需要一个JSONObject作为POST请求的主体。在输入JSON的键和值之后,我得到了下面这行代码:
{
"xxxx":"zzzzzzz",
"yyyy":"uuuuuuu"
}
但是服务器得到了以下信息:
{
"name_value_pairs": {
"xxxx":"zzzzzzz",
"yyyy":"uuuuuuu"
}
}
我已经尝试了JSONStringer,但它没有真正的帮助,因为请求的Content-Type
是application/json
。
更新
我并没有试图构造一个JSONObject,因为它已经通过使用下面的代码行(与@osayilgan给出的代码相同)完成了:
JSONObject jsonRequest = new JSONObject();
jsonRequest.put("xxxx", "zzzzzzz");
jsonRequest.put("yyyy", "uuuuuuu");
这里没有问题。下面描述的接口是用来与服务器通信的。
public interface MyService {
@Headers({"Content-type: application/json",
"Accept: */*"})
@POST("/test")
void testFunction(@Body JSONObject jsonObject, Callback<Response> callback);
}
服务器收到的请求是第二个JSON作为Body,这令人失望。我注意到关键字name_value_pairs
被自动添加到对象中。
有人知道我该怎么解决这个问题吗?
8条答案
按热度按时间ecbunoof1#
版本:
默认情况下,Retrofit使用GSON将HTTP主体转换为JSON,或者将JSON转换为HTTP主体。使用@Body注解指定的对象将被传递到GSON进行序列化,这基本上将JAVA对象转换为JSON表示。此JSON表示将成为HTTP请求主体。
JSONObject将所有键-值Map存储在一个名为
nameValuePairs
的成员变量中。当您将JSONObject传递给@Body注解时,此JSONObject被序列化,因此HTTP请求正文包含:{“名称值对”:“实际JSON对象”}。
解决方案:
将实际的JAVA对象传递给@Body注解,而不是它对应的JSONObject。GSON将负责将它转换为JSON表示。
例如:
替代解决方案:
如果您仍然希望将原始JSON作为HTTP请求主体发送,请遵循Retrofit作者here提到的解决方案。
建议的解决方案之一是使用TypedInput:
dldeef672#
请使用com.google.gson.jsonObject,而不要使用org.json.jsonObject。
更改为
然后在界面
JSONObject类使用变量名
nameValuePairs
保存LinkedHashMap
中的值,当Gson尝试将JSONObject的示例转换为JSON时,GSON保存了结构(其中包含变量nameValuePairs
)。这导致了此问题。daupos2t3#
必须将JSON对象转换为GSON的JSON对象
沿着这条路走
然后传递到主体
46scxncf4#
感谢13KZ,为我指明了正确的方向,在这里充实它就是我现在要解决的问题。
定义
初始化
用途
其中data是一个字符串,value是一个int,在for循环中添加多个值
然后把它们组合在一起
最后我的接口
我的服务器上显示的是
6rvt4ljy5#
看起来您正在尝试传输实际的
JSONObject
,而不是对象的JSON文本字符串表示。查看JSONObject
类的规范,您应该使用.toString()
方法来获取由JSONObject
保存的数据结构的JSON文本表示。因此,您应该能够更改:至:
唯一的变更是
JSONObject jsonObject
变更为String jsonObject.toString()
。或者,您也可以直接使用JSON中的字符串,将
'"name_value_pairs": {'
替换为''
,将字符串中的最后一个'}'
替换为''
,这两个替换将生成一个有效的JSON文本对象,空格缩进对人来说看起来并不正确,但是解析JSON字符串的机器并不关心空格是否正确。ztyzrc3y6#
我的解决方案基于13KZ的
yuvru6vn7#
rur96b6h8#