매일 조금씩

01/27 ! - Spring MVC (1) : Dynamic Web Project + Spring lib와 Maven Project로 구현하기 본문

빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정

01/27 ! - Spring MVC (1) : Dynamic Web Project + Spring lib와 Maven Project로 구현하기

mezo 2021. 2. 25. 19:59
728x90
반응형

>> MVC 패턴이란 ?

enterprise (대용량, 분산, 분업)를 위한 아키텍처를 말한다.

XML, annotation 이렇게 두가지로 구현한다.

 

>> POJO,  DI,  AOP란 ?

  • POJO : Plain Old Java Object의 약자로 평범한 Java Object를 말하며, 개발자가 마음대로 정의할
                   수 있는 객체다.
                    l ight-weight(가볍게), fiexible(유연하게), simple(간단하게) 의 특징을 가지고 있다.
                  ※ 생긴 이유 :  EJB같은 경우 프레임워크에 종속적이여서 무거운 객체를 만들기 때문에 
                                             그에 반대되는 이유로 생긴 개념.
  • DI : Dependency Injection(의존성 주입)의 약자로 객체 간의 의존관계를 객체 자신이 아닌 
            외부의 조립기가 수행해주는 것을 말한다.
            스프링의 IOC 핵심 개념이며, 스프링에서는 각 객체를 빈(bean)으로 관리한다.
  • AOP  Aspect Oriented Programming(관점 지향 프로그래밍 기법)의 약자이며 공통의 
                  관심사항을 적용하여 의존관계의 복잡성과 코드 중복을 해소해 주는 
    것을 말한다.

 

EJB란,  기업환경의 시스템을 구현하기 위한 서버측 컴포넌트 모델을 말하는데

Spring MVC에선 다음 두가지를 사용하여 효율적으로 이를 구현한다. 

 

1) Spring DI   -  객체 풀링(라이프 사이클 관리)

                              주입

                              라이프사이클에서 특정 작업(proxy)

2) Spring AOP  -  Servlet Filter

                                 Aspect (공통관심사항- 보안, 트랜잭션) - 공통으로 일괄적으로 전처리나 후처리 해야할 일

                                 DI

                                 AspectJ

                                 Spring API annotation

 

그렇게 Spring MVC model2 를 다음 세가지로 구현한다.

  1. Dynamic Web Project + Spring lib
  2. Maven Project
  3. Spring MVC Project

 

아래 그림에서 '프론트 컨트롤러'는 우리가 기존에 서블릿으로 만들었던 컨트롤러고 '컨트롤러'는 action 페이지다.

아래 그림의 Dispatcher Servlet 은 위 그림의 프론트 컨트롤러다.

xml 같은 파일의 설정들을 읽어서 DI를 구현한다.

 

 


[ Spring MVC 구현 방법 ]

1. Dynamic Web Project + Spring lib

2. Maven Project

3. Spring MVC Project


 

1. Dynamic Web Project + Spring lib

 기본적으로 web.xml을 가진다.

 

1-1. 구현 방법 및 순서

> SpringMVCEx01

1) web.xml을 포함하게 해서 Dynamic Web Project를 만들기

 

2) Spring API들을 복사해서 lib에 넣기

 

3) web.xml 에 서블릿 태그를 추가

이건 검사를 안해줘서 에러나기가 쉽다.

<!-- Spring용 Front Controller 설정 -->
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- DispatcherServlet로 아래 xml파일을 읽어서 request를 결정한다. -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/dispatcher-serlvet.xml</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

 

4) view페이지 만들기

listview1.jsp 를 만들었다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
listview1.jsp
</body>
</html>

 

 

5) WEB-INF에 bean configuration file만들어서 프론트 컨트롤러 완성하기

beans, mvc 포함시키기

dispatcher-serlvet.xml

여기서 '파일명.do' 가 들어오면 '파일명.jsp'로 가도록 설정해준다.

여기선 list.do가 들어오면 listview1.jsp로 가도록 아래와 같이 적어줬다.

