11

we are developing a JSON web service to receive data via the @RequestBody annotation. In case a property is included in the request that does not match with the deserialized bean, we expect an HTTP 400 (Bad request) response, but instead the property is simply ignored. Here is an example:

@RestController
@Slf4j
public class TestController {

  @RequestMapping(method = RequestMethod.POST, value = "/query")
  public void parse(@RequestBody Query query) {
    log.info("Received query: {}", query.toString());
  }
}


@Data
class Query {
  private String from;
  private String to;
}

When posting

{ "from" : "123", "to": "456", "foo" : "bar" }

we get a HTTP 200 response. How can we make Spring MVC return HTTP 400 in this case?

Any help or pointers are highly appreciated.

Note that this is different from this question: How to return 400 HTTP error code when some property of a RequestBody parameter is null?.

Since that question asks how to return 400 when an expected property is absent.

Community
  • 1
  • 1
user152468
  • 3,202
  • 6
  • 27
  • 57

4 Answers4

15

Put this into application.properties:

spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES=true

Here are the relevant docs: Customize the Jackson ObjectMapper

Laurel
  • 5,965
  • 14
  • 31
  • 57
user152468
  • 3,202
  • 6
  • 27
  • 57
7

You can reconfigure your Jackson (assuming you are using it) ObjectMapper to fail on unknown properties.

ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);

In this case your unknown property will throw JsonMappingException and you can introduce custom exception handler to return in this case Response 400.

Ali Dehghani
  • 46,221
  • 15
  • 164
  • 151
Ilya Dyoshin
  • 4,459
  • 1
  • 19
  • 18
  • Good point. But will this help? I should probably do this on the Spring Bean that Spring uses? I will try searching where I get that Bean from. Thanks. – user152468 Mar 11 '16 at 11:00
  • Seems like here is some help: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html#howto-customize-the-jackson-objectmapper – user152468 Mar 11 '16 at 11:01
  • Customization of the Spring Jackson deserialization Bean is done using an application property. See my answer below. – user152468 Mar 11 '16 at 11:29
-1

How about this -

 private String to;

comparing against

{ "from" : "123", "foo" : "bar" }

I think you are comparing to against foo. So deserialization fails.

Anand Vaidya
  • 1,374
  • 11
  • 26
-1

You can use Validation for this Job , the validator will check if these fields are not null , if they are it spring will return 400 error bad request so here is how you do it:

In your Bean:

public class A {
@NotNull
private String firstName;

   public String getFirstName() {
       return firstName;
   }

    public void setFirstName(String firstName) {
       this.firstName = firstName;
   }
}

In your Controler:

@ResponseBody
@RequestMapping(path = "/rest")
public B treatRequest(@RequestBody @Validated A a) {...}

In your Configuration File you should activate the validation like this(probably you allready have it):

    <mvc:annotation-driven/>
achabahe
  • 2,445
  • 1
  • 12
  • 21
  • 1
    I am not asking to validate that some fields are not null. Instead I am asking to fail if fields are given, that are not expected. See my answer below. – user152468 Mar 11 '16 at 11:21