我对 Android 上的 HTTP REST 操作有些陌生,我正在使用的服务器使用 PUT 命令来处理更新。我很难将 Spring(适用于 Android)与 Jackson2 一起使用。服务器似乎不适用于application/json
put 请求(尽管它会回复它们),并且似乎只适用于application/x-www-form-urlencoded
版本(使用 python 和 curl 测试。在 python 上,如果我将标头类型设置为application/json
,它会失败。
我正在使用最新版本的 Spring 和 Jackson2,并且我知道一切设置正确,因为我在同一个 URL 上的 get 请求为我提供了所有正确的信息。
我正在使用 Robospice,但我真的不认为这是相关的。这是我的请求代码。
@Override
public GPIO loadDataFromNetwork() throws Exception {
String url = String.format("http://%s/api/control/gpio", ip);
RestTemplate rt = getRestTemplate();
DefaultHttpClient client = new DefaultHttpClient();
Credentials defaultcreds = new UsernamePasswordCredentials("admin",
password);
client.getCredentialsProvider().setCredentials(
new AuthScope(routerip, 80, AuthScope.ANY_REALM), defaultcreds);
// Makes authentication work.
rt.setRequestFactory(new HttpComponentsClientHttpRequestFactory(client));
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity request = new HttpEntity(data, requestHeaders);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
MappingJackson2HttpMessageConverter map = new MappingJackson2HttpMessageConverter();
messageConverters.add(map);
messageConverters.add(new FormHttpMessageConverter());
rt.setMessageConverters(messageConverters);
ResponseEntity<GPIO> r = rt.exchange(url, HttpMethod.PUT, request, GPIO.class);
return r.getBody();
}
我收到异常说明它找不到转换的方法:
02-01 10:59:29.466: E//DefaultRequestRunner.java:138(30086):
10:59:29.474 Thread-11651 An exception occurred during request network
execution :Could not write request: no suitable HttpMessageConverter
found for request type [com.xxxxx.control.gpio.GPIO] and content
type [application/x-www-form-urlencoded]
GPIO 是我的 POJO 对象。我想将它“放入”服务器,就像序列化并放入它一样。
我查看了以下似乎相当相关的问题:
但是,我需要 put 命令的结果,这需要我使用exchange()
,因为 Springput()
什么都不返回。
我尝试了几个不同的项目(例如删除 GPIO 引用、设置特定的头...),但似乎没有一个工作。我有一种感觉,这可能是一个我不知道如何解决的简单解决方案。如果有人可以帮助我,那就太好了。
TLDR:我将 Spring for Android 与 Jackson2 一起使用。我想序列化我的对象(在本例中为 GPIO),以便可以使用内容类型 application/x-www-form-urlencoded 执行 PUT 请求。但是我无法让杰克逊转换为该类型,只能转换为 application/json,这对我不起作用。我不知道如何解决这个问题,而且我已经没有想法了。如果我找不到解决方案,我可能不得不让 robospice 变笨。(或杰克逊,还不确定哪个。)
解决方案
Spring for Android 似乎并没有简化事情,所以我将它转储并直接在我的 loadDataFromNetwork() 方法中使用了 apache 客户端。Robospice 处理得很好,我可以得到我需要的响应。如果您像我一样花时间学习 apache 客户端,是 HTTP 的新手,我认为这要容易得多。调整 ObjectMapper(比如创建一个 JsonTree 并对其进行解析)可以更轻松地获取我需要的数据,而无需对 POJO 对象做太多工作。