Skip to content

Commit e51ecaa

Browse files
committed
Add validation annotations to models and controllers + Added Application Exception Handler
1 parent 112d38a commit e51ecaa

File tree

13 files changed

+424
-333
lines changed

13 files changed

+424
-333
lines changed

pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
<scope>runtime</scope>
5353
<optional>true</optional>
5454
</dependency>
55+
<dependency>
56+
<groupId>org.springframework.boot</groupId>
57+
<artifactId>spring-boot-starter-validation</artifactId>
58+
</dependency>
5559

5660
<dependency>
5761
<groupId>io.springfox</groupId>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.couchbase.quickstart.springboot.advice;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import org.springframework.http.HttpStatus;
7+
import org.springframework.validation.FieldError;
8+
import org.springframework.web.bind.MethodArgumentNotValidException;
9+
import org.springframework.web.bind.annotation.ExceptionHandler;
10+
import org.springframework.web.bind.annotation.ResponseStatus;
11+
import org.springframework.web.bind.annotation.RestControllerAdvice;
12+
@RestControllerAdvice
13+
public class ApplicationExceptionHandler {
14+
15+
@ResponseStatus(HttpStatus.BAD_REQUEST)
16+
@ExceptionHandler(MethodArgumentNotValidException.class)
17+
public Map<String, String> handleValidationExceptions(
18+
MethodArgumentNotValidException ex) {
19+
Map<String, String> errorMap = new HashMap<>();
20+
21+
ex.getBindingResult().getAllErrors().forEach(error -> {
22+
String fieldName = ((FieldError) error).getField();
23+
String errorMessage = error.getDefaultMessage();
24+
errorMap.put(fieldName, errorMessage);
25+
});
26+
27+
return errorMap;
28+
}
29+
}

src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.net.URI;
44
import java.util.List;
55

6+
import javax.validation.Valid;
7+
68
import org.couchbase.quickstart.springboot.configs.DBProperties;
79
import org.couchbase.quickstart.springboot.models.Airline;
810
import org.springframework.http.HttpStatus;
@@ -54,7 +56,7 @@ public ResponseEntity<Airline> getAirline(@PathVariable String id) {
5456
}
5557