<!-- list1.do -> listview1.jsp -->
<bean name="/list1.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
    <property name="viewName" value="listview1.jsp" />
</bean>

 

6) 맨처음 view 요청하는 페이지 만들기

index.jsp를 만들었다.

여기서 링크를 누르면 그 링크가 list.do를 가리키고 

프론트 컨트롤러가 dispatcher-serlvet.xml에서 list.do의 request를 처리하여 listview1.jsp로 응답시킨다.

7) 만약 WEB-INF 안의 폴더 안에 view페이지가 있다면?

dispatcher-servlet.xml에서 다음과 같이 작성한다.

<!-- list3.do -> listview3.jsp -->
<bean name="/list3.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
    <property name="viewName" value="/WEB-INF/views/listview3.jsp" />
</bean>

 

직접 실행시킬 수 없기 때문에 이방법을 더 많이 쓴다.

 

 

8) url에 폴더명이 붙으면?

> index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<ul>
	<!-- ./ 생략가능 -->
	<li><a href="./list1.do">list1.do</a></li>
	<li><a href="./list2.do">list2.do</a></li>
	<li><a href="./list3.do">list3.do</a></li>
	<li><a href="board/list1.do">list1.do</a></li>
</ul>
</body>
</html>

 

> dispatcher-servlet.xml

<bean name="/board/list1.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
    <property name="viewName" value="../listview1.jsp" />
</bean>

list1.do 경로와 listview1.jsp경로가 맞아야해서 

listview1.jsp앞에 ../를 붙여줘야한다.

 

 

9) 접두, 접미 사용하기

> SpringMVCEx02

> dispatcher-servlet.xml

<bean name="/list1.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
    <property name="viewName" value="listview1" />
</bean>

<bean name="/list2.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
    <property name="viewName" value="listview2" />
</bean>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
</bean>

 

 

 

 

 다음거 하기전에......

갑자기 tomcat 실행안되는 에러발생 ㅎ

Servers 더블클릭해서 나오는 포트 8005, 8081둘다 변경해줘야한다.

8006과 8082로 바꿔준다.

 

 

 

1-2. action 페이지 써서 model2로 구현

10) action 페이지로 구현하기

action 페이지가 들어가게 되면 다음과 같은 흐름이 된다.

 

     front controller          back controller

list1.do ListAction1.class /WEB-INF/views/listview1.jsp

list2.do ListAction2.class /WEB-INF/views/listview2.jsp

 

이렇게 action 페이지가 있게 되면

request로 *.do가 들어오면 프론트 컨트롤러가 설정해놓은 대로 action페이지로 넘긴다. 

action 페이지는 Controller를 implements 하여 백 컨트롤러로서 ModelAndView를 사용해 view 페이지를 넘긴다.

src 폴더안에 action페이지를 만든다.

 

action 페이지에서 Controller를 implements할때는 

Controller를 import한 후, 다음처럼 클래스명에 생기는 빨간줄에 마우스를 갖다대서 'Add unimplemented methods'를 누른다.

그러면 다음처럼 handleRequest 메서드가 생긴다!

> ListAction1.java

package spring;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class ListAction1 implements Controller{

	@Override
	public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
		// TODO Auto-generated method stub
		
		System.out.println("ListAction1 호출");
		return new ModelAndView("listview1");
	}
}

 

 

1-3. 다국어 처리

> SpringMVCEx03

11) 필터로 다국어 처리하기

write.do -> WriteAction  -> /WEB-INF/views/write.jsp

write_ok.do -> WriteOkAction  -> /WEB-INF/views/write_ok.jsp

 

전에 Servlet을 배울때 filter를 배운적이 있다.

web.xml에 filter를 명시해주고, Filter를 implements하는 filter클래스를 따로 구현했어야 했다. 

 

그러나 Spring에선 filter를 제공해서 web.xml에만 명시해주면 된다.

