기본 콘텐츠로 건너뛰기

[Spring] Spring MVC 기초내용을 살펴보자

이번시간에는 Spring MVC 기초내용에 대해 알아보려 한다.
이런 흐름을 알아야 개발시에 생각하며(?) 개발을 할 수 있다.
용어에 친숙해지고, 흐름에 친숙해지자!!

스프링 MVC

스프링  MVC는 자바 기반의 웹 애플리케이션을 개발할 떄 사용하는 프레임워크로, 프레임워크 아키텍처로 MVC 패턴을 채택했다.
모델, 뷰, 컨트롤러와 같은 세 가지 역할의 컴포넌트로 구성되 있어 클라이언트의 요청을 처리한다.
  • 모델 : 애플리케이션 상태나 비즈니스 로직을 제공하는 컴포넌트
  • 뷰 : 모델이 보유한 애플리케이션 상태를 참조하고 클라이언트에 반환할 응답 데이터를 생성한다.
  • 컨트롤러 : 요청을 받아 모델과 뷰 호출을 제어하는 컴포넌트. 요청과 응답의 흐름을 제어한다.
MVC 패턴을 채택했다곤 하지만 정확히는 프론트 컨트롤러를 채택한 것이다.

스프링 MVC 애플리케이션

스프링 MVC 적용
ContextLoaderListener 설정
웹 애플리케이션에서 사용할 애플리케이션 컨텍스트를 만드려면 서블릿 컨테이너에 ContextLoaderListner 클래스를 등록해야 한다.

DispatcherServlet 설정
스프링 MVC의 프런트 컨트롤러를 이용하기 위해 DispatcherServlet 클래스를 서블릿 컨테이너에 등록한다.
스프링 MVC에선 웹 애플리케이션용 컨텍스트와 별개로 DispatcherServlet용 애플리케이션 컨텍스트를 별도로 만든다.
@EnableWebMvc를 붙이면 스플이 MVC가 제공하는 설정 클래스가 임포트 되어  스프링 MVC를 이용할 때 필요한 컴포넌트의 빈 정의가 자동으로 이뤄진다.
WebMvcConfigurerAdapter 클래스를 상속받으면 기본적으로 적용된 빈 정의를 커스터마이징 할 수 있다.

ViewResolver 설정
스프링 MVC에서 논리적인 뷰 이름을 보고 실제 표시할 물리적 뷰가 무엇인지 판단할 때 ViewResolver 라는 컴포넌트를 사용한다.
@Configuration
@EnableWebMvc
@ComponentScan("examples.boot.jboard")
public class WebMvcConfig implements WebMvcConfigurer {
  @Override
  public void configureViewResolvers(ViewResolverRegistry registry) {
      registry.jsp();
  }
}

최상위 페이지의 표시 처리 구현
뷰이름만 반환하는 처리 방식은 스프링 MVC에서 제공되는 뷰 컨트롤러가 제공하는 기능이다.

컨트롤러 구현
@Controller
public class WelcomeContrller {
  @RequestMapping("/")
  public String home(Model model) {
      return "index";
  }
}
  • 최상위 페이지 표시 요청을 처리하는 메스드 추가와 @RequestMapping 애노테이션으로 경로를 지정한다.
  • 리턴값은 jsp 이름이 된다. 즉 index.jsp가 호출된다. (webapp/WEB-INF/index.jsp)
  • Mode에 추가한 객체는 HttpServletRequest에 익스포트 되는 구조라 JSP에서 요청 스코드상에 있는 객체로 참조할 수 있다.

입력값 전송과 결과값 출력
@RequestMapping(method=RequestMethod.POST)
public String echo(Board form) {
  return "echo/output";
}
  • echo함수 매개변수에 클래스를 지정하면, 입력 화면에서 입력한 값을 클래스 객체에 저장해서 받을 수 있다.
  • 또한 인수에서 받은 Board 객체는 모델에도 자동으로 추가 되는 구조라 모델에 추가할 필요가 없다. 클래스의 앞글자를 소문자로한 board가 모델에 추가됨.

입력값 검사 구현
피수값 겁사와, 최대 문자수 검사 등을 할 수 있다.

입력값 검사 규칙 지정
스프링 MVC의 입력값 검사는 자바의 Bean Validation 매커니즘을 활용하고 있는데, 객체의 프로퍼티에 입력값 검사 규칙을 적용하는 방식을 채택하고 있다.

public class Board {
  @Id @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  private String category;
  @NotEmpty
  @Size(max=50)
  private String title;
  private LocalDateTime regdate;
}
  • @NotEmpty : 필수 값

컨트롤러 구현
입력값 검사 기능을 활성화하고 입력값 검사 오류를 처리하는 내용을 구현한다.
@RequestMapping(method=RequestMethod.POST)
public String echo(@Valid Board form, BindingResult result) {
  if(result.hasErrors()) {
      return "echo/input";
  }
  return "echo/output";
}
  • 클래스 인수에 @valid를 지정하면 프런트 컨트롤러는 폼 클래스의 입력값 검사를 하고 검사 결과를 BindingResult에 저장한다.
  • BindingResult는 폼 클래스 파라미터 바로 다음에 위치해야 한다. Model에 자동 추가 되 추가적으로 명시할 필욘 없다.

스프링 MVC 아키텍처

프레임워크 아키텍처
스프링 MVC는 front controller라고 하는 아키텍처를 채택하고 있다. 클라이언트 요청을 프런트컨트롤러라는 컴포넌트가 받아 요청 내부에 따라 수행하는 핸들러(컨트롤러)를 선택한다.
공통적인 처리를 프런트컨트롤러에 통합할 수 있어서 핸들러에서 처리하는 내용을 줄일 수 있다.
다음의 기능을 프런트 컨트롤러가 한다.
  • 클라이언트 요청 접수
  • 요청 데이터를 자바 객체로 변환
  • 입력값 검사 실행
  • 핸들러 호출
  • 뷰 선택
  • 클라이언트에 요청 결과 응답
  • 예외 처리

