How to use @PathVariable and @RequestParam in Spring Boot’s RestController
When creating a Rest API in Spring Boot, you will probably use @PathVariable and @RequestParam for GET requests, but it is difficult to understand the difference in usage, so I will organize them.
@PathVariable
Use @PathVariable to include a Rest-style url, such as {age}.
@GetMapping(value = "/getMethod/{age}") public Long get(@PathVariable("age") Long age) { return age; }
The url specified by @GetMapping annotation with {age} is retrieved and returned by @PathVariable(“age”).
@RequestParam
Use @RequestParam to append a query string, such as “?a=1” to a Rest-style url to obtain its value.
@GetMapping(value = "/getMethod") public Long get(@RequestParam("age") Long age) { return age; }
This is an example of adding “?age=25” to the url specified in the @GetMapping annotation.
How to use date and time (LocalDate) for @PathVariable
When specifying LocalDate for @PathVariable, @DateTimeFormat must be used as a set.
You can specify a date in the URL by writing as follows
Example.)http://xxx/getXX/20190101
getXX(@DateTimeFormat(pattern="yyyyMMdd" @PathVariable LocalDate targetDate) { // 〜some form of processing }
Path Parameter | Request Param |
---|---|
/getMethod/1/2 | ?id=1&age=2 |
Check path parameters and request parameters with @Validated,@Valid
How to perform validation checks on request parameters.
Add a dependency in build.gradle. Without this dependency, validation will not be performed.
implementation "org.springframework.boot:spring-boot-starter-validation:2.3.2.RELEASE"
Class is annotated with @Validated annotation.
Grant @Valid before @RequestParam.
package jp.co.confrage.presentation.controller; import javax.validation.Valid; import javax.validation.constraints.Pattern; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Validated @RestController public class ValidationController { @RequestMapping( path = "/valids", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<?> valids( @RequestHeader HttpHeaders headers, @Valid @Pattern(regexp = "(ja|en)") @RequestParam(name = "lang", defaultValue = "ja") final String lang) throws Exception { return new ResponseEntity<>("", headers, HttpStatus.OK); } }
If it is not ja or en, an error is assumed. Error handling creates a new class.
ConstraintViolationException will be raised, so specify ConstraintViolationException as the first argument.
package jp.co.confrage.infrastructure.exception; import javax.validation.ConstraintViolationException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @RestControllerAdvice public class RestExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler public ResponseEntity<?> handleConstraintViolationException( ConstraintViolationException ex, WebRequest request) { return super.handleExceptionInternal(ex, "", null, HttpStatus.BAD_REQUEST, request); } }
Now if the query parameter is not ja,en, it will transition to a class that handles exceptions and BAD_REQUEST (400 error).
Note that the handling will not work well if AOP is used.
Allow null in @Validated,@Valid,@Pattern
Validation checks will result in a bad request if the parameter is null.
To allow nulls while performing validation checks and pattern checks, wrap the request in an Optional class.
If the @RequestParam’s required attribute is set to false, a 400 error will not occur even if the query parameter is unspecified.
@Valid @Pattern(regexp = "(ja|en)") @RequestParam(name = "lang", required = false)
If this attribute is omitted, it is true, resulting in a 400 error.
コメント