즉,  Spring은 여기서 필요한 utf-8 필터를 제공한다. 

 

다음 코드를 web.xml에 추가하면 filter로 다국어 처리가 된다.

<!-- 다국어 처리 필터 -->
<filter>
    <filter-name>encodingFilter</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>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>*.do</url-pattern>
</filter-mapping>

 

 

 

1-4. 데이터 전달

action 페이지가 받은 데이터를 넘기는 방법은 두가지가 있다.

12) 데이터 넘겨주기 (전통 방식)

arg0.setAttribute("data", arg0.getParameter("data"));

위 코드에서 arg0은 action페이지의 handleRequest메서드의 request 인자값이다. 

 

 

13) 데이터 넘겨주기 (Spring 방식)

ModelAndView로 데이터를 넘긴다. 

ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("write_ok");
modelAndView.addObject("data", arg0.getParameter("data"));

return new ModelAndView("write_ok");

이렇게 하면 setAttribute를 한적이 없어도 받는쪽에서 getAttribute로 여기서 addObject한 데이터를 받을수 있다.

 

 

전체 프로젝트 구성은 다음과 같다.

 

 

1-5. 우편번호 검색기 model2 구현

> ZipcodeMVCEx01

14) 우편번호 검색기 만들기

zipcode.do -> ZipcodeAction  -> /WEB-INF/views/zipcode.jsp

zipcode_ok.do -> ZipcodeOkAction  -> /WEB-INF/views/zipcode_ok.jsp

 

> dispatcher-servlet.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">


	<bean name="/zipcode.do" class="model2.ZipcodeAction" />
	
	<bean name="/zipcode_ok.do" class="model2.ZipcodeOkAction" />
	
	<!-- action 페이지에서 return 받은 생성자함수의 인자값으로 다음 페이지 명을 받음 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
</beans>

 

> views > zipcode.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<form action="zipcode_ok.do" method="post">
동이름: <input type="text" name="dong" />
<input type="submit" value="전송" />
</form>

</body>
</html>

 

> views > zipcode_ok.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ page import="model1.ZipcodeTO"%>
<%@ page import="java.util.ArrayList"%>


<%
	StringBuffer html = new StringBuffer();	
	ArrayList<ZipcodeTO> lists = (ArrayList)request.getAttribute("lists");
			
	html.append( "<table width='600' border='1'>" );
	for(ZipcodeTO to : lists) {
		html.append( "<tr>" );
		html.append( "	<td>" + to.getZipcode() + "</td>" );
		html.append( "	<td>" + to.getSido() + "</td>" );
		html.append( "	<td>" + to.getGugun() + "</td>" );
		html.append( "	<td>" + to.getDong() + "</td>" );
		html.append( "	<td>" + to.getRi() + "</td>" );
		html.append( "	<td>" + to.getBunji() + "</td>" );
		html.append( "</tr>" );
	}
	html.append( "</table>" );
	
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<%= html %>

</body>
</html>

 

> model2 > ZipcodeAction.java

package model2;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class ZipcodeAction implements Controller{

	@Override
	public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
		// TODO Auto-generated method stub
		return new ModelAndView("zipcode");
	}
}

 

> model2 > ZipcodeOkAction.java

package model2;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import model1.ZipcodeDAO;
import model1.ZipcodeTO;

public class ZipcodeOkAction implements Controller{

	@Override
	public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
		
		System.out.println("ZipcodeAction 호출");
		
		
		// model1 부분 호출
		String strDong = arg0.getParameter("dong");
		
		ZipcodeDAO dao = new ZipcodeDAO();
		ArrayList<ZipcodeTO> lists = dao.searchLists(strDong);
		
		System.out.println(lists.size());
		
		// 데이터를 ok 페이지로 넘겨주는 부분
		// 뷰페이지명 말고도 넘겨줄 데이터가 존재하므로
		// ModelAndView를 기본 생성자를 만든 후에 내재된 함수로 view를 set하고 data를 담는다.
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("zipcode_ok");
		modelAndView.addObject("lists", lists);
		
		return modelAndView;
	}

	

}

 

 

 

2. Maven Project  (wepapp)

2-1. 구현 방법 및 순서

> web01

1) tomcat 서버 연결하기

tomcat server가 안걸려 있기 때문에 Java Build Path에서 Add Library 해서 tomcat v9.0넣어준다.

 

2) pom.xml 수정하기

필요한 라이브러리의 코드들만 추가해도 자동 라이브러리 추가됨.

라이브러리 버전 관리가 용이!

 

3) web.xml에 filter, servlet(프론트 컨트롤러)태그 코드 추가하기

dispatcher가 tomcat이 시작됨과 동시에 띄워지게 다음 코드를 serlvet태그에 추가한다.

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

 

> web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
	<display-name>Archetype Created Web Application</display-name>

	<!-- 다국어 처리 필터 -->
	<filter>
		<filter-name>encodingFilter</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>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>*.do</url-pattern>
	</filter-mapping>
	
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/mvc-config.xml</param-value>
		</init-param>
		<!-- tomcat이 시작하면 바로 띄워라 -->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
</web-app>

 

4) mvc-config.xml 만들기 

WEB-INF에 bean configuration file로 beans와 mvc 추가해서 만들기

> mvc-config.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

	<bean name="/list1.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
		<property name="viewName" value="listview1.jsp" />
	</bean>
	
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

 

2-2. model2 게시판을 Spring MVC로 만들기

5) model2 게시판을 Spring MVC로 만들기

> board01

  1. web.xml을 포함하는 Maven 프로젝트를 만든다.
  2. Build Path로 tomcat을 추가한다.
  3. pom.xml에 maven repository에서 찾은 mariadb코드를 추가한다.
  4. META-INF에 context.xml추가한다.
  5. web.xml에 servlet과 filter를 추가한다.
  6. mvc-config.xml를 작성한다.
  7. action페이지 인터페이스를 삭제하고 모든 action페이지를 1-2 방법으로 바꾼다.
  8. 모든 view페이지의 페이지 링크를 수정한다.  ex) board_list1.jsp  -> list.do 또는 list.spring 등 정한대로 ..

context.xml을 

> web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
	<display-name>Archetype Created Web Application</display-name>

	<!-- 다국어 처리 필터 -->
	<filter>
		<filter-name>encodingFilter</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>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>*.spring</url-pattern>
	</filter-mapping>

	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/mvc-config.xml</param-value>
		</init-param>
		<!-- tomcat이 시작하면 바로 띄워라 -->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>*.spring</url-pattern>
	</servlet-mapping>
</web-app>

*.do가 아닌 *.spring으로 한것을 확인할 수 있다.

 

> mvc-config.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

	<mvc:resources mapping="/resources/**" location="/resources/" />

	<bean name="/write.spring" class="model2.WriteAction" />
	<bean name="/write_ok.spring" class="model2.WriteOkAction" />
	<bean name="/list.spring" class="model2.ListAction" />
	<bean name="/view.spring" class="model2.ViewAction" />
	<bean name="/modify.spring" class="model2.ModifyAction" />
	<bean name="/modify_ok.spring" class="model2.ModifyOkAction" />
	<bean name="/delete.spring" class="model2.DeleteAction" />
	<bean name="/delete_ok.spring" class="model2.DeleteOkAction" />
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

 

 

오류 해결!

여기서 css, images가 안먹는데 

먼저 src > main > webapp > resources 에 css, images를 넣는다.

이때, resources 폴더가 없으면 만들어야한다.

 

그리고 프론트 컨트롤러 역할을 하는 mvc-config.xml에 아래 코드를 추가한다.

<mvc:resources mapping="/resources/**" location="/resources/" />

 

그리고 모든 view 페이지에 css, images 파일의 링크를

'/resource/css/파일명' 그리고 '/resource/images/파일명' 으로 바꾼다.

 

 

 

728x90
반응형