Ian's Archive 🏃🏻

thumbnail
스프링 웹 MVC - 백기선
Spring
2025.01.12.

스프링 MVC 동작 원리

M 모델: 평범한 자바 객체 POJO V 뷰: HTML. JSP, 타임리프, … C 컨트롤러: 스프링 @MVC

MVC 패턴의 장점

  • 동시 다발적(Simultaneous) 개발 - 백엔드 개발자와 프론트엔드 개발자가 독립적으로 개발을 진행할 수 있다.
  • 높은 결합도 - 논리적으로 관련있는 기능을 하나의 컨트롤러로 묶거나, 특정 모델과 관련있는 뷰를 그룹화 할 수 있다.
  • 낮은 의존도 - 뷰, 모델, 컨트롤러는 각각 독립적이다.
  • 개발 용이성 - 책임이 구분되어 있어 코드 수정하는 것이 편하다.
  • 한 모델에 대한 여러 형태의 뷰를 가질 수 있다.

MVC 패턴의 단점

  • 코드 네비게이션 복잡함
  • 코드 일관성 유지에 노력이 필요함
  • 높은 학습 곡선

서블릿

서블릿 (Servlet)

  • 자바 엔터프라이즈 에디션은 웹 어플리케이션 개발용 스팩과 API제공
  • 요청 당 쓰레드 (만들거나, 풀에서 가져다가) 사용
  • 그 중에서 가장 중요한 클래스 중 하나가 HttpServlet

장점 (CGI에 비해)

  • 빠르다.
  • 플랫폼 독립적
  • 보안
  • 이식성

서블릿 엔진 또는 서블릿 컨테이너가 하는 일

  • 세션 관리
  • 네트워크 서비스
  • MIME기반 메시지 인코딩, 디코딩
  • 서블릿 생명 주기 관리

서블릿 생명 주기

  • 서블릿 컨테이너가 서블릿 인스턴스의 init() 메소드를 호출하여 초기화한다.
    • 최초 요청 시 한번 초기화하고 이 과정 생략
  • 서블릿이 초기화가 된 다음부터 클라이언트의 요청을 처리할 수 있다. 각 요청은 별도의 쓰레드로 처리하고 이 때 서블릿 인스턴스의 service() 메소드를 호출한다.
    • 이 안에서 HTTP요청을 받고 클라이언트로 보낼 HTTP응답을 만든다.
    • service()는 보통 HTTP Method에 따라 doGet(), doPost()등으로 처리를 위임한다.
    • 따라서 보통 doGet() 또는 doPost()를 구현한다.
  • 서블릿 컨테이너의 판단에 따라 해당 서블릿을 메모리에서 내려야 할 시점에 destory()를 호출한다.

서블릿 리스너와 필터

서블릿 리스너

  • 웹 애플리케이션에서 발생하는 주요 이벤트를 감지하고 각 이벤트에 특별한 작업이 필요한 경우에 사용할 수 있다

서블릿 필터

  • 들어온 요청을 서블릿으로 보내고, 또 서블릿이 작성한 응답을 클라이언트로 보내기 전에 특별한 처리가 필요한 경우에 사용할 수 있다.

실행 순서

서블릿 리스너 -> 서블릿 필터 -> 서블릿 … -> 서블릿 종료 -> 서블릿 필터 종료 -> 서블릿 리스너 종료

chain

스프링 IoC컨테이너 연동

스프링을 사용한다는 이야기는 크게 2가지 의미

  1. 스프링이 제공하는 IoC Container를 사용하겠다.
  2. 스프링 MVC를 사용하겠다.

ContextLoaderListener

  • 서블릿 리스너 구현체
  • ApplicationContext를 만들어 준다.
  • ApplicationContext를 서블릿 컨텍스트 라이프사이클에 따라 등록하고 소멸시켜준다.
  • 서블릿에서 IoC 컨테이너를 ServletContext를 통해 꺼내 사용할 수 있다.

서블릿에서 IoC컨테이너 ContextLoaderListener를 사용해서 웹어플리케이션 컨텍스트를 만들고

그것을 서블릿에서 사용하는 방법

web.xml에 정의 -> 설정방법이 좀 어려워서 이렇게 정리하고 끝내자 (필요하면 강의 찾아보자)

스프링 MVC와 연동

DispatcherServlet

  • 스프링 MVC의 핵심.
  • Front Controller 역할을 한다.

DispatcherServlet 동작 원리

스프링 MVC1 강의 정리 - 김영한강의 정리할 때 잘 정리해놔서 이거 참고

DispatcherServlet 초기화

  • 다음의 특별한 타입의 빈들을 찾거나, 기본 전략에 해당하는 빈들을 등록한다. ● HandlerMapping: 핸들러를 찾아주는 인터페이스
  • HandlerAdapter: 핸들러를 실행하는 인터페이스
  • HandlerExceptionResolver
  • ViewResolver

DispatcherServlet 동작 순서

  1. 요청을 분석한다. (로케일, 테마, 멀티파트 등)
  2. (핸들러 맵핑에게 위임하여) 요청을 처리할 핸들러를 찾는다.
  3. (등록되어 있는 핸들러 어댑터 중에) 해당 핸들러를 실행할 수 있는 “핸들러 어댑터”를 찾는다.
  4. 찾아낸 “핸들러 어댑터”를 사용해서 핸들러의 응답을 처리한다.
  • 핸들러의 리턴값을 보고 어떻게 처리할지 판단한다.
    • 뷰 이름에 해당하는 뷰를 찾아서 모델 데이터를 랜더링한다.
    • @ResponseBody가 있다면 Converter를 사용해서 응답 본문을 만들고.
  1. (부가적으로) 예외가 발생했다면, 예외 처리 핸들러에 요청 처리를 위임한다.
  2. 최종적으로 응답을 보낸다.

스프링 MVC구성 요소

DispatcherServlet

DispatcherSerlvet의 기본 전략

  • DispatcherServlet.properties

MultipartResolver

  • 파일 업로드 요청 처리에 필요한 인터페이스
  • HttpServletRequest를 MultipartHttpServletRequest로 변환해주어 요청이 담고 있는 File을 꺼낼 수 있는 API 제공.

LocaleResolver

  • 클라이언트의 위치(Locale) 정보를 파악하는 인터페이스
  • 기본 전략은 요청의 accept-language를 보고 판단.

ThemeResolver

HandlerMapping

  • 요청을 처리할 핸들러를 찾는 인터페이스

HandlerAdapter

  • HandlerMapping이 찾아낸 “핸들러”를 처리하는 인터페이스
  • 스프링 MVC 확장력의 핵심 HandlerExceptionResolver
  • 요청 처리 중에 발생한 에러 처리하는 인터페이스

RequestToViewNameTranslator

  • 핸들러에서 뷰 이름을 명시적으로 리턴하지 않은 경우, 요청을 기반으로 뷰 이름을 판단하는 인터페이스

ViewResolver

  • 뷰 이름(string)에 해당하는 뷰를 찾아내는 인터페이스

FlashMapManager

  • FlashMap 인스턴스를 가져오고 저장하는 인터페이스
  • FlashMap은 주로 리다이렉션을 사용할 때 요청 매개변수를 사용하지 않고 데이터를 전달하고 정리할 때 사용한다.
  • redirect:/events

결국엔 (굉장히 복잡한) 서블릿
=> DispatcherServlet

DispatcherServlet 초기화

  1. 특정 타입에 해당하는 빈을 찾는다.
  2. 없으면 기본 전략을 사용한다. (DispatcherServlet.properties)

스프링 부트 사용하지 않는 스프링 MVC

  • 서블릿 컨네이너(ex, 톰캣)에 등록한 웹 애플리케이션(WAR)에 DispatcherServlet을 등록한다.
    • web.xml에 서블릿 등록
    • 또는 WebApplicationInitializer에 자바 코드로 서블릿 등록 (스프링 3.1+, 서블릿 3.0+)
  • 세부 구성 요소는 빈 설정하기 나름.

스프링 부트를 사용하는 스프링 MVC

  • 자바 애플리케이션에 내장 톰캣을 만들고 그 안에 DispatcherServlet을 등록한다.
    • 스프링 부트 자동 설정이 자동으로 해줌.
  • 스프링 부트의 주관에 따라 여러 인터페이스 구현체를 빈으로 등록한다.

스프링 MVC 설정

@EnableWebMvc

애노테이션 기반 스프링 MVC를 사용할 때 편리한 웹 MVC 기본 설정

copyButtonText
@Configuration
@EnableWebMvc
public class WebConfig {
}

WebMvcConfigurer 인터페이스

@EnableWebMvc가 제공하는 빈을 커스터마이징할 수 있는 기능을 제공하는 인터페이스

