@DateTimeFormat
typeMismatch)@DateTimeFormat을통해 형식을 알려줘야지 예외없이 작동.@Slf4j @Controller @RequestMapping("/member") @RequiredArgsConstructor public class MemberController { @GetMapping("/list") public String list(@ModelAttribute MemberSearch search){ log.info(search.toString()); return "member/list"; } }MemberSearch
@Data public class MemberSearch { @DateTimeFormat(pattern="yyyyMMdd") private LocalDate sDate; // 검색 시작일 @DateTimeFormat(pattern="yyyyMMdd") private LocalDate eDate; // 검색 종료일 }
사용자에게 에러를 보여주기
MemberController@GetMapping("/list") public String list(@Valid @ModelAttribute MemberSearch search, Errors errors){ log.info(search.toString()); return "member/list"; }list.jsp
<%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="c" uri="jakarta.tags.core" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <h1>회원목록</h1> <form:form method="get" autocomplete="off" modelAttribute="memberSearch"> 가입일 <form:input path="sDate" /> <form:errors path="sDate"/> ~ <form:input path="eDate" /> <form:errors path="eDate"/> <button type="submit">검색하기</button> </form:form>validations.properties
typeMismatch.java.time.LocalDate=날짜 형식이 아닙니다(예 - 20240716).
@Slf4j
@Controller
@RequestMapping("/member")
@RequiredArgsConstructor
public class MemberController {
@ResponseBody
@GetMapping({"/info/{id}/{id2}", "/info/{id}"}) //경로변수, 여러개도 가능.
public void info(@PathVariable("id") String email, @PathVariable(value = "id2", required = false) String email2){
log.info("email: {}, email2: {}", email, email2);
}
}
웹브라우저에서 입력된 url주소가 경로변수로 유입됨.

ModelHttpServletRequestHttpServletResponseHttpSessionMemberController
//BadRequestException이 발생하면 처리, 그 외 예외는 처리되지않는다.
@ExceptionHandler(BadRequestException.class)
public String errorHandler(BadRequestException e){
e.printStackTrace();
return "error/common";
}
//다중으로 에러 처리가 가능
@ExceptionHandler({BadRequestException.class, RuntimeException.class})
public String errorHandler(BadRequestException e, HttpServletRequest request, HttpServletResponse response, Model model){
e.printStackTrace();
return "error/common";
}
//Exception.class으로 다형성을 통해 모든 예외를 처리 할 수도 있다.
@ExceptionHandler(Exception.class)
public String errorHandler(BadRequestException e, HttpServletRequest request, HttpServletResponse response, Model model){
e.printStackTrace();
return "error/common";
}
status : HTTP 상태 코드
error : 에러코드
path :예외 발생한 URI
exception :
message :
timestamp : 예외 발생한 시간
특정 패키지 범위의 컨트롤러에 공통적인 예외처리 등 수행
@ModelAttribute : 공통 값 유지
@ExcptionHandler : 공통 에러 페이지 처리
컨트롤러에서 작성된 ExceptionHandler는 member에서만 예외처리를 한다.
모든 컨트롤러에서 공통적으로 처리하기위해서는@ControllerAdvice사용한다.
@ControllerAdvice는 컨트롤러보다 우선순위가 더 낮음.
@Slf4j
@ControllerAdvice("org.choongang")
public class CommonControllerAdvice {
@ExceptionHandler(Exception.class)
public String errorHandler(BadRequestException e, HttpServletRequest request, HttpServletResponse response, Model model){
e.printStackTrace();
log.info("advice에서 유입");
return "error/common";
}
}
위 코드로 에러처리를 하면 웹페이지에서는 200상태코드를 받게된다.
예외에 해당하는 상태코드를 보여줘야하기 때문에 아래 같이 한다.
기본적으로 예외에는 상태코드가 없기 때문에, 기본에러는 500으로 처리하고, 커스텀예외인CommonException에 해당하는 에러는 400으로 처리한다.CommonException에 해당하는 예외인지 확인하기 위해instaceof()메서드를 사용하여 해당하는지 확인한다.
또한 반환값을ModelAndView자료형으로 지정해서setStatus()메서드를 통해 상태코드를 설정하고 반환한다.
@Slf4j
@ControllerAdvice("org.choongang")
public class CommonControllerAdvice {
@ExceptionHandler(Exception.class)
public ModelAndView errorHandler(Exception e, HttpServletRequest request, HttpServletResponse response, Model model){
e.printStackTrace();
log.info("advice에서 유입");
// 기본 HTTP 상태 코드를 INTERNAL_SERVER_ERROR(500)으로 설정
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; //500
// 발생한 예외가 CommonException 타입인 경우 해당 예외의 상태 코드를 사용
if(e instanceof CommonException commonException){
//CommonException commonException = (CommonException) e;
status = commonException.getStatus();
}
ModelAndView mv = new ModelAndView();
mv.setStatus(status);
mv.setViewName("error/common");
return mv;
}
}
