프로젝트/PongGame

Account Controller

히포파타마스 2022. 5. 11. 12:28

Account Controller

API 명세에 따라 Account의 Controller를 구현한다.

 

 

 

 

1. AccountController

■ AccountController

API 요청시 호출되는 메서드(Controller)를 구현한 클래스

 

[AccountController]

@RestController
@RequiredArgsConstructor
public class AccountController {

    private final AccountService accountService;
    private final FileProcessor fileProcessor;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Value("${file.profile}")
    private String profileImgPath;
    
    .
    .
    .
    
}

 

 

□ createAccount

form-data 형식으로 Account 생성에 필요한 정보를 담아 API를 요청하면 Account를 생성, 저장해주는 컨트롤러

 

[createAccount]

@PostMapping("/account")
public ResultMessage createAccount(@Valid @ModelAttribute AccountForm accountForm) throws IOException {
    String profileImgName = "default.jpeg";   //[1]
    if (accountForm.getProfileImgFile() != null) {
        profileImgName = fileProcessor.storeFile(accountForm.getProfileImgFile(), profileImgPath);
    }

    String encodePassword = bCryptPasswordEncoder.encode(accountForm.getPassword());

    Account account = accountForm.toAccount(profileImgName, encodePassword);   //[2]

    accountService.saveAccount(account);   //[3]

    return new ResultMessage("success create Account");
}

 

● [1] : profileImgFile을 등록하지 않았을 경우 default 이미지를 저장

● [2] : 비밀번호는 암호화한뒤 저장된 프로필 이미지 이름과 함께 AccountForm.toAccount()로 Account 생성

● [3] : 생성된 account를 DB에 저장

 

 

□ getMyAccount

현재 로그인한 Account를 조회하는 컨트롤러

 

[getMyAccount]

@GetMapping("/account")
public AccountDto getMyAccount(@LoginAccountId Long loginAccountId) {
    Account account = accountService.findById(loginAccountId);
    return new AccountDto(account);
}

반환은 DTO를 사용한다.

 

 

□ getAccount

경로 변수로 받은 id의 Account를 조회하는 컨트롤러

 

[getAccount]

@GetMapping("/account/{accountId}")
public AccountDto getAccount(@PathVariable Long accountId) {
    Account account = accountService.findById(accountId);
    return new AccountDto(account);
}

 

 

□ getAccountList

모든 Account를 조회해서 List로 반환하는 컨트롤러

 

[getAccountList]

@GetMapping("/account/all")
public Result<List<AccountDto>> getAccountList() {
    List<AccountDto> accountDtoList = accountService.findAll().stream()
            .map(AccountDto::new)
            .collect(Collectors.toList());   //[1]
    return new Result<>(accountDtoList);   //[2]
}

● [1] : stream을 사용해서 List의 Accont를 모두 DTO로 변환한다.

● [2] : List 하나만을 반환할 경우 Json 스펙에 맞지않게 되기 때문에 Result 객체로 감싸서 반환한다.

 

 

▣ Result

Generic으로 받은 타입 T를 필드로 갖는 클래스.

특정 타입 T의 데이터를 객체안에 넣어야 할 때 사용된다.

 

[Result]

@Data
@AllArgsConstructor
public class Result<T> {
    private T data;

    public Result() {
    }
}

 

 

□ getAccountByPage

검색조건과 page 정보를 담아 요청하면 페이징된 Account 정보가 반환되는 컨트롤러

 

[getAccountByPage]

@GetMapping("/accounts")
public Page<AccountDto> getAccountByPage(AccountSearchCond accountSearchCond, Pageable pageable) {
    QueryResults<Account> accountQueryResults = accountService.findAccountByPage(accountSearchCond, pageable);
    List<AccountDto> accountDtoList = accountQueryResults.getResults().stream()
            .map(AccountDto::new)
            .collect(Collectors.toList());   //[1]
    return new PageImpl<>(accountDtoList, pageable, accountQueryResults.getTotal());   //[2]
}

● [1] : 페이징된 Account를 Dto로 변환

● [2] : AccountDto와 paging 정보로 Page<AccountDto>를 생성해서 반환

 

 

□ getProfileImg

경로 변수인 id로 찾아진 Account의 profileImgFile을 조회하는 컨트롤러

 

[getProfileImg]

@GetMapping("/account/profileImg/{accountId}")
public ResponseEntity<Resource> getProfileImg(@PathVariable Long accountId) throws MalformedURLException {
    Account account = accountService.findById(accountId);
    String profileImgFullPath = fileProcessor.getFullPath(profileImgPath, account.getProfileImgName());

    UrlResource urlResource = new UrlResource("file:" + profileImgFullPath);   //[1]
    String mediaType = fileProcessor.getMediaType(account.getProfileImgName());   //[2]
    if (urlResource.exists()) {   //[3]
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_TYPE, mediaType)
                .body(urlResource);
    }
    throw new NonExistResourceException("profileImgFile이 존재하지 않습니다.");
}

● [1] : Account의 profileImgName으로 구해진 전체 경로로부터 정보를 읽어온다.

● [2] : profileImg의 확장자로 mediaType을 결정한다.

● [3] : 바로 UrlResource를 반환하면 바이트코드의 형태로 조회되기 때문에 ResponseEntity로 CONTENT_TYPE을 지정해주어야 한다.

 

 