copyButtonText
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
  @Override
  public void configureViewResolvers(ViewResolverRegistry registry) {
    registry.jsp("/WEB-INF/", ".jsp");
  }
}

Spring MVC

WebApplicationInitialazer설정 or web.xml 설정 후 Dispatcher servlet설정하고

위의 설정이 기본 Spring MVC설정 방법


Spring Boot

  • application.properties
  • @Configuration + Implements WebMvcConfigurer: 스프링 부트의 스프링 MVC 자동설정 + 추가 설정
  • @Configuration + @EnableWebMvc + Imlements WebMvcConfigurer: 스프링 부트의 스프링 MVC 자동설정 사용하지 않음.

Formatter

  • Parser: 어떤 문자열을 (Locale 정보를 참고하여) 객체로 어떻게 변환할 것인가
  • Printer: 해당 객체를 (Locale 정보를 참고하여) 문자열로 어떻게 출력할 것인가

포매터 추가하는 방법 1

  • WebMvcConfigurer의 addFormatters(FormatterRegistry) 메소드 정의

포매터 추가하는 방법 2 (스프링 부트 사용시에만 가능 함)

  • 해당 포매터를 빈으로 등록 (@Component)

Converter는 객체 <-> 객체

Tip!!

@WebMvcTest -> web과 관련된 빈만 등록 @SpringBootTest -> 모든 빈 등록


핸들러 인터셉터

HandlerInterceptor

  • 핸들러 맵핑에 설정할 수 있는 인터셉터
  • 핸들러를 실행하기 전, 후(아직 랜더링 전) 그리고 완료(랜더링까지 끝난 이후) 시점에 부가 작업을 하고 싶은 경우에 사용할 수 있다.
  • 여러 핸들러에서 반복적으로 사용하는 코드를 줄이고 싶을 때 사용할 수 있다.
    • 로깅, 인증 체크, Locale 변경 등…

boolean preHandle(request, response, handler)

  • 핸들러 실행하기 전에 호출 됨
  • “핸들러”에 대한 정보를 사용할 수 있기 때문에 서블릿 필터에 비해 보다 세밀한 로직을 구현할 수 있다.
  • 리턴값으로 계속 다음 인터셉터 또는 핸들러로 요청,응답을 전달할지(true) 응답 처리가 이곳에서 끝났는지(false) 알린다.

void postHandle(request, response, modelAndView)

  • 핸들러 실행이 끝나고 아직 뷰를 랜더링 하기 이전에 호출 됨
  • “뷰”에 전달할 추가적이거나 여러 핸들러에 공통적인 모델 정보를 담는데 사용할 수도 있다. ● 이 메소드는 인터셉터 역순으로 호출된다.
  • 비동기적인 요청 처리 시에는 호출되지 않는다.

void afterCompletion(request, response, handler, ex)

  • 요청 처리가 완전히 끝난 뒤(뷰 랜더링 끝난 뒤)에 호출 됨
  • preHandler에서 true를 리턴한 경우에만 호출 됨
  • 이 메소드는 인터셉터 역순으로 호출된다.
  • 비동기적인 요청 처리 시에는 호출되지 않는다.

리소스 핸들러

이미지, 자바스크립트, CSS 그리고 HTML 파일과 같은 정적인 리소스를 처리하는 핸들러 등록하는 방법


HTTP메시지 컨버터

HTTP 메시지 컨버터

  • 요청 본문에서 메시지를 읽어들이거나(@RequestBody), 응답 본문에 메시지를 작성할 때(@ResponseBody) 사용한다.

괄호는 의존성 설정 필요

  • 바이트 배열 컨버터
  • 문자열 컨버터
  • Resource 컨버터
  • Form 컨버터 (폼 데이터 to/from MultiValueMap<String, String>)
  • (JAXB2 컨버터)
  • (Jackson2 컨버터)
  • (Jackson 컨버터)
  • (Gson 컨버터)
  • (Atom 컨버터)
  • (RSS 컨버터)

스프링 부트를 사용하지 않는 경우

  • 사용하고 싶은 JSON 라이브러리를 의존성으로 추가
  • GSON
  • JacksonJSON
  • JacksonJSON 2

스프링 부트를 사용하는 경우

  • 기본적으로 JacksonJSON 2가 의존성에 들어있다.
  • 즉, JSON용 HTTP 메시지 컨버터가 기본으로 등록되어 있다.

그밖에 WebMvcConfigurer 설정

