【发布时间】:2019-10-18 07:46:24
【问题描述】:
我很难通过 HTTP PUT (使用 Spring MVC) 让服务器接受复杂的 JSON。
我有两个实体:
建筑
@Entity
@Table
public class Building {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "description")
private String description;
@OneToMany(mappedBy = "building", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
@JsonBackReference
private Set<Floor> floors;
// Default Constructor, Getters, Setters
}
地板
@Entity
@Table
public class Floor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST})
@JsonManagedReference
private Building building;
@Column(name = "number", nullable = false)
private short number;
@Column(name = "description")
private String description;
// Default Constructor, Getters, Setters
}
控制器
@RestController
@RequestMapping("/admin/Floors")
public class AdminFloorController {
// Autowired Floor Service + Setter
// Other methods
@PutMapping(value = "/Save",
consumes = "application/json",
produces = MediaType.TEXT_HTML_VALUE)
public ResponseEntity<String> save(@RequestBody Floor floor) {
return floorService.save(floor) ?
new ResponseEntity<String>("Floor was successfully saved.", HttpStatus.OK) :
new ResponseEntity<String>("Floor was not saved. An error may have occured.", HttpStatus.OK);
}
}
这里是 AJAX 请求。 (来自 ID 为“main-form”的表单)
$("#main-form").submit(function(e) {
e.preventDefault();
$.ajax({
type: "PUT",
url: "Floors/Save",
data: JSON.stringify({
"id": $("#main-form").find("input[name='id']").val(),
"number": $("#main-form").find("input[name='number']").val(),
"building": {
"id": $("#main-form").find("select[name='building.id']").val()
}
}),
contentType: "application/json",
success: function(data) {
$("#main-modal").modal("hide");
createTable();
}
});
});
正确构造了 AJAX 请求以及 JSON 对象。 但是当它发送时,服务器总是以错误 415: Unsupported Media Type 来响应。
我明确告诉 AJAX 发送带有 JSON 正文和代码的请求:
内容类型:“应用程序/json”
并且控制器方法被注释为:
@PutMapping(url, consumes = "application/json")
但它不起作用。我的 Building REST Controller 中有几乎相同的代码,并且工作起来很吸引人。但我似乎无法让它与这个实体一起工作。
编辑
我的问题已解决。原来问题出在 Jackson 的注释 @JsonManagedReference 上。我只是删除了上述注释,但将反向引用保留在一侧。
【问题讨论】:
-
你明确地说你的控制器返回
text/html(即使它没有)。删除所有显式的produces/consumes并让 Spring 自动执行此操作。 (此外,出于多种原因,直接将 DAO 类用于 DTO 是一个坏主意,现在是时候将它们分开了。MapStruct 可以成为你的朋友。) -
您要发送json格式,还要接收json格式吗?
-
@chrylis 我放弃了它们。还是不行。你的意思是在 DTO 中直接使用 DAO 是个坏主意?我的意思是这不是让代码松耦合吗?我将在太平洋标准时间晚些时候尝试修复我的代码。一路上我会看看 MapStruct。谢谢
-
@Sambit 我想以 JSON 格式发送。我认为 AJAX 编写 JSON 部分没有问题..控制器是我认为的问题..
-
在使用 Ajax 调用之前,您是否检查过使用 Postman 等其他客户端?如果您能够使用任何其他客户端发送和接收响应,那么您的 ajax 调用可能存在问题。首先检查邮递员客户端,看看你得到了什么。