【问题标题】:Why are related entities being escaped when converted to JSON?为什么在转换为 JSON 时相关实体会被转义?
【发布时间】:2020-09-15 18:29:33
【问题描述】:

我有一个 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

似乎这种情况发生在相关模型被序列化,然后附加到模型,然后被序列化时。不知道如何预防。

【问题讨论】:

  • 你试过了吗:jsonRegion.put("language", new JSONObject(region.getLanguage())) ?
  • getLanguage() 方法返回什么?它是普通的吸气剂还是有更多的东西?

标签: java json spring hibernate jpa


【解决方案1】:

这是由于序列化而发生的,为了正确解析消息,有些字符被替换:

退格替换为 \b, 换页被替换为 \f, 换行符替换为\n, 回车替换为\r, 制表符替换为 \t, 双引号替换为 ", 反斜杠替换为 \

您可以使用 Apache Commons lang 中的 StringEscapeUtils.unescapeJava(stringToUnEscape) 来删除解析后的转义。

【讨论】:

    猜你喜欢
    • 2019-07-17
    • 2017-06-25
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    相关资源
    最近更新 更多