简体   繁体   中英

rest POST object using spring for android

I'm trying to POST to a rest service using spring for android(I'm new at this)

The restful service has this structure

@POST
@Path("/ider")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public SearchOutRO hashTrackInJSON(SearchInRO in);

with(shortened object code):

public class SearchInRO implements Serializable {
    private Double latitud;
    private Double longitud;
}

public class SearchOutRO implements Serializable {
    private Integer searchId;
}

so I'm trying this(from android)

String url = BASE_URL + "ider";
HttpHeaders requestHeaders = new HttpHeaders();

requestHeaders.setContentType(MediaType.APPLICATION_JSON);

MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
body.add("searchInRO[latitud]", String.valueOf(user.getLatitud()));
body.add("searchInRO[longitud]", String.valueOf(user.getLongitud()));

HttpEntity<?> requestEntity = new HttpEntity<Object>(body, requestHeaders);
RestTemplate restTemplate = new RestTemplate();

List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new FormHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
restTemplate.setMessageConverters(messageConverters);
try {
    ResponseEntity<SearchOutRO> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, SearchOutRO.class);

    HttpStatus status = response.getStatusCode();
    if (status == HttpStatus.CREATED) {
        return true;
    } else {
        return false;
    }
} catch (Exception e) {
    e.printStackTrace();
    return false;
}

and getting this exception:

org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [application/json]

Could you help me pointing out what am I doing wrong?(and how make it right).
I think it may the the "body" MultiValueMap.

Thanks in advance

EDIT: I tried what @Krisl suggested. I succeed to connect to the server side, but it seems the object is not correctly marshalled.

WARNING: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"latitud"). Expected elements are <{}searchInRO>]

I would appreciate any ideas.

it seems to be your assumption is right, MultiValueMap is causing the trouble.

Try this

Instead of using MultiValueMap set the lat and lng in SearchInRO object and add it.

Change

HttpEntity<?> requestEntity = new HttpEntity<Object>(body, requestHeaders);

to

SearchInRO searchInRO = new SearchInRO();

set the lat and lng

HttpEntity<?> requestEntity = new HttpEntity<Object>(searchInRO , requestHeaders);

Also add MappingJacksonHttpMessageConverter

 messageConverters.add(new MappingJacksonHttpMessageConverter());

UPDATE : I just checked one of my old project which uses REST and noticed that I used jersey-json jar also (my case maven dependency).
Try this add jersey-json jar to your classpath and update the web.xml like given below

<init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

I think you are missing HttpMessageConverter bean. If you are producing and consuming JSON data, there should be some way to convert java POJO to JSON and vice-versa. Try adding following bean in your context xml file.

<beans:bean id="jacksonMessageChanger"
    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
    <beans:property name="supportedMediaTypes" value="application/json" />
</beans:bean>

<beans:bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <beans:property name="messageConverters">
        <util:list id="beanList">
            <beans:ref bean="jacksonMessageChanger" />
        </util:list>
    </beans:property>
</beans:bean>

Also you would need to add maven dependencies for jackson mappers.

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.8.5</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.8.5</version>
</dependency>

diff approach using jackson with a writer to go to string before you set the HttpEntity...

ref

ObjectNode rootOb = new ObjectMapper().createObjectNode();
  { create obj nodes , adding each to rootNode }
  {jackson api to go to string }

    StringWriter writer = new StringWriter();
    new ObjectMapper().writeValue(writer, rootOb);
    String poststr=writer.toString();

httpPost.setEntity(new StringEntity(poststr));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM