Jessica Campbell 8 лет назад
Родитель
Сommit
cefd0a9552

+ 16
- 0
src/main/Resources/import.sql Просмотреть файл

@@ -0,0 +1,16 @@
1
+insert into poll (poll_id, question) values (1, 'Who is your favorite music artist?');
2
+insert into option (option_id, option_value, poll_id) values (1, 'Beyonce', 1);
3
+insert into option (option_id, option_value, poll_id) values (2, 'The Weeknd', 1);
4
+insert into option (option_id, option_value, poll_id) values (3, 'Drake', 1);
5
+insert into option (option_id, option_value, poll_id) values (4, 'Rihanna', 1);
6
+insert into option (option_id, option_value, poll_id) values (5, 'Ariana Grande', 1);
7
+insert into option (option_id, option_value, poll_id) values (6, 'Miguel', 1);
8
+insert into option (option_id, option_value, poll_id) values (7, 'Ed Sheeran', 1);
9
+insert into option (option_id, option_value, poll_id) values (8, 'Demi Lovato', 1);
10
+insert into option (option_id, option_value, poll_id) values (9, 'Selena Gomez', 1);
11
+insert into option (option_id, option_value, poll_id) values (10, 'Justin Bieber', 1);
12
+insert into option (option_id, option_value, poll_id) values (11, 'Bruno Mars', 1);
13
+insert into option (option_id, option_value, poll_id) values (12, 'Imagine Dragons', 1);
14
+insert into option (option_id, option_value, poll_id) values (13, 'Halsey', 1);
15
+insert into option (option_id, option_value, poll_id) values (14, 'J. Cole', 1);
16
+insert into option (option_id, option_value, poll_id) values (15, 'Kendrick Lamar', 1);

+ 2
- 0
src/main/Resources/messages.properties Просмотреть файл

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

+ 21
- 13
src/main/java/io/zipcoder/tc_spring_poll_application/Controller/PollController.java Просмотреть файл

@@ -3,6 +3,7 @@ package io.zipcoder.tc_spring_poll_application.Controller;
3 3
 import io.zipcoder.tc_spring_poll_application.Domain.Poll;
4 4
 import io.zipcoder.tc_spring_poll_application.Exception.ResourceNotFoundException;
5 5
 import io.zipcoder.tc_spring_poll_application.Repositories.PollRepository;
6
+import org.springframework.beans.factory.annotation.Autowired;
6 7
 import org.springframework.http.HttpHeaders;
7 8
 import org.springframework.http.HttpStatus;
8 9
 import org.springframework.http.ResponseEntity;
@@ -10,6 +11,7 @@ import org.springframework.web.bind.annotation.*;
10 11
 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
11 12
 
12 13
 import javax.inject.Inject;
14
+import javax.validation.Valid;
13 15
 import java.net.URI;
14 16
 
15 17
 @RestController
@@ -17,17 +19,19 @@ public class PollController {
17 19
     @Inject
18 20
     PollRepository pollRepository;
19 21
 
20
-    public PollController(){
22
+    @Autowired
23
+    public PollController() {
21 24
         this.pollRepository = pollRepository;
22 25
     }
23 26
 
24
-    @RequestMapping(value="/polls", method= RequestMethod.GET)
27
+    @RequestMapping(value = "/polls", method = RequestMethod.GET)
25 28
     public ResponseEntity<Iterable<Poll>> getAllPolls() {
26 29
         Iterable<Poll> allPolls = pollRepository.findAll(); // reads all the polls using the poll repository
27 30
         return new ResponseEntity<>(allPolls, HttpStatus.OK); // poll data becomes part of the response body & responds as OK (200)
28 31
     }
29
-    @RequestMapping(value="/polls", method=RequestMethod.POST)
30
-    public ResponseEntity<?> createPoll(@RequestBody Poll poll) { // ensures client has some way of knowing the URI of the newly created poll
32
+
33
+    @RequestMapping(value = "/polls", method = RequestMethod.POST)
34
+    public ResponseEntity<?> createPoll(@Valid @RequestBody Poll poll) { // ensures client has some way of knowing the URI of the newly created poll
31 35
         poll = (Poll) pollRepository.save(poll);
32 36
         URI newPollUri = ServletUriComponentsBuilder
33 37
                 .fromCurrentRequest()
@@ -38,26 +42,30 @@ public class PollController {
38 42
         httpHeaders.setLocation(newPollUri);
39 43
         return new ResponseEntity<>(httpHeaders, HttpStatus.CREATED);
40 44
     }
41
-    @RequestMapping(value="/polls/{pollId}", method=RequestMethod.GET) // enables us to access an individual poll
45
+
46
+    @RequestMapping(value = "/polls/{pollId}", method = RequestMethod.GET) // enables us to access an individual poll
42 47
     public ResponseEntity<?> getPoll(@PathVariable Long pollId) {
43 48
         Poll p = pollRepository.findOne(pollId);
44
-        return new ResponseEntity<> (p, HttpStatus.OK);
49
+        return new ResponseEntity<>(p, HttpStatus.OK);
45 50
     }
46
-    @RequestMapping(value="/polls/{pollId}", method=RequestMethod.PUT)
47
-    public ResponseEntity<?> updatePoll(@RequestBody Poll poll, @PathVariable Long pollId) { // enables us to update a poll
51
+
52
+    @RequestMapping(value = "/polls/{pollId}", method = RequestMethod.PUT)
53
+    public ResponseEntity<?> updatePoll(@Valid @RequestBody Poll poll, @PathVariable Long pollId) { // enables us to update a poll
48 54
         // Save the entity
49 55
         Poll p = pollRepository.save(poll);
50 56
         return new ResponseEntity<>(HttpStatus.OK);
51 57
     }
52
-    @RequestMapping(value="/polls/{pollId}", method=RequestMethod.DELETE) // enables us to delete a poll
58
+
59
+    @RequestMapping(value = "/polls/{pollId}", method = RequestMethod.DELETE) // enables us to delete a poll
53 60
     public ResponseEntity<?> deletePoll(@PathVariable Long pollId) {
54 61
         pollRepository.delete(pollId);
55 62
         return new ResponseEntity<>(HttpStatus.OK);
56 63
     }
57 64
 
58
-    public void verifyPoll() throws ResourceNotFoundException{
59
-        Poll poll = pollRepository.findOne(pollId);
60
-        if(poll == null){
65
+    public void verifyPoll(Long pollId) throws ResourceNotFoundException {
66
+        Poll p = pollRepository.findOne(pollId);
67
+        if (p == null) {
61 68
             throw new ResourceNotFoundException("Poll with id " + pollId + " not found");
69
+        }
62 70
     }
63
-}}
71
+}

+ 5
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/Domain/Poll.java Просмотреть файл

@@ -1,6 +1,9 @@
1 1
 package io.zipcoder.tc_spring_poll_application.Domain;
2 2
 
3
+import org.hibernate.validator.constraints.NotEmpty;
4
+
3 5
 import javax.persistence.*;
6
+import javax.validation.constraints.Size;
4 7
 import java.util.Set;
5 8
 
6 9
 @Entity
@@ -11,11 +14,13 @@ public class Poll {
11 14
     private long id;
12 15
 
13 16
     @Column(name = "QUESTION")
17
+    @NotEmpty
14 18
     private String question;
15 19
 
16 20
     @OneToMany(cascade = CascadeType.ALL)
17 21
     @JoinColumn(name = "POLL_ID")
18 22
     @OrderBy
23
+    @Size(min = 2, max = 6)
19 24
     private Set<Option> options;
20 25
 
21 26
     public Poll(){

+ 69
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/Dto/Error/ErrorDetail.java Просмотреть файл

@@ -0,0 +1,69 @@
1
+package io.zipcoder.tc_spring_poll_application.Dto.Error;
2
+
3
+import java.util.List;
4
+import java.util.Map;
5
+
6
+public class ErrorDetail {
7
+
8
+    String title;
9
+    int status;
10
+    String detail;
11
+    long timeStamp;
12
+    String developerMessage;
13
+    Map<String, List<ValidationError>> errors;
14
+
15
+    public ErrorDetail(){
16
+        this.detail = detail;
17
+        this.developerMessage = developerMessage;
18
+        this.status = status;
19
+        this.title = title;
20
+        this.timeStamp = timeStamp;
21
+        this.errors = errors;
22
+    }
23
+    public String getTitle() {
24
+        return title;
25
+    }
26
+
27
+    public void setTitle(String title) {
28
+        this.title = title;
29
+    }
30
+
31
+    public int getStatus() {
32
+        return status;
33
+    }
34
+
35
+    public void setStatus(int status) {
36
+        this.status = status;
37
+    }
38
+
39
+    public String getDetail() {
40
+        return detail;
41
+    }
42
+
43
+    public void setDetail(String detail) {
44
+        this.detail = detail;
45
+    }
46
+
47
+    public long getTimeStamp() {
48
+        return timeStamp;
49
+    }
50
+
51
+    public void setTimeStamp(long timeStamp) {
52
+        this.timeStamp = timeStamp;
53
+    }
54
+
55
+    public String getDeveloperMessage() {
56
+        return developerMessage;
57
+    }
58
+
59
+    public void setDeveloperMessage(String developerMessage) {
60
+        this.developerMessage = developerMessage;
61
+    }
62
+    public Map<String, List<ValidationError>> getErrors() {
63
+        return errors;
64
+    }
65
+
66
+    public void setErrors(Map<String, List<ValidationError>> errors) {
67
+        this.errors = errors;
68
+    }
69
+}

+ 67
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/Dto/Error/RestExceptionHandler.java Просмотреть файл

@@ -0,0 +1,67 @@
1
+package io.zipcoder.tc_spring_poll_application.Dto.Error;
2
+
3
+import io.zipcoder.tc_spring_poll_application.Exception.ResourceNotFoundException;
4
+import org.springframework.context.MessageSource;
5
+import org.springframework.http.HttpStatus;
6
+import org.springframework.http.ResponseEntity;
7
+import org.springframework.validation.FieldError;
8
+import org.springframework.web.bind.MethodArgumentNotValidException;
9
+import org.springframework.web.bind.annotation.ControllerAdvice;
10
+import org.springframework.web.bind.annotation.ExceptionHandler;
11
+
12
+import javax.inject.Inject;
13
+import javax.servlet.http.HttpServletRequest;
14
+import java.util.ArrayList;
15
+import java.util.Date;
16
+import java.util.List;
17
+
18
+@ControllerAdvice
19
+public class RestExceptionHandler {
20
+    private final MessageSource messageSource;
21
+
22
+    @Inject
23
+    public RestExceptionHandler(MessageSource messageSource){
24
+        this.messageSource = messageSource;
25
+    }
26
+
27
+    @ExceptionHandler(ResourceNotFoundException.class)
28
+    public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException rnfe, HttpServletRequest request) {
29
+
30
+        ErrorDetail errorDetail = new ErrorDetail();
31
+        errorDetail.setTimeStamp(new Date().getTime());
32
+        errorDetail.setStatus(HttpStatus.NOT_FOUND.value());
33
+        errorDetail.setTitle("Resource Not Found");
34
+        errorDetail.setDetail(rnfe.getMessage());
35
+        errorDetail.setDeveloperMessage(rnfe.getClass().getName());
36
+
37
+        return new ResponseEntity<>(errorDetail, null, HttpStatus.NOT_FOUND);
38
+    }
39
+
40
+    @ExceptionHandler(MethodArgumentNotValidException.class)
41
+    public ResponseEntity<?>
42
+    handleValidationError(MethodArgumentNotValidException manve, HttpServletRequest request) {
43
+
44
+        ErrorDetail errorDetail = new ErrorDetail();
45
+        errorDetail.setTitle("Bad Request");
46
+        errorDetail.setDetail(manve.getMessage());
47
+        errorDetail.setDeveloperMessage(manve.getClass().getName());
48
+        errorDetail.setStatus(HttpStatus.BAD_REQUEST.value());
49
+        errorDetail.setTimeStamp(new Date().getTime());
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
+    }
66
+
67
+}

+ 25
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/Dto/Error/ValidationError.java Просмотреть файл

@@ -0,0 +1,25 @@
1
+package io.zipcoder.tc_spring_poll_application.Dto.Error;
2
+
3
+public class ValidationError {
4
+    String code;
5
+    String message;
6
+
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
+
24
+
25
+}