2

After two days, I'm stuck with the following...

If I specify the type in the controller, it works:

@RestController
public class FooController {
    @RequestMapping(method = RequestMethod.POST)
    protected ResponseModel bar(@Valid @RequestBody Foo foo) {
        // here I have foo of type Foo
    }
}

However, if I try to take advantage of generics, it doesn't work:

public class Base<U> {
    @RequestMapping(method = RequestMethod.POST)
    protected ResponseModel bar(@Valid @RequestBody U entity) {
        // here I get java.util.LinkedHashMap instead of U
        // which, in the FooController, should be Foo
    }
}

@RestController
public class FooController extends Base<Foo> {
}

Looking at the logs, when it hits the controller with defined type I get:

Read [class com...Foo] as "application/json;charset=UTF-8" with [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@cee662]

While at the generic one:

Read [U] as "application/json;charset=UTF-8" with [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@cee662]

Q: What should I do to take advantage of the Generic Type, and to be able to cut the repeated code from the controllers?

Note: this is NOT a duplicate, since all the other questions are about List<T> or from an issue on ~2.6.*

Addendum: Yuri-M-Dias suggested downgrading, which I did, so 2.5.5 works with a Generic Type, but 2.8.4 doesn't. (At least for now I have a bad and good revision to work with...)

Going further into the downgrade...

I found out that the revision 2.7.9 is a good one, I get Foo out of U, while on the 2.8.0 I get the LinkedHashMap<K,V>... maybe I missed something from the 2.8.0 release ?

Community
  • 1
  • 1
joaumg
  • 1,238
  • 1
  • 12
  • 27
  • Why don't you use a String and then convert it using Jackson's ObjectMapper? – zakaria amine Mar 10 '17 at 15:21
  • This could solve to a simple entity with no `List` inside of it. But once I get there, I would lose the type infer which Jackson does quite well... And I would also lose the possibility to solve the `List` issue with type annotation... – joaumg Mar 10 '17 at 15:48
  • Might be related to these Jackson issues: [Deserialization with generic types not working since 2.7.0](https://github.com/FasterXML/jackson-databind/issues/1210) / [Deserialization Not Working Right with Generic Types and Builders](https://github.com/FasterXML/jackson-databind/issues/921). 1st link notes a fix in 2.7.4. 2nd link experiences same symptoms, receiving `LinkedHashMap` instead of expected class but doesn't appear anyone is working on the issue currently. – Jon Sampson Mar 10 '17 at 20:17

1 Answers1

0

I don't know if you happened to see Generic Controller in Spring MVC, but it may be instructive. Still, I'm not happy with what I'm about to describe, because I see what you're trying to do above. Additionally, I can't give you the reason behind the possible "necessity." Hopefully someone else will be able to fill that it.

@RestController
public class FooController extends Base<Foo> {
    @RequestMapping(method = RequestMethod.POST)
    protected ResponseModel bar(@Valid @RequestBody Foo foo) {
        super.bar(foo);
    }
}

Seems like that should make everything happy.

Community
  • 1
  • 1
Jon Sampson
  • 1,473
  • 1
  • 21
  • 31