title: Spring generic REST controller: parsing request body
body: <p>I have following controller:</p>
  
  <pre><code>@RestController
  @RequestMapping(value = "/{entity}", produces = MediaType.APPLICATION_JSON_VALUE)
  public class CrudController&lt;T extends SomeSuperEntity&gt; {
  
      @RequestMapping(method = GET)
      public Iterable&lt;T&gt; findAll(@PathVariable String entity) {
      }
  
      @RequestMapping(value = "{id}", method = GET)
      public T findOne(@PathVariable String entity, @PathVariable String id) {
      }
  
      @RequestMapping(method = POST)
      public void save(@PathVariable String entity, @RequestBody T body) {
      }
  }
  </code></pre>
  
  <p><code>SomeSuperEntity</code> class looks like:</p>
  
  <pre><code>public abstract class SomeSuperEntity extends AbstractEntity {
      // some logic
  }
  </code></pre>
  
  <p>And <code>AbstractEntity</code> its abstract class with some field:</p>
  
  <pre><code>public abstract class AbstractEntity implements Comparable&lt;AbstractEntity&gt;, Serializable {
  
      private Timestamp firstField;
      private String secondField;
  
      public Timestamp getFirstField() {
          return firstField;
      }
  
      public void setFirstField(Timestamp firstField) {
          this.firstField = firstField;
      }
  
      public String getSecondField() {
          return secondField;
      }
  
      public void setSecondField(String secondField) {
          this.secondField = secondField;
      }
  }
  </code></pre>
  
  <p>All subclasses of <code>SomeSuperEntity</code> - simple JavaBeans.
  In case with <code>findAll()</code> and <code>findOne(id)</code> methods - everything works fine.
  I create entity in service layer and it returns to client as JSON with all fields that declared in subclass and in <code>AbstractEntity</code>.    </p>
  
  <p>But when i tried to get request body in <code>save(entity, body)</code>, i got following error: </p>
  
  <blockquote>
    <p>Could not read document: Can not construct instance of
    SomeSuperEntity, problem: abstract types either need to be mapped to
    concrete types, have custom deserializer, or be instantiated with
    additional type information</p>
  </blockquote>
  
  <p>If i remove abstract from <code>SomeSuperEntity</code>, everything works, but i request body i got only those fields, that declared in <code>AbstractEntity</code>.</p>
  
  <p>And here is my question, is there any workaround for such problems in my case?
  If not, what would by the best solution here without any structure changes (making subcontloller for each entity is not an option)? Is retrieve body as plain text would be a good idea? Or it would be better to use <code>Map</code> for this?</p>
  
  <p>I'm using Spring v4.2.1 and Jackson 2.6.3 as converter.  </p>
  
  <p>There is a bit of information about generic controllers, but i couldn't find anything that cover my case. So, please, navigate in case of duplicate question.</p>
  
  <p>Thanks in advance.</p>
  
  <p><strong>UPD</strong>: Currently its working as follow:
  I add add additional check in my <code>MessageConverter</code> and define <code>@RequestBody</code> as <code>String</code></p>
  
  <pre><code>@Override
      public Object read(Type type, Class&lt;?&gt; contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
          if (IGenericController.class.isAssignableFrom(contextClass)) {
              return CharStreams.toString(new InputStreamReader(inputMessage.getBody(), getCharset(inputMessage.getHeaders())));
          }
          return super.read(type, contextClass, inputMessage);
      }
  </code></pre>
  
  <p>Then, on service layer, i define what entity received (in plain json) and convert it:</p>
  
  <pre><code>final EntityMetaData entityMetadata = getEntityMetadataByName(alias);
  final T parsedEntity = getGlobalGson().fromJson(entity, entityMetadata.getEntityType());
  </code></pre>
  
  <p>Where <code>EntityMetaData</code> is <code>enum</code> with defined relations between entity alias and class. Alias comes as <code>@PathVariable</code>. </p>