[Spring] MVC Pattern Basics

NoowaH·2021년 10월 5일
0
post-thumbnail

🛠 환경 설정 :


Spring의 front controller 기능의 API 등록 :

web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         id="WebApp_ID" 
         version="4.0">
    
  <display-name>step05_springMVC</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
    
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
	  

<load-on-startup>1</load-on-startup>

  • 서버가 web.xml 검증 후에 메모리에 설정 정보 로딩
  • 메모리에 로딩시에 가장 먼저 생성하라는 우선순위 부여
  • client 접속 여부와 무관하게 front controller는 가장 먼저 생성

<welcome-file-list>

  • intro


Maven

pom.xml :

  	<properties>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<spring-framework.version>4.3.30.RELEASE</spring-framework.version>
	</properties>
	
	<dependencies>
		<!-- Spring MVC 즉 Spring 기반의 웹 개발에 필요한 필수 library -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2.2</version>
		</dependency>
		
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.7.3</version>
		</dependency>
		
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.8</version>
		</dependency>
	</dependencies>


dispatcher-servlet.xml :

image-20211005105740030

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
    	
	<mvc:annotation-driven/>
	<mvc:default-servlet-handler/>
    
    <context:component-scan base-package="controller"/>
    
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"/>
		<property name="suffix" value=".jsp"/>
	</bean>

</beans>

🔵 <mvc:annotation-driven/> & <mvc:default-servlet-handler/>

  • html 문서를 정상 실행되게 해주는 설정

  • 생략시 404 에러 발생

🔵 <context:component-scan base-package="controller"/>

  • src.controller 스캔해서 controller 객체 bind

ViewResolver

🔵 <bean id="viewResolver"></bean>

  • View 영역 구현
  • 요청한 것에 대한 응답 view를 렌더링 하는 역할
  • JSP를 사용할 경우 InternalResourceViewResolver을 bean으로 등록

🚩 필수사항

  • dispatcher-sevlet : xml 파일 명 고정

  • <bean id="viewResolver"> : ViewResolver bean id 고정


prefix & suffix : 자원의 경로

  • prefix 의 value : 파일들 위치의 경로
  • suffix 반환 데이터의 형식 지정 (예 : .jsp)


Controller 주요 Annotations


  1. @Controller

  2. @RequestMapping

  3. @ModelAttribute

  4. @ExceptionHander


1 @Controller


Spring 기반의 사용자 정의 http 처리 클래스

Class 선언구에 작성

@Controller
public class Step01Controller {
	... 아래 나오는 예시 메소드들의 위치
}


2 @RequestMapping


  • client가 url상에 요청하는 이름, 방식과 매핑하는 설정
  • 개별 메소드별 선언구
<a href="hello1">1. hello1요청 - jsp로 redirect 웹페이지 이동</a>
	@RequestMapping("hello1")
	public String m1() {
		return "redirect:step01redirectView.jsp";
	}

🔵@RequestMapping(value = "", method = RequestMethod.GET)

  • method를 지정하지 않을 시 default = GET
  • method생략 시 value 키 생략 가능

🔵 html <a href="hello1"> 클릭 시 "hello1"@RequestMappingm1() 메소드 실행


