【问题标题】:Accepting request body in controller method在控制器方法中接受请求正文
【发布时间】:2020-01-09 21:55:19
【问题描述】:

在我的控制器中,我有一个使用以下映射映射的方法: @PostMapping("/")。

此方法需要一个我试图捕获的请求正文,如下所述:

公共字符串创建(@RequestBody 任务任务)

Task 是我创建的一个自定义类,它映射到请求中预期的请求正文的结构。

我是 Spring Boot 新手,不确定最佳实践标准如何。

我的疑问是在我的方法 create() 中,我应该直接在我的实体类中捕获请求体,还是应该有一个类似的 pojo 来捕获请求体,然后我将它映射到我的实体类?

任何关于最佳实践和标准约定的建议都会有所帮助。

使用这两种方法对我来说效果很好,如果直接在实体类中接受请求正文是一个好主意和最佳实践,我只是进退两难。

不想在控制器类中公开我的实体类,因为我不确定这是否是个好主意。

@PostMapping("/")
public String create(@Valid @RequestBody Task task) {


}

Task.java

public final class Task {

@NonNull
private int id;

@NotBlank(message = "Name is a mandatory field")
private String name;

private String decription;

@NotBlank(message = "date is a mandatory field")
private String date;

private boolean status;

@NotBlank(message = "severenes is a mandatory field")
private String severenes;

public Task(int id, String name, String decription, String date, boolean status, String severenes) {
    super();
    this.id = id;
    this.name = name;
    this.decription = decription;
    this.date = date;
    this.status = status;
    this.severenes = severenes;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getDecription() {
    return decription;
}

public void setDecription(String decription) {
    this.decription = decription;
}

public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}

public boolean isStatus() {
    return status;
}

public void setStatus(boolean status) {
    this.status = status;
}

public String getSeverenes() {
    return severenes;
}

public void setSeverenes(String severenes) {
    this.severenes = severenes;
}   

}

Tasks.java(实体类)

@Entity
@Table(name = "tasks")
public class Tasks {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id")
private int id;

@Column(name = "name")
private String name;

@Column(name = "description")
private String description;

@Column(name = "date")
private LocalDateTime date;

@Column(name = "status")
private boolean status;

@Column(name = "severenes")
private String severenes;


public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public LocalDateTime getDate() {
    return date;
}

public void setDate(LocalDateTime date) {
    this.date = date;
}

public boolean isStatus() {
    return status;
}

public void setStatus(boolean status) {
    this.status = status;
}

public String getSeverenes() {
    return severenes;
}

public void setSeverenes(String severenes) {
    this.severenes = severenes;
}

}

上述两种方法给出了相同的结果,更多的是关注要遵循的最佳实践。

【问题讨论】:

    标签: spring-boot java-8


    【解决方案1】:

    它更多地与软件设计原则有关。在此示例中,这与关注点分离有关。假设您直接将单个 Tasks 实体用于 DB 操作和 REST 操作,而不是将其分开 Task(一种 DTO)和 Tasks(实体)。

    为 DB 和 REST 操作使用任务实体:

    • 您有一个在页面上显示任务的 UI。
    • 您将任务存储在数据库中。
    • 要求现已更改。您不再将任务 status 存储在数据库中,而是需要从 3rd 端点动态获取。
    • 您需要从“任务实体”字段中删除状态字段,但仍需要将其返回给 UI。由于您对两个图层使用了相同的实体,因此无法轻松清晰地删除它,您应该怎么做,一些将来难以维护的变通方法?
    • 您需要做更多工作才能提供此功能,一项需求更改会影响应有的更多层。

    将任务用于 REST,将任务实体用于数据库操作

    • 您有一个在页面上显示任务的 UI。
    • 您将任务存储在数据库中。
    • 要求现已更改。您不再将任务 status 存储在数据库中,而是需要从 3rd 端点动态获取。
    • 您需要从“任务实体”字段中删除状态字段,并且可以。
    • 您从第 3 方检索到状态字段。
    • 您通过聚合来自第 3 方和任务实体的状态创建了任务对象
    • 您只是更改了一层而不是两层。 UI 甚至没有意识到需求发生了变化,甚至你的逻辑层也不关心它。单一职责原则让您无需担心变化。

    是的,似乎存在一些缺点,例如您需要更多的类来表示单个对象,但它是分离的。它使可维护的项目,易于重构/更改代码并最大限度地减少更改的影响。

    【讨论】:

      【解决方案2】:

      您应该创建类CreateTaskRequest,并且该类应该是您的控制器的参数。通过端点公开您的域是个坏主意。你可以看看here我是如何在我的一个项目中做到这一点的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-30
        • 2019-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多