CORS 설정

  • Cross Origin 요청 처리 설정
  • 같은 도메인에서 온 요청이 아니더라도 처리를 허용하고 싶다면 설정한다.

리턴 값 핸들러 설정

  • 스프링 MVC가 제공하는 기본 리턴 값 핸들러 이외에 리턴 핸들러를 추가하고 싶을 때 설정한다.

아큐먼트 리졸버 설정

  • 스프링 MVC가 제공하는 기본 아규먼트 리졸버 이외에 커스텀한 아규먼트 리졸버를 추가하고 싶을 때 설정한다.

뷰 컨트롤러

  • 단순하게 요청 URL을 특정 뷰로 연결하고 싶을 때 사용할 수 있다.

비동기 설정

  • 비동기 요청 처리에 사용할 타임아웃이나 TaskExecutor를 설정할 수 있다.

뷰 리졸버 설정

  • 핸들러에서 리턴하는 뷰 이름에 해당하는 문자열을 View 인스턴스로 바꿔줄 뷰 리졸버를 설정한다.

Content Negotiation 설정

  • 요청 본문 또는 응답 본문을 어떤 (MIME) 타입으로 보내야 하는지 결정하는 전략을 설정한다.

스프링 MVC 설정은 즉 DispatcherServlet이 사용할 여러 빈 설정.

  • HandlerMapper
  • HandlerAdapter
  • ViewResolver
  • ExceptionResolver
  • LocaleResolver

일일히 등록하려니 너무 많고, 해당 빈들이 참조하는 또 다른 객체들까지 설정하려면 설정할게 너무 많다.

@EnableWebMvc

  • 애노테이션 기반의 스프링 MVC 설정 간편화
  • WebMvcConfigurer가 제공하는 메소드를 구현하여 커스터마이징할 수 있다. 스프링 부트
  • 스프링 부트 자동 설정을 통해 다양한 스프링 MVC 기능을 아무런 설정 파일을 만들지 않아도 제공한다.
  • WebMvcConfigurer가 제공하는 메소드를 구현하여 커스터마이징할 수 있다. - @EnableWebMvc를 사용하면 스프링 부트 자동 설정을 사용하지 못한다. 스프링 MVC 설정 방법
  • 스프링 부트를 사용하는 경우에는 application.properties 부터 시작.
  • WebMvcConfigurer로 시작
  • @Bean으로 MVC 구성 요소 직접 등록

스프링 MVC 활용

HTTP요청 매핑

  • @RequestMapping(method=RequestMethod.GET)
  • @RequestMapping(method={RequestMethod.GET, RequestMethod.POST})
  • @GetMapping, @PostMapping

RequestMapping은 따로 지정하지 않으면 모든 메서드 허용

잘못된 요청을 해 매핑이 되지 않는 경우 405에러

GET

  • 캐싱 가능
  • 브라우저 기록이 남는다.
  • Bookmark사용이 가능

POST

  • 캐시 x, 브라우저 기록 x, 북마크 x
  • 데이터 길이 제한이 없다.

PUT

  • URI에 해당하는 데이터를 새로 만들거나 수정할 때 사용한다.
  • Post와 다른점은 URL에 대한 의미가 다르다
    • POST는 URI는 보내는 데이터를 처리할 리소스를 지칭하며
    • PUT의 URI는 보내는 데이터에 해당하는 리소스를 지칭한다

PATCH

  • PUT과 비슷하지만, 기존 엔티티와 새 데이터의 차이점만 보낸다는 차이가 있다.

DELETE

  • URI에 해당하는 리소스를 삭제할 때 사용한다.

HEAD

  • GET 요청과 동일하지만 응답 본문을 받아오지 않고 응답 헤더만 받아온다.

OPTIONS

  • 사용할 수 있는 HTTP Method 제공
  • 서버 또는 특정 리소스가 제공하는 기능을 확인할 수 있다.
  • 서버는 Allow 응답 헤더에 사용할 수 있는 HTTP Method 목록을 제공해야 한다.

미디어 타입 맵핑

특정한 타입의 데이터를 담고 있는 요청만 처리하는 핸들러

  • @RequestMapping(consumes=MediaType.APPLICATION_JSON_UTF8_VALUE)
  • Content-Type 헤더로 필터링
  • 매치가 되지 않는 경우 415 Unsupported Media Type 응답

특정한 타입의 응답을 만드는 핸들러

  • @RequestMapping(produces=”application/json”)
  • 매치 되지 않는 경우에 406 Not Acceptable 응답

