执行RESTful服务的验证

验证是所有服务中的普遍要求。我们将讨论Java验证API, 以在我们的bean文件中添加验证。当我们收到创建用户的请求时, 我们应该验证其内容。如果无效, 我们应该返回适??当的答复。
让我们看看如何验证请求。
步骤1:打开UserResource.java文件。
步骤2:添加@Valid批注。它是一个Javax验证API。它的默认类路径是spring-boot-starter-web。
UserResource.java

package com.srcmini.server.main.user; import java.net.URI; import java.util.List; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @RestControllerpublic class UserResource {@Autowiredprivate UserDaoService service; @GetMapping("/users")public List< User> retriveAllUsers(){return service.findAll(); }//retrieves a specific user detail@GetMapping("/users/{id}")public User retriveUser(@PathVariable int id){User user= service.findOne(id); if(user==null)//runtime exceptionthrow new UserNotFoundException("id: "+ id); return user; }//method that delete a user resource@DeleteMapping("/users/{id}")public void deleteUser(@PathVariable int id){User user= service.deleteById(id); if(user==null)//runtime exceptionthrow new UserNotFoundException("id: "+ id); }//method that posts a new user detail and returns the status of the user resource@PostMapping("/users")public ResponseEntity< Object> createUser(@Valid @RequestBody User user) {User sevedUser=service.save(user); URI location=ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(sevedUser.getId()).toUri(); return ResponseEntity.created(location).build(); }}

现在, 我们将在User类中添加有关姓名和出生日期的验证。假设名称至少应包含五个字符, 并且出生日期应该是过去而不是现在。
步骤3:打开User.java文件。
步骤4:在name变量上方添加@Size(min = 5)批注。
步骤5:在dob变量上方添加@Past批注。
User.java
package com.srcmini.server.main.user; import java.util.Date; import javax.validation.constraints.Past; import javax.validation.constraints.Size; public class User {private Integer id; @Size(min=5)private String name; @Pastprivate Date dob; //default constructor protected User(){ }public User(Integer id, String name, Date dob) {super(); this.id = id; this.name = name; this.dob = dob; }public Integer getId() {return id; }public void setId(Integer id) {this.id = id; }public String getName() {return name; }public void setName(String name) {this.name = name; }public Date getDob() {return dob; }public void setDob(Date dob) {this.dob = dob; }@Overridepublic String toString() {//return "User [id=" + id + ", name=" + name + ", dob=" + dob + "]"; return String.format("User [id=%s, name=%s, dob=%s]", id, name, dob); }}

步骤5:打开Rest客户端Postman并发送一个新用户名Tony k的POST请求。它返回状态:201已创建。
执行RESTful服务的验证

文章图片
现在, 我们发送另一个POST请求。但是名称应少于五个字符。它返回状态:400错误的请求。
执行RESTful服务的验证

文章图片
创建RESTful服务时, 我们需要考虑消费者, 消费者如何知道出了什么问题。若要解决此问题, 我们将添加一个方法handleMethodArgumentNotValid(), 该方法在ResponseEntityExceptionHandler类中定义。这是发生错误请求时触发的方法。
protected ResponseEntity< Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {return handleExceptionInternal(ex, null, headers, status, request); }

步骤6:将上述方法复制并粘贴到CustomizedResponseEntityExceptionHandler.java文件中。
步骤7:通过添加注释@Override覆盖方法。
CustomizedResponseEntityExceptionHandler.java
package com.srcmini.server.main; import java.util.Date; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; import com.srcmini.server.main.exception.ExceptionResponse; import com.srcmini.server.main.user.UserNotFoundException; //defining exception handling for all the exceptions @ControllerAdvice@RestControllerpublic class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler{@ExceptionHandler(Exception.class)//override method of ResponseEntityExceptionHandler classpublic final ResponseEntity< Object> handleAllExceptions(Exception ex, WebRequest request){//creating exception response structureExceptionResponse exceptionResponse= new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false)); //returning exception structure and specific status return new ResponseEntity(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR); }@ExceptionHandler(UserNotFoundException.class)//override method of ResponseEntityExceptionHandler classpublic final ResponseEntity< Object> handleUserNotFoundExceptions(UserNotFoundException ex, WebRequest request){//creating exception response structureExceptionResponse exceptionResponse= new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false)); //returning exception structure and specific status return new ResponseEntity(exceptionResponse, HttpStatus.NOT_FOUND); }@Overrideprotected ResponseEntity< Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {ExceptionResponse exceptionResponse= new ExceptionResponse(new Date(), ex.getMessage(), ex.getBindingResult().toString()); //returning exception structure and specific status return new ResponseEntity(exceptionResponse, HttpStatus.BAD_REQUEST); }}

步骤8:现在, 我们通过邮递员发送POST请求。它返回异常结构, 并显示消息验证参数和其他详细信息失败。
执行RESTful服务的验证

文章图片
很难为用户理解该消息。因此, 我们现在将使用字符串验证失败来自定义消息, 而不是获取消息。
@Overrideprotected ResponseEntity< Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {ExceptionResponse exceptionResponse= new ExceptionResponse(new Date(), "Validation Failed", ex.getBindingResult().toString()); //returning exception structure and specific status return new ResponseEntity(exceptionResponse, HttpStatus.BAD_REQUEST); }

步骤9:再次发送POST请求。它返回我们已定制的消息。
执行RESTful服务的验证

文章图片
这可能对消费者有用。现在, 我们再次自定义消息, 并使其更加针对错误。
步骤10:打开User.java文件, 并在@Size批注中添加属性message =“名称应至少包含5个字符”。
@Size(min=5, message="Name should have at least 5 characters")

步骤11:再次, 发送POST请求。它返回我们指定的更具体的异常。
执行RESTful服务的验证

文章图片
【执行RESTful服务的验证】我们可以通过遵循BindingResult接口来进一步自定义异常。有各种各样的异常消息。在validation-api-2.0.1.Final.jar中定义了以下验证类。
执行RESTful服务的验证

文章图片

    推荐阅读