티스토리 뷰
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
- 리퀘스트 메핑은 Servlet의 URI 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
'KH 정보교육원 [ Java ]' 카테고리의 다른 글
KH 112일차 - Spring ( Controller ) (****) (0) | 2022.08.05 |
---|---|
KH 111일차 - Spring ( Spring MVC - Controller ) (*****) (0) | 2022.08.04 |
KH 109일차 - Spring ( mybatis-spring : mapper ) (******) (0) | 2022.08.02 |
KH 108일차 - Spring ( MyBatis와 연동 ) (****) (0) | 2022.08.01 |
KH 107일차 - Spring ( 설정 / 히카리CP ) (****) (0) | 2022.07.29 |