控制器 returns JSON 包含两个实体而不是一个
Controller returns JSON containing two entities instead of one
这是我的控制器:
// CREATE NEW TODOITEM FROM SENT JSON
@PostMapping("/todos")
@ResponseStatus(HttpStatus.OK)
public ToDoItem newToDo(
@RequestBody ToDoItem toDoItem,
Principal principal
) {
User currentUser = userService.findLoggedInUser(principal);
return toDoItemService.addToDo(toDoItem, currentUser);
}
toDoItemService.addToDo:
public ToDoItem addToDo(ToDoItem toDoItem, User user) {
String toDoTitle = toDoItem.getTitle();
LocalDate toDoDueDate = toDoItem.getDueDate();
ToDoItem newToDo = new ToDoItem(user, toDoTitle, toDoDueDate);
return toDoItemRepository.save(newToDo);
}
ToDoItem 实体(省略构造函数和 getters/setters):
@Entity
@Table (name = "TO_DO_ITEMS")
public class ToDoItem extends BaseEntity {
@Column(name = "TITLE", nullable = false)
private String title;
@Column(name = "COMPLETED")
private boolean completed;
@Column(name = "DUE_DATE", nullable = false)
@Convert(converter = LocalDateAttributeConverter.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate dueDate;
// a ToDoItem is only associated with one user
@ManyToOne(cascade=CascadeType.PERSIST)
@JoinColumn(name = "USER_ID")
private User user;
我的 toDoItemRepository 只是扩展了 CrudRepository。
当我拍摄时:
{
"title":"testtodo3",
"dueDate": [
2015,
12,
6
]
}
在 localhost:8080/todos
我明白了:
{
"id": 1,
"title": "testtodo3",
"completed": false,
"dueDate": [
2015,
12,
6
],
"user": {
"id": 1,
"username": "gruchacz",
"password": "password",
"email": "newUser@example.com"
}
}
为什么当我只 returning ToDoItem 时我的用户的所有详细信息都可见(就像从 CrudRepository 保存一样)?我知道我的 ToDoItem 已链接到用户,但我希望它仅 return ID、标题、完成和到期日期而不包含用户数据?我知道我可以覆盖 ToDoItem 实体中的 toString 方法和来自该控制器的 return 字符串,但它非常不优雅,我更愿意只返回 ToDoItem 和 jackson 来处理到 JSON.
的转换
您有两种选择:
1: 在 ToDoItem
的 User 字段上添加 @JsonIgnore,Jackson 会忽略它,或者
2:使用DTO
模式,创建另一个值对象将其传回HTTP层。
我会推荐第二个选项
这是我的控制器:
// CREATE NEW TODOITEM FROM SENT JSON
@PostMapping("/todos")
@ResponseStatus(HttpStatus.OK)
public ToDoItem newToDo(
@RequestBody ToDoItem toDoItem,
Principal principal
) {
User currentUser = userService.findLoggedInUser(principal);
return toDoItemService.addToDo(toDoItem, currentUser);
}
toDoItemService.addToDo:
public ToDoItem addToDo(ToDoItem toDoItem, User user) {
String toDoTitle = toDoItem.getTitle();
LocalDate toDoDueDate = toDoItem.getDueDate();
ToDoItem newToDo = new ToDoItem(user, toDoTitle, toDoDueDate);
return toDoItemRepository.save(newToDo);
}
ToDoItem 实体(省略构造函数和 getters/setters):
@Entity
@Table (name = "TO_DO_ITEMS")
public class ToDoItem extends BaseEntity {
@Column(name = "TITLE", nullable = false)
private String title;
@Column(name = "COMPLETED")
private boolean completed;
@Column(name = "DUE_DATE", nullable = false)
@Convert(converter = LocalDateAttributeConverter.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate dueDate;
// a ToDoItem is only associated with one user
@ManyToOne(cascade=CascadeType.PERSIST)
@JoinColumn(name = "USER_ID")
private User user;
我的 toDoItemRepository 只是扩展了 CrudRepository。
当我拍摄时:
{
"title":"testtodo3",
"dueDate": [
2015,
12,
6
]
}
在 localhost:8080/todos
我明白了:
{
"id": 1,
"title": "testtodo3",
"completed": false,
"dueDate": [
2015,
12,
6
],
"user": {
"id": 1,
"username": "gruchacz",
"password": "password",
"email": "newUser@example.com"
}
}
为什么当我只 returning ToDoItem 时我的用户的所有详细信息都可见(就像从 CrudRepository 保存一样)?我知道我的 ToDoItem 已链接到用户,但我希望它仅 return ID、标题、完成和到期日期而不包含用户数据?我知道我可以覆盖 ToDoItem 实体中的 toString 方法和来自该控制器的 return 字符串,但它非常不优雅,我更愿意只返回 ToDoItem 和 jackson 来处理到 JSON.
的转换您有两种选择:
1: 在 ToDoItem
的 User 字段上添加 @JsonIgnore,Jackson 会忽略它,或者
2:使用DTO
模式,创建另一个值对象将其传回HTTP层。
我会推荐第二个选项