Account Controller
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");
}
}