Parcourir la source

Started part 6

CWinarski il y a 8 ans
Parent
révision
cc91c9252f

+ 5
- 2
src/main/java/io/zipcoder/tc_spring_poll_application/controller/PollController.java Voir le fichier

10
 import org.springframework.web.bind.annotation.*;
10
 import org.springframework.web.bind.annotation.*;
11
 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
11
 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
12
 
12
 
13
+import javax.validation.Valid;
13
 import java.net.URI;
14
 import java.net.URI;
14
 
15
 
15
 @RestController// marks entity as a controller following REST specs
16
 @RestController// marks entity as a controller following REST specs
42
         return new ResponseEntity<>(newHeaders, HttpStatus.CREATED);
43
         return new ResponseEntity<>(newHeaders, HttpStatus.CREATED);
43
     }
44
     }
44
 
45
 
46
+    @Valid
45
     @RequestMapping(value="/polls/{pollId}", method=RequestMethod.GET)
47
     @RequestMapping(value="/polls/{pollId}", method=RequestMethod.GET)
46
     public ResponseEntity<?> getPoll(@PathVariable Long pollId) {
48
     public ResponseEntity<?> getPoll(@PathVariable Long pollId) {
47
         verifyPoll(pollId);
49
         verifyPoll(pollId);
49
         return new ResponseEntity<> (p, HttpStatus.OK);
51
         return new ResponseEntity<> (p, HttpStatus.OK);
50
     }
52
     }
51
 
53
 
54
+    @Valid
52
     @RequestMapping(value="/polls/{pollId}", method=RequestMethod.PUT)
55
     @RequestMapping(value="/polls/{pollId}", method=RequestMethod.PUT)
