-2

I have a rest API that consumes a simple JSON object, ie: { "prop": "value" }

@Consumes(MediaType.APPLICATION_JSON)
public Response apiName(@HeaderParam("field1") String field1, JsonElement payload){
   ...
}

I don't want to create a POJO for this or for other APIs that I will have later on. Instead, is there an automatic way for Jersey/Gson to deserialize the payload into a generic JsonElement/JsonObject?

I know I can do

new Gson().fromJson(payload,JsonObject.class)

at the beginning of each API but I'm sure that there is an automatic way to achieve this but I couldn't find any. All the docs/videos explaining this, they were using a POJO. If Jackson is better for this, do let me know. I'm not bounded to Gson.

I tried both JsonElement and JsonObject and for both I got: Cannot construct instance of com.google.gson.JsonElement (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information

Amos
  • 415
  • 1
  • 4
  • 10
  • 1
    Jackson can do it and I'm pretty sure Gson can as well. The documentation should help here. – Thomas Apr 16 '21 at 09:24
  • Btw, you might want to work on your terms: serialize = java objects to json string, deserialize = json string to java objects. So do you want to serialize that `JsonElement` or something like `Map` to `String` or do you want to deserialize a json `String` to objects? – Thomas Apr 16 '21 at 09:27
  • I searched over and over and in all docs and videos explaining, I saw a pojo, I found none about a "generic" json object. Regarding the serialization/deserialization, thanks, corrected. – Amos Apr 16 '21 at 09:30
  • Well, a quick search came up with this, does it help? `JsonObject jsobj = new Gson().fromJson( payload, JsonObject.class)` – Thomas Apr 16 '21 at 09:32
  • I just finished re-editing my question. I was referring to an automatic deserialization so the parameter (JsonElement) payload will already be a json element. You can send a response back in json without the need to manually serialize it, I wonder how can I do it for the payload as well. – Amos Apr 16 '21 at 09:35
  • Well, `JsonElement` would be the superclass for `JsonObject` and `JsonArray` so you could try using the type you require directly in your method signature or cast as needed (don't forget to check for the actual implementation first). Since you'd need to add code to extract the data from those generic objects anyway, adding a line or 2 for conversion shouldn't be that big of an issue. – Thomas Apr 16 '21 at 09:38
  • I tried both JsonElement and JsonObject and for both I got: Cannot construct instance of `com.google.gson.JsonElement` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information – Amos Apr 16 '21 at 09:39
  • This might help: https://stackoverflow.com/questions/27188753/retrieve-jsonobject-in-post-with-jersey (see the second answer which describes the GsonBodyHandler - you might also look for any standard impementation that might have been provided by Jersey or Gson since 2017) – Thomas Apr 16 '21 at 09:43

1 Answers1

1

I am not sure about Gson, but Jackson surely works.

...
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
...


@PostMapping("/create")
public JsonNode create(@RequestBody JsonNode jsonNode){
    System.out.println(jsonNode.toString());
    return jsonNode;
}
Pramod
  • 787
  • 4
  • 19