英文:
Why are related entities being escaped when converted to JSON?
问题
我有一个Spring MVC控制器,通过查询获取一些实体。这些实体有一个相关的实体被“急切地”获取。然而,当我使用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;
}
// 实体 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
似乎出现在将相关模型序列化,然后附加到模型时发生,然后再次进行序列化。不确定如何阻止它。
英文:
I have a Spring MVC controller which fetches some entities via a query. These entities have a related entity that is eagerly
fetched. However, when I use JSONObject.toString()
it escapes the related model data:
{
"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,
}
]
}
}
The value in the language
property is an escaped JSON object from the related entity. Why is it being escaped like that? How do I prevent it?
// Entity 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;
}
// Entity 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;
}
// Controller
...
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
is just a POJO that is the data object we use to transmit data back from the API.
Why is language
getting escaped? Is there an annotation I am missing?
UPDATE
I know that this is not JSONObject
doing it, as I created a test case here:
https://repl.it/repls/GlossyScaredLock
It seems as though the occurrence happens when the related model is serialized, then attached to the model, which is then serialized. Not sure how to prevent it .
答案1
得分: 0
这是由于序列化造成的,为了使消息能够被正确解析,某些字符被替换为以下内容:
退格被替换为 \b,
换页被替换为 \f,
新行被替换为 \n,
回车被替换为 \r,
制表符被替换为 \t,
双引号被替换为 ",
反斜杠被替换为 \
你可以使用 Apache Commons Lang 中的 StringEscapeUtils.unescapeJava(stringToUnEscape) 方法,在解析后移除这些转义。
英文:
This happens due to the serialization, there are some chars which are replaced in order for the message to be parsed properly :
Backspace is replaced with \b,
Form feed is replaced with \f,
Newline is replaced with \n,
Carriage return is replaced with \r,
Tab is replaced with \t,
Double quote is replaced with ",
Backslash is replaced with \
You can use StringEscapeUtils.unescapeJava(stringToUnEscape) from Apache Commons lang in order to remove those escaping after parsed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论