36

Suppose I have three classes.

public abstract class Animal {}

public class Cat extends Animal {}

public class Dog extends Animal {}

Can I do something like this?

Input: a JSON which it is Dog or Cat

Output: a dog/cat depends on input object type

I don't understand why the following code doesn't work. Or should I use two separate methods to handle new dog and cat?

@RequestMapping(value = "/animal", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
private @ResponseBody <T extends Animal>T insertAnimal(@RequestBody T animal) {
    return animal;
}

Error message:

HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalArgumentException: Type variable 'T' can not be resolved

Null
  • 1,950
  • 9
  • 30
  • 33
tl1181231
  • 1,063
  • 1
  • 8
  • 10
  • 2
    What do you mean with "code doesnt work." Runtime error? Compiler error? Where is the error log? You have to help us to understand the problem. Thanks. – Selim Ok Nov 27 '14 at 12:13
  • I'm a bit late, but I think you should accept your own answer. – PhoneixS Apr 04 '18 at 09:17
  • Possible duplicate of [Spring @RequestBody containing a list of different types (but same interface)](https://stackoverflow.com/questions/17247189/spring-requestbody-containing-a-list-of-different-types-but-same-interface) – PhoneixS Apr 04 '18 at 09:19

1 Answers1

62

ref link

I just found the answer myself and here is the reference link.

What I have done is added some code above the abstract class

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.*;

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Cat.class, name = "cat"),
    @JsonSubTypes.Type(value = Dog.class, name = "dog")
})
public abstract class Animal{}

Then in the json input in HTML,

var inputjson = {
    "type":"cat",
    //blablabla
};

After submitting the json and finally in the controller,

@RequestMapping(value = "/animal", method = RequestMethod.POST, produces = "application/json; charset=utf-8", consumes=MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody insertanimal(@RequestBody Animal tmp) {
    return tmp;
}

In this case variable tmp is automatically converted to a Dog or Cat object, depending on json input.

Community
  • 1
  • 1
tl1181231
  • 1,063
  • 1
  • 8
  • 10
  • 4
    is it any way to put some annotation on Cat or Dog, without putting `@JsonSubTypes` on animal? – dmitryvim Nov 10 '16 at 11:26
  • 1
    What is the best practice for this ? – fuat Apr 11 '20 at 17:33
  • For the record, as specified in https://stackoverflow.com/questions/33611199/jackson-jsontypeinfo-property-is-being-mapped-as-null if you want the property to be mapped in the request object, use `visible = true` – user3083022 Jul 28 '23 at 09:32