Search code examples
javahelidon

Get raw JSON on POST method using Helidon 2.0.0-M2


I've a POST endpoint below. I want to get access to the raw JSON that is being sent inside the handler method. Ideally this would either be as a String or converted to a Map. The data in the JSON could vary and I don't want to cast it to a specific class as is done in the Pokemon example.

I've tried two methods below, one trying to access the data from the request object and the second using a handler with String.class. The first logs the following error "SEVERE org.eclipse.yasson.internal.Unmarshaller Thread[nioEventLoopGroup-3-2,10,main]: Unexpected char 39 at (line no=1, column no=1, offset=0)".

The second prints the first part of the JSON "{key1:value1,".

curl POST command


curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:8090/datastore/type

method 1

.post("/type", this::addDataTypeItem)
private void addDataTypeItem(ServerRequest request, ServerResponse response) {

    // get RAW JSON as String or Map of JSON contents

    // this code does not work.
    // SEVERE org.eclipse.yasson.internal.Unmarshaller Thread[nioEventLoopGroup-3-2,10,main]: Unexpected char 39 at (line no=1, column no=1, offset=0)
    request.content().as(JsonObject.class)
            .thenAccept(jo -> printValue(jo));

}

method 2

.post("/type", Handler.create(String.class, this::addDataTypeItem))
private void addDataTypeItem(ServerRequest request, ServerResponse response, String value) {

    // get RAW JSON as String or Map of JSON contents

    // below prints "value: '{key1:value1,"
    System.out.println("value: "+value);

}

Pokemon example

.post("/pokemon", Handler.create(Pokemon.class, this::insertPokemon))

 private void insertPokemon(ServerRequest request, ServerResponse response, Pokemon pokemon) {
        dbClient.execute(exec -> exec
                .createNamedInsert("insert-pokemon")
                .indexedParam(pokemon)
                .execute())
                .thenAccept(count -> response.send("Inserted: " + count + " values\n"))
                .exceptionally(throwable -> sendError(throwable, response));
    }

What is the best way to get the JSON as a string or a Map in the POST handler method?

Thanks


Solution

  • Hi method 2 seems to work just fine:

    public static void main(final String[] args) throws IOException {
            WebServer.builder(Routing.builder()
                    .register("/datastore", rules ->
                            rules.post("/type",
                                    Handler.create(String.class, (req, res, value) -> System.out.println("String json: " + value))
                            )
                    ).build()
            ).build()
                    .start()
                    .thenAccept(ws -> System.out.println("curl -d '{\"key1\":\"value1\", \"key2\":\"value2\"}' " +
                            "-H \"Content-Type: application/json\" " +
                            "-X POST http://localhost:" + ws.port() + "/datastore/type")
                    );
        }
    

    After calling curl:

    curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:50569/datastore/type
    

    Output:

    String json: {"key1":"value1", "key2":"value2"}