如何在通过 POST 提交数据时应用 Hibernate 验证器并在 PUT 时省略?
How to apply Hibernate validator when data submitted via POST and omit when PUT?
POST
和 PUT
方法具有相同的 DTO 对象:
class AcmeRequest {
private String id;
@NotEmpty
private String productCode;
private String description;
}
对于 POST
请求我总是希望看到 productCode
字段,这就是为什么我指定 @NotEmpty
注释但是当 PUT
收到请求时 productCode
应该是可选。
当请求为 PUT
时,是否可以跳过 @NotEmpty
?
每个 Hibernate Validator 注释都有一个 groups
参数。通过界面,您可以控制激活哪些验证。在 docs.
查看更多信息
在控制器级别,指定必须使用 @Validated
注释激活哪个 groups
。
下面是我的一个演示项目中的一个小示例。我曾经和你有过同样的疑问
实体:
@Entity
@Table(name = "tasks")
@Getter @Setter
public class Task
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Null(message = "You can't provide a task ID manually. ID's are automatically assigned by our internal systems.", groups = {TaskInsertValidatorGroup.class})
@NotNull(message = "You must provide an id" , groups = TaskUpdateValidatorGroup.class)
private Integer id;
@NotBlank(message = "Task description cannot be empty")
@Length(max = 255 , message = "Task description length must not exceed 255 characters")
private String description;
@JsonProperty("is_completed")
@Column(name = "is_completed")
private Boolean isCompleted = false;
@CreationTimestamp
@JsonProperty("created_on")
@JsonFormat(pattern="dd-MM-yyyy HH:mm:ss")
@Column(name = "created_on", updatable = false)
private Timestamp creationDate;
@UpdateTimestamp
@JsonProperty("last_modified")
@JsonFormat(pattern="dd-MM-yyyy HH:mm:ss")
@Column(name = "last_modidied")
private Timestamp lastModificationDate;
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Task task = (Task) o;
return id.equals(task.id);
}
@Override
public int hashCode()
{
return Objects.hash(id);
}
}
接口:
public interface TaskInsertValidatorGroup {}
public interface TaskUpdateValidatorGroup{}
控制器:
RestController
@RequestMapping("/api")
public class TaskRestController
{
@Autowired
private TaskService taskService;
@GetMapping("/tasks/{id}")
public ResponseEntity<?> getTask(@PathVariable Integer id)
{
return new ResponseEntity<>(taskService.findTask(id),HttpStatus.OK);
}
@GetMapping("/tasks")
public ResponseEntity<?> getTasks()
{
return new ResponseEntity<>(taskService.findAllTasks(),HttpStatus.OK);
}
@PostMapping("/tasks")
public ResponseEntity<?> addTask(@Validated(TaskInsertValidatorGroup.class) @RequestBody Task task)
{
taskService.saveTask(task);
APISuccessResponse response = APISuccessResponse.builder()
.info("Task added")
.build();
return new ResponseEntity<>(response,HttpStatus.OK);
}
@RequestMapping(value = "/tasks" , method = RequestMethod.PATCH)
public ResponseEntity<?> updateTask(@Validated(TaskUpdateValidatorGroup.class) @RequestBody Task task)
{
taskService.updateTask(task);
APISuccessResponse response = APISuccessResponse.builder()
.info("Task Updated")
.build();
return new ResponseEntity<>(response,HttpStatus.OK);
}
@RequestMapping(value = "/tasks/{id}", method = RequestMethod.DELETE)
public ResponseEntity<?> removeTask(@PathVariable Integer id)
{
taskService.removeTask(id);
APISuccessResponse response = APISuccessResponse.builder()
.info("Task Deleted")
.build();
return new ResponseEntity<>(response,HttpStatus.OK);
}
}
POST
和 PUT
方法具有相同的 DTO 对象:
class AcmeRequest {
private String id;
@NotEmpty
private String productCode;
private String description;
}
对于 POST
请求我总是希望看到 productCode
字段,这就是为什么我指定 @NotEmpty
注释但是当 PUT
收到请求时 productCode
应该是可选。
当请求为 PUT
时,是否可以跳过 @NotEmpty
?
每个 Hibernate Validator 注释都有一个 groups
参数。通过界面,您可以控制激活哪些验证。在 docs.
在控制器级别,指定必须使用 @Validated
注释激活哪个 groups
。
下面是我的一个演示项目中的一个小示例。我曾经和你有过同样的疑问
实体:
@Entity
@Table(name = "tasks")
@Getter @Setter
public class Task
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Null(message = "You can't provide a task ID manually. ID's are automatically assigned by our internal systems.", groups = {TaskInsertValidatorGroup.class})
@NotNull(message = "You must provide an id" , groups = TaskUpdateValidatorGroup.class)
private Integer id;
@NotBlank(message = "Task description cannot be empty")
@Length(max = 255 , message = "Task description length must not exceed 255 characters")
private String description;
@JsonProperty("is_completed")
@Column(name = "is_completed")
private Boolean isCompleted = false;
@CreationTimestamp
@JsonProperty("created_on")
@JsonFormat(pattern="dd-MM-yyyy HH:mm:ss")
@Column(name = "created_on", updatable = false)
private Timestamp creationDate;
@UpdateTimestamp
@JsonProperty("last_modified")
@JsonFormat(pattern="dd-MM-yyyy HH:mm:ss")
@Column(name = "last_modidied")
private Timestamp lastModificationDate;
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Task task = (Task) o;
return id.equals(task.id);
}
@Override
public int hashCode()
{
return Objects.hash(id);
}
}
接口:
public interface TaskInsertValidatorGroup {}
public interface TaskUpdateValidatorGroup{}
控制器:
RestController
@RequestMapping("/api")
public class TaskRestController
{
@Autowired
private TaskService taskService;
@GetMapping("/tasks/{id}")
public ResponseEntity<?> getTask(@PathVariable Integer id)
{
return new ResponseEntity<>(taskService.findTask(id),HttpStatus.OK);
}
@GetMapping("/tasks")
public ResponseEntity<?> getTasks()
{
return new ResponseEntity<>(taskService.findAllTasks(),HttpStatus.OK);
}
@PostMapping("/tasks")
public ResponseEntity<?> addTask(@Validated(TaskInsertValidatorGroup.class) @RequestBody Task task)
{
taskService.saveTask(task);
APISuccessResponse response = APISuccessResponse.builder()
.info("Task added")
.build();
return new ResponseEntity<>(response,HttpStatus.OK);
}
@RequestMapping(value = "/tasks" , method = RequestMethod.PATCH)
public ResponseEntity<?> updateTask(@Validated(TaskUpdateValidatorGroup.class) @RequestBody Task task)
{
taskService.updateTask(task);
APISuccessResponse response = APISuccessResponse.builder()
.info("Task Updated")
.build();
return new ResponseEntity<>(response,HttpStatus.OK);
}
@RequestMapping(value = "/tasks/{id}", method = RequestMethod.DELETE)
public ResponseEntity<?> removeTask(@PathVariable Integer id)
{
taskService.removeTask(id);
APISuccessResponse response = APISuccessResponse.builder()
.info("Task Deleted")
.build();
return new ResponseEntity<>(response,HttpStatus.OK);
}
}