
1. UserRepository에서
package shop.mtcoding.blog.user;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import shop.mtcoding.blog.board.BoardResponse;
import java.util.List;
@Repository // IoC에 new하는 방법
public class UserRepository {
// DB에 접근할 수 있는 매니저 객체
// 스프링이 만들어서 IoC에 넣어둔다.
// DI에서 꺼내 쓰기만 하면된다.
private EntityManager em; // 컴포지션
// 생성자 주입 (DI 코드)
public UserRepository(EntityManager em) {
this.em = em;
}
@Transactional // db에 write 할때는 필수
public void save(UserRequest.JoinDTO requestDTO){
Query query = em.createNativeQuery("insert into user_tb(username, password, email, created_at) values(?,?,?, now())");
query.setParameter(1, requestDTO.getUsername());
query.setParameter(2, requestDTO.getPassword());
query.setParameter(3, requestDTO.getEmail());
query.executeUpdate();
}
public User findByUsernameAndPassword(UserRequest.LoginDTO requestDTO) {
Query query = em.createNativeQuery("select * from user_tb where username=? and password=?", User.class); // 알아서 매핑해줌
query.setParameter(1, requestDTO.getUsername());
query.setParameter(2, requestDTO.getPassword());
try { // 내부적으로 터지면 터지는 위치를 찾아서 내가 잡으면 됨
User user = (User) query.getSingleResult();
return user;
} catch (Exception e) {
return null;
}
}
}
2. _core.handler 패키지 생성
CustomExceptionHandler 클래스 생성
package shop.mtcoding.blog._core.handler;
public class CustomExceptionHandler {
}

