`@PostMapping`与多个`RequestBody`

huangapple go评论101阅读模式
英文:

@PostMapping with multiple RequestBody

问题

以下是翻译好的部分:

我对Java Spring非常新手,有一个小问题。

我想在请求体(在Postman中)中发送employee_id(来自employees实体)到assignment实体。目前它是可以工作的,因为我将employee_id作为PathVariable发送,而且我正在使用ResponseBody发送assignment数据。

  1. @PostMapping("/add/{employee_id}")
  2. public void addEmployee(@PathVariable(value = "employee_id", required = false) Long employee_id,
  3. @RequestBody Assignment a) {
  4. Employee employeeById = employeeRepository.findById(employee_id)
  5. .orElseThrow(() -> new RuntimeException("Employee not found"));
  6. a.setEmployee(employeeById);
  7. assignmentRepository.addAssignment(a);
  8. }

它可以与URL localhost:8080/add/35 一起工作。35是employee_id,分配数据可以在Postman的请求体中发送。我想要做的是,也将employee_id放在请求体中(这样URL应该只是/add),但我无法让它工作。

就像这样:

  1. {
  2. "employee_id": 35,
  3. "title": "abc"
  4. }

编辑后:

Assignment.java

  1. public class Assignment {
  2. @Id
  3. @GeneratedValue(strategy = GenerationType.IDENTITY)
  4. private Integer id;
  5. @OneToOne(optional = false)
  6. @JoinColumn(name = "employee_id", nullable = false)
  7. private Employee employee;
  8. @Size(min = 3, max = 50)
  9. private String assignment_title;
  10. public Assignment() {
  11. }
  12. public Assignment(String assignment_title) {
  13. super();
  14. this.assignment_title = assignment_title;
  15. }
  16. public Integer getId() {
  17. return id;
  18. }
  19. public void setId(Integer id) {
  20. this.id = id;
  21. }
  22. public String getAssignment_title() {
  23. return assignment_title;
  24. }
  25. public void setAssignment_title(String assignment_title) {
  26. this.assignment_title = assignment_title;
  27. }
  28. public Employee getEmployee() {
  29. return employee;
  30. }
  31. public void setEmployee(Employee employee) {
  32. this.employee = employee;
  33. }
  34. }

AssignmentService.java

  1. public void addAssignment(Assignment e) {
  2. assignmentRepository.save(e);
  3. }

AssignmentRepository.java

  1. public interface AssignmentRepository extends CrudRepository<Assignment, Integer> {
  2. }

Employee.java

  1. public class Employee {
  2. @Id
  3. @GeneratedValue(strategy = GenerationType.IDENTITY)
  4. private Integer id;
  5. @OneToOne(optional = false)
  6. @JoinColumn(name = "user_id", nullable = false)
  7. private User user;
  8. @Size(min=3, max = 100)
  9. private String title;
  10. @Size(min=3, max = 50)
  11. private String staff;
  12. private Long degree;
  13. public Employee() {}
  14. public Employee(String title, String staff, Long degree) {
  15. super();
  16. this.title = title;
  17. this.staff = staff;
  18. this.degree = degree;
  19. }
  20. public Integer getId() {
  21. return id;
  22. }
  23. public void setId(Integer id) {
  24. this.id = id;
  25. }
  26. public String getTitle() {
  27. return title;
  28. }
  29. public void setTitle(String title) {
  30. this.title = title;
  31. }
  32. public String getStaff() {
  33. return staff;
  34. }
  35. public void setStaff(String staff) {
  36. this.staff = staff;
  37. }
  38. public Long getDegree() {
  39. return degree;
  40. }
  41. public void setDegree(Long degree) {
  42. this.degree = degree;
  43. }
  44. public User getUser() {
  45. return user;
  46. }
  47. public void setUser(User user) {
  48. this.user = user;
  49. }
  50. }

EmployeeRepository.java

  1. public interface EmployeeRepository extends CrudRepository<Employee, Integer> {
  2. Optional<Employee> findById(Long id);
  3. }

提前感谢您的帮助!

英文:

I'm very new to Java Spring and have a little Problem.

I wan't to send the employee_id (from employees entity) to assignment entity in the body part (in Postman). Currently it's working, because I'm sending the employee_id as a PathVariable and I'm sending the assignment data with ResponseBody.

  1. @PostMapping(&quot;/add/{employee_id}&quot;)
  2. public void addEmployee(@PathVariable(value = &quot;employee_id&quot;, required = false) Long employee_id,
  3. @RequestBody Assignment a) {
  4. Employee employeeById = employeeRepository.findById(employee_id)
  5. .orElseThrow(() -&gt; new RuntimeException(&quot;Employee not found&quot;));
  6. a.setEmployee(employeeById);
  7. assignmentRepository.addAssignment(a);
  8. }