헤더와 매개 변수

특정한 헤더가 있는 요청을 처리하고 싶은 경우

  • @RequestMapping(headers = “key”)

특정한 헤더가 없는 요청을 처리하고 싶은 경우

  • @RequestMapping(headers = “!key”)

특정한 헤더 키/값이 있는 요청을 처리하고 싶은 경우

  • @RequestMapping(headers = “key=value”)

특정한 요청 매개변수 키를 가지고 있는 요청을 처리하고 싶은 경우

  • @RequestMapping(params = “a”)

특정한 요청 매개변수가 없는 요청을 처리하고 싶은 경우

  • @RequestMapping(params = “!a”)

특정한 요청 매개변수 키/값을 가지고 있는 요청을 처리하고 싶은 경우

  • @RequestMapping(params = “a=b”)

핸들러 메소드

핸들러 안에서 사용할 수 있는 메소드 아규먼트 타입과 리턴타입이 굉장히 다양하다

@PathVariable

  • 요청 URI 패턴의 일부를 핸들러 메소드 아규먼트로 받는 방법.

@RequestParam

  • 요청 매개변수에 들어있는 단순 타입 데이터를 메소드 아규먼트로 받아올 수 있다.
  • 값이 반드시 있어야 한다.
  • Map<String, String> 또는 MultiValueMap<String, String>에 사용해서 모든 요청 매개변수를 받아 올 수도 있다.
  • form data도 @RequestParam으로 받을 수 있다.
  • RequestParam은 생략이 가능하다.

@ModelAttribute

  • URI 패스, 요청 매개변수, 세션 등 있는 단순 타입 데이터를 복합 타입 객체로 받아오거나 해당 객체를 새로 만들 때 사용할 수 있다.
  • 생략이 가능하다
  • @ModelAttribute는 세션에 있는 데이터도 바인딩한다.

예시

copyButtonText
@PostMapping("/event")
@ResponseBody
// public Event getEvent(@ModelAttribute Event event) {
public Event getEvent(Event event) {
  return event;
}

값을 바인딩 할 수 없는 경우

  • BindException 발생 400 에러

바인딩 에러를 직접 다루고 싶은 경우

  • BindingResult 타입의 아규먼트를 바로 오른쪽에 추가한다.

바인딩 이후에 검증 작업을 추가로 하고 싶은 경우

  • @Valid 또는 @Validated 애노테이션을 사용한다.

@SessionAttribute

Tip!

  • Web기능 테스트 할 때 MockMvc사용

예시 코드

copyButtonText
@Autowired
MockMvc mockMvc;

@Test
public void createEvent() throws Exception {
  mockMvc.perform(
    post("/events")
      .contentType(MediaType.APPLICATION_JSON_UTF8)
      .accept(MediaType.APPLICATION_JSON)
  ).andExpect(status().isOk());
}

@SessionAttribute

세션에 있는 값을 바로 읽어올 수 있다.

예제에선 Interceptor를 활용해 session에 localdatetime을 넣어주고 실행

copyButtonText
@PostMapping("/event")
public Event getEvent(Model model, @SessionAttribute LocalDateTime visitTime) {
  return event;
}

RedirectAttributes

SpringMVC에서는 Redirect될 때 자동으로 설정된 값에 의해서 model값이 담겨서 쿼리 파라미터로 자동으로 담긴다

SpringBoot는 그 설정을 꺼져있다

이 경우 RedirectAttributes에 설정해 넘겨준다. (Query Parameter에 담긴다)

copyButtonText
@PostMapping("/event/form/limit")
public Event eventsFormLimitSubmit(@Validated @ModelAttribute Event evnt,
  BindingResult bindingResult,
  SessionStatus sessionStatus,
  RedirectAttributes attributes) {
    attributes.addAttribute("name", event.getName());
    attributes.addAttribute("limit", event.getLimit());
  return "redirect:/events/list;
}

Flash Attributes

주로 리다이렉트시에 복합적인 데이터를 전달할 때 사용한다.

RedirectAttributes에 보면은 addFlashAttribute()메소드가 존재한다.

인자값으로 객체를 넣는데 바로 HTTP 세션에 들어간다.

넘어가고 나서는 세션에서 제거가 된다 -> 1회성 데이터

URL Path에 붙기 때문에 전부 String으로 변환이 가능해야 한다.

Model안에 담겨 꺼낼 수 있다.