o o o o o
5번째에서 오류가 터지면 null이 처리하는 첫번쨰 레이어까지 와야함 -. 매우 복잡해짐
가까이에 있으면 상관없음
깊숙하면 문제가 됨
따로 exceptionhandler 클래스를 하나 만들어서
try/catch가 터지면 직접 처리하지 않고 throw 날리면 위임해서 뒤로 위임함
컨트롤러가 throw를 날리면 ds까지 감
문제는 우리가 ds를 손을 못됨
이제 모든 에러를 다 throw를 날려서 ds에게 위임 시킬 것
그럼 ds가 위임 받아서 처리할 방법을 제공해줄 것
exceptionhandler를 만들어서 @ControllerAdvice 하나만 붙이면 ds가 처리해줌
package shop.mtcoding.blog.user;
import jakarta.servlet.http.HttpSession;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import shop.mtcoding.blog._core.util.Script;
@AllArgsConstructor
@Controller // 파일을 리턴함 -> @ResponseBody로 메세지 자체를 리턴
public class UserController {
// fianl 변수는 반드시 초기화 되어야 함
private final UserRepository userRepository; // null
private final HttpSession session;
// @AllArgsConstructor를 사용하면서 필요 없어짐
// public UserController(UserRepository userRepository, HttpSession session) {
// this.userRepository = userRepository;
// this.session = session;
// }
// 원래는 get요청이나 예외 post요청하면 됨
// 민감한 정보는 쿼리 스트링에 담아보낼 수 없음
//원래는 get요청이나 예외 post요청하면 됨
//민감한 정보는 쿼리 스트링에 담아보낼 수 없음
@PostMapping("/login")
public String login(UserRequest.LoginDTO requestDTO) {
// 1. 유효성 검사
if(requestDTO.getUsername().length() < 3) {
return "error/400";
}
// 2. 모델 필요 select * from user_tb where username=? and password=?
User user = userRepository.findByUsernameAndPassword(requestDTO); // DB에 조회할때 필요하니까 데이터를 받음
session.setAttribute("sessionUser", user);
return "redirect:/";
}
@PostMapping("/join")
public @ResponseBody String join(UserRequest.JoinDTO requestDTO) {
System.out.println(requestDTO);
try{
userRepository.save(requestDTO);
} catch (Exception e) {
return Script.back("아이디가 중복되었어요");
}
return Script.href("/loginForm"); // 메세지를 자바스크립트로 주면 302를 줄 필요 없음
}
@GetMapping("/joinForm") // view만 원함
public String joinForm() {
return "user/joinForm";
}
@GetMapping("/loginForm") // view만 원함
public String loginForm() {
return "user/loginForm";
}
@GetMapping("/user/updateForm")
public String updateForm() {
return "user/updateForm";
}
@GetMapping("/logout")
public String logout() {
// 1번 서랍에 있는 uset를 삭제해야 로그아웃이 됨
session.invalidate(); // 서랍의 내용 삭제
return "redirect:/";
}
}
3. exception 만드는 방법
- Ex400 이라는 클래스 만들어서 extends Runtiom Exception하면 exception 이 됨
- 터뜨릴때 throw new Ex400으로 터뜨리고
- handler에서 Ex400으로 받으면 됨
- 상태 코드로 클래스 만들면 됨
- @ControllerAdvice // 비정상적일때 처리하는 응답 에러 컨트롤러 -> view(파일)를 리턴
- @ResponseBody붙이면 메세지를 리턴
- @RestControllerAdvice
- @Controller -> @ResponseBody붙이면 메세지를 리턴
package shop.mtcoding.blog._core.handler;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import shop.mtcoding.blog._core.util.Script;
@ControllerAdvice // 비정상적일때 처리하는 응답 에러 컨트롤러 -> view(파일)를 리턴 -> @ResponseBody붙이면 됨
// @RestControllerAdvice : 응답을 직접 반환
// @Controller -> @ResponseBody붙이면 됨
public class CustomExceptionHandler {
// 어떤 에러가 나타날때 처리할지 -> 분기해야함
@ExceptionHandler(Exception.class)
public @ResponseBody String error1(Exception e) {
return Script.back(e.getMessage());
}
}
package shop.mtcoding.blog.user;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import shop.mtcoding.blog.board.BoardResponse;
import java.util.List;
@Repository // IoC에 new하는 방법
public class UserRepository {
// DB에 접근할 수 있는 매니저 객체
// 스프링이 만들어서 IoC에 넣어둔다.
// DI에서 꺼내 쓰기만 하면된다.
private EntityManager em; // 컴포지션
// 생성자 주입 (DI 코드)
public UserRepository(EntityManager em) {
this.em = em;
}
@Transactional // db에 write 할때는 필수
public void save(UserRequest.JoinDTO requestDTO){
Query query = em.createNativeQuery("insert into user_tb(username, password, email, created_at) values(?,?,?, now())");
query.setParameter(1, requestDTO.getUsername());
query.setParameter(2, requestDTO.getPassword());
query.setParameter(3, requestDTO.getEmail());
query.executeUpdate();
}
public User findByUsernameAndPassword(UserRequest.LoginDTO requestDTO) {
Query query = em.createNativeQuery("select * from user_tb where username=? and password=?", User.class); // 알아서 매핑해줌
query.setParameter(1, requestDTO.getUsername());
query.setParameter(2, requestDTO.getPassword());
try { // 내부적으로 터지면 터지는 위치를 찾아서 내가 잡으면 됨
User user = (User) query.getSingleResult();
return user;
} catch (Exception e) {
throw new RuntimeException("아이디 혹은 비밀번호를 찾을 수 없습니다");
}
}
}
package shop.mtcoding.blog.user;
import jakarta.servlet.http.HttpSession;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import shop.mtcoding.blog._core.util.Script;
@AllArgsConstructor
@Controller // 파일을 리턴함 -> @ResponseBody로 메세지 자체를 리턴
public class UserController {
// fianl 변수는 반드시 초기화 되어야 함
private final UserRepository userRepository; // null
private final HttpSession session;
// @AllArgsConstructor를 사용하면서 필요 없어짐
// public UserController(UserRepository userRepository, HttpSession session) {
// this.userRepository = userRepository;
// this.session = session;
// }
// 원래는 get요청이나 예외 post요청하면 됨
// 민감한 정보는 쿼리 스트링에 담아보낼 수 없음
//원래는 get요청이나 예외 post요청하면 됨
//민감한 정보는 쿼리 스트링에 담아보낼 수 없음
@PostMapping("/login")
public String login(UserRequest.LoginDTO requestDTO) {
// 1. 유효성 검사
if(requestDTO.getUsername().length() < 3) {
return "error/400";
}
// 2. 모델 필요 select * from user_tb where username=? and password=?
User user = userRepository.findByUsernameAndPassword(requestDTO); // DB에 조회할때 필요하니까 데이터를 받음
session.setAttribute("sessionUser", user);
return "redirect:/";
}
@PostMapping("/join")
public @ResponseBody String join(UserRequest.JoinDTO requestDTO) {
System.out.println(requestDTO);
try{
userRepository.save(requestDTO);
} catch (Exception e) {
return Script.back("아이디가 중복되었어요");
}
return Script.href("/loginForm"); // 메세지를 자바스크립트로 주면 302를 줄 필요 없음
}
@GetMapping("/joinForm") // view만 원함
public String joinForm() {
return "user/joinForm";
}
@GetMapping("/loginForm") // view만 원함
public String loginForm() {
return "user/loginForm";
}
@GetMapping("/user/updateForm")
public String updateForm() {
return "user/updateForm";
}
@GetMapping("/logout")
public String logout() {
// 1번 서랍에 있는 uset를 삭제해야 로그아웃이 됨
session.invalidate(); // 서랍의 내용 삭제
return "redirect:/";
}
}




