简体   繁体   中英

Spring Boot, Spring MVC JSON RequestBody: Unknown property ignored

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.

Put this into application.properties:

spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES=true

Here are the relevant docs: Customize the Jackson ObjectMapper

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.

How about this -

 private String to;

comparing against

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

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

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/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM