728x90
728x90

MVC 패턴


애플리케이션의 역할을 모델(Model), 뷰(View), 컨트롤러(controller)로 나누어 작업
Smalltalk-80 처음 소개
업무 서비스와 도메인 객체를 사용자 인터페이스로부터 분리, 하나 이상의 컨트롤러를 통해서 이들 사이 상호작용을 통제하는 아키텍처 패턴

 

 

MVC 모델 구성 요소

 

모델 : 데이터를 실어서 보내준다.


애플리케이션의 핵심적인 기능 제공
뷰와 컨트롤러 등록
데이터 변경 시 뷰와 컨트롤러에 통지



관련된 컨트롤러 생성, 초기화, 사용자에게 정보 표시
데이터 변경이 통지될 때 모델로부터 데이터를 읽어 처리


컨트롤러


사용자 입력을 이벤트로 받아들여 해석하여 모델에 대한 요청을 서비스하거나 뷰에 대한 요청을 표시
데이터 변경이 통지될 때 모델로부터 데이터 읽어와 처리
Front Controller 패턴 적용 – 컨트롤러가 중심이 되는 변형된 구조를 가짐 (이전 글의 BoardServlet 같은 전단서블릿)

 

 

CRUD MVC 패턴 총정리 : 게시판만들기

오라클에서 테이블 만들기 select * from tab; //테이블 뭐가 있나 조회 create table test( bno number primary key, writer varchar2(20), title varchar2(100), content varchar2(1000), reg_data date default..

coding-restaurant.tistory.com

 

동작


클라이언트가 컨트롤러에게 데이터 조회, 저장 등의 작업 요청
컨트롤러 : 서블릿으로 구현, 업무 로직 처리, 모델생성, 모델의 데이터 갱신, 뷰에 모델 전송, 뷰가 변경된 데이터 사용 가능하게 함
모델 : POJO Java 클래스로 구현, 데이터와 데이터처리에 필요한 메서드 포함, 자신이 관리하는 데이터에 집중
뷰 : JSP로 구현, 컨트롤러가 제공한 모델을 사용하여 데이터에 액세스하여 웹페이지(뷰)를 렌더링하여 응답을 생성하고 컨트롤러에 전달
컨트롤러는 클라이언트에 응답을 전송하고 서비스 종료

 

 

Spring MVC 매커니즘

 

 

BoardServlet 만들 필요 없이 기본으로 Servlet MVC 패턴은 Dispatcher Servlet을 제공한다.
또한 annotation도 제공한다.

1. 핸들러 맵핑 : 어떤 요청이 들어왔는지 확인한다.
2. 실질적으로 일을 처리할 컨트롤러를 선택한다.
3. 처리 결과를 Model(데이터를 실어준다)과 논리View(데이터를 표시)로 다시 Dispatcher Servlet으로 돌려준다. 
4. ViewResolver, 진짜 물리적인 뷰를 찾아서 내용을 보여준다.

* 논리뷰와 물리적인 뷰의 차이는>

 

 

 

스프링 프로젝트 작성 두 가지 방법


Spring Boot를 이용하는 방법 

File -> new -> Spring Start Project


Spring 템플릿 프로젝트를 이용하는 방법 (이 글에서 사용할 전통적인 방법)
File>New>Spring Legacy Project
New Spring Project 위저드의 Spring Project 화면에서 Spring MVC Project 항목을 선택, 프로젝트 이름: SpringProject01로 지정하고 next 선택
Project Setting>Spring MVC Project화면에서 패키지명을 com.pgm.project01로 지정, finish 선택

 

 

디렉토리 구조 살펴보기


src/main/java - controller (dto, dao...)
resources - 자원
webapp - view

 

 


--- 디렉토리는 * 두개, 파일이름은 하나

 

스피링 한글 처리 인코딩 필터

한글 처리 시 web.xml에 CharacterEncodingFilter 추가

<filter>
	<filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param> 
    	<param-name>encoding</param-name>
    	<param-value>UTF-8</param-value>
    </init-param>
    <init-param>
    	<param-name>forceEncoding</param-name>
        <param-value>true</param-value>
   </init-param> 
</filter> 

<filter-mapping> //필터 지정 위치
	<filter-name>characterEncodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

 

 

root 웹 애플리케이션 컨텍스트


IoC 컨테인 애플리케이션 컨텍스트는 트리 구조를 가짐
모든 애플리케이션 컨텍스트는 부모 애플리케이션 컨텍스트를 가질 수 있으며, 계층구조 안에 모든 애플리케이션 컨텍스트는 각각 독립적인 설정 정보를 사용하여 Spring 빈 객체를 생성하고 관리
의존성 주입을 위해 Spring 빈을 찾을 때 먼저 자신의 애플리케이션컨텍스트를 관리하는 Spring 빈 중에서 찾는다
자신을 관리하는 Spring 빈 중에 없는 경우 부모 애플리케이션 컨텍스에게 Spring 빈을 찾아 줄 것을 요청
계층구조를 따라 최상위 root 컨텍스트까지 요청 가능

 

 

컨트롤러 구현

 

 

 

데이터를 받는 두 가지 방법

 

 

데이터(커맨드) 객체 이용

 

 

 

Get /Post 방식 처리

 

 

 


 

실습하기

 

1. Spring Legacy Project 프로젝트를 생성한다.

 

 

스프링은 항상 디폴트 패키지를 적어야한다.
사용하지 않는 프로젝트는 클로즈 시켜서 닫아두어야 엉키는 등의 에러가 없다.

 

 

