Sandeep Rai
Sandeep Rai

Reputation: 3

How to avoid escape characters in Spring REST Controller response that returns list of JSON strings?

Use case: Return a list of JSON Strings from Spring Rest Controller (the JSON strings come from a third party library).

Problem: Response from REST Controller has escape characters. This happens only when the return type is List or array or any other collection type. Returning a single string works fine.
How to return list of JSON formatted strings but avoid the escape characters.

Code:

import java.util.Arrays;
import java.util.List;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("restjson")
public class RestJsonController {

    @GetMapping(value="list", produces = {MediaType.APPLICATION_JSON_VALUE})
    public List<String> getValues(){
        String value1 = "{\"name\":\"John\", \"age\":30}";
        String value2 = "{\"name\":\"Tom\", \"age\":21}";
        
        return Arrays.asList(value1, value2);
        //response has escape characters: 
        //["{\"name\":\"John\", \"age\":30}","{\"name\":\"Tom\", \"age\":21}"]
    }

    @GetMapping(value="single", produces = {MediaType.APPLICATION_JSON_VALUE})
    public String getValue(){
        String value1 = "{\"name\":\"John\", \"age\":30}";
        String value2 = "{\"name\":\"Tom\", \"age\":21}";
        
        return value1.concat(value2);
        //response has no escape characters: 
        //{"name":"John", "age":30}{"name":"Tom", "age":21}
    }
}

Springboot version: 2.7.0
Full code at: https://github.com/rai-sandeep/restjson/blob/main/src/main/java/com/sdprai/restjson/controller/RestJsonController.java

EDIT:
To avoid any confusion related to string concatenation, I have updated the code (see below). Returning a list even with just one JSON string results in escape characters in the response. But returning just a string does not have this problem. I don't understand the reason behind this difference. For my use case, is there a way to return a list of JSON strings without the escape characters?

import java.util.Collections;
import java.util.List;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("restjson")
public class RestJsonController {

    @GetMapping(value="list", produces = {MediaType.APPLICATION_JSON_VALUE})
    public List<String> getValues(){
        String value1 = "{\"name\":\"John\", \"age\":30}";
        
        return Collections.singletonList(value1);
        //returns: ["{\"name\":\"John\", \"age\":30}"]
    }

    @GetMapping(value="single", produces = {MediaType.APPLICATION_JSON_VALUE})
    public String getValue(){
        String value1 = "{\"name\":\"John\", \"age\":30}";
        
        return value1;
        //returns: {"name":"John", "age":30}
    }
}

Upvotes: 0

Views: 6975

Answers (4)

Mark Bramnik
Mark Bramnik

Reputation: 42461

Basically, Spring MVC (a part of spring boot responsible for handling the Rest Controllers among other things) handles the JSON responses by converting the regular java objects to a valid json string (without backslashes).

So the question is why do you need to work with Strings at all? Try the following code:

public class Person {
   private String name;
   private int age;
   // constructors, getters, etc.
}

 @GetMapping(value="list", produces = {MediaType.APPLICATION_JSON_VALUE})
    public List<Peron> getValues(){
        Person value1 = new Person("John", 30);
        Person value2 = new Person("Tom", 21);
        
        return Arrays.asList(value1, value2);

    }

Now if you say that the strings like {\"name\":\"John\", \"age\":30} are already coming to you from some thirdparty and you're kind of "forced" to return a List<String> instead of List<Person> this is like saying - I don't want spring to convert anything for me, I'll do it by myself. In this case you should understand why does your thirdparty returns string like this and what you can do with it

Upvotes: 2

Abilash Sethu
Abilash Sethu

Reputation: 41

I know it's a little late, But I hope it will be helpful to others I was having an almost similar issue

There's a field in my response DTO object called String additionalLanguages Basically, it's a JSON object represented as String. Normally when I return the response I get something like this, a string with escape characters Eg: "additionalLanguages": "[{"abbr":"ar","title":"الأماكن"}]", Inorder to fix this I Just had to add an annotation

@JsonRawValue

Now the response Looks like this

 "additionalLanguages": [
        {
            "abbr": "ar",
            "title": "الأماكن"
        }
    ],

Upvotes: 2

Pash0002
Pash0002

Reputation: 110

You can try this to avoid escaping.

@GetMapping(value="list", produces = {MediaType.APPLICATION_JSON_VALUE})
    public String getValues(){
        String value1 = "{\"name\":\"John\", \"age\":30}";
        String value2 = "{\"name\":\"Tom\", \"age\":21}";
        return Arrays.asList(value1, value2).toString();
    }

Upvote & Accept if this works.

Upvotes: 0

Hasan Khan
Hasan Khan

Reputation: 544

value1.concat(value2);

Above code joining two Strings so no escaping characters are produced in result String.

        String value1 = "{\"name\":\"John\", \"age\":30}";
        String value2 = "{\"name\":\"Tom\", \"age\":21}";
        
        return Arrays.asList(value1, value2);

In the above code, you are adding a String to the list. So you see escape characters i.e \" for ".

If you want an Object list, convert String to Object using object mapper or GSON library and add these objects to the list.

UPDATE

You are adding JSON(which is String) to the list. So you got a string with an escape character.

There is another way you can do this. create a JSON object and add response1, and response2 to that object and return that object.

Upvotes: 0

Related Questions