프로그래밍/SPRING BOOT

[인프런 : spring-boot] 프로그래밍으로 제어하는 Filtering

공또뤼 2022. 9. 1. 13:44
반응형

이번에는 클라이언트에게 제공하는 데이터 필드를 프로그래밍 관점에서 제어하는 방법에 대해 알아보려고 한다.

 

@JsonIgnore / @JsonIgnoreProperties 가 아닌 @JsonFilter 를 사용한다.

@JsonFilter("UserInfo")

처럼 "UserInfo"라는 임의의 값을 지정해주면 컨트롤러나, 서비스에서 불러서 사용할 것이다.

( 이전에 설정한 JsonIgnore 관련 설정들은 다 주석처리 해준다. )

 

package com.example.restfulwebservice.User;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;

import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import java.util.Date;

@Data
@AllArgsConstructor
//@JsonIgnoreProperties(value = {"password","ssn"})
@JsonFilter("UserInfo")
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;

}

 

그 다음으로 관리자만을 위한 Controller 를 생성해준다.

그 후 URI 부분에 ("/admin/users")로 변경을 해준다.

package com.example.restfulwebservice.User;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.validation.Valid;
import java.net.URI;
import java.util.List;

@RestController
public class AdminUserController {
    private UserDaoService service;

    public AdminUserController(UserDaoService service){
        this.service = service;
    }

    //전체 사용자 목록 반환 메서드
    @GetMapping("/admin/users")
    public List<User> retrieveAllUsers(){
        return service.findAll();
    }

    //사용자 1명 반환 메서드
    @GetMapping("/admin/users/{id}")
    public User retrieveUser(@PathVariable int id){
        User user = service.findOne(id);

        if(user == null){
            throw new UserNotFoundException(String.format("ID[%s] not found",id));
        }

        return user;
    }

}

이런 방법으로 선언을 할 수 있고, 클래스별로 설정할 수 있다.

 

@RequestMapping 을 이용하여 선언을 하면 클래스에 해당하는 메서드들이 공통적인 매핑을 갖는다.

package com.example.restfulwebservice.User;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.validation.Valid;
import java.net.URI;
import java.util.List;

@RestController
@RequestMapping("/admin")
public class AdminUserController {
    private UserDaoService service;

    public AdminUserController(UserDaoService service){
        this.service = service;
    }

    //전체 사용자 목록 반환 메서드
    @GetMapping("/users")
    public List<User> retrieveAllUsers(){
        return service.findAll();
    }

    //사용자 1명 반환 메서드
    @GetMapping("/users/{id}")
    public User retrieveUser(@PathVariable int id){
        User user = service.findOne(id);

        if(user == null){
            throw new UserNotFoundException(String.format("ID[%s] not found",id));
        }

        return user;
    }


}

 

 


[ 개별 사용자 조회 ]

 

관리자 권한을 이용하여 사용자에게는 제어된 데이터만 전송시키지만 관리자에겐 모든 정보를 나타내주려고 한다.

    @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;
    }

[ SimpleBeanPropertyFilter ]  - filterOutAllExcept : 지정된 필드들만 JSON 변환

                                               - serializeAllExcept : 지정된 필드들 제외한 나머지 JSON 변환

[ MappingJacksonValue ] - filter 적용할 수 있는 다른 타입으로 변경 (해당 타입으로 데이터 반환)

 

포스트맨에서 실행시켜보면 해당하는 정보들을 가져온 것을 볼 수 있다.

 

 


[ 전체 사용자 조회 ]

필터링 되어있는 데이터값을 반환하기 위해서는 일반적인 도메인을 반환하지못하고 MappingJacksonValue로 바꿔 반환해줘야 한다.

 

    //전체 사용자 목록 반환 메서드
    @GetMapping("/users")
    public MappingJacksonValue retrieveAllUsers(){
        List<User> users = service.findAll(); // 리스트 객체에 포함시키고 그 객체를 반환

        // service.findAll을 변수로 선언시킨 상태에서 분리하고싶다면
        //오른쪽 > Refactor > introduce Variable or Ctrl + Alt + V

        SimpleBeanPropertyFilter filter
                = SimpleBeanPropertyFilter
                .filterOutAllExcept("id","name","joinDate","password");
        FilterProvider filters = new SimpleFilterProvider().addFilter("UserInfo",filter);
        MappingJacksonValue mapping = new MappingJacksonValue(users);

        mapping.setFilters(filters);

        return mapping; //mapping 값 반환
    }

이렇게 나타내고자 하는 정보들이 제대로 나오는 것을 볼 수 있다.

 

반응형