13

I have SpringBoot application with that dependencies:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jersey</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

I have a method at my controller as follows:

@RequestMapping(value = "/liamo", method = RequestMethod.POST)
@ResponseBody
public XResponse liamo(XRequest xRequest) {
    ...
    return something;
}

I send a JSON object from my HTML via AJAX with some fields of XRequest type object (it is a plain POJO without any annotations). However my JSON is not constructed into object at my controller method and its fields are null.

What I miss for an automatic deserialisation at my controller?

so-random-dude
  • 15,277
  • 10
  • 68
  • 113
kamaci
  • 72,915
  • 69
  • 228
  • 366
  • probably the `@RequestBody` annotation on your `xRequest` parameter: http://stackoverflow.com/questions/11291933/requestbody-and-responsebody-annotations-in-spring - btw, you don't need `spring-boot-starter-jersey` if you use spring-mvc for your controllers. – zapl Oct 25 '16 at 18:59
  • You are missing `@RequestBody` like @zapl noticed and if you are sending JSON I would also add `consumes = "application/json"` to `@RequestMapping`. – VladoDemcak Oct 25 '16 at 19:14
  • Answer is that. Missing RequestBody, thanks! Could you write it as an answer to accept it. – kamaci Oct 25 '16 at 20:31

2 Answers2

32

Spring boot comes with Jackson out-of-the-box which will take care of un-marshaling JSON request body to Java objects

You can use @RequestBody Spring MVC annotation to deserialize/un-marshall JSON string to Java object... For example.

Example

@RestController
public class CustomerController {
    //@Autowired CustomerService customerService;

    @RequestMapping(path="/customers", method= RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    public Customer postCustomer(@RequestBody Customer customer){
        //return customerService.createCustomer(customer);
    }
}

Annotate your entities member elements with @JsonProperty with corresponding json field names.

public class Customer {
    @JsonProperty("customer_id")
    private long customerId;
    @JsonProperty("first_name")
    private String firstName;
    @JsonProperty("last_name")
    private String lastName;
    @JsonProperty("town")
    private String town;
}
so-random-dude
  • 15,277
  • 10
  • 68
  • 113
  • How does the createCustomer() look in this scenario? This answer was a big help, except my create() method takes a bunch of strings instead of an object – Mike Nor Nov 27 '18 at 16:39
  • How does it map? I mean what if two properties have same name. – ravi Dec 14 '18 at 04:43
  • @ravi It will error out as you try to start the application. That being said, have you tried it yourself? – so-random-dude Dec 14 '18 at 15:13
  • If you are using SpringBoot, you can also use this [SpringBoot solution](https://stackoverflow.com/questions/30924816/make-json-payload-fields-case-insensitive-when-mapping-to-java-object-in-rest-ap) – jausen brett Jan 24 '19 at 18:20
0

SpringBoot by default comes with this functionality. You just have to use @RequestBody annotation in parameter declaration of your controller method but in contrast to @so-random-dude's answer you don't have to annotate fields with @JsonProperty, that is not required.

You just have to provide getters and setters for your custom XML object class. I am posting an example below for simplicity.

Example:

Controller method declaration:-

@PostMapping("/create")
    public ResponseEntity<ApplicationResponse> createNewPost(@RequestBody CreatePostRequestDto createPostRequest){
        //do stuff
        return response;
    }

Your custom XML object class:-

public class CreatePostRequestDto {
    String postPath;

    String postTitle;

    public String getPostPath() {
        return postPath;
    }

    public void setPostPath(String postPath) {
        this.postPath = postPath;
    }

    public String getPostTitle() {
        return postTitle;
    }

    public void setPostTitle(String postTitle) {
        this.postTitle = postTitle;
    }
}
Paramvir Singh Karwal
  • 597
  • 1
  • 10
  • 24