5658
@PostMapping("/{id}")
57-
public ResponseEntity<Airline> createAirline(@PathVariable String id, @RequestBody Airline airline) {
59+
public ResponseEntity<Airline> createAirline(@PathVariable String id,@Valid @RequestBody Airline airline) {
5860
try {
5961
airlineCol.insert(id, airline);
6062
Airline createdAirline = airlineCol.get(id).contentAs(Airline.class);
@@ -66,7 +68,7 @@ public ResponseEntity<Airline> createAirline(@PathVariable String id, @RequestBo
6668
}
6769

6870
@PutMapping("/{id}")
69-
public ResponseEntity<Airline> updateAirline(@PathVariable String id, @RequestBody Airline airline) {
71+
public ResponseEntity<Airline> updateAirline(@PathVariable String id,@Valid @RequestBody Airline airline) {
7072
try {
7173
airlineCol.replace(id, airline);
7274
Airline updatedAirline = airlineCol.get(id).contentAs(Airline.class);

src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.net.URI;
44
import java.util.List;
55

6+
import javax.validation.Valid;
7+
68
import org.couchbase.quickstart.springboot.configs.DBProperties;
79
import org.couchbase.quickstart.springboot.models.Airport;
810
import org.springframework.http.HttpStatus;
@@ -52,7 +54,7 @@ public ResponseEntity<Airport> getAirport(@PathVariable String id) {
5254
}
5355

5456
@PostMapping("/{id}")
55-
public ResponseEntity<Airport> createAirport(@PathVariable String id, @RequestBody Airport airport) {
57+
public ResponseEntity<Airport> createAirport(@PathVariable String id,@Valid @RequestBody Airport airport) {
5658
try {
5759
airportCol.insert(id, airport);
5860
Airport createdAirport = airportCol.get(id).contentAs(Airport.class);
@@ -63,7 +65,7 @@ public ResponseEntity<Airport> createAirport(@PathVariable String id, @RequestBo
6365
}
6466

6567
@PutMapping("/{id}")
66-
public ResponseEntity<Airport> updateAirport(@PathVariable String id, @RequestBody Airport airport) {
68+
public ResponseEntity<Airport> updateAirport(@PathVariable String id,@Valid @RequestBody Airport airport) {
6769
try {
6870
airportCol.replace(id, airport);
6971
Airport updatedAirport = airportCol.get(id).contentAs(Airport.class);

src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.net.URI;
44
import java.util.List;
55

6+
import javax.validation.Valid;
7+
68
import org.couchbase.quickstart.springboot.configs.DBProperties;
79
import org.couchbase.quickstart.springboot.models.Route;
810
import org.springframework.http.HttpStatus;
@@ -52,7 +54,7 @@ public ResponseEntity<Route> getRoute(@PathVariable String id) {
5254
}
5355

5456
@PostMapping("/{id}")
55-
public ResponseEntity<Route> createRoute(@PathVariable String id, @RequestBody Route route) {
57+
public ResponseEntity<Route> createRoute(@PathVariable String id,@Valid @RequestBody Route route) {
5658
try {
5759
routeCol.insert(id, route);
5860
Route createdRoute = routeCol.get(id).contentAs(Route.class);
@@ -63,7 +65,7 @@ public ResponseEntity<Route> createRoute(@PathVariable String id, @RequestBody R
6365
}
6466

6567
@PutMapping("/{id}")
66-
public ResponseEntity<Route> updateRoute(@PathVariable String id, @RequestBody Route route) {
68+
public ResponseEntity<Route> updateRoute(@PathVariable String id,@Valid @RequestBody Route route) {
6769
try {
6870
routeCol.replace(id, route);
6971
Route updatedRoute = routeCol.get(id).contentAs(Route.class);
@@ -86,7 +88,7 @@ public ResponseEntity<Void> deleteRoute(@PathVariable String id) {
8688
@GetMapping("/list")
8789
public ResponseEntity<List<Route>> listRoutes() {
8890
try {
89-
String statement = "SELECT airport.* FROM `" + dbProperties.getBucketName() + "`.`inventory`.`route`";
91+
String statement = "SELECT route.* FROM `" + dbProperties.getBucketName() + "`.`inventory`.`route`";
9092
List<Route> routes = cluster
9193
.query(statement, QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS))
9294
.rowsAs(Route.class);
Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,43 @@
11
package org.couchbase.quickstart.springboot.models;
22

3+
import java.io.Serializable;
4+
5+
import javax.validation.constraints.NotBlank;
6+
import javax.validation.constraints.Pattern;
7+
38
import lombok.AllArgsConstructor;
9+
import lombok.Data;
410
import lombok.Getter;
511
import lombok.NoArgsConstructor;
612
import lombok.Setter;
713

8-
import java.io.Serializable;
9-
1014
@Getter
1115
@Setter
1216
@AllArgsConstructor
1317
@NoArgsConstructor
18+
@Data
1419
public class Airline implements Serializable {
1520

21+
@NotBlank(message = "ID is mandatory")
1622
private String id;
1723

24+
@NotBlank(message = "Type is mandatory")
1825
private String type;
1926

27+
@NotBlank(message = "Name is mandatory")
2028
private String name;
2129

30+
@NotBlank(message = "IATA code is mandatory")
31+
@Pattern(regexp = "^[A-Z]{2}$", message = "IATA code must be a 2-letter uppercase code")
2232
private String iata;
2333

34+
@NotBlank(message = "ICAO code is mandatory")
35+
@Pattern(regexp = "^[A-Z]{3}$", message = "ICAO code must be a 3-letter uppercase code")
2436
private String icao;
2537

38+
@NotBlank(message = "Callsign is mandatory")
2639
private String callsign;
2740

41+
@NotBlank(message = "Country is mandatory")
2842
private String country;
2943
}

src/main/java/org/couchbase/quickstart/springboot/models/Airport.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package org.couchbase.quickstart.springboot.models;
22

3+
import javax.validation.Valid;
4+
import javax.validation.constraints.NotBlank;
5+
import javax.validation.constraints.Pattern;
6+
37
import lombok.AllArgsConstructor;
48
import lombok.Getter;
59
import lombok.NoArgsConstructor;
@@ -11,22 +15,33 @@
1115
@NoArgsConstructor
1216
public class Airport {
1317

18+
@NotBlank(message = "ID is mandatory")
1419
private String id;
1520

21+
@NotBlank(message = "Type is mandatory")
1622
private String type;
1723

24+
@NotBlank(message = "Airport name is mandatory")
1825
private String airportname;
1926

27+
@NotBlank(message = "City is mandatory")
2028
private String city;
2129

30+
@NotBlank(message = "Country is mandatory")
2231
private String country;
2332

33+
// @NotBlank(message = "FAA is mandatory")
34+
@Pattern(regexp = "[A-Z]{3}", message = "FAA must be 3 uppercase letters")
2435
private String faa;
2536

37+
// @NotBlank(message = "ICAO is mandatory")
38+
@Pattern(regexp = "[A-Z]{4}", message = "ICAO must be 4 uppercase letters")
2639
private String icao;
2740

41+
@NotBlank(message = "Timezone is mandatory")
2842
private String tz;
2943

44+
@Valid
3045
private Geo geo;
3146

3247
@Getter
@@ -35,10 +50,13 @@ public class Airport {
3550
@NoArgsConstructor
3651
public static class Geo {
3752

53+
// @NotBlank(message = "Altitude is mandatory")
3854
private double alt;
3955

56+
// @NotBlank(message = "Latitude is mandatory")
4057
private double lat;
4158

59+
// @NotBlank(message = "Longitude is mandatory")
4260
private double lon;
4361
}
4462
}

src/main/java/org/couchbase/quickstart/springboot/models/Route.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
import java.util.List;
44

5+
import javax.validation.Valid;
6+
import javax.validation.constraints.NotBlank;
7+
import javax.validation.constraints.NotNull;
8+
59
import lombok.AllArgsConstructor;
10+
import lombok.Data;
611
import lombok.Getter;
712
import lombok.NoArgsConstructor;
813
import lombok.Setter;
@@ -11,26 +16,37 @@
1116
@Setter
1217
@AllArgsConstructor
1318
@NoArgsConstructor
19+
@Data
1420
public class Route {
1521

22+
@NotBlank(message = "ID is mandatory")
1623
private String id;
1724

25+
@NotBlank(message = "Type is mandatory")
1826
private String type;
1927

28+
@NotBlank(message = "Airline is mandatory")
2029
private String airline;
2130

22-
private String airlineId;
31+
@NotBlank(message = "Airline ID is mandatory")
32+
private String airlineid;
2333

24-
private String sourceAirport;
34+
@NotBlank(message = "Source airport is mandatory")
35+
private String sourceairport;
2536

26-
private String destinationAirport;
37+
@NotBlank(message = "Destination airport is mandatory")
38+
private String destinationairport;
2739

40+
@NotNull(message = "Stops is mandatory")
2841
private int stops;
2942

43+
@NotBlank(message = "Equipment is mandatory")
3044
private String equipment;
3145

46+
@Valid
3247
private List<Schedule> schedule;
3348

49+
@NotNull(message = "Distance is mandatory")
3450
private double distance;
3551

3652
@Getter
@@ -39,10 +55,14 @@ public class Route {
3955
@NoArgsConstructor
4056
public static class Schedule {
4157

58+
@NotNull(message = "Day is mandatory")
4259
private int day;
4360

44-
private String flight;
45-
61+
@NotBlank(message = "UTC is mandatory")
4662
private String utc;
63+
64+
@NotBlank(message = "Flight is mandatory")
65+
private String flight;
66+
4767
}
4868
}

0 commit comments

Comments
 (0)