Question

I am somewhat new to HTTP REST operations on Android, and a server I am working with uses PUT commands to process updates. I am having a difficult time using Spring (for Android) with Jackson2. The server doesn't seem to work with application/json put requests (though it will reply with them), and only seem to work with application/x-www-form-urlencoded versions (tested with python and curl. On python, if I set the header type to application/json, it fails.

I am using the latest versions of Spring and Jackson2, and I know everything is setup properly because my get request on the same URL gets me all the correct information.

I am using Robospice, but I don't really think that is relevant. Here is my request code.

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

I am getting the exception stating it cannot find a way to convert:

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 is my POJO object. I want to 'put' that to the server, as in serialize and put it.

I have looked at the following question that seems fairly relevant:

However, I need the result of my put command, and that requires me to use exchange() because Spring's put() returns nothing.

I have tried several different items (such as removing GPIO references, setting specific headres...) and none seem to work. I have a feeling this is probably an easy solution that I don't know how to fix. If anyone can help me that would be great.

TLDR: I'm using Spring for Android with Jackson2. I want to serialize my object (in this example, GPIO) so I can do a PUT request with the content type application/x-www-form-urlencoded. However I cannot get jackson to convert to that type, only to application/json, which does not work for me. I am not sure how to fix this, and I have run out of ideas. If I can't find a solution I'll probably have to dumb robospice. (or jackson, not sure which yet.)

Solution

Spring for Android doesn't seem to simplify things, so I dumped it and used the apache client directly in my loadDataFromNetwork() method. Robospice handles it pretty well and I can get the responses I need. If you are new to HTTP like I was take the time and learn the apache client, it's far easier in my opinion. Tweaking the ObjectMapper (like making a JsonTree and parsing that) made it much easier to get the data I needed without having to do as much work with POJO objects.

Was it helpful?

Solution

If you can format the data you want to send into MultiValueMap<String, String>, then a possible way around this is to use FormHttpMessageConverter.

FormHttpMessageConverter: (you can see examples in the link)

An HttpMessageConverter implementation that can read and write form data from the HTTP request and response. By default, this converter reads and writes the media type application/x-www-form-urlencoded. Form data is read from and written into a MultiValueMap<String,String>.

OTHER TIPS

After re-reading, here's a shot at a real answer - you are explicitly using the x-www-form-urlencoded content type by using this RequestHeader:

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

You should be using APPLICATION_JSON - Here's the Javadoc.

You should also consider specifying the charset and datatype in the headers. Jaxson is very specific about this, and if you don't have access to the server code you don't know what headers they expect.

dude i am using Loopj's AsyncHttpClient for rest and json dataset. Here is the link below Here

Very simple and easy to understand. U can try this thing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top