用例:从 Spring Rest Controller 返回 JSON 字符串列表(JSON 字符串来自第三方库)。
问题:来自 REST 控制器的响应包含转义字符。只有当返回类型是列表或数组或任何其他集合类型时才会发生这种情况。返回单个字符串工作正常。
如何返回 JSON 格式字符串列表但避免转义字符。
代码:
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版本:2.7.0
完整代码:https://github.com/rai-sandeep/restjson/blob/main/src/main/java/com/sdprai/restjson/controller/RestJsonController.java
编辑:
为了避免与字符串连接相关的任何混淆,我更新了代码(见下文)。即使只有一个 JSON 字符串返回列表也会导致响应中出现转义字符。但是只返回一个字符串就没有这个问题。我不明白这种差异背后的原因。对于我的用例,有没有办法返回不带转义字符的 JSON 字符串列表?
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}
}
}
基本上,Spring MVC(spring boot 的一部分,负责处理 Rest Controllers 等)通过将常规 java 对象转换为有效的 json 字符串(没有反斜杠)来处理 JSON 响应。
所以问题是为什么你需要使用字符串? 试试下面的代码:
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);
}
现在,如果您说像
{\"name\":\"John\", \"age\":30}
这样的字符串已经从某些第三方传给您,并且您有点“被迫”返回 List<String>
而不是 List<Person>
这就像在说-我不想spring 为我转换任何东西,我会自己做。在这种情况下你应该明白为什么你的第三方会返回这样的字符串以及你可以用它做什么
我知道有点晚了,但我希望这对其他人有帮助 我有一个几乎相似的问题
我的响应 DTO 对象中有一个字段叫做
String additionalLanguages
基本上,它是一个表示为字符串的 JSON 对象。通常,当我返回响应时,我会得到类似这样的内容,一个带有转义字符的字符串,例如:
"additionalLanguages": "[{"abbr":"ar","title":"الأماكن"}]",
为了解决这个问题,我只需要添加一个注释
@JsonRawValue
现在的响应看起来像这样
"additionalLanguages": [
{
"abbr": "ar",
"title": "الأماكن"
}
],
你可以试试这个避免逃跑。
@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();
}
如果可行,请投票并接受。
value1.concat(value2);
上面的代码连接了两个字符串,因此在结果字符串中不会产生转义字符。
String value1 = "{\"name\":\"John\", \"age\":30}";
String value2 = "{\"name\":\"Tom\", \"age\":21}";
return Arrays.asList(value1, value2);
在上面的代码中,您向列表中添加了一个字符串。所以你会看到转义字符,即 \" 代表 ".
如果你想要一个对象列表,使用对象映射器或 GSON 库将字符串转换为对象,并将这些对象添加到列表中。
更新
您正在将 JSON(字符串)添加到列表中。所以你得到了一个带有转义字符的字符串。
还有另一种方法可以做到这一点。 创建一个 JSON 对象并将 response1 和 response2 添加到该对象并返回该对象。