프런트 컨트롤러 아키텍처
스프링 MVC의 프런트 컨트롤러는 DispatcherServlet 클래스로 구현되 있다.
다음 으름으로 처리한다.
  • DispatcherServlet 클래스는 클라이언트의 요청을 받는다.
  • DispatcherServlet은 HandlerMapping 인터페이스의 gethander 메서드를 호출해 요청 처리를 하는 Handler 객체(컨트롤러)를 가져온다.
  • HandlerAdatoer 인터페이스의 handle 메서드를 호출 해 Handler 객체의 메서드를 호출을 의뢰한다.
  • DispatcherServlet는 ViewResolver 인터페이스의 resolveViewName 메서드를 호출해 Handler 객체에서 반환된 뷰 이름에 대응 하는 View 인터페이스 객체를 가져온다.
  • DispatcherServlet는 View 인터페이스의 render 메서드를 호출해 응답 데이터에 대한 랜더링을 요청한다.
  • DispatcherServlet 클래스는 클라이언트에 응답을 반환한다.

DispatcherServlet
프런트 컨트롤러와 연동되는 진입점 역할을 한다. 기본적인 처리흐름을 제어하는 사령탑 역할.

Handler
스프링 MVC에서 하는 일은 프런트 컨트롤러가 받은 요청에 따라 필요한 처리를 수행하는 것이다. 큰트롤러를 만들 때 @Controller를 붙이도록 한다.

HandlerMapping
요청에 대한 핸들러(컨트롤러)를 선택하는 역할을 수행한다. @RequestMapping에 정의된 설정 정보를 바탕으로 실행할 핸들러를 선택한다.

HandlerAdapter
핸들러 메서드를 호출하는 역할을 한다.

ViewResolver
핸들러에서 반환한 뷰 이름을 보고, 이후 사용할 View 인터페이스의 구현 클래스를 선택하는 역할을 한다.

View

View 인터페이스는 클라이언트에 반환하는 응답 데이터를 생성하는 역할을 한다.

마지막으로 스프링 MVC 흐름의 사진을 투척하며 마무리한다.
spring mvc에 대한 이미지 검색결과
뭔가 복잡해 보이지만 우리 개발자가 직접 건들이는 건 '보라색' 부분이다
일부만 구현하게 되어 나름(?) 안심이 된다.^^;;

끝~!!

댓글

이 블로그의 인기 게시물

[자바 웹 프로그래밍]2장 문자열 계산기 구현을 통한 테스트와 리펙토링

이번엔 2장에 나와 있는 내용 정리와 느낀점을 정리 해 보겠다. 1. main() 메소드를 활용한 테스트의 문제점.   - 소스코드 구현 후 정상적으로 동작하는지 확인 위해 일반적인 방법은 main()메소드를 활용하는 것이다.   - 실제 서비스를 담당하는 프로덕션 코드와 이 프로덕션 코드가 정상 동작 하는지 확인을 위한 main() 으로 나뉜다.   - 이 방법의 첫번째 문제점은 프로덕션코드와 main() 메서드가 함께 있다는 것이다.   - 프로덕션 코드와 테스트코드(main)을 분리할 수 있다.   - 두 번째 문제는 내가 구현하고 있는 메서드만 집중 할 수 없고, 클래스가 가지고 있는 모든 메서드를 테스트 할 수 밖에 없다.   - 다른 문제는 항상 콘솔로 확인을 할 수 밖에 없다는 것이다.   - 이를 위해 등장한 라이브러리가 JUnit 이다. 내 관심을 가지는 메서드에 대해 테스트 가능하다. 2. JUnit을 활용해 main() 메서드 문제 극복 2.1 한 번에 메서드 하나에만 집중.   - JUnit관련 라이브러리 추가 후  테스트 메서드에 @Test를 붙이면 된다.   - test 관련 코드 작성 후 Run > Run as> JunitTest를 실행해 보자.   - 각각 테스트 메서드를 독립적으로 실행할 수 있기 때문에 현재 내가 구현하고 있는 프로덕션 코드의 메서드에 집중할 수 있다. import org.junit.Test; public class CalculatorTest { @Test public void add() { Calculator cal = new Calculator(); System.out.println(cal.add(1,2)); } } 2.2 결과 값을 눈이 아닌 프로그램을 통해 자동화 import org.junit.Test; import static org.junit.Assert.assertEquals;

[고량주] 라오왕 연태고량주 플러스

나에게 처음 고량주란 이런것이다 라는걸 알려준 녀석이다. 부모님이 중국집을 하다 보니 가끔 초록색병 고량주를 먹었을때  역한 공업용 알콜 맛에 고량주는 나랑 안맞는다 생각했다가 우연히 양고기에 이녀석을 접한 뒤로 고량주의 맛을 알아버렸다... 제품명 : 라오왕 연태고량주플러스 제품유형 : 일반증류주 도수 : 34.2% 가격 : 9000원(홈플러스 익스프레스 기준) 재구매 의사 : 있다 시음평 : 역시 고량주 특유의 향인데, 열대과일 향도나고, 배향, 살짝 달달한 향이 난다.            목넘김은 34.2%에도 불구하고 그리 힘들지 않았다(주당이 된걸수도..)             중국요리나 양꼬치집에서 맛있는 술이 땡긴다면 강력추천한다.