Validation
Controller에는 아래와 같이 @Valid 어노테이션 사용해야함
@PostMapping("/users") // 체크하는 순서는 Post인지 먼저 체크하고, uri를 체크해서 이쪽으로 오게됨
public ResponseEntity createUser(**@Valid** @RequestBody User user) { //오브젝트 형식의 데이터를 전달하려면 @RequestBody가 필요함
User savedUser = service.save(user);
URI location = ServletUriComponentsBuilder.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(savedUser.getId())
.toUri();
return ResponseEntity.created(location).build();
}
User.java 도메인은 아래와 같이 사이즈와 과거만 사용할 수 있도록 어노테이션 붙여야함
@Size(min=2)
private String name;
@Past //과거만 사용가능
private Date joinDate;
위와 같이 설정을 해놓고, 커스텀한 익셉션에다가 내용을 추가해야한다.
ResponseEntityExceptionHandler 를 상속 받아서 사용하고 있는 커스템 익셉션핸들러를 수정해줘야한다.
ResponseEntityExceptionHandler 클래스를 들어가보면, handleMethodArgumentNotValid 추상클래스의 메서드를 재정의 해줘야한다. 해당 메서드는 오버라이드를 해서 사용하는 것이기 때문에 @Override 어노테이션을 사용해야한다.
CustomizedResponseEntityExceptionHandler.java
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(),
ex.getMessage(), ex.getBindingResult().toString());
return new ResponseEntity(exceptionResponse, HttpStatus.BAD_REQUEST);
}
위와 같이 ResponseEntityExceptionHandler의 handleMethodArgumentNotValid 메서드를 재정의 해주면, 도메인에서 Validation 정의 해준 어노테이션에 어떤것이 잘못됐는지 Response에 표현하게 된다.
Internationalization (다국어 처리)
메인 소스에다가 아래와 같이 작성한다. LocaleResolver 사용
야믈파일에 아래와 같이 spring - messages - basename을 지정한다.
메세지라는 프로퍼티 파일을 생성한다.
각자의 파일에다가
해당 언어에 맞게 greeting.message를 추가해 준다.
XML format으로 반환하기
잘돌아가는 api의 key에 Accept = application/xml 로 입력했을 때, Status가 406 으로 오는 것을 확인할 수 있다. 4xx대는 클라이언트가 잘못했을 경우에 나오는 에러이다.
xml로도 받을 수 있도록 설정해보도록 하자.
pom.xml 들어가서 아래와 같이 dependency를 추가해보도록 하자.
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<scope>2.10.2</scope>
</dependency>
그러면 아래와 같이 xml로 받을 수 있게 변경된다.
Filtering
중요한 정보들이 들어가있는 것들을 보이지 않도록 하게 하는 것이다. (주민번호, 고객정보 등)
1. @JsonIgnore
도메인에 @JsonIgnore를 추가해서 조회가 안되도록 할 수 있다.
@Data
@AllArgsConstructor
public class User {
//lombok으로 프로퍼티만 만들어도 됨
private Integer id;
@Size(min=2, message = "Name은 2글자 이상 입력해 주세요.")
private String name;
@Past //과거만 사용가능
private Date joinDate;
@JsonIgnore
private String password;
@JsonIgnore
private String ssn;
}
2. @JsonIgnoreProperties
@JsonIgnoreProperties 어노테이션을 도메인 클래스에다가 지정해서도 사용할 수 있다.
@Data
@AllArgsConstructor
@JsonIgnoreProperties(value = {"password"})
public class User {
//lombok으로 프로퍼티만 만들어도 됨
private Integer id;
@Size(min=2, message = "Name은 2글자 이상 입력해 주세요.")
private String name;
@Past //과거만 사용가능
private Date joinDate;
private String password;
private String ssn;
}
3. admin Controller를 만들어서 사용해보자
1) @JsonFilter("UserInfo")
@JsonFilter("UserInfo") 어노테이션을 도메인에다가 사용한다.
기존의 Controller를 앞에 admin을 붙여서 관리자만 들어갈 수 있도록 변경했다. 그리고 @RequestMapping어노테이션을 사용해서 컨트롤러에서 매핑 되어있는 uri앞에 모두 “/admin”이 붙도록 설정할 수 있다.
2) 사용자 1명 조회 하는 법
한명의 유저를 얻어내는 컨트롤러 메서드를 수정해보자.
반환되는 값은 MappingJacksonValue 로 변경하고, 아래와 같이 필터로 보고싶은 변수들의 명을 작성해보자.
@GetMapping("/users/{id}")
public MappingJacksonValue retrieveUser(@PathVariable int id) { //알아서 인티저로 변경해서 사용하려면 형을 정확하게 입력해ㅝ야함
User user = service.findOne(id);
if (user == null) {
throw new UserNotFoundException(String.format("ID[%s] not found",id));
}
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter
.filterOutAllExcept("id", "name", "joinDate", "ssn");
FilterProvider filters = new SimpleFilterProvider().addFilter("UserInfo",filter);
MappingJacksonValue mapping = new MappingJacksonValue(user);
mapping.setFilters(filters);
return mapping;
}
3. 전체 사용자 조회하는 법
@GetMapping("/users")
public MappingJacksonValue retrieveAllUsers() {
List<User> users = service.findAll();
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter
.filterOutAllExcept("id", "name", "joinDate", "ssn");
FilterProvider filters = new SimpleFilterProvider().addFilter("UserInfo",filter);
MappingJacksonValue mapping = new MappingJacksonValue(users);
mapping.setFilters(filters);
return mapping;
}
Version 관리
1) URI 를 통한 버전관리
도메인이 버전이 변경되면서, 아이디를 조회하는 항목이 하나 더 추가되는 상황을 만들어보자.
먼저, 도메인 버전 2를 만들자
UserV2.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonFilter("UserInfoV2")
public class UserV2 extends User{
private String grade;
}
기존의 유저를 상속받아서 그레이드라는 항목이 추가하면 된다.
그리고 아래와 같이 기존의 조회하던 user/{id} 앞에 /v2를 추가해서 URI로 분기를 타게 만들면 된다.
또한 BeanUtils.copyPropertise를 사용해서 객체를 옮기는 작업을 하고, 새롭게 추가된 그레이드만 직접 넣어주면 된다.
AdminUserController.java
@GetMapping("/v2/users/{id}")
public MappingJacksonValue retrieveUser2(@PathVariable int id) { //알아서 인티저로 변경해서 사용하려면 형을 정확하게 입력해ㅝ야함
User user = service.findOne(id);
if (user == null) {
throw new UserNotFoundException(String.format("ID[%s] not found",id));
}
// User -> User2
UserV2 userV2 = new UserV2();
BeanUtils.copyProperties(user, userV2);
userV2.setGrade("VIP");
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter
.filterOutAllExcept("id", "name", "joinDate", "grade");
FilterProvider filters = new SimpleFilterProvider().addFilter("UserInfoV2",filter);
MappingJacksonValue mapping = new MappingJacksonValue(userV2);
mapping.setFilters(filters);
return mapping;
}
2) Request Parameter와 Header를 이용한 버전관리
2-1) 파라를 통해 버전관리
아래와 같이 getmapping 안에 version을 넣어서 사용한다.
포스트맨에서 물음표를 사용해서 버전 분기를 탈 수 있다.
2-2) 헤더를 통해 버전관리
헤더에다가 버전을 작성해서 사용하면된다.
아래와 같이 결과가 나온다.
2-3) produces 을 사용하는 방법
역시나 헤더에 값을 입력해서 사용하면 아래와 같이 정상 작동되는 것을 확인할 수 있다.
버전관리의 몇가지 옵션을 위와 깉이 알아봤다.
헤더에 넣어서 사용하는 것은 일반 브라우저에서 실행이 안되기 때문에 포스트맨과 같은 프로그램을 이용해서 사용하면 된다.
'Back-end > Spring' 카테고리의 다른 글
[Spring] Java Persistence API 사용 (0) | 2022.11.06 |
---|---|
[Spring] Spring Boot API 사용 (0) | 2022.11.06 |
[Spring] User Service API 추가 (0) | 2022.11.06 |
[Spring] Spring Boot로 개발하는 RESTful Service (0) | 2022.11.06 |
[Spring] Web Service와 Web Application (1) | 2022.11.04 |