53
     public ResponseEntity<?> updatePoll(@RequestBody Poll poll, @PathVariable Long pollId) {
56
     public ResponseEntity<?> updatePoll(@RequestBody Poll poll, @PathVariable Long pollId) {
54
         // Save the entity
57
         // Save the entity
66
 
69
 
67
     public void verifyPoll(Long pollId){
70
     public void verifyPoll(Long pollId){
68
         Poll poll = pollRepository.findOne(pollId);
71
         Poll poll = pollRepository.findOne(pollId);
69
-        if(pollId == null){
70
-            throw new ResourceNotFoundException("The given poll id" + pollId + "does not exist!");
72
+        if(poll == null){
73
+            throw new ResourceNotFoundException("The given poll id " + pollId + " does not exist!");
71
         }
74
         }
72
     }
75
     }
73
 
76
 

+ 5
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/domain/Poll.java Voir le fichier

1
 package io.zipcoder.tc_spring_poll_application.domain;
1
 package io.zipcoder.tc_spring_poll_application.domain;
2
 
2
 
3
+import org.hibernate.validator.constraints.NotEmpty;
4
+
3
 import javax.persistence.*;
5
 import javax.persistence.*;
6
+import javax.validation.constraints.Size;
4
 import java.util.Set;
7
 import java.util.Set;
5
 
8
 
6
 @Entity
9
 @Entity
11
     @Column(name = "POLL_ID")
14
     @Column(name = "POLL_ID")
12
     private Long id;
15
     private Long id;
13
 
16
 
17
+    @NotEmpty
14
     @Column(name = "QUESTION")
18
     @Column(name = "QUESTION")
15
     private String question;
19
     private String question;
16
 
20
 
21
+    @Size(min=2, max = 6)
17
     @OneToMany(cascade = CascadeType.ALL)// indicates that a Poll instance can contain zero or more Option instances. The CascadeType.All indicates that any database operations such as persist, remove, or merge on a Poll instance needs to be propagated to all related Option instances
22
     @OneToMany(cascade = CascadeType.ALL)// indicates that a Poll instance can contain zero or more Option instances. The CascadeType.All indicates that any database operations such as persist, remove, or merge on a Poll instance needs to be propagated to all related Option instances
18
     @JoinColumn(name = "POLL_ID")// indicates this entity is the owner of the relationship. It has a key to the column with options
23
     @JoinColumn(name = "POLL_ID")// indicates this entity is the owner of the relationship. It has a key to the column with options
19
     @OrderBy// orders by ASC default
24
     @OrderBy// orders by ASC default

+ 13
- 1
src/main/java/io/zipcoder/tc_spring_poll_application/error/ErrorDetail.java Voir le fichier

1
 package io.zipcoder.tc_spring_poll_application.error;
1
 package io.zipcoder.tc_spring_poll_application.error;
2
 
2
 
3
+import java.util.List;
4
+import java.util.Map;
5
+
3
 public class ErrorDetail {
6
 public class ErrorDetail {
4
 
7
 
5
     private String title; // title of error condition
8
     private String title; // title of error condition
6
     private int status; // HTTP status code for current request
9
     private int status; // HTTP status code for current request
7
     private String detail; // short readable description of error
10
     private String detail; // short readable description of error
8
-    private long timeStamp; // time in milliseconds when error occured
11
+    private long timeStamp; // time in milliseconds when error occurred
9
     private String developerMessage; // detailed info as such exception class or trace
12
     private String developerMessage; // detailed info as such exception class or trace
13
+    private Map<String, List<ValidationError>> errors;
10
 
14
 
11
     public String getTitle() {
15
     public String getTitle() {
12
         return title;
16
         return title;
47
     public void setDeveloperMessage(String developerMessage) {
51
     public void setDeveloperMessage(String developerMessage) {
48
         this.developerMessage = developerMessage;
52
         this.developerMessage = developerMessage;
49
     }
53
     }
54
+
55
+    public Map<String, List<ValidationError>> getErrors() {
56
+        return errors;
57
+    }
58
+
59
+    public void setErrors(Map<String, List<ValidationError>> errors) {
60
+        this.errors = errors;
61
+    }
50
 }
62
 }

+ 23
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/error/ValidationError.java Voir le fichier

1
+package io.zipcoder.tc_spring_poll_application.error;
2
+
3
+public class ValidationError {
4
+
5
+    private String code;
6
+    private String message;
7
+
8
+    public String getCode() {
9
+        return code;
10
+    }
11
+
12
+    public void setCode(String code) {
13
+        this.code = code;
14
+    }
15
+
16
+    public String getMessage() {
17
+        return message;
18
+    }
19
+
20
+    public void setMessage(String message) {
21
+        this.message = message;
22
+    }
23
+}

+ 40
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/exception/RestExceptionHandler.java Voir le fichier

1
 package io.zipcoder.tc_spring_poll_application.exception;
1
 package io.zipcoder.tc_spring_poll_application.exception;
2
 
2
 
3
 import io.zipcoder.tc_spring_poll_application.error.ErrorDetail;
3
 import io.zipcoder.tc_spring_poll_application.error.ErrorDetail;
4
+import io.zipcoder.tc_spring_poll_application.error.ValidationError;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.context.MessageSource;
4
 import org.springframework.http.HttpStatus;
7
 import org.springframework.http.HttpStatus;
5
 import org.springframework.http.ResponseEntity;
8
 import org.springframework.http.ResponseEntity;
9
+import org.springframework.validation.FieldError;
10
+import org.springframework.web.bind.MethodArgumentNotValidException;
6
 import org.springframework.web.bind.annotation.ControllerAdvice;
11
 import org.springframework.web.bind.annotation.ControllerAdvice;
7
 import org.springframework.web.bind.annotation.ExceptionHandler;
12
 import org.springframework.web.bind.annotation.ExceptionHandler;
8
 
13
 
9
 import javax.servlet.http.HttpServletRequest;
14
 import javax.servlet.http.HttpServletRequest;
15
+import java.util.ArrayList;
10
 import java.util.Date;
16
 import java.util.Date;
17
+import java.util.List;
11
 
18
 
12
 @ControllerAdvice
19
 @ControllerAdvice
13
 public class RestExceptionHandler {
20
 public class RestExceptionHandler {
14
 
21
 
22
+    @Autowired
23
+    MessageSource messageSource;
24
+
15
     @ExceptionHandler(ResourceNotFoundException.class)
25
     @ExceptionHandler(ResourceNotFoundException.class)
16
     public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException rnfe, HttpServletRequest request){
26
     public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException rnfe, HttpServletRequest request){
17
         //make error detail object and fill it?
27
         //make error detail object and fill it?
23
         errorDetail.setDeveloperMessage(rnfe.getClass().getName());
33
         errorDetail.setDeveloperMessage(rnfe.getClass().getName());
24
         return new ResponseEntity<>(errorDetail, null,  HttpStatus.NOT_FOUND);
34
         return new ResponseEntity<>(errorDetail, null,  HttpStatus.NOT_FOUND);
25
     }
35
     }
36
+
37
+    @ExceptionHandler(MethodArgumentNotValidException.class)
38
+    public ResponseEntity<?> handleValicationError(MethodArgumentNotValidException manve, HttpServletRequest request){
39
+        ErrorDetail errorDetail = new ErrorDetail();
40
+        errorDetail.setTitle("Validation Failed");
41
+        errorDetail.setStatus(HttpStatus.BAD_REQUEST.value());
42
+        errorDetail.setDetail("Input validation failed");
43
+        errorDetail.setTimeStamp(new Date().getTime());
44
+        errorDetail.setDeveloperMessage(manve.getClass().getName());
45
+
46
+        String requestPath = (String) request.getAttribute("javax.servlet.error. request_uri");
47
+        if(requestPath == null) {
48
+            requestPath = request.getRequestURI();
49
+        }
50
+
51
+        List<FieldError> fieldErrors =  manve.getBindingResult().getFieldErrors();
52
+        for(FieldError fe : fieldErrors) {
53
+
54
+            List<ValidationError> validationErrorList = errorDetail.getErrors().get(fe.getField());
55
+            if(validationErrorList == null) {
56
+                validationErrorList = new ArrayList<>();
57
+                errorDetail.getErrors().put(fe.getField(), validationErrorList);
58
+            }
59
+            ValidationError validationError = new ValidationError();
60
+            validationError.setCode(fe.getCode());
61
+            validationError.setMessage(messageSource.getMessage(fe, null));
62
+            validationErrorList.add(validationError);
63
+        }
64
+        return new ResponseEntity<>(errorDetail, HttpStatus.BAD_REQUEST);
65
+    }
26
 }
66
 }

+ 2
- 0
src/main/resources/messages.properties Voir le fichier

1
+NotEmpty.poll.question=Question is a required field
2
+Size.poll.options=Options must be greater than {2} and less than {1}