□ updateInfo

AccountUpdateInfoForm으로 들어온 정보로 현재 로그인한 Account의 개인 정보를 수정하는 컨트롤러

 

[updateInfo]

@PutMapping("/account/info")
public ResultMessage updateInfo(@LoginAccountId Long loginAccountId,
                                @Valid @RequestBody AccountUpdateInfoForm accountUpdateInfoForm) {
    accountService.updateInfo(loginAccountId, accountUpdateInfoForm.toAccount());
    return new ResultMessage("success update Account Info");
}

 

 

□ updateProfileImg

 현재 로그인한 Account의 profileImg를 수정하는 컨트롤러

 

[updateProfileImg]

@PostMapping("/account/profileImg")
public ResultMessage updateProfileImg(@LoginAccountId Long loginAccountId,
                                      @Valid @ModelAttribute AccountProfileFileForm accountProfileFileForm)
        throws IOException {
    accountService.updateProfileImg(loginAccountId, accountProfileFileForm.getProfileImgFile());
    return new ResultMessage("success update Account profileImg");
}

 

 

□ updatePassword

현재 로그인한 Account의 password를 수정하는 컨트롤러

 

[updatePassword]

@PutMapping("account/password")
public ResultMessage updatePassword(@LoginAccountId Long loginAccountId,
                                    @Valid @RequestBody AccountUpdatePasswordForm accountUpdatePasswordForm) {
    accountService.updatePassword(loginAccountId, accountUpdatePasswordForm.getNewPassword());
    return new ResultMessage("success update password");
}

 

 

 

■ 전체 코드

[AccountController 전체 코드]

@RestController
@RequiredArgsConstructor
public class AccountController {

    private final AccountService accountService;
    private final FileProcessor fileProcessor;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Value("${file.profile}")
    private String profileImgPath;

    @PostMapping("/account")
    public ResultMessage createAccount(@Valid @ModelAttribute AccountForm accountForm) throws IOException {
        String profileImgName = "default.jpeg";
        if (accountForm.getProfileImgFile() != null) {
            profileImgName = fileProcessor.storeFile(accountForm.getProfileImgFile(), profileImgPath);
        }

        String encodePassword = bCryptPasswordEncoder.encode(accountForm.getPassword());

        Account account = accountForm.toAccount(profileImgName, encodePassword);

        accountService.saveAccount(account);

        return new ResultMessage("success create Account");
    }

    @GetMapping("/account")
    public AccountDto getMyAccount(@LoginAccountId Long loginAccountId) {
        Account account = accountService.findById(loginAccountId);
        return new AccountDto(account);
    }

    @GetMapping("/account/{accountId}")
    public AccountDto getAccount(@PathVariable Long accountId) {
        Account account = accountService.findById(accountId);
        return new AccountDto(account);
    }

    @GetMapping("/account/all")
    public Result<List<AccountDto>> getAccountList() {
        List<AccountDto> accountDtoList = accountService.findAll().stream()
                .map(AccountDto::new)
                .collect(Collectors.toList());
        return new Result<>(accountDtoList);
    }

    @GetMapping("/accounts")
    public Page<AccountDto> getAccountByPage(AccountSearchCond accountSearchCond, Pageable pageable) {
        QueryResults<Account> accountQueryResults = accountService.findAccountByPage(accountSearchCond, pageable);
        List<AccountDto> accountDtoList = accountQueryResults.getResults().stream()
                .map(AccountDto::new)
                .collect(Collectors.toList());
        return new PageImpl<>(accountDtoList, pageable, accountQueryResults.getTotal());
    }

    @GetMapping("/account/profileImg/{accountId}")
    public ResponseEntity<Resource> getProfileImg(@PathVariable Long accountId) throws MalformedURLException {
        Account account = accountService.findById(accountId);
        String profileImgFullPath = fileProcessor.getFullPath(profileImgPath, account.getProfileImgName());

        UrlResource urlResource = new UrlResource("file:" + profileImgFullPath);
        String mediaType = fileProcessor.getMediaType(account.getProfileImgName());
        if (urlResource.exists()) {
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_TYPE, mediaType)
                    .body(urlResource);
        }
        throw new NonExistResourceException("profileImgFile이 존재하지 않습니다.");
    }

    @PutMapping("/account/info")
    public ResultMessage updateInfo(@LoginAccountId Long loginAccountId,
                                    @Valid @RequestBody AccountUpdateInfoForm accountUpdateInfoForm) {
        accountService.updateInfo(loginAccountId, accountUpdateInfoForm.toAccount());
        return new ResultMessage("success update Account Info");
    }

    @PostMapping("/account/profileImg")
    public ResultMessage updateProfileImg(@LoginAccountId Long loginAccountId,
                                          @Valid @ModelAttribute AccountProfileFileForm accountProfileFileForm)
            throws IOException {
        accountService.updateProfileImg(loginAccountId, accountProfileFileForm.getProfileImgFile());
        return new ResultMessage("success update Account profileImg");
    }

    @PutMapping("account/password")
    public ResultMessage updatePassword(@LoginAccountId Long loginAccountId,
                                        @Valid @RequestBody AccountUpdatePasswordForm accountUpdatePasswordForm) {
        accountService.updatePassword(loginAccountId, accountUpdatePasswordForm.getNewPassword());
        return new ResultMessage("success update password");
    }
}