title: Spring REST with both JSON and XML
body: <p>I want to provide <strong>one</strong> comprehensive REST API with support for both <code>JSON</code> and <code>XML</code>.</p>
  
  <p>The domain model is of complex type and we note that to produce friendly <code>JSON</code> and <code>XML</code> on the same model using <code>MappingJacksonHttpMessageConverter</code> and <code>JaxbMarshaller</code> respectively tends to give <em>either</em> readable XML or readable JSON <sup>1)</sup>. </p>
  
  <p>What's the best way to proceed? </p>
  
  <p><sup>1) Due to how objects such as maps, root tags and relations are modelled differently in <code>json</code> than in <code>xml</code>, the objects to serialize needs to be designed differently to get both tidy <code>json</code> and tidy <code>xml</code>. Utilities such as jaxb annotations only goes that far.</sup></p>
  
  <hr>
  
  <p>I can think of a few candidates</p>
  
  <h2>1) Create both a json and xml controller/model</h2>
  
  <pre><code>public class Controller { 
     public Foo foo() { 
         return new Foo(); 
     } 
  }
  
  public class XmlController extends Controller {
     @Override
     public XmlFoo foo() { 
         return new new XmlFoo(super.foo()); 
     } 
  }
  
  public class JsonController extends Controller {
     @Override
     public JsonFoo foo() { 
         return new JsonFoo(super.foo()); 
     } 
  }
  </code></pre>
  
  <p>Given a model object <code>Foo</code> create a <code>JsonFoo</code> and <code>XmlFoo</code></p>
  
  <h2>2) Write a custom message converter</h2>
  
  <p>I tried this and it turned out to be a bit complicated since the view must know how to resolve e.g., a <code>Foo</code> to a <code>JsonFoo</code> to be able to serialize it into a readable format. </p>
  
  <h2>3) Let each model object serialize itself, e.g.,</h2>
  
  <pre><code>public class Foo {
      public String serialize(Serializer s) {
         return s.serialize(this);
      }
  }
  </code></pre>
  
  <p>Based on some arbitration parameter let the controller inject the correct serializer</p>
  
  <pre><code>new Foo(new FooJsonSerializer());
  new Foo(new FooXmlSerializer());
  </code></pre>