2

我对 Android 上的 HTTP REST 操作有些陌生,我正在使用的服务器使用 PUT 命令来处理更新。我很难将 Spring(适用于 Android)与 Jackson2 一起使用。服务器似乎不适用于application/jsonput 请求(尽管它会回复它们),并且似乎只适用于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 对象做太多工作。

4

3 回答 3

1

如果您可以格式化要发送到的数据MultiValueMap<String, String>,那么解决此问题的一种可能方法是使用FormHttpMessageConverter.

FormHttpMessageConverter:(您可以在链接中查看示例)

一个 HttpMessageConverter 实现,可以从 HTTP 请求和响应中读取和写入表单数据。默认情况下,此转换器读取和写入媒体类型 application/x-www-form-urlencoded。表单数据被读取并写入到MultiValueMap<String,String>.

于 2014-02-10T17:37:13.607 回答
0

重新阅读后,这是一个真实答案的镜头 - 您通过使用以下内容明确使用x-www-form-urlencoded内容类型RequestHeader

HttpHeaders requestHeaders = new HttpHeaders(); 
requestHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

您应该使用APPLICATION_JSON-这是 Javadoc

您还应该考虑在标题中指定字符集和数据类型。Jaxson 对此非常具体,如果您无权访问服务器代码,您将不知道他们期望什么标头。

于 2014-02-03T18:43:41.893 回答
0

伙计,我正在使用 Loopj 的 AsyncHttpClient 用于休息和 json 数据集。这是下面的链接这里

非常简单易懂。你可以试试这个东西。

于 2014-02-10T14:31:26.357 回答