It is working with the url localhost:8080/add/35. 35 is the employee_id and the assignment data can be send in the Body (of Postman). What I want to do is, to send the employee_id in the body too (so the url should only be /add), but I could not get it to work.

Like that:

  1. {
  2. &quot;employee_id&quot;: 35,
  3. &quot;title&quot;: &quot;abc&quot;
  4. }

Edited:

Assignment.java

  1. public class Assignment {
  2. @Id
  3. @GeneratedValue(strategy = GenerationType.IDENTITY)
  4. private Integer id;
  5. @OneToOne(optional = false)
  6. @JoinColumn(name = &quot;employee_id&quot;, nullable = false)
  7. private Employee employee;
  8. @Size(min = 3, max = 50)
  9. private String assignment_title;
  10. public Assignment() {
  11. }
  12. public Assignment(String assignment_title) {
  13. super();
  14. this.assignment_title = assignment_title;
  15. }
  16. public Integer getId() {
  17. return id;
  18. }
  19. public void setId(Integer id) {
  20. this.id = id;
  21. }
  22. public String getAssignment_title() {
  23. return assignment_title;
  24. }
  25. public void setAssignment_title(String assignment_title) {
  26. this.assignment_title = assignment_title;
  27. }
  28. public Employee getEmployee() {
  29. return employee;
  30. }
  31. public void setEmployee(Employee employee) {
  32. this.employee = employee;
  33. }
  34. }

AssignmentService.java

  1. public void addAssignment(Assignment e) {
  2. AssignmentRepository.save(e);
  3. }

AssignmentRepository.java

  1. public interface AssignmentRepository extends CrudRepository&lt;Assignment, Integer&gt;{
  2. }

Employee.java

  1. public class Employee{
  2. @Id
  3. @GeneratedValue(strategy = GenerationType.IDENTITY)
  4. private Integer id;
  5. @OneToOne(optional = false)
  6. @JoinColumn(name = &quot;user_id&quot;, nullable = false)
  7. private User user;
  8. @Size(min=3, max = 100)
  9. private String title;
  10. @Size(min=3, max = 50)
  11. private String staff;
  12. private Long degree;
  13. public Employee() {}
  14. public Employee( String title, String staff, Long degree) {
  15. super();
  16. this.title = title;
  17. this.staff = staff;
  18. this.degree = degree;
  19. }
  20. public Integer getId() {
  21. return id;
  22. }
  23. public void setId(Integer id) {
  24. this.id = id;
  25. }
  26. public String getTitle() {
  27. return title;
  28. }
  29. public void setTitle(String title) {
  30. this.title = title;
  31. }
  32. public String getStaff() {
  33. return staff;
  34. }
  35. public void setStaff(String staff) {
  36. this.staff = staff;
  37. }
  38. public Long getDegree() {
  39. return degree;
  40. }
  41. public void setDegree(Long degree) {
  42. this.degree = degree;
  43. }
  44. public User getUser() {
  45. return user;
  46. }
  47. public void setUser(User user) {
  48. this.user = user;
  49. }
  50. }

EmployeeRepository.java

  1. public interface EmployeeRepository extends CrudRepository&lt;Employee, Integer&gt;{
  2. Optional&lt;Employee&gt; findById(Long id);
  3. }

Thanks for your help in advance!

答案1

得分: 3

你需要确保你的身体类型Assignment具有以下属性,如下所示:

  1. public class Assignment {
  2. public Long employee_id;
  3. // 省略其他
  4. }

并且在你的方法中获取它,如下所示:

  1. @PostMapping("/add")
  2. public void addEmployee(@PathVariable(value = "employee_id", required = false) Long employee_id, @RequestBody Assignment a) {
  3. Long employee_id = a.employee_id;
  4. Employee employeeById = employeeRepository.findById(employee_id)
  5. .orElseThrow(() -> new RuntimeException("Employee not found"));
  6. a.setEmployee(employeeById);
  7. assignmentRepository.addAssignment(a);
  8. }

但是这样的实现不符合HTTP标准。请考虑实际情况,几乎符合这些标准,你应该像这样重命名你的API:POST URL/v1/employees/{employee_id}。这个博客解释了这些标准。