🔵 return "redirect:step01redirectView.jsp"

  • redirect 방식으로 step01redirectView.jsp 반환
  • redirect: 를 앞에 추가 안하면 default 실행방식 = forward
  • forward 방식: prefix & suffix 기준으로 작성
  • redirect&forward`의 기본 반환 타입은 String


Forward 방식 API


👀 API : ModelAndView

<a href="hello2">2. hello2요청 - ModelAndView API 활용,</a>
	@RequestMapping("hello2")
	public ModelAndView m2() {
		ModelAndView mv = new ModelAndView();
		
		mv.setViewName("step01hello2");
		mv.addObject("data1", "hellooooo");
		
		return mv;
	}

🔵 mv.setViewName()

  • Forward 할 jsp 이름 : bean configuration 에서 지정한 prefix &suffix 기준으로 작성

🔵 mv.addObject("key","value")

  • requestScope.setAttribiute("key", "value") 와 동일하게 작동

🔵 return mv

  • 기본 String 타입 반환이 아닌 ModelAndView객체로 반환 하며 setViewName()메소드로 지정한 view 반환


👀 API : Model

	@RequestMapping("hello7")
	public String m6(Model model) {
		
		model.addAttribute("key", "value");
		
		return "step01hello7";
	}

🔵 ModelAndView 와의 차이점

  • 기본 반환 타입 String 유지


Redirect 방식 API


👀 API :RedirectAttribute

Redirect 방식에서 parameter값 적용 가능한 API

<a href="hello4">4.hello4요청 - RedirectAttributes</a>
	@RequestMapping("hello4")
	public String m4(RedirectAttributes attr)  {

		attr.addAttribute("key", "value");
		return "redirect:step04redirectView.jsp";
//      return "redirect:step04redirectView.jsp?key=value";
	}

🔵 public String m4(RedirectAttributes attr)

  • 메소드의 parameter로 API를 받 String으로 반환

🔵 attr.addAttribute("key", "value");

  • return "redirect:step04redirectView.jsp?key=value"; 와 동일하게 작동


++ 👀👀 More Examples


🙄 전송받는 데이터는 어떻게 처리할 수 있을까?

<a href="hello6?id=tester&age=100"> 전송받는 데이터는 어떻게 처리할 수 있을까?

👨‍💻 Forward 방식

	@RequestMapping("hello5")
	public String m5() {
		return "step01hello5";
	}

http request는 forward방식일때 jsp와도 공유

때문에 Controller에서 따로 추가 코드가 필요 없음

❗ but! : requestScope을 활용지 않고 바로 query를 사용

  • EL tag 사용시 ${param.id} 를 사용 가능
  • EL tag ${requestScope.id} 는 출력되지 않는다
  • controller에서 추가로 넣고싶은 데이터가 있다면 ModelAndView &Model객체 활용

👨‍💻 DTO 생성!?

입력된 Query String의 key와 일치되는 변수로 구성된 DTO 활용 기술

DTO :

package model.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class Customer {
	private String id;
	private int age;
}
	@RequestMapping("hello8")
	public String m8(Customer cust) {
		return "step01hello8";
	}

🔵 Customer 객체를 parameter로 입력

  • new Customer().setId(id).setAge(age) 와 동일하게 작동하며 DTO 객체 생성
  • ❗ 객체를 생성할 수 있지만 실제 객체를 반환하여 jsp로 전달을 못 함

3.@ModelAttribute


✅ Controller 에서 예외처리를 해결하는 메소드 지정

	@RequestMapping("hello8")
	public String m8(@ModelAttribute("cust") Customer cust) { // 
		return "step01hello8";
	}

😥 골뱅형이 왜 거기서 나와...?

🔵 m8(@ModelAttribute("cust") Customer cust)

  • request.setAttribute("cust", new Customer().setId(id).setAge(age)) 와 동일하게 작동
  • jsp에서 RequestScope을 활용하여 ${requestScope.cust.id}와 같이 DTO 데이터 반환 가능


4. @ExceptionHandler


Controller 에서 예외처리를 해결하는 메소드 지정

<a href="hello3">3.hello3요청 - Exception Test</a>
	@RequestMapping("hello3")
	public String m3() throws java.lang.Exception {
		if(true) {
			throw new Exception("예외발생");
		}
		return null;
	}

	@ExceptionHandler
	public String handler(Exception e) {
		System.out.println("예외처리" + e.getMessage());
		return "redirect:failView.jsp";
	}
  • hello3에 binding 된 m3()메소드는 항상 Exception을 날리는 구조

  • @ExceptionHander Annotation이 지정되어 있는 handler()라는 메소드는 Controller 내부에서 Exception이 발생할때 실행

profile
조하운

0개의 댓글