From 1ef4645323cd8ea0e6197e2f5b88270be89b5ab5 Mon Sep 17 00:00:00 2001 From: jwierzbo Date: Thu, 8 Feb 2018 13:39:10 +0100 Subject: [PATCH] Validation example --- pom.xml | 14 +++-- .../rest/api/MovieV2SwaggerController.java | 5 +- .../rest/api/MovieV3ValidController.java | 57 +++++++++++++++++++ .../java/net/jwierzbo/rest/model/Movie.java | 7 +++ .../net/jwierzbo/rest/validation/Name.java | 22 +++++++ .../rest/validation/NameValidator.java | 14 +++++ 6 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 src/main/java/net/jwierzbo/rest/api/MovieV3ValidController.java create mode 100644 src/main/java/net/jwierzbo/rest/validation/Name.java create mode 100644 src/main/java/net/jwierzbo/rest/validation/NameValidator.java diff --git a/pom.xml b/pom.xml index 6c24433..3d2e15b 100644 --- a/pom.xml +++ b/pom.xml @@ -3,12 +3,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 1.5.10.RELEASE - - net.jwierzbo.rest REST-movie-service 0.1 @@ -19,12 +13,20 @@ UTF-8 1.8 2.8.0 + 1.5.10.RELEASE + + org.springframework.boot + spring-boot-starter-parent + 1.5.10.RELEASE + + org.springframework.boot spring-boot-starter-web + ${spring.boot.version} com.fasterxml.jackson.datatype diff --git a/src/main/java/net/jwierzbo/rest/api/MovieV2SwaggerController.java b/src/main/java/net/jwierzbo/rest/api/MovieV2SwaggerController.java index 3cbb992..38315f5 100644 --- a/src/main/java/net/jwierzbo/rest/api/MovieV2SwaggerController.java +++ b/src/main/java/net/jwierzbo/rest/api/MovieV2SwaggerController.java @@ -23,9 +23,10 @@ import java.util.List; -/* This is example Controller class with extends description for SwaggerApi +/* +* This is example Controller class with extended description for SwaggerApi * These @Api*** annotations are not necessary if we use @ResponseStatus -* and return Model objects instead of generic response +* and @ResponseBody objects instead of generic response */ @Api(value="MovieController", description="List of favourite Movies") diff --git a/src/main/java/net/jwierzbo/rest/api/MovieV3ValidController.java b/src/main/java/net/jwierzbo/rest/api/MovieV3ValidController.java new file mode 100644 index 0000000..6ce4ae1 --- /dev/null +++ b/src/main/java/net/jwierzbo/rest/api/MovieV3ValidController.java @@ -0,0 +1,57 @@ +package net.jwierzbo.rest.api; + +import net.jwierzbo.rest.dao.MovieDAO; +import net.jwierzbo.rest.model.Movie; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +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.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.List; + +/* +* This is example of Validation flow in RestController +*/ + +@RestController +@RequestMapping("/v3") +public class MovieV3ValidController { + + @Autowired + private MovieDAO movieDAO; + + @GetMapping("/movies") + public List getMovies() { + return movieDAO.list(); + } + + @GetMapping("/movies/{id}") + public Movie getMovie(@PathVariable("id") Long id) { + return movieDAO.get(id).get(); + } + + @PostMapping(value = "/movies") + @ResponseStatus(value = HttpStatus.CREATED) + public Movie createMovie(@Valid @RequestBody Movie movie) { // Validate input + return movieDAO.create(movie); + } + + @DeleteMapping("/movies/{id}") + @ResponseStatus(value = HttpStatus.NO_CONTENT) + public void deleteMovie(@Valid @PathVariable Long id) { // Validate input + movieDAO.delete(id); + } + + @PutMapping("/movies/{id}") + public Movie updateMovie(@PathVariable Long id, @RequestBody Movie movie) { + return movieDAO.update(id, movie); + } +} \ No newline at end of file diff --git a/src/main/java/net/jwierzbo/rest/model/Movie.java b/src/main/java/net/jwierzbo/rest/model/Movie.java index 3de6174..38a1402 100644 --- a/src/main/java/net/jwierzbo/rest/model/Movie.java +++ b/src/main/java/net/jwierzbo/rest/model/Movie.java @@ -3,17 +3,24 @@ import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +import net.jwierzbo.rest.validation.Name; +import javax.validation.constraints.NotNull; import java.time.LocalDate; + @ApiModel(value = "Movie") public class Movie { @ApiModelProperty(notes = "The database generated product ID") private Long id; + // example of default Bean validation + @NotNull(message = "title can not be null") private String title; + // example of custom Bean validation + @Name(message = "Invalid director name - it has to start with uppercase!") private String director; @JsonFormat(pattern = "yyyy-MM-dd") diff --git a/src/main/java/net/jwierzbo/rest/validation/Name.java b/src/main/java/net/jwierzbo/rest/validation/Name.java new file mode 100644 index 0000000..8590730 --- /dev/null +++ b/src/main/java/net/jwierzbo/rest/validation/Name.java @@ -0,0 +1,22 @@ +package net.jwierzbo.rest.validation; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Documented +@Constraint(validatedBy = NameValidator.class) +@Target( { ElementType.METHOD, ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Name { + + String message() default "{Name}"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} \ No newline at end of file diff --git a/src/main/java/net/jwierzbo/rest/validation/NameValidator.java b/src/main/java/net/jwierzbo/rest/validation/NameValidator.java new file mode 100644 index 0000000..4d91240 --- /dev/null +++ b/src/main/java/net/jwierzbo/rest/validation/NameValidator.java @@ -0,0 +1,14 @@ +package net.jwierzbo.rest.validation; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +public class NameValidator implements ConstraintValidator { + public void initialize(Name constraintAnnotation) { + } + + public boolean isValid(String value, ConstraintValidatorContext context) { + return !value.isEmpty() && Character.isUpperCase(value.charAt(0)); + } +} +