根据提供的规范进行编辑:

  1. @PostMapping(values = {"/v1/employees", "/v1/employees/{employee_id}"})
  2. public void addEmployee(@PathVariable(value = "employee_id", required = false) Long employee_id, @RequestBody Assignment a) {
  3. Long yourId = employee_id != null ? employee_id : a.employee_id;
  4. if (yourId == null) {
  5. throw new RuntimeException("No id given"); // 不太干净,但由OP实现
  6. } else {
  7. Employee employeeById = employeeRepository.findById(yourId)
  8. .orElseThrow(() -> new RuntimeException("Employee not found"));
  9. a.setEmployee(employeeById);
  10. assignmentRepository.addAssignment(a);
  11. }
  12. }

由于路径变量是可选的,你首先尝试从URL中获取它,然后从你的请求体对象中获取它。

第二次编辑:一个Assignment可能没有Employee_id
第一种情况:你接受Assignment可能没有Employee
只需更改从AssignmentEmployee的关系:

  1. @OneToOne(optional = true)
  2. @JoinColumn(name = "employee_id", nullable = true)
  3. private Employee employee;

第二种情况:你想先创建一个新的Employee,然后将其绑定到你的Assignment,因为一个Assignment应该始终有一个Employee

  1. @PostMapping(values = {"/v1/employees", "/v1/employees/{employee_id}"})
  2. public void addEmployee(@PathVariable(value = "employee_id", required = false) Long employee_id, @RequestBody Assignment a) {
  3. Long yourId = employee_id != null ? employee_id : a.employee_id;
  4. Employee employeeById = yourId != null ?
  5. employeeRepository.findById(yourId).orElseThrow(() -> new RuntimeException("Employee not found"))
  6. : new Employee("title","staff",2L);
  7. a.setEmployee(employeeById);
  8. assignmentRepository.addAssignment(a);
  9. }
英文:

You need to ensure your body type Assignment has such property like

  1. public class Assignment {
  2. public Long employee_id;
  3. // ommitted
  4. }

And get it in your method like

  1. @PostMapping(&quot;/add&quot;)
  2. public void addEmployee(@PathVariable(value = &quot;employee_id&quot;, required = false) Long employee_id, @RequestBody Assignment a) {
  3. Long employee_id = a.employee_id;
  4. Employee employeeById = employeeRepository.findById(employee_id)
  5. .orElseThrow(() -&gt; new RuntimeException(&quot;Employee not found&quot;));
  6. a.setEmployee(employeeById);
  7. assignmentRepository.addAssignment(a);
  8. }

But such implementation does not respect HTTP standards.
Please consider that your actual implementation almost respect those standards and you should rename your API this way : POST URL/v1/employees/{employee_id}
This blog explains those standards

EDIT with provided specifications:

  1. @PostMapping(values = {&quot;/v1/employees&quot;, &quot;/v1/employees/{employee_id}&quot;})
  2. public void addEmployee(@PathVariable(value = &quot;employee_id&quot;, required = false) Long employee_id, @RequestBody Assignment a) {
  3. Long yourId = employee_id != null ? employee_id : a.employee_id;
  4. if (yourId == null) {
  5. throw new RuntimeException(&quot;No id given&quot;); // Not clean either but implemented by OP
  6. } else {
  7. Employee employeeById = employeeRepository.findById(yourId)
  8. .orElseThrow(() -&gt; new RuntimeException(&quot;Employee not found&quot;));
  9. a.setEmployee(employeeById);
  10. assignmentRepository.addAssignment(a);
  11. }
  12. }

As the pathvariable is optionnal you try to get it first from url and then from your body object.

EDIT 2 : An Assignment might be created with no Employee_id
First case : You accept that an Assignment might have no Employee.
Simply change your relation from Assignment to Employee :

  1. @OneToOne(optional = true)
  2. @JoinColumn(name = &quot;employee_id&quot;, nullable = true)
  3. private Employee employee;

Second case : You want to create a new Employee first and then bind it to your assignement as an Assignment should always have an Employee

  1. @PostMapping(values = {&quot;/v1/employees&quot;, &quot;/v1/employees/{employee_id}&quot;})
  2. public void addEmployee(@PathVariable(value = &quot;employee_id&quot;, required = false) Long employee_id, @RequestBody Assignment a) {
  3. Long yourId = employee_id != null ? employee_id : a.employee_id;
  4. Employee employeeById = yourId != null ?
  5. employeeRepository.findById(yourId).orElseThrow(() -&gt; new RuntimeException(&quot;Employee not found&quot;))
  6. : new Employee(&quot;title&quot;,&quot;staff&quot;,2L);
  7. a.setEmployee(employeeById);
  8. assignmentRepository.addAssignment(a);
  9. }

huangapple
  • 本文由 发表于 2020年9月15日 23:36:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63905270.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定