처음 플젝 만들 때마다 시작 전 구축이 빨라진 이유는 아래 사진처럼
디폴트로 받아야하는 라이브러리가 이미 생성되어있기 때문이다. 

 

 

 

2. Maven Repository 바로가기

스프링의 장점! 직접 찾아 라이브러리를 넣어줄 필요없이
pom.xml에 라이브러리를 등록해놓으면 알아서 프로그램이 찾아간다.

 

 

Maven Repository: Search/Browse/Explore

Vert.x Web Client Last Release on Aug 26, 2019

mvnrepository.com

 

프로젝트 아래 pom.xml을 수정한다.
. Maven을 사용하는 프로젝트에는 설정 파일인 pom.xml 파일이 있다.
POM Project Object Model의 약자

출처 : https://offbyone.tistory.com/163

 

pom.xml 수정 전 기본내용은?

...더보기
//수정 전 기본내용
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.lje</groupId>
	<artifactId>exam01</artifactId>
	<name>exam01</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
		<java-version>1.6</java-version>
		<org.springframework-version>3.1.1.RELEASE</org.springframework-version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
		<org.slf4j-version>1.6.6</org.slf4j-version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				 </exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
				
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>	
		
		<!-- Logging -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>javax.mail</groupId>
					<artifactId>mail</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency>

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
				
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	
		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>        
	</dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

 

자바버전 수정, 스프링 현재버전(5.1.9)으로 바꾸고  junit 버전을 고친다.
스프링 현재버전 확인은 아래 홈페이지에서.

 

 

pom.xml 변경 후 플젝의 버전들이 자동으로 바뀐 것을 확인해볼 수 있다.
메이븐을 사용하여 프로젝트의 라이브러리 의존성을 관리하면 실제 .jar 파일들을 관리할 필요없이 pom.xml 파일만 잘 관리하며 되는 것

 

 

다른 방법으로는 Maven > Update Project 한 후 프로퍼티에 들어가 확인한다.

 

 

 

pom.xml 바뀐 코드

...더보기
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.lje</groupId>
	<artifactId>exam01</artifactId>
	<name>exam01</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
		<java-version>1.8</java-version>
		<org.springframework-version>5.1.9.RELEASE</org.springframework-version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
		<org.slf4j-version>1.6.6</org.slf4j-version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				 </exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
				
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>	
		
		<!-- Logging -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>javax.mail</groupId>
					<artifactId>mail</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency>

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
				
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	
		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>        
	</dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

 

 

로딩 순서

실행 시 web.xml을 가장 먼저 읽는다. 스프링에서 루트는 webapp이다. (jsp의 WebContent와 같은 것)

 

 

 

Web.xml

...더보기
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets 
		and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>

	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<!-- 디폴트서블릿 -->
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	
	<filter>
		<filter-name>characterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter
		</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	
</web-app>

 

디폴트 패키지에 가서 컨트롤러를 보고, 그 후 RequestMapping 에 보면 / (루트,경로)가 적혀있다.
요청을 찾는다는 뜻.

 

 

 

TestController.java

...더보기
package com.lje.exam01;

import javax.servlet.http.HttpServletRequest;

import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.lje.exam01.vo.MemberInfo;

@Controller
public class TestController {

	@RequestMapping(value = "/test", method = RequestMethod.POST)
	public String test(HttpServletRequest req, Model model) {
		String name = req.getParameter("name");
		model.addAttribute("name", name);
		return "test";
	}

	// public void test(){}해도 찾아진다.
	// public String test(){return "test"; //논리뷰}

	@RequestMapping("/input")
	public String input() {
		return "board/input";
	}

//	@RequestMapping(value="/memberPro", method=RequestMethod.POST)
//	public String member(Request..??? request, Model model) {
//		String id = request.getParameter("id");
//		String pw = request.getParameter("pw");
//		String name = request.getParameter("name");
//		String tel = request.getParameter("tel");
//		model.addAttribute("id", id);
//		model.addAttribute("pw", pw);
//		model.addAttribute("name", name);
//		model.addAttribute("tel", tel);
//		return "board/memberPro";
//	}
	
	@RequestMapping(value="/memberPro", method=RequestMethod.POST)
	public String member(@RequestParam("id") String id, 
			@RequestParam("pw") String pw, Model model) 
	{
		model.addAttribute("id", id);
		model.addAttribute("pw", pw);
		return "board/memberPro";
	}

	/* @RequestMapping("/view") */
	public ModelAndView view() {
		ModelAndView mv = new ModelAndView();
		mv.addObject("id", "abcd");
		mv.addObject("pw", "1234");
		mv.setViewName("board/view");
		return mv;
	}

	// 위랑 같은 내용 다른 문법
	@RequestMapping("/view")
	public String view(Model model) {
		model.addAttribute("id", "abcd");
		model.addAttribute("pw", "1234");
		return "board/view";
	}
	
	@RequestMapping("/test2")
	public String view2(@RequestParam("id") 
	String id, Model model) {
		model.addAttribute("id", id);
		return "board/view";
	}
	
	//@RequestMapping("/test3")
	public String memberView(MemberInfo memberInfo ) {
		return "board/view3"; 
	}
	
	//test3의 다른 방법
	@RequestMapping("/test3")
	public String memberView(HttpServletRequest request, 
			Model model) {
		MemberInfo memberInfo = new MemberInfo();
		memberInfo.setName(request.getParameter("name"));
		memberInfo.setId(request.getParameter("id"));
		memberInfo.setPw(request.getParameter("pw")); 
		memberInfo.setTel(request.getParameter("tel")); 
		model.addAttribute("memberInfo", memberInfo);
		return "board/view3"; 
	}
	

}

 

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,

v