UserController
package com.tenco.blog_v3.board;
import com.tenco.blog_jpa_step4.commom.errors.Exception403;
import com.tenco.blog_jpa_step4.commom.errors.Exception404;
import com.tenco.blog_jpa_step4.commom.utils.ApiUtil;
import com.tenco.blog_jpa_step4.commom.utils.Define;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/**
* UserController 사용자(User)와 관련된 HTTP 요청을 처리하는 컨트롤러 계층입니다.
*/
@Slf4j
@RestController
@RequiredArgsConstructor
public class UserController {
private final UserService userService; // UserService 주입
// 회원 정보 조회 -- > 추후 api/users/{id} 로 수정
@GetMapping("/api/users/{id}")
public ResponseEntity<ApiUtil<UserResponse.DTO>> userinfo(@PathVariable(name = "id") Integer id,
HttpServletRequest request) {
// 인터셉터에서 설정한 사용자 정보를 가져오기
User sessionUser = (User) request.getAttribute(Define.SESSION_USER);
if (sessionUser == null) {
throw new Exception404("사용자를 찾을 수 없습니다."); // 사용자가 존재하지 않는 경우 예외 던지기
}
UserResponse.DTO resDTO = userService.findUserById(sessionUser.getId());
return ResponseEntity.ok(new ApiUtil<>(resDTO));
}
/**
* 사용자 정보 수정 요청 처리
*
* @param id 수정할 사용자 ID
* @param reqDTO 수정된 사용자 정보 DTO
* @return 수정된 사용자 정보의 DTO
*/
@PutMapping("/api/users/{id}")
public ResponseEntity<ApiUtil<UserResponse.DTO>> updateUser(@PathVariable int id,
@RequestBody UserRequest.UpdateDTO reqDTO,
HttpServletRequest request) {
// 인터셉터에서 설정한 사용자 정보를 가져오기
User sessionUser = (User) request.getAttribute(Define.SESSION_USER);
if (sessionUser == null) {
throw new Exception404("사용자를 찾을 수 없습니다."); // 사용자가 존재하지 않는 경우 예외 던지기
}
if (sessionUser.getId() != id) {
throw new Exception403("해당 사용자를 수정할 권한이 없습니다."); // 권한 없음 예외 던지기
}
UserResponse.DTO resDTO = userService.updateUser(id, reqDTO, sessionUser);
return ResponseEntity.ok(new ApiUtil<>(resDTO));
}
@PostMapping("/join")
public ResponseEntity<ApiUtil<UserResponse.DTO>> join(@RequestBody UserRequest.JoinDTO reqDTO) {
UserResponse.DTO resDTO = userService.signUp(reqDTO);
return ResponseEntity.ok(new ApiUtil<>(resDTO));
}
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody UserRequest.LoginDTO reqDTO) {
String jwt = userService.signIn(reqDTO);
return ResponseEntity.ok()
// 반드시 주의!!! Bearer 문자열 뒤에 반드시 한칸에 공백을 넣어 주세요 ~~
.header("Authorization", "Bearer " + jwt)
.body(new ApiUtil<>(null));
}
@GetMapping("/logout")
public ResponseEntity<?> logout(HttpSession session) {
session.invalidate();
return ResponseEntity.ok(new ApiUtil<>(null));
}
}
BoardService
package com.tenco.blog_v3.board;
import com.tenco.blog_jpa_step4.commom.errors.Exception400;
import com.tenco.blog_jpa_step4.commom.errors.Exception401;
import com.tenco.blog_jpa_step4.commom.errors.Exception404;
import com.tenco.blog_jpa_step4.commom.utils.JwtUtil;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Optional;
@RequiredArgsConstructor
@Service // 서비스 계층으로 등록 및 IoC
public class UserService {
private final UserJPARepository userJPARepository;
/**
* 회원 정보 조회 서비스
*
* @param id 조회할 사용자 ID
* @return 조회된 사용자 객체의 DTO
* @throws Exception404 사용자를 찾을 수 없는 경우 발생
*/
public UserResponse.DTO findUserById(int id){
User user = userJPARepository.findById(id)
.orElseThrow(() -> new Exception404("회원정보를 찾을 수 없습니다"));
return new UserResponse.DTO(user);
}
/**
* 회원가입 서비스
*
* @param reqDTO 회원가입 요청 DTO
* @return 회원가입 완료된 사용자 정보의 DTO
* @throws Exception400 중복된 유저네임인 경우 발생
*/
@Transactional // 트랜잭션 관리
public UserResponse.DTO signUp(UserRequest.JoinDTO reqDTO) {
// 1. 유저네임 중복검사 (DB 연결이 필요한 것은 Controller 에서 작성하지 말자)
Optional<User> userOP = userJPARepository.findByUsername(reqDTO.getUsername());
if (userOP.isPresent()) {
throw new Exception400("중복된 유저네임입니다");
}
// 2. 회원가입
User savedUser = userJPARepository.save(reqDTO.toEntity());
return new UserResponse.DTO(savedUser);
}
/**
* 로그인 서비스
*
* @throws Exception401 인증 실패 시 발생
*/
// 리턴 타입 변경
public String signIn(UserRequest.LoginDTO reqDTO) {
User user = userJPARepository.findByUsernameAndPassword(reqDTO.getUsername(), reqDTO.getPassword())
.orElseThrow(() -> new Exception401("인증되지 않았습니다"));
// session.setAttribute("sessionUser", user); // 세션에 사용자 정보 저장
// jwt 문자열 반환 처리
return JwtUtil.create(user); // 로그인 시 이메일 정보 제외
}
/**
* 회원 정보 수정 서비스
*
* @param id 수정할 사용자 ID
* @param reqDTO 수정된 사용자 정보 DTO
* @return 수정된 사용자 객체의 DTO
* @throws Exception404 사용자를 찾을 수 없는 경우 발생
*/
@Transactional // 트랜잭션 관리
public UserResponse.DTO updateUser(int id, UserRequest.UpdateDTO reqDTO, User sessionUser) {
// 1. 사용자 조회 및 예외 처리
User user = userJPARepository.findById(sessionUser.getId())
.orElseThrow(() -> new Exception404("회원정보를 찾을 수 없습니다"));
// 2. 사용자 정보 수정
user.setPassword(reqDTO.getPassword());
user.setEmail(reqDTO.getEmail());
// 더티 체킹을 통해 변경 사항이 자동으로 반영됩니다.
return new UserResponse.DTO(user);
}
}
'Spring boot' 카테고리의 다른 글
Session이란 무엇인가 (0) | 2025.01.07 |
---|---|
Board JWT 적용 (3) | 2024.11.07 |
JWT 인터셉터 적용 (1) | 2024.11.07 |
JDBC란 뭘까? - 1 (1) | 2024.11.07 |
Reply JWT 적용 (2) | 2024.11.07 |