How to use @PathVariable and @RequestParam in Spring Boot’s RestController

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 @PathVariable and @RequestParam in Spring Boot's RestController

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.

コメント

タイトルとURLをコピーしました