에러가 터지면 하나하나 잡아주지 않아도 된다.

하나의 클래스로 빼서 관리하면 편하다

이 클래스로 모든 에러를 전부 관리함

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 == 파일 리턴)
public class CustomExceptionHandler {

    @ExceptionHandler(Exception.class)
    public @ResponseBody String error1(Exception e) {
        return Script.back(e.getMessage());
    }
}

UserRepository 수정

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("아이디 혹은 비밀번호를 찾을 수 없습니다.");
        }
    }

UserController 수정

@PostMapping("/login")
    public String login(UserRequest.LoginDTO requestDTO){
        System.out.println(requestDTO); // toString -> @Data

        if(requestDTO.getUsername().length() < 3){
            return "error/400"; // ViewResolver 설정이 되어 있음. (앞 경로, 뒤 경로)
        }

        User user = userRepository.findByUsernameAndPassword(requestDTO);
        session.setAttribute("sessionUser", user); // 락카에 담음 (StateFul)

        return "redirect:/"; // 컨트롤러가 존재하면 무조건 redirect 외우기
    }

@PostMapping("/join")
    public String join(UserRequest.JoinDTO requestDTO){
        System.out.println(requestDTO);

        try {
            userRepository.save(requestDTO);
        } catch (Exception e) {
            throw new RuntimeException("ID가 중복 되었습니다.");
        }

        return "redirect:/loginForm";
    }