copyButtonText
@PostMapping("/event/form/limit")
public Event eventsFormLimitSubmit(@Validated @ModelAttribute Event evnt,
  BindingResult bindingResult,
  SessionStatus sessionStatus,
  RedirectAttributes attributes) {
    attributes.addFlashAttribute("newEvent", event);

  return "redirect:/events/list;
}

@PostMapping("/event/list")
public Event eventsFormLimitSubmit(@Validated @ModelAttribute Event evnt,
  Model model) {

  return "/events/list";
}
  • 데이터가 URI에 노출되지 않는다.
  • 임의의 객체를 저장할 수 있다.
  • 보통 HTTP 세션을 사용한다.

리다이렉트 하기 전에 데이터를 HTTP 세션에 저장하고 리다이렉트 요청을 처리 한 다음 그 즉시 제거한다. RedirectAttributes를 통해 사용할 수 있다.

MultipartFile

MultipartFile

  • 파일 업로드시 사용하는 메소드 아규먼트
  • MultipartResolver 빈이 설정 되어 있어야 사용할 수 있다. (스프링 부트 자동 설정이 해 줌)
  • POST multipart/form-data 요청에 들어있는 파일을 참조할 수 있다.
  • List 아큐먼트로 여러 파일을 참조할 수도 있다.
copyButtonText
<form method="POST" enctype="multipart/form-data" action="#" th:action="@{/file}"> File: <input type="file" name="file"/>
<input type="submit" value="Upload"/>
</form>

@PostMapping("/file")
public String uploadFile(@RequestParam MultipartFile file, RedirectAttributes attributes) {
  String message = file.getOriginalFilename() + " is uploaded.";
  System.out.println(message);
  attributes.addFlashAttribute("message", message);
  return "redirect:/events/list";
}

ResponseEntity

파일 리소스를 읽어오는 방법

  • 스프링 ResourceLoader 사용하기

파일 다운로드 응답 헤더에 설정할 내용

  • Content-Disposition: 사용자가 해당 파일을 받을 때 사용할 파일 이름
  • Content-Type: 어떤 파일인가
  • Content-Length: 얼마나 큰 파일인가

파일의 종류(미디어 타입)을 알아내는 방법

  • Tika라이브러리 사용

ResponseEntity

  • 응답 상태 코드
  • 응답 헤더
  • 응답 본문
copyButtonText
@PostMapping("/file")
public String uploadFile(@RequestParam MultipartFile file, RedirectAttributes attributes) {
    String message = file.getOriginalFilename() + " is uploaded.";
    System.out.println(message);
    attributes.addFlashAttribute("message", message);
    return "redirect:/events/list";
}

@RequestBody

@RequestBody

  • 요청 본문(body)에 들어있는 데이터를 HttpMessageConveter를 통해 변환한 객체로 받아올 수 있다.
  • @Valid 또는 @Validated를 사용해서 값을 검증 할 수 있다.
  • BindingResult 아규먼트를 사용해 코드로 바인딩 또는 검증 에러를 확인할 수 있다.

@ResponseBody & ResponseEntity

@ResponseBody

  • 데이터를 HttpMessageConverter를 사용해 응답 본문 메시지로 보낼 때 사용한다.
  • @RestController 사용시 자동으로 모든 핸들러 메소드에 적용 된다.
    • @ResponseBody를 명시하지 않고 객체만 써도 적용된다는 의미

ResponseEntity

  • 응답 헤더 상태 코드 본문을 직접 다루고 싶은 경우에 사용한다.

@InitBinder

특정 컨트롤러에서 바인딩 또는 검증 설정을 변경하고 싶을 때 사용

copyButtonText
@InitBinder
public void initEventBinder(WebDataBinder webDataBinder) {
    webDataBinder.setDisallowedFields("id");
}

위 코드에서는 id를 form에서 보내주더라도 걸러준다.

바인딩 설정

  • webDataBinder.setDisallowedFields();

포매터 설정

  • webDataBinder.addCustomFormatter();

Validator 설정

  • webDataBinder.addValidators()

@ExceptionHandler

  • MVC에서 요청을 처리하다가 에러를 직접 발생하거나
  • JAVA에서 발생하는 예외가 발생했을 떄 정의한 Handler로 처리해서 응답을 어떻게 보내줄지 정의할 수 있다.

Reference

스프링 웹 MVC - 백기선

Thank You for Visiting My Blog, I hope you have an amazing day 😆
© 2023 Ian, Powered By Gatsby.