Spring에서 Context는 스프링이 관리하는 빈들이 담겨있는 컨테이너이다.


root context, application context는 전역으로 공유되는 context이고
web application context, servlet context는 servlet 내부에서만 공유되는 context이다.
<context:component-scan base-package="com.nhnacademy.springmvc" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
use-default-filters를 false로 두는 이유는 scope를 정해주기 위해서이다. 스켄이 될 필요가 없는 Bean을 제외하기 위해 필요한 것만 처리를 하기 위해 사용한다.
Listener를 사용하면 Servlet에 의존하고 Initializer는 Servlet에 독립적이라 확장이 용이하다.
메서드 인자로 선언된 경우 : 모델에서 속성 값을 추출해올 때 사용
@PostMapping("/user/register")
public String registerUser(@ModelAttribute UserRegisterRequest userRequest) {
// ...
}
@ModelAttribute를 사용하지 않는다면
@PostMapping
public ModelAndView registerUser(String id, String password, String age) {
// ...
}
Request Parameter Binding은 사실 @ModelAttribute를 생략할 수 있다.
public ModelAndView registerUser(UserRegisterRequest userRequest){
//...
}
메서드에 선언된 경우 : 모든 @RequestMapping에 앞서 호출되어 공통 속성을 제공
@ModelAttribute("user")
public User getUser(@PathVariable("userId") String userId) {
return userRepository.getUser(userId);
}
@GetMapping("/{userId}")
public String getUserInfo(@ModelAttribute("user") User user, Model model) {
if (Objects.isNull(user)) {
model.addAttribute("exception", new UserNotFoundException());
return "error";
}
model.addAttribute("user", user);
return "userInfo";
}
@Controller
**@RestController
Post form 같은 경우는 @Requestparam을 사용해서 처리할 수는 있지만 parameter가 많아질 수 있기 때문에 비효율적이므로 @ModelAttribute를 통해 처리한다.
@ControllerAdvice는 스프링 프레임워크에서 전역으로 적용되는 컨트롤러에서 발생하는 예외를 처리하고 공통된 코드를 적용하는 데 사용되는 어노테이션이다.
이 어노테이션을 사용하면 여러 컨트롤러에 대한 예외 처리를 한 곳에서 일괄적으로 관리할 수 있다.
@ExceptionHandler 어노테이션을 사용하여 특정 예외 타입에 대한 처리 로직을 정의할 수 있다.
이 예외 처리 로직은 어떤 컨트롤러에서든 발생한 예외에 대해 적용된다.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception e) {
ModelAndView modelAndView = new ModelAndView("errorView");
modelAndView.addObject("error", e.getMessage());
return modelAndView;
}
}
@ModelAttribute 어노테이션을 사용하여 전역적으로 모델 속성을 추가할 수 있다.
이는 모든 컨트롤러에서 공통적으로 사용되는 데이터를 설정할 때 유용하다.
@ControllerAdvice
public class GlobalControllerAdvice {
@ModelAttribute("commonAttribute")
public String addCommonAttribute() {
return "This is a common attribute";
}
}
@InitBinder 어노테이션을 사용하여 컨트롤러에서 전역적으로 초기화 작업을 수행할 수 있다.
주로 데이터 바인딩 설정이나 검증 관련 초기화에 사용된다.
@ControllerAdvice
public class GlobalInitBinder {
@InitBinder
public void initBinder(WebDataBinder binder) {
// 데이터 바인딩 설정
}
}
Spring에서 Validation을 적용하기 위해서는 Validator interface를 구현해야한다.
public interface Validator {
boolean supports(Class<?> clazz);
void validate(Object target, Errors errors);
}
@Component
public class PostRegisterRequestValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return PostRegisterRequest.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "title", "", "title is empty");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "content", "", "content is empty");
PostRegisterRequest request = (PostRegisterRequest) target;
String content = request.getContent();
if (content.length() > 100) {
errors.rejectValue("content", "", "content max length is 100");
}
}
}