6

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
  • 16,175
  • 10
  • 47
  • 53
  • May I know why you expecting it under anXMLMessage field ? Try http://stackoverflow.com/questions/4118670/sending-multipart-file-as-post-parameters-with-resttemplate-requests – Rudy Mar 11 '13 at 07:36
  • @Rudy the XML message itself will be produced by serializing a Map using XStream. I'll add that information to my question. Thank you for the link :) – zfranciscus Mar 11 '13 at 08:48

1 Answers1

2

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).

artbristol
  • 32,010
  • 5
  • 70
  • 103
  • It 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 – zfranciscus Mar 11 '13 at 11:31
  • I noticed that the `StringHttpMessageConverter` by default adds the HTTP header `Content-Type: text/plain` rather than your desired `text/html` - configuring that correctly (in the way you configured the `Jaxb2RootElementHttpMessageConverter` in your question) might fix it – artbristol Mar 11 '13 at 11:51
  • @artbristol I also have similar question [here](http://stackoverflow.com/questions/27758462/how-to-post-xml-data-through-resttemplate-in-the-body-of-request) 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. – john Jan 04 '15 at 12:14