Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map list of arbitrary name value pair from @RequestBody to java object

I am using Spring boot mvc to build a REST service. The PUT input data are like

[
   {
      "PERSON":"John"
   },
   {
      "PLACE":"DC"
   },
   {
      "PERSON":"John"
   },
   {
      "PERSON":"Joe"
   },
   {
      "RANDOM NAME 011":"random string"
   },
   {
      "OTHER RANDOM NAME":"John"
   }
]

Notice that the name part is arbitrary, so is the value part. How to convert it using spring's automatic conversion? My code is like

@RequestMapping(value = "/cleansing", method = RequestMethod.PUT)
public ResponseEntity<Void> cleanse(@RequestBody List<CategoryItem> data) {

I know @RequestBody List<CategoryItem> data part is not right, I don't know how to write CategoryItem class to make it work. What is aright alternative?

like image 905
jay.m Avatar asked Oct 19 '22 09:10

jay.m


1 Answers

What Object do you want it to be?

As the HTTP PUT payload is, your signature would work as a List<Map<String, String>>, but that is a bit clunky to be honest. To retrieve values would be especially cumbersome, considering your keys are random. Something like this would work for processing the whole set of data:

@RequestMapping(value = "/cleansing", method = RequestMethod.PUT)
public ResponseEntity<Void> cleanse(@RequestBody List<Map<String, String>> data) {
    for(final Map<String, String> map : data) {
        for(final Map.Entry<String, String> e : map.entrySet()) {
            System.out.println("Key: " + e.getKey() + " :: Value: " + e.getValue());
        }
    }
}

Like I was saying...a little bit clunky.

A more flexible approach would be to use a Jackson JsonDeserializer, along with a custom class:

public class MyClassDeserializer extends JsonDeserializer<MyClass> {
    public abstract MyClass deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        //...
    }
}

@JsonDeserialize(using=MyClassDeserializer.class)
public class MyClass {
    //...
}

And then using that in your controller method:

@RequestMapping(value = "/cleansing", method = RequestMethod.PUT)
public ResponseEntity<Void> cleanse(@RequestBody MyClass data) {
    //...
}
like image 152
nicholas.hauschild Avatar answered Oct 21 '22 05:10

nicholas.hauschild