2

I am struggling with the Quarkus RestClient.

First create a Controller that simply print our request body: e.G.

    @Path("/test")
    public class ExampleController {
        @PUT
        public void test(String data) {
            System.out.println(data);
        }
    }

Now we create a RestClient that accepts any Object as the request body:

    @RegisterRestClient(baseUri = "http://localhost:8081/test")
    public interface RestClientExample {
        @PUT
        @Produces(MediaType.APPLICATION_JSON)
        @Consumes(MediaType.APPLICATION_JSON)
        void put(Object data);
    }

Pleas notice that we say @Consumes(MediaType.APPLICATION_JSON) so the body should JSON serialized during the request.

Do a quick test:

    @QuarkusTest
    class TestPrimitives {
        @Inject
        @RestClient
        RestClientExample example;
        @Test
        void test() {
            example.put("hello\nworld");
            example.put(new TestRequest());
        }
        public static class TestRequest {
            private String data = "hello\nworld";
            public String getData() {
                return data;
            }
        }
    }

You will see:

hello
world
{"data":"hello\nworld"}

If you send any type of Objects that are no primitves, the body will be respresented as JSON. If you send a String the body is not JSON serialized (the linebreak should be a \n like in the second request). Unfortently I need also the Strings serialized. How can i achive that?

Update

so that I can be better understood: Replace the Controller with: So we do the JSON parsing.

@PUT
    @Consumes(MediaType.APPLICATION_JSON)
    public void test(String data) {
        System.out.println(Json.createReader(new StringReader(data)).readValue());
    }

This will fail:

Caused by: javax.json.stream.JsonParsingException: Unexpected char 104 at (line no=1, column no=1, offset=0)
    at org.glassfish.json.JsonTokenizer.unexpectedChar(JsonTokenizer.java:577)
user3046582
  • 341
  • 3
  • 15
  • JSON follows the format of { "variable" : "valueOfVariable"}, how would you expect it to be able to send a JSON of {"hello\world"} https://www.w3schools.com/js/js_json_syntax.asp – JCompetence Nov 30 '20 at 12:03
  • No but "hello\\nworld" (like if you do `JsonbBuilder.create().toJson("hello\nworld")`) – user3046582 Nov 30 '20 at 12:12

1 Answers1

0

Unfortunatly, you tell your rest client to send JSON and a String is a valid JSON Object, so your result is logical.

As you logged the String using System.out, the \n character is displayed as a line break.

For me there is nothing wrong on this code and it works as it should work.

If you relly want your \n to not be evaluated as a line break, you need to escape the \ from you call site (the rest client code is OK)

@QuarkusTest
class TestPrimitives {
    @Inject
    @RestClient
    RestClientExample example;
    @Test
    void test() {
        example.put("hello\\nworld");
        example.put(new TestRequest());
    }
    public static class TestRequest {
        private String data = "hello\nworld";
        public String getData() {
            return data;
        }
    }
}
loicmathieu
  • 5,181
  • 26
  • 31
  • I am not with you, that any String is a valid JSON Object. (It is Indeed not, since if you try to parse "hello\nworld" as json it will fail.) The correct way would be, like the string in the object is handelt. Here the JSON serialize handels the linebrake for me. – user3046582 Nov 30 '20 at 12:09
  • A String is a value in the JSON terminology and is valid, see https://www.json.org/json-en.html But be careful of special character handling (by Java, JSON and the console), this is where the confusion comes from. – loicmathieu Dec 01 '20 at 10:13
  • With this I agree. But nevertheless, the Quarkus handling is wrong here. If you enable DEBUG log level, you will see the body: "User-Agent: Apache-HttpClient/4.5.12 (Java/11.0.8)[\r][\n]" http-outgoing-0 >> "[\r][\n]" http-outgoing-0 >> "hello[\n]" http-outgoing-0 >> "world" do you see that there is a real line break? I would expect ""hello\nworld"" so the linebreak is escaped (and also there are quotes around that.) – user3046582 Dec 01 '20 at 13:12
  • Again, no, I don't agree, if you want it to be escapped, you need to write `Hello\\nWorld"` and if you want the doube-quote you need to escape them: `"\"Hello\\nWorld\""` Double quotes are string delimiters so are not part of the String value. You saw them in your code but they didn't really exist, same for JSON. Line break is not really `\n` it's a way to express them inside a String in Java, but the reprensentation is different. – loicmathieu Dec 01 '20 at 15:58
  • I did understand how to do it (Simply use for exmaple Jackons example.put(new ObjectMapper().writeValueAsString("hello\nworld"));) This would work, but in my case i have a RestClient that should accept all objects and do the serialisation part. And it seems that I have to handel Strings differnt than all other Objects, and with this I have my problem. From the developer point of view, I should not know anything which serialisation is used during the transfer. – user3046582 Dec 01 '20 at 16:14