loadAll() 和 loadById(Long id) 时 JSON 序列化的差异
Differences in JSON serialization when loadAll() and loadById(Long id)
我创建了文件夹class (java springboot),它描述了用于书签管理的多级文件夹结构:
@Entity
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
**public class Folder** implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "parent_id")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
private Folder parent;
@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
private List<Folder> children = new ArrayList<>();
private String name;
private String path;
@OneToMany(mappedBy = "folder", cascade = CascadeType.PERSIST)
@JsonManagedReference
private List<Bookmark> bookmarkList = new ArrayList<>();
}
@Entity
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
**public class Bookmark** implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String url;
private String description;
/**
* parent folder
*/
@ManyToOne
@JsonBackReference
private Folder folder;
}
我的问题是,当 loadAll() 和 loadById(Long id):
时,我可以看到序列化 JSON 的差异
@Service
@Transactional
**public class FolderService** {
private FolderRepo folderRepo;
@Autowired
public FolderService(FolderRepo folderRepo) {
this.folderRepo = folderRepo;
}
public void save(Folder folder) {
folderRepo.save(folder);
}
public List<Folder> loadAll() {
List<Folder> folderList = folderRepo.findAll();
return folderList;
}
public Folder loadById(Long id) {
Folder folder = folderRepo.findById(id).get();
return folder;
}
}
@RestController
@RequestMapping("/bookmarks-app")
**public class FolderControllerRest** {
private FolderService folderService;
@Autowired
public FolderControllerRest(FolderService folderService) {
this.folderService = folderService;
}
@GetMapping("/folders/all")
public List<Folder> getFolderListAll() {
List<Folder> folderList = folderService.loadAll();
return folderList;
}
@GetMapping("/folder/{id}")
public Folder getFolderById(
@PathVariable(name = "id") String id
) {
if (!"undefined".equals(id)) {
Long folderId = Long.parseLong(id);
return folderService.loadById(folderId);
} else return null;
}
}
也就是说,区别是ex。在 folder.id=2.
当我全部加载时使用 ajax:
$.ajax({
url: "/bookmarks-app/folders/all",
data: {},
method: "GET",
dataType: "JSON"
});
父实体序列化为它的“id”号(如我所愿),
但是当使用 ajax:
$.ajax({
url: "/bookmarks-app/folder/2",
data: {},
method: "GET",
dataType: "JSON"
})
父实体序列化为对象(下面的屏幕截图)。
screenshoot
我认为你误用了@JsonIdentityInfo,文档说
@JsonIdentityInfo allows to serialize a POJO by id when it is encountered second time during serialization.
然后在 'list' 模式下你得到 id,在单一模式下你得到整个对象。
也许你应该使用 TypeAdaptor 来获取 id
我创建了文件夹class (java springboot),它描述了用于书签管理的多级文件夹结构:
@Entity
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
**public class Folder** implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "parent_id")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
private Folder parent;
@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
private List<Folder> children = new ArrayList<>();
private String name;
private String path;
@OneToMany(mappedBy = "folder", cascade = CascadeType.PERSIST)
@JsonManagedReference
private List<Bookmark> bookmarkList = new ArrayList<>();
}
@Entity
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
**public class Bookmark** implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String url;
private String description;
/**
* parent folder
*/
@ManyToOne
@JsonBackReference
private Folder folder;
}
我的问题是,当 loadAll() 和 loadById(Long id):
时,我可以看到序列化 JSON 的差异@Service
@Transactional
**public class FolderService** {
private FolderRepo folderRepo;
@Autowired
public FolderService(FolderRepo folderRepo) {
this.folderRepo = folderRepo;
}
public void save(Folder folder) {
folderRepo.save(folder);
}
public List<Folder> loadAll() {
List<Folder> folderList = folderRepo.findAll();
return folderList;
}
public Folder loadById(Long id) {
Folder folder = folderRepo.findById(id).get();
return folder;
}
}
@RestController
@RequestMapping("/bookmarks-app")
**public class FolderControllerRest** {
private FolderService folderService;
@Autowired
public FolderControllerRest(FolderService folderService) {
this.folderService = folderService;
}
@GetMapping("/folders/all")
public List<Folder> getFolderListAll() {
List<Folder> folderList = folderService.loadAll();
return folderList;
}
@GetMapping("/folder/{id}")
public Folder getFolderById(
@PathVariable(name = "id") String id
) {
if (!"undefined".equals(id)) {
Long folderId = Long.parseLong(id);
return folderService.loadById(folderId);
} else return null;
}
}
也就是说,区别是ex。在 folder.id=2.
当我全部加载时使用 ajax:
$.ajax({
url: "/bookmarks-app/folders/all",
data: {},
method: "GET",
dataType: "JSON"
});
父实体序列化为它的“id”号(如我所愿),
但是当使用 ajax:
$.ajax({
url: "/bookmarks-app/folder/2",
data: {},
method: "GET",
dataType: "JSON"
})
父实体序列化为对象(下面的屏幕截图)。
screenshoot
我认为你误用了@JsonIdentityInfo,文档说
@JsonIdentityInfo allows to serialize a POJO by id when it is encountered second time during serialization.
然后在 'list' 模式下你得到 id,在单一模式下你得到整个对象。
也许你应该使用 TypeAdaptor 来获取 id