1

I am trying to receive a JSON object in @RequestBody which is not known to me i.e. the JSON Object could be of any length and data.

Let's say, JSON could be as shown below

{'seqNo': 10 }

{'country': 'US', 'state': 'CA'}

{'customer': 'Alex', product: 'UPS', date:'25-Mar-2018'}

And In Spring Boot Api, I have a method to receive that JSON Object.

@PostMapping(value = "/lookup")
public ResponseEntity<AppResponse> getLookup(@RequestBody LookupRequestObject lookupRequestObject) {

        // THIS METHOD KNOWS WHICH FIELD TO USE
        // FURTHER LOGIC WOULD BE HERE.


        return ResponseEntity.ok(response);

    }

I have read about Jackson Serialization but still finding solution for this.

Customize the Jackson ObjectMapper

Any help would be much appreciated.

4

3 回答 3

6

You could just use a map for your input. Then you can access filed in the map depending on what kind of fields it contains.

@PostMapping(value = "/lookup")
public ResponseEntity<AppResponse> getLookup(@RequestBody Map<String, Object> lookupRequestObject) {

    // THIS METHOD KNOWS WHICH FIELD TO USE
    // FURTHER LOGIC WOULD BE HERE.

    return ResponseEntity.ok(response);
}
于 2019-04-02T06:54:57.787 回答
3

If JSON object structure is not known, you can always use Map<String, Object> type and convert it to POJO or directly work on Map. In case you need POJO you can use convertValue method:

@PostMapping(value = "/lookup")
public ResponseEntity<AppResponse> getLookup(@RequestBody Map<String, Object> payload) {
    // read map
    ObjectMapper objectMapper = new ObjectMapper();
    if (payload.containsKey("seqNo")) {
        Sequence seq = objectMapper.convertValue(payload, Sequence.class);
        // other logic
    } else if (payload.containsKey("country")) {
        Country country = objectMapper.convertValue(payload, Country.class);
    }
    // the same for other types

    // FURTHER LOGIC WOULD BE HERE.
    return ResponseEntity.ok(response);
}

You can also try with deserialising to com.fasterxml.jackson.databind.JsonNode but it binds controller with Jackson which is not good from other side.

于 2019-04-02T06:56:15.413 回答
1

The answer by @Patrick Adler is absolutely correct. You can use Map as your parameter of the method. Two important additions: Map corresponds to JSON Object so when a JSON object is passed to your method Spring (using Jackson by default) will convert it to map, so no additional code needed. Also to be sure you can add to your annotation that you expect to receive JSON input: So change the line

@PostMapping(value = "/lookup")

to

@PostMapping(value = "/lookup", headers = "Accept=application/json")

And finally the input that you posted is not a valid single JSON Object. It is 3 separate JSON Objects. So either you expect a JSON array containing JSON Objects or a Single JSON Object. If you expect a JSON Array then instead of Map<String, Object> parameter in your method use List<Map<String, Object>> so your solution should look either

@PostMapping(value = "/lookup", headers = "Accept=application/json")
public ResponseEntity<AppResponse> getLookup(@RequestBody Map<String, Object> lookupRequestObject) {

    // THIS METHOD KNOWS WHICH FIELD TO USE
    // FURTHER LOGIC WOULD BE HERE.

    return ResponseEntity.ok(response);
}

or the same but with List<Map<String, Object>> param instead of just map

于 2019-04-02T07:40:22.140 回答