티스토리 뷰

1.    Spring MVC( Model-View-Controller )

-      Spring의 여러 하위 프로젝트 중 하나이다.

-      어노테이션( Annotaion )을 이용해서 간편하게 설정할 수 있다.

-      다양한 View를 지원한다.

 

2.    지금까지 배운 Spring의 하위 프로젝트

-      1 ) spring-context : Spring Beans Container + DI( 의존성 주입 )

-      + 스프링 빈즈 컨테이너의 규격을 정의한 타입 : ApplicationContext

-      + WebApplicationContext에서는 웹과 관련된 빈이 들어가 있는 servlet-context.xml과 웹과 관련이 없는 root-context.xml이 구분되어 있으나, 같이 연동되는 방식으로 동작하기에 설정을 분리해도 통합해서 사용이 가능하다.

-      2 ) spring-webmvc : Spring MVC 강제

-      3 ) spring-jdbc / spring-tx : DB( 데이터 베이스 ) 처리

-      4 ) spring-test : Junit과 함께 테스트 클래스에서 스프링 프레임워크 구동

 

3.    Request Mapping

-      리퀘스트 메핑은 ServletURI Mapping과 같은 기능을 한다.


[ 1. Spring MVC 생성하기 ] (***)

 

[ 1 - 1. Controller 만들기 ( @RequestMapping ) ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;


@Log4j2
@NoArgsConstructor

// ================================================================================
@RequestMapping("/sample/*")
// + /sample/*는 sample/ 뒤에 무엇이 오든 처리하겠다는 의미로 Base URI라고도 불린다.
// + ex. http://localhost:8080/sample/A( B, C, D도 가능 )
@Controller 
// + 컨트롤러로 만들어 주는 어노테이션
// + 컨트롤러가 빈으로 등록되어야 하기 때문에, 자바 빈즈 규약을 지켜야 한다.
//================================================================================
public class SampleController {
	
	// ============================================================================
	@RequestMapping(value="handleA", method=RequestMethod.GET)
	// + 이렇게 RequestMapping을 할 경우에는 위의 매핑과 합쳐져서
	// + http://localhost:8080/sample/handleA만 처리하게 된다.
	// + method를 통해 GET방식인지 POST방식인지 지정할 수 있다.
	// + GET 방식으로 지정하였는데, 만약 POST 방식으로 전송이 오면 405 오류가 뜬다.
	// + method를 생략하여, @RequestMapping(value="A")로만 작성해도 된다.
	// ============================================================================
	public void handleA() {
		log.trace(">>>>>>>> handleA() invoked.");
	} // handleA
	
	// ============================================================================
	@RequestMapping(path="A")
	// + path로 지정해 줘도, value로 지정해 줘도 된다.
	// ============================================================================
	public String doA() {
		log.trace(">>>>>>>> doA() invoked.");
		
		return "A"; 
		// + View의 이름 반환
		// + -> A.jsp View를 찾게 된다.
		// + View는 Views 폴더 내에서 생성하면 된다.
		
	} // doA
	
	// ============================================================================
	@RequestMapping("B")
	// + 이와 같이 value나 path로 지정하지 않고 지정해줘도 된다.
	// ============================================================================
	public String doB() {
		log.trace(">>>>>>>> doB() invoked.");
		
		return "B";
		// + /WEB-INF/views/B.jsp 파일을 불러오게 된다.
	} //doB
	
	// ============================================================================
	
	@RequestMapping(path="C", method=RequestMethod.GET)
	public String doC() {
		log.trace(">>>>>>>> doC() invoked.");
		return "ABC";
		// + /WEB-INF/views/ABC.jsp 파일을 불러오게 된다.
	} // doC
	
	// ============================================================================
	@RequestMapping(path="C", method=RequestMethod.POST)
	// + 이렇게 되면, 전송파라미터가 오는 방식에 따라서 달라지는데
	// + 동일한 http://localhost:8080/sample/C 경로로 요청이 들어와도
	// + 방식이 GET인지, POST인지에 따라서 doc가 발생하는지,
	// + doCWhenPost 발생하는지 달라지게 된다.
	// ============================================================================
	public String doCWhenPost() {
		log.trace(">>>>>>>> doCWhenPost() invoked.");
		
		return "ABC";
		// + /WEB-INF/views/ABC.jsp 파일을 불러오게 된다.
		// + servlet-context.xml 설정파일에 아래와 같은 설정이 있다 :
		// + <jsp prefix="/WEB-INF/views/" suffix=".jsp" />
		// + 최종 호출할 뷰의 경로는 아래와 같이 설정된다.
		// + " 접두사 + 반환된 뷰의 이름(return) + 접미사 " 
		// + => /WEB-INF/views/ + 반환된 뷰 이름 + .jsp
		// + => /WEB-INF/views/반환된 뷰 이름.jsp
		
	} // doC
	
	// ============================================================================
	@RequestMapping("WONDERWOMAN") // 상세 URI
	// + 만약, 전송방식(HTTP method)을 특정하지 않았을 경우에는 모든 전송방식을 수용한다는 의미다.
	// + 만일 이와 같이 타입선언부 위에 @RequestMapping(path)가 있다면, 최종 매핑URI는
	// + 기본 URI + 상세 URI가 된다. ( /sample + /WONDERWOMAN )
	// ============================================================================
	public String superHero() {
		log.trace(">>>>>>>> superHero() invoked.");
		
		// 비지니스 로직 생략 -> MODEL 데이터도 발생하지 X -> 뷰에 전달 할 것이 없음
		
		return "superHero";
	} // superHero

} // end class

 

[ 1 - 2.  Servlet-context.xml 파일에서  컨트롤러 빈으로 등록하기 ]

 

더보기

[ + 코드 보기 ]

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<!-- /resources/**의 의미는 resources폴더 아래에 있는 어떠한(모든) 자원을 의미한다. -->
	<!-- < resources mapping location >의 경우 파일을 생성하여 매핑할 수 있으며, 같은 location이여도 mapping을 추가할 수 있다. -->
	<!-- 설정파일을 수정하였으면, WAS를 내렸다가 올려야 한다. -->
	<!-- 아래의 태그로 인해 URL mapping처럼 http://localhost:8080/resources/파일명으로 접근이 가능하다. -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<!-- View로 어떤 JSP가 사용되어야 하는지 알려준다. -->
	<!-- ViewResolver는 MVC 패턴에서 Model 데이터를 이용하여 최종 응답화면을 생성할 View 역할을 수행할 대상을 찾아낸다. -->
	<!-- [ 예전 버전 ] -->
	<!-- + 예전 버전은 빈으로 등록하는 방법을 사용했다. -->
	<!-- <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> -->
		<!-- beans:property는 setPrefix와 setSuffix를 value값으로 해주는것이다. -->
		<!-- <beans:property name="prefix" value="/WEB-INF/views/" /> -->
		<!-- <beans:property name="suffix" value=".jsp" /> -->
	<!-- </beans:bean> -->

	<!-- [ 현재 버전 ] -->
	<!-- View Resolver -->
	<view-resolvers>
		<jsp prefix="/WEB-INF/views/" suffix=".jsp" />
	</view-resolvers>
	
	<!-- base-package에 작성한 패키지 내에 있는 것을 빈으로 등록시킨다. -->
	<context:component-scan base-package="org.zerock.myapp.controller" />
	
</beans:beans>

 

[ 1 - 3. View 만들기 ( return이 요청하는 view를 views 폴더 내에서 생성 ) ]

 

더보기

[ + 코드 보기 ]

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>View - A.jsp</title>
</head>

<body>

    <h1>/WEB-INF/views/A.jsp</h1>
    <hr>

    <h1>A</h1>
    
</body>

</html>

[ 2. Spring MVC - Controller 연습 ] (***)

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.zerock.myapp.domain.SampleDTO;

import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;


@Log4j2
@NoArgsConstructor

@RequestMapping("/sample2/") // 기본 URI ( base URI )
@Controller 
public class SampleController2 {
	
	// =======================================================
	// ===================================================
	//  	매개변수		|			리턴타입
	// ===================================================
	//			x			|				x
	//			x			|				o
	//			o			|				x
	//			o			|				o
	// ===================================================
	// + 각각의 Case가 약간씩 다르게 처리된다.
	// =======================================================
	
	// =======================================================
		// 1. @RequestMapping or RequestMapping("")
	// =======================================================
	
	@RequestMapping
	// + 이 경우에는 상세 URI가 지정되어 있지 않기에 기본 URI만 남게 된다.
	// + 이 경우에는 http://localhost:8080/sample2/로 요청을 보내야 한다.
	// + 실행하면 basic() invoked.가 찍히게 된다.
	public String basic() {
		log.trace("basic() invoked.");
		return "sample";
	} // basic
	
	// =======================================================
		// 2. @RequestMapping(path="", method=GET/POST)
	// =======================================================
	
	@RequestMapping(path="/basicGet", method=RequestMethod.GET)
	// + 전체 URI = 기본 URI + 상세 URI -> /sample2//basicGet...? (x)
	// + spring이 /sample2/basicGet로 처리해 준다.
	public String basicGet() {
		log.trace("basicGet() invoked.");
		return "sample";
	} // basicGet
	
	// =======================================================
		// 3. @RequestMapping(path="", method=GET/POST)
	// =======================================================
	
	@RequestMapping(
			path={"/basicGet2", "/basicGet3", "/basicGet4"}, 
			method= {RequestMethod.GET})
	// + 위와 같이 배열 안에 { } 여러 개를 지정할 수 있다.
	// + method에서도 { }를 통해서 GET방식과 POST 방식 모두 지정해 줄 수 있다.
	public String basicGet2() {
		log.trace("basicGet2() invoked.");
		return "sample";
	} // basicGet2
	
	// =======================================================
	
	@RequestMapping(
			path= {"/basicGet70", "/basicGet80"},
	        method= {RequestMethod.GET, RequestMethod.POST} // get 방식 , post 방식 둘다 요청 가능
	   ) // http://localhost:8080/sample/basicGet
	   public String basicGet88(){ 
	      log.trace("basicGet88() invoked.");
	      return "sample";
	   } // basicGet88
	
	// =======================================================
		// 4. @RequestMapping 어노테이션 축약형 :
		// + 1 ) @GetMapping(path)
		// + 2 ) @PostMapping(path)
	// =======================================================
	
	@GetMapping("/basicOnlyGet")
	public String basicOnlyGet () {
		log.trace("basicOnlyGet() invoked.");
		return "sample";
	} // basicOnlyGet
	
	@PostMapping("/basicOnlyPost")
	public String basicOnlyPost () {
		log.trace("basicOnlyPost() invoked.");
		return "sample";
	} // basicOnlyPost
	
	// =======================================================
		// 5. @GetMapping(path) with DTO parameter ( 매개변수 o ) (***)
	// =======================================================
	
   @GetMapping("/ex01")
   public String ex01(SampleDTO dto) {
	   log.info("ex01(SampleDTO dto) invoked.");
	   
	   log.info("\t + dto : {}", dto);
	   
	   return "sample";
   } // ex01
   
// =======================================================
   
   @GetMapping("/ex02")
   public String ex02(String name, Integer age) {
	   log.info("ex02(SampleDTO dto) invoked.");
	   
	   log.info("\t + name : {}, age : {}", name, age );
	   
	   return "sample";
   } // ex02

} // end class
728x90
댓글
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
최근에 올라온 글
Total
Today
Yesterday
공지사항