package shop.mtcoding.blog.user;
import jakarta.servlet.http.HttpSession;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import shop.mtcoding.blog._core.util.Script;
@AllArgsConstructor
@Controller // 파일을 리턴함 -> @ResponseBody로 메세지 자체를 리턴
public class UserController {
// fianl 변수는 반드시 초기화 되어야 함
private final UserRepository userRepository; // null
private final HttpSession session;
// @AllArgsConstructor를 사용하면서 필요 없어짐
// public UserController(UserRepository userRepository, HttpSession session) {
// this.userRepository = userRepository;
// this.session = session;
// }
// 원래는 get요청이나 예외 post요청하면 됨
// 민감한 정보는 쿼리 스트링에 담아보낼 수 없음
//원래는 get요청이나 예외 post요청하면 됨
//민감한 정보는 쿼리 스트링에 담아보낼 수 없음
@PostMapping("/login")
public String login(UserRequest.LoginDTO requestDTO) {
// 1. 유효성 검사
if(requestDTO.getUsername().length() < 3) {
return "error/400";
}
// 2. 모델 필요 select * from user_tb where username=? and password=?
User user = userRepository.findByUsernameAndPassword(requestDTO); // DB에 조회할때 필요하니까 데이터를 받음
session.setAttribute("sessionUser", user);
return "redirect:/";
}
@PostMapping("/join")
public String join(UserRequest.JoinDTO requestDTO) {
System.out.println(requestDTO);
try{
userRepository.save(requestDTO);
} catch (Exception e) {
throw new RuntimeException("아이디가 중복되었어요"); // 위임시키면 로직의 변화없이 오류를 위임하고 끝남
}
return "redirect:/loginForm";
}
@GetMapping("/joinForm") // view만 원함
public String joinForm() {
return "user/joinForm";
}
@GetMapping("/loginForm") // view만 원함
public String loginForm() {
return "user/loginForm";
}
@GetMapping("/user/updateForm")
public String updateForm() {
return "user/updateForm";
}
@GetMapping("/logout")
public String logout() {
// 1번 서랍에 있는 uset를 삭제해야 로그아웃이 됨
session.invalidate(); // 서랍의 내용 삭제
return "redirect:/";
}
}



Share article