// 데이터 저장
@PostMapping("persons2")
public ResponseEntity<PersonDTO> save2(@RequestBody PersonDTO dto) {
log.info("logger:findById:{}", dto);
int n = personService.save(dto);
//return ResponseEntity.badRequest().build(); //400
//return ResponseEntity.notFound().build(); //404
//return ResponseEntity.internalServerError().build(); //500
//return ResponseEntity.noContent().build(); //204
//return ResponseEntity.created(null).build(); //201
//return ResponseEntity.status(201).build(); //201
//return ResponseEntity.ok().build(); //201
return ResponseEntity.ok(dto); //200
}
// 데이터 저장
@PostMapping("persons2")
public ResponseEntity<PersonDTO> save2(@RequestBody PersonDTO dto) {
log.info("logger:findById:{}", dto);
int n = personService.save(dto);
URI location = ServletUriComponentsBuilder.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(dto.getId())
.toUri();
return ResponseEntity.created(location).build(); //201
}
WebMvcLinkBuilder: 추가적인 링크 생성
EntityModel : 링크 저장소 역할
@GetMapping("/persons/{id}")
public EntityModel<PersonDTO> findById(@PathVariable int id) {
log.info("logger:findById:::::{}", id);
PersonDTO dto = personService.findById(id);
////////////////////
// 저장소 만들기
EntityModel<PersonDTO> entityModel = EntityModel.of(dto);
// 링크1 - 현재 요청 링크
WebMvcLinkBuilder link1 = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(this.getClass()).findById(id));
// 링크2 - 다음 요청 링크
WebMvcLinkBuilder link2 = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(this.getClass()).findById(id+1));
// 링크3 - 다음 요청 링크
WebMvcLinkBuilder link3 = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(this.getClass()).findAll());
// 링크를 모델에 저장
entityModel.add(link1.withRel("current_link"));
entityModel.add(link2.withRel("next_link"));
entityModel.add(link3.withRel("all_link"));
return entityModel;
}
현재는 요청한 데이터가 없어도 status 값은 200이고 Body는 no Content로 반환됨.
이 상황을 좀 더 직관적인 status로 알려주자
public class UserException extends RuntimeException {
public UserException(String mesg) {
super(mesg);
}
}
@GetMapping("/persons/{id}")
public PersonDTO findById(@PathVariable int id) {
log.info("logger:findById:::::{}", id);
PersonDTO dto = personService.findById(id);
if(dto == null) {
throw new UserException("요청한 " + id +"에 해당하는 데이터가 없습니다 !!!!");
}
return dto;
}
public class PersonDTO {
int id;
@NotEmpty(message="이름은 필수입네다")
String username;
@Past(message="과거 날짜만 가능합니다")
LocalDate birthdate;
}
@PostMapping("/persons")
public PersonDTO save(@Valid @RequestBody PersonDTO dto) {
log.info("logger: PersonDTO-{}", dto);
int n = personService.save(dto);
return dto;
}
==> 여기까지 설정한 후 실습하면 조건에 위배되었을 경우에 400 에러가 발생이 된다
@ControllerAdvice // 전역 예외처리
public class CustomResponseEntityExceptionHandler
extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
//에러메시지 저장
ErrorDetails details = ErrorDetails.builder()
.timestamp(LocalDateTime.now())
.message(ex.getMessage())
.path(request.getDescription(false))
.build();
return new ResponseEntity(details, HttpStatus.BAD_REQUEST);
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
class ErrorDetails{
LocalDateTime timestamp;
String message;
String path;
}
src/main/resource
bundle
message.properties (기본)
message_en.properties (영어)
message_ko.properties (한국어)
#리소스 번들 파일 등록
spring.messages.basename=bundle/message
spring.messages.encoding=utf-8
spring.messages.fallback-to-system-locale=false
public class PersonDTO {
int id;
@JsonProperty("user_name")
String username;
@JsonIgnore
LocalDate birthdate;
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
type : JWT
알고리즘
request:
{
"userid":"inky4832",
"passwd":"1234",
추가정보:값
}
response:
{
"token":토큰값
}
===> react에서 local storage에 저장해두고 필요시 사용됨
{
Authorization: Bearer 토큰값
}