Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind request params without setters?

I have a simple controller with a GET handler that accepts an object to bind request parameters:

@RestController
@RequestMapping("/test")
public class SampleController {

    @GetMapping
    public SomeResponse find(RequestParams params) {
       // some code
    }

}

The RequestParams is a simple POJO class:

public class RequestParams  {

    private String param1;
    private String param2;

    // constructor, getter, and setters

}

Everthing works fine, but I would like to get rid of the setters to make the object immutable to public use. In the documentation for @RequestMapping handler method up to Spring 5.0.2, we read that possible valid method arguments are:

Command or form objects to bind request parameters to bean properties (via setters) or directly to fields

Is it possible to somehow override the default Spring Boot configuration so that request parameters are bound to class properties using reflection and not with setters?

Update 2018

In the later versions of Spring's documentation, the quoted statement has been rephrased and no longer contain information about binding request parameters directly to fields.

like image 333
Daniel Olszewski Avatar asked Nov 30 '16 19:11

Daniel Olszewski


2 Answers

In addition to JSON annotations suggested by @jihor you can try to use custom Web Data binder, adding following code to your controller or to Controller Advice class to span functionality across multiple controllers.

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.initDirectFieldAccess();
}
like image 162
udalmik Avatar answered Nov 08 '22 11:11

udalmik


Spring Boot libraries depend on Jackson (spring-boot-starter-web<-spring-boot-starter-json<-jackson libraries), so one can use its annotations to control json bindings.

@JsonCreator-annotated constructors or static methods allow to instantiate objects without explicit setters:

@JsonCreator
public RequestParams(@JsonProperty("param1") String param1, 
                     @JsonProperty("param2") String param2) {
    this.param1 = param1;
    this.param2 = param2;
}

Documentation

  • https://fasterxml.github.io/jackson-annotations/javadoc/2.8/com/fasterxml/jackson/annotation/JsonCreator.html
  • https://github.com/FasterXML/jackson-annotations/wiki
like image 2
jihor Avatar answered Nov 08 '22 11:11

jihor