0

Consider this code:

Foo{ String prop1; String prop2 }
Bar{ String prop1; int prop2 }
@GetMapping("/getFoo")
public Mono<ResponseEntity<Foo>> getFoo() {
        return Mono.just(new Bar("a", 1))
                   .map(f -> new ResponseEntity(f, HttpStatus.OK);
    }
@Test
public void test() {
        webTestClient.get()
                     .uri("/getFoo")
                     .exchange()
                     .expectBody(Foo.class)
                     .consumeWith(f -> { assertEquals("a", f.getProp1());});
    }

The test works while I've never created the entity of type Foo. Java being strongly typed I would expect a cast error somewhere. I assume that Spring Web does introspection to avoid the error, but it surprises me. Is it really of feature of Spring Web ? Or do I miss something ?

ThCollignon
  • 976
  • 3
  • 14
  • 31

1 Answers1

0

What you are seeing is coercion by the JSON serialize/deserialize process. By default Jackson (and other JSON providers) will automatically convert integers to and from Strings as part of processing the payload.

For example your Bar payload would be:

{
   "prop1": "a",
   "prop2": 1
}

And then Jackson (or your json library if you're using something else) will turn the 1 into a string for you when it is deserialized.

This can be disabled using a custom deserializer if you want that type of call to fail.

Disable conversion of scalars to strings when deserializing with Jackson

Disable the Number to String automatic conversion in jackson

The call you're making doesn't know anything about the underlying classes and is going to and from an intermediate format that matches based on field names.

Joe W
  • 2,773
  • 15
  • 35
  • Does this JSON serialization happen when instantiating the ResponseEntity ? If no, it's the place where I would expect to have a cast error. – ThCollignon Aug 11 '20 at 08:32