LFilips
LFilips

Reputation: 96

Spring @InitBinder on @RequestBody

I'm trying to use the @InitBind annotation to map only certain fields on the object in the request body.

I have a spring controller defined in this way:

@RequestMapping(value = "addAddress", method = RequestMethod.POST)
public Object addAddressToPerson(
        HttpServletRequest request,
        HttpServletResponse res,
        @RequestParam(value = "name", required = false) String name,
        @RequestParam(value = "surname", required = false) String surname,
        @RequestBody personDTO personJson,BindingResult result) {

The client request will be a a json representing a personDTO, but I don't want that field except the address to be mapped in the object for security reasons.

The input will be something like:

{ "address":"123 Street","........}

The personDTO contains many fields, and since spring map all of them directly in a DTO, that can be a problem.

I've seen that a solution is to use a Binder to declase the allowed or Disallowed field, but if I check the personDTO inside the controller, other fields are populate (for example if pass "id":"1234").

Any Hints?

The binder code is the following:

    @InitBinder("orderJson")
protected void orderJsonBinder(WebDataBinder binder){
    binder.setAllowedFields(new String[]{"address"});
}

Am I missing something?

Best Regards,

Luca.

Upvotes: 5

Views: 4660

Answers (1)

Serge Ballesta
Serge Ballesta

Reputation: 149105

But you are not binding request parameters to a model attribute bean, you are just asking spring to use an appropriate MessageConverter to convert the request body. As you say it is Json, you will use a MappingJackson2HttpMessageConverter (or MappingJacksonHttpMessageConverter with Jackson 1.x). The Spring Reference Manual says for this converter :

[This is an] HttpMessageConverter implementation that can read and write JSON using Jackson's ObjectMapper. JSON mapping can be customized as needed through the use of Jackson's provided annotations. When further control is needed, a custom ObjectMapper can be injected through the ObjectMapper property for cases where custom JSON serializers/deserializers need to be provided for specific types. By default this converter supports (application/json).

@InitBinder can only configure binding of @ModelAttribute annotated parameters. It is useless here. If Jackson annotations are not enough, you will have to use a custom object mapper.

And I am surprised that you can use a BindingResult after a @RequestBody parameter, because the documentation says that it should follow a @ModelAttribute one.

Upvotes: 3

Related Questions