java - 为什么在转换为 JSON 时相关实体会被转义?
问题描述
我有一个 Spring MVC 控制器,它通过查询获取一些实体。这些实体具有被eagerly
提取的相关实体。但是,当我使用JSONObject.toString()
它时,它会转义相关的模型数据:
{
"totalRecords": 29,
"hasErrors": false,
"data": {
"regs": [
{
"is_active": 1,
"name": "NAR",
"modified": "09/14/2020 08:46 AM",
"language": "{\"name\":\"English\",\"id\":1,\"shortcode\":\"en\"}", <--
"id": 1,
},
{
"is_active": 1,
"name": "SAR",
"modified": "09/14/2020 08:46 AM",
"language": "{\"name\":\"English\",\"id\":1,\"shortcode\":\"en\"}", <--
"id": 2,
}
]
}
}
属性中的值language
是来自相关实体的转义 JSON 对象。为什么就这样被逃跑了?我该如何预防?
// 实体Reg
public class CmsRegions extends CmsModel implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@JsonManagedReference
@ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.DETACH)
@JoinColumn(name = "language_id", referencedColumnName = "id")
private SysLanguages language;
}
// 实体语言
public class SysLanguages extends Model implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 100)
@Column(name = "name")
private String name;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "language")
private Set<CmsRegions> regions;
}
// 控制器
...
JSONArray objs = new JSONArray();
for (CmsRegions region : regions) {
JSONObject jsonRegion = new JSONObject();
jsonRegion.put("id", region.getId());
jsonRegion.put("name", region.getName());
jsonRegion.put("description", region.getDescription());
jsonRegion.put("language", region.getLanguage());
objs.put(jsonRegion);
}
String response = new JSONObject(payload).toString();
...
Payload
只是一个 POJO,它是我们用来从 API 传回数据的数据对象。
为什么language
要逃跑?我缺少注释吗?
更新
我知道这不是JSONObject
这样做的,因为我在这里创建了一个测试用例:
https://repl.it/repls/GlossyScaredLock
似乎这种情况发生在相关模型被序列化,然后附加到模型,然后被序列化时。不知道如何防止它。
解决方案
这是由于序列化而发生的,为了正确解析消息,有一些字符被替换:
退格替换为\b,换页符替换为\f,换行符替换为\n,回车替换为\r,制表符替换为\t,双引号替换为“,反斜杠替换为\
您可以使用 Apache Commons lang 中的 StringEscapeUtils.unescapeJava(stringToUnEscape) 来删除解析后的转义。
推荐阅读
- vb.net - 可以在函数中更改公共变量,还是这是不好的做法?
- firebase - Flutter Firebase 延迟功能
- asp.net - 如何在 ASP.NET Core 5.0 中忽略对 favicon.ico 的请求?
- python - 调用属性装饰器的类比?
- c# - 如何防止一个类多次具有相同类型的属性?
- javascript - Discord.js:如何确保机器人不会从列表中选择两个相同的单词
- swift - SplitViewController 在启动时总是显示 DetailViewController
- python - 我们如何编码时间戳并将 DBSCAN 集群的集群保存为 json 和 csv?
- visual-studio - 如何构建应用来调用 Power BI 刷新历史记录?
- azure - 将私有 Azure Docker Registry 的 Pull-Only 权限授予第三方的最安全方法