How to POST XML using RestTemplate
You don't need to use Spring's JAXB marshalling message converter - you've already done the work by making it into a String
. Just POSTing the String
(like in your code) ought to work (lose the String.class
argument though, that's intended for URL variables, and get rid of the setMessageConverters
call, because that is preventing the default StringHttpMessageConverter
from working).
zfranciscus
I am a software developer and a writer for How-To Geek. You can find me tweeting at twitter or bookmarking interesting sites on delicious .
Updated on June 07, 2022Comments
-
zfranciscus almost 2 years
I intend to POST an XML message using Spring Rest Template. After a number of failures, I am starting to doubt whether Spring Rest Template can POST an XML message. This is a Restful client that I developed. The RestTemplate is intended to do an HTTP post of an XML to a RestFul webservice:
Class RestClient{ public static void main(String[] args) { RestTemplate restTemplate = new RestTemplate(); List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>(); //This JAXB Message converter is intended to marshal an XML message over HTTP. //However, I find this converter is not doing the intended function. Jaxb2RootElementHttpMessageConverter jaxbMessageConverter = new Jaxb2RootElementHttpMessageConverter(); List<MediaType> mediaTypes = new ArrayList<MediaType>(); mediaTypes.add(MediaType.TEXT_HTML); jaxbMessageConverter.setSupportedMediaTypes(mediaTypes); messageConverters.add(jaxbMessageConverter); restTemplate.setMessageConverters(messageConverters); restTemplate.postForLocation("http://localhost:8080/RecipeProject/restCallConsumer", "<add><somefield></somefield></add>",String.class); }
}
This controller is intended to consume the XML message. The controller was written to test that the client can send the XML message appropriately:
@RequestMapping("/") @Controller public class HomeController { @RequestMapping(value = "/restCallConsumer", method = RequestMethod.POST) public String restCallConsumer(String anXML) { System.out.println("anXML: " + anXML); return "aView"; } }
Most of the example I found around using XML with RestTemplate involves using an object mapping tool. This tool maps object to an XML and vice versa. In my case, I only have an XML string that I want to send via HTTP post. Has anyone accomplished what I am trying to do ? It could be that RestFul client is not intended for what I am trying to do. Any answer would be appreciated :)
EDIT
THe XML message is produced by serializing a Map using Xstream. This is the code that does that:
com.google.common.collect.LinkedListMultimap.ListMultimap<String, String> multimap = com.google.common.collect.LinkedListMultimap.LinkedListMultimap.create(); multimap.put("x", "1"); multimap.put("x", "2"); multimap.put("y", "3"); XStream xStream = new XStream(new DomDriver()); xStream.registerConverter(new MapEntryConverter(xStream.getMapper())); xStream.alias("add", multimap.getClass()); String xml = xStream.toXML(multimap); System.out.println(xml);
This code is intended to convert the multimap into an XML string using a converter named MapEntryConverter. This is the code for the Converter:
public static class MapEntryConverter extends MapConverter { public MapEntryConverter(Mapper mapper) { super(mapper); } public boolean canConvert(Class clazz) { return ListMultimap.class.isAssignableFrom(clazz); } public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) { ListMultimap<String, String> map = (ListMultimap<String, String>) value; for (String key : map.keys()) { writer.startNode(key); writer.setValue(map.get(key).get(0)); writer.endNode(); } } }
EDIT
I change my code as per @artbristol recommended. I saw this in the log file:
DEBUG: org.springframework.web.client.RestTemplate - Writing [ 1 1 3 ] using [org.springframework.http.converter.StringHttpMessageConverter@1d34263a]
It looks like the restTemplate is POST-ing the XML message. However, the anXML parameter in the controller is null. Does this mean that the XML message could not reach the controller ? Could it be that the controller is not implemented correctly ?
-
zfranciscus about 11 yearsIt look like it works :) However, I could not print out the XML message in the controller. The XML message is null. I added more info in my question. Thank you @artbristol
-
artbristol about 11 yearsI noticed that the
StringHttpMessageConverter
by default adds the HTTP headerContent-Type: text/plain
rather than your desiredtext/html
- configuring that correctly (in the way you configured theJaxb2RootElementHttpMessageConverter
in your question) might fix it -
john over 9 years@artbristol I also have similar question here on
RestTemplate
. If possible, can you help me out? I am stuck on that for a while and not able to understand how to make it work. Any help will be greatly appreciated.