Day53
키워드 : Spring-MyBatis 연동 / 스프링을 이용한 기존 웹 구조에서의 작업 / Spring-MVC 설정 / 스프링 기반 MVC 직접 만들기 / AutoScan / AutoScan을 활용한 참조형 변수의 값 출력하기
****
0. 복습
(1) Framework : 소프트웨어의 구체적인 부분에 해당하는 설계와 구현을 재사용이 가능하게끔 만든 것
일련의 협업화된 형태로 클래스들을 제공한다.
라이브러리와 달리 애플리케이션의 틈과 구조를 결정한다.
(2) Spring : 자바 기반으로 개발에 필요한 틀을 편하게 사용할 수 있도록 제공해주는 프레임워크
(3) DI (Dependency Injection) : 객체간 의존성을 나타내는 개념으로, 자신이 아닌 외부에서 주입해준다.
(4) AOP : 관점 지향 프로그래밍으로 핵심기능과 부가기능으로 나누어, 필요한 지점에서 삽입하는 것
※ 기존 JDBC 와 스프링 JDBC 차이
기존 JDBC | 스프링 JDBC |
- Connection 연결과 종료 - SQL문 실행 - SQL문 실행 결과 행에 대한 반복 처리 - 예외 처리 |
- 반복적인 JDBC 처리를 개발자 대신 프레임워으카 거칠 - 개발자가 구현할 부분 : SQL문 정의 : 파라미터 설정 : ResultSet에서 결과를 각 레코드 별로 처리 |
① 스프링 JDBC 설정
※ pom.xml에 작성되는 스프링 JDBC 설정
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
※ (참고) pom.xml에 작성되는 DBCP 설정 (DBCP는 커넥션 풀을 사용한다)
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
② DataSource 설정
※ database.properties 파일
jcdb.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.0.17:1521:orcl
jdbc.username=scott
jdbc.passwod=tiger
※ applicationContext.xml 파일
<context:property-placeholder location="classpath:config/database.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
③ 빈 의존성 주입
ㄱ) applicationContext.xml
<!-- 빈 객체 생성 -->
<context:component-scan base-package="board.impl" />
ㄴ) BoardServiceImpl 클래스
@Service("boardService")
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardDAOSpring boardDAO;
ㄷ) BoardDAOSpring 클래스
@Repository
public class BoardDAOSpring {
@Autowired
private JdbcTemplate jdbcTemplate;
④ JdbcTemplate 클래스 제공 메소드
queryForObject | - 하나의 결과 레코드 중에서 하나의 컬럼 값을 가져올 때 - RowMapper와 함께 사용하면 하나의 레코드 정보를 객체에 매핑할 수 있음 |
queryForMap | - 하나의 결과 레코드 정보를 Map 형태로 매핑할 수 있음 |
queryForList | - 여러 개의 결과 레코드를 가져올 때 |
query | - ResultSetExtractor, RowCallbackHandler와 함께 조회할 때 사용 |
update | - INSERT, UPDATE, DELETE 실행 |
(ⅰ) 마이바티스 개요
: 자바 오브젝트와 SQL문 사이의 자동 Mapping 기능을 지원하는 ORM 프레임워크
* 마이바티스는 SQL을 별도의 파일로 분리해서 관리하게 해주며, 객체-SQL 사이의 파라미터 Mapping 작업을 자동으로 해주기 때문에 많은 인기를 얻고 있는 기술이다. |
* 마이바티스는 Hibernate나 JPA(Java Persistence Api)처럼 새로운 DB 프로그래밍 패러다임을 익혀야 하는 부담이 없이, 개발자가 익숙한 SQL을 그대로 이용하면서 JDBC 코드 작성의 불편함도 제거해주고, 도메인 객체나 VO 객체를 중심으로 개발이 가능하다는 장점이 있다. |
(ⅱ) 마이바티스 특징
※ 쉬운 접근성과 코드의 간결함
- 가장 간단한 퍼시스턴스 프레임워크 - 복잡한 JDBC 코드를 걷어내며 깔끔한 소스 코드를 유지할 수 있다. - 수동적인 파라미터 설정과 쿼리 결과에 대한 맵핑 구문을 제거할 수 있다. |
※ SQL문과 프로그래밍 코드의 분리
- SQL에 변경이 있을 때마다 자바 코드를 수정하거나 컴파일 하지 않아도 된다. - SQL 작성과 관리 또는 컴토를 DBA과 같은 개발자가 아닌 다른 사람에게 맡길 수도 있다. |
(ⅲ) 마이바티스 중요 요소
Mybatis 설정 파일 ( mybatis-config.xml ) |
- 데이터베이스의 접속 주소 정보나 Mapping 파일의 경로 등의 고정된 환경정보를 설정한다. |
mapping 파일 ( mapper.xml ) |
- SQL문과 OR Mapping 을 설정한다. |
SqlSession FactoryBuilder | - Mybatis 설정 파일을 바탕으로 SqlSessionFactory를 생성한다. |
SqlSessionFactory | - SqlSession 을 생성한다. |
SqlSession | - 핵심적인 역할을 하는 클래스로서 SQL 실행이나 트랜잭션 관리를 실행한다. - SqlSession 오브젝트는 Thread-Safe 하지 않으므로 Thread마다 필요에 따라 생성한다. |
(ⅳ) 마이바티스 설정 파일
(1) mybatis-config.xml 파일 생성 |
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org/DTD config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
(2) DB 연결 정보 - db.properties 파일 |
jcdb.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.0.17:1521:orcl
jdbc.username=scott
jdbc.passwod=tiger
(3) DB 연결 설정 - mybatis-config.xml 에 추가 |
<!--Properties 파일 설정 -->
<properties resourcce="session/db.properties" />
<!-- DataSource 설정 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
(4) SQL Mapper 설정 - mybatis-config.xml 에 추가 |
<!-- SQL Mapper 설정 -->
<mappers>
<mapper resourcce="session/mappings/board-mapping.xml" />
</mappers>
(5) VO 클래스 별칭 설정 |
<!-- Alias 설정 -->
<typeAliases>
<typeAlias alias="board" type="board.BoardVO" />
</typeAliases>
(ⅴ) SQL Mapper 파일
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org/DTD config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<mapper namespace="BoardDAO">
<insert id="insertBoard">
INSERT INTO board(seq, title, writer, content, regdate, cnt)
VALUES (board_seq.nextval, #{title}, #{writer}, #{content}, sysdate, 0)
</insert>
<select id="getBoard" resultType="board">
SELECT * FROM board WHERE SEQ=#{seq}
</select>
<select id="getBoardList" resultType="board">
SELECT * FROM board
WHERE title LIKE '%'||#{searchKeyword}||'%'
ORDER BY SEQ DESC
</select>
</mapper>
(ⅵ) Mapper 요소 호출
mapper.xml 파일의 id값과 동일한 이름으로 호출한다. |
public class BoardDAO {
private SqlSession mybatis;
public BoardDAO() {
mybatis = SqlSessionFactoryBean.getSqlSessionInstance();
}
public void insertBoard(BoardVO vo) {
mybatis.insert("BoardDAO.insertBoard", vo);
mybatis.commit();
}
public List<BoardVO> getBoardList(BoardVO vo) {
return mybatis.selectList("BoardDAO.getBoardList", vo);
}
< Spring-Mybatis >
(1) Mybatis-Spring 중요 요소
Mybatis 설정 파일 (mybatis-config.xml) |
- VO 객체의 정보를 설정한다. |
SqlSessionFactoryBean | - Mybatis 설정 파일을 바탕으로 SqlSessionFactory를 생성한다. - Spring Bean으로 등록해야 한다. |
SqlSessionTemplate | - 핵심적인 역할을 하는 클래스로서 SQL 실행이나 트랜잭션 관리를 실행한다. |
Mapping 파일 (board-mapping.xml) |
- SQL문과 OR Mapping을 설정한다. |
Spring Bean 설정 파일 | - SqlSessionFactoryBean을 Bean 등록할 때 DataSource 정보와 Mybatis Config 파일 정보, Mapping 파일의 정보를 함께 설정한다. - SqlSessionTemplate을 Bean으로 등록한다. |
(2) 라이브러리 추가 - pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
<dependency>
<!-- Spring JDBC 필요 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- DBCP 필요 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
(3) 스프링 설정 파일 - applicationContext.xml
<!-- 자동 빈 생성 -->
<context:component-scan base-package="board.impl" />
<!-- DataSource 설정 -->
<context:property-placeholder location="classpath:config/db.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSourcce" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- Spring과 Mybatis 연동 설정 -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
<bean class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSession" />
</bean>
(4) Mybatis 설정 - mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org/DTD config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- Alias 설정 -->
<typeAliases>
<typeAlias alias="board" type="board.BoardVO" />
</typeAliases>
<!-- SQL Mapper 설정 -->
<mappers>
<mapper resourcce="session/mappings/board-mapping.xml" />
</mappers>
</configuration>
(5) 애노테이션 지정
@Service("boardService")
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardDAOMybatis boardDAO;
@Repository("boardDAO")
public class BoardDAOMybatis {
@Autowired
private SqlSessionTemplate mybatis;
1. Spring-Mabatis 사용을 위한 요약 실습
(기본 설정 및 이름찾기가 최고 관건이 된다!)
(1) mapper를 생성하기
① eSpringMybatis 프로젝트 - src - mappings 패키지 안에 "emp-mapping.xml" 파일 생성 후,
기존의 board-mapping.xml에서 상단부 스크립트를 복사해온다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="BoardDAO">
② <mapper> 태그의 namespace가 중복되지 않도록 새로운 이름을 부여하고 SQL을 작성한다.
<mapper namespace="EmpDAO">
<select id='selectEmp'>
SELECT e.ename ename, e.sal sal, e.deptno deptno, d.dname dname
FROM emp e INNER JOIN dept d
ON e.deptno=d.deptno
</select>
</mapper>
③ <mapper>를 찾아갈 수 있도록 마이바티스 설정파일인 mybatis-config.xml에서
"emp-mapping.xml"의 Sql Mapper 설정을 해주도록 한다.
<mappers>
<mapper resource='mappings/board-mapping.xml' />
<mapper resource='mappings/emp-mapping.xml' />
</mappers>
④ 외부로부터 값을 받아오진 않으므로 parameterType은 불필요하지만
SELECT 결과값은 받아와야 하므로 resultType은 필요하다.
지금 작성한 SQL에서는 조인을 사용해서 기존 VO가 존재하지 않는다.
이전 실습에서는 Class를 새롭게 만들어서 받아온 결과값을 담았지만,
앞으로 실무에서는 클래스를 마음대로 생성하지 못한다.
이 때, HashMap을 사용하면 클래스를 대신할 수 있다.
들어오는 데이터에 따라 자동으로 배열로 받아서 처리해준다.
<select id='selectEmp' resultType="hashmap">
key | value |
ename | JAMES |
... | ... |
(2) 새로 생성한 Mapper를 사용할 클래스를 생성한다.
① board.impl 패키지에 EmpDAOImpl.java 클래스를 생성
② board.impl 패키지에 EmpServiceImpl.java 클래스를 생성
(3) EmpDAOImpl.java를 Repository 로 애노테이션 붙이면서 생성될 빈의 이름을 "empDAO"로 지정해주고,
해당 클래스에서 객체를 직접 만들지 않고 스프링이 생성하도록 Autowired 애노테이션을 붙인다.
@Repository("empDAO")
public class EmpDAOImpl { // 자동객체명 empDAOImpl
// 객체를 직접 만들지 않고 스프링이 직접 생성하도록 만들 것
@Autowired
private SqlSessionTemplate sqlSession;
(4) EmpDAOImpl.java에서 selectEmp( ) 메소드를 작성한다.
→ 팀플에서 직접 작성해야 하는 부분이 바로 여기!!
public List<HashMap> selectEmp() {
System.out.println("EmpDAOImpl에서 selectEmp() 호출");
return sqlSession.selectList("EmpDAO.selectEmp");
}
(5) EmpServiceImpl.java를 Service로 애노테이션 붙이면서 빈의 이름을 "empService"로 지정해주고,
해당 클래스에서 객체를 직접 만들지 않고 스프링이 생성하도록 Autowired 애노테이션을 붙인다.
@Service("empService")
public class EmpServiceImpl { // 자동변수명 : empServiceImpl
@Autowired
private EmpDAOImpl empDAO;
(6) EmpServiceImpl.java에서 selectEmp( ) 메소드를 작성한다.
public List<HashMap> selectEmp() {
return empDAO.selectEmp();
}
(7) MainApp.java에서 Service의 빈을 얻어오고 selectEmp( ) 메소드를 수행하도록 한다.
★★★★★ 컬럼 이름은 반드시 대문자 사용!!!! SQL 결과가 대문자로 나오기 때문임!!!
public class MainApp {
public static void main(String[] args) {
// 1. Spring 컨테이너를 구동한다.
AbstractApplicationContext container = new GenericXmlApplicationContext("applicationContext.xml");
EmpServiceImpl empService = container.getBean("empService", EmpServiceImpl.class);
List<HashMap> list = empService.selectEmp();
for (HashMap m :list) {
System.out.println(m.get("ENAME") + "/" + m.get("DNAME"));
}
// 5. Spring 컨테이너 종료
container.close();
}
}
( 실행결과 )
ADAMS/RESEARCH
홍순이/RESEARCH
FORD/RESEARCH
....
< emp-mapping.xml 전체 소스 코드 >
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="EmpDAO">
<!-- 조인을 한 경우 (VO가 존재하지 않음) -->
<select id='selectEmp' resultType="hashmap">
SELECT e.ename ename, e.sal sal, e.deptno deptno, d.dname dname
FROM emp e INNER JOIN dept d
ON e.deptno=d.deptno
</select>
</mapper>
< EmpDAOImpl.java 전체 소스 코드 >
package board.impl;
import java.util.HashMap;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository("empDAO")
public class EmpDAOImpl { // 자동객체명 empDAOImpl
// 객체를 직접 만들지 않고 스프링이 직접 생성하도록 만들 것
@Autowired
private SqlSessionTemplate sqlSession;
public List<HashMap> selectEmp() {
System.out.println("EmpDAOImpl에서 selectEmp() 호출");
return sqlSession.selectList("EmpDAO.selectEmp");
}
}
< EmpServiceImpl.java 전체 소스 코드 >
package board.impl;
import java.util.HashMap;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("empService")
public class EmpServiceImpl { // 자동변수명 : empServiceImpl
@Autowired
private EmpDAOImpl empDAO;
public List<HashMap> selectEmp() {
return empDAO.selectEmp();
}
}
< MainApp.java 전체 소스 코드 >
import java.util.HashMap;
import java.util.List;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import board.impl.EmpServiceImpl;
public class MainApp {
public static void main(String[] args) {
// 1. Spring 컨테이너를 구동한다.
AbstractApplicationContext container = new GenericXmlApplicationContext("applicationContext.xml");
EmpServiceImpl empService = container.getBean("empService", EmpServiceImpl.class);
List<HashMap> list = empService.selectEmp();
for (HashMap m :list) {
System.out.println(m.get("ENAME") + "/" + m.get("DNAME"));
}
// 5. Spring 컨테이너 종료
container.close();
}
}
2. 스프링에서 기존 웹 구조로 만들기 위한 준비 (1) 프로젝트 및 서버 준비
※ 팀플에서는 기존 웹 구조인 Dynamic Web Project 또는 Spring Legacy Project 중 선택하면 된다.
(1) 워크스페이스 변경 후 Preference 설정을 해준다.
(2) 좌측의 Package Explorer에서 우클릭
- New
- Dynamic Web Project 선택
- 마지막단계에서 xml을 생성하도록 Generate 체크 후 Finish
(3) Maven Project로 설정하고 Spring Project 환경으로 변경한다.
- Convert to Maven Project
- add Spring Project Nature
(4) 자동생성된 pom의 내용을 실습파일에 있는 pom.xml의 내용으로 변경 후 저장한다.
pom.xml이 알아서 필요한 라이브러리를 다운 받아주기 시작한다.
좌측 Package Explorer에 Maven Dependencies가 생성된다. (안 보이면 우측 상단에서 JavaEE 말고 Spring으로 변경)
(5) 서버가 없는 상태이므로 하단의 Servers 탭에서 서버를 만들어준다.
(6) 서버가 정상적으로 구동하는지 JSP 파일을 만들어 테스트 해볼 수 있다.
< pom.xml 전체 소스 코드 >
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fDynamicWeb</groupId>
<artifactId>fDynamicWeb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- spring web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
3. 스프링에서 기존 웹 구조로 만들기 위한 준비 (2) 스프링 MVC 설정
(1) WebContent 폴더 안에 start.jsp 파일 생성 후 정상적으로 구동되는지 확인
(2) WEB-INF 폴더 안에 web.xml (프로젝트의 설정파일)이 있는지 확인
(3) WEB-INF 폴더 우클릭 - New - other - Web - JSP File - Next - Imsi.jsp 파일 생성 - 실행시 404 에러 발생
→ 즉, WEB-INF 폴더는 실행하더라도 접근하지 못한다.
WebContent 폴더만 접근한다.
(4) WEB-INF 폴더의 web.xml 안에서는 처음 접속했을 때 어떤 페이지를 보여줄지에 대한 설정이 들어있다.
index.jsp 페이지를 보여줄 것이라면 나머지 <welcome-file> 태그는 필요하지 않다. (지워도 무방하다는 뜻!)
<?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>fDynamicWeb</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
(5) 스프링 서블릿 설정 (컨트롤러 담당)
(탐캣 서버는 잠시 끄고 다음 스크립트를 작성한다. 켜두면 자꾸 뭘 하려고 하기 때문)
<servlet>
<servlet-name>servletMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
(6) WEB-INF에 springConfig 라는 이름으로 폴더 생성하고,
그 안에 스프링 환경설정 파일을 springMVC-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
(7) web.xml 에서 어떤 설정값을 초기화하여 지정하려면 <servlet> 태그 안에서 <init-param> 태그를 작성해준다.
param-value : 위치
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springConfig/springMVC-servlet.xml</param-value>
</init-param>
(8) Start.jsp 에서 "시작"이란 글씨를 클릭하면 <a> 태그를 통해 'Start.do' 가 있는 곳으로 이동하게끔 한다.
<a href='start.do'>시작</a>
(9) start.do 가 있는 곳으로 이동하기 위해 컨트롤러를 거쳐야하므로,
src 에 spring.mvc.sample 패키지 생성 후 컨트롤러로 쓰일 HelloController.java 클래스를 만든다.
(10) HelloController 클래스가 컨트롤러 역할을 수행할 수 있도록 @Controller 애노테이션을 붙이고,
@RequestMapping 애노테이션을 통해 "start.do"에 매핑되는 함수 test( )를 작성한다.
web.xml에서 작성된 DispatcherServlet 이
컨트롤러 역할을 하는 클래스를 애노테이션을 통해 찾아준다.
@Controller
public class HelloController {
@RequestMapping("start.do")
public void test() {
// 1. 컨트롤러까지 왔는지 확인
System.out.println("start 요청입니다.");
}
}
(11) springMVC-servlet.xml 에서 컨트롤러가 될 HelloController.java의 빈 설정을 해준다.
<bean class="spring.mvc.sample.HelloController"></bean>
( 실행결과 ) 콘솔에서 출력내용을 확인할 수 있음 (현재 웹 페이지 404 에러 뜨는 것이 정상임)
(12) 컨트롤러에서 ModelAndView 클래스를 사용하여 뷰를 지정한다.
* setViewName( ) : 보여줄 페이지의 이름
* addObject( "key" , "Value" ) : 페이지에 출력될 내용
public ModelAndView test() {
// 1. 컨트롤러까지 왔는지 확인
System.out.println("start 요청입니다.");
// 2. 데이터 & 뷰를 지정
ModelAndView mv = new ModelAndView();
mv.setViewName("hello.jsp");
mv.addObject("message", "오늘은 점심 뭐 드십니까?");
return mv;
}
(13) hello.jsp 페이지를 만들고, 컨트롤러에서 넘어오는 message라는 이름의 데이터가 출력되도록 작성한다.
<body>
start.do 요청에 의한 뷰 페이지입니다. <br/>
${message}가 전달되었습니다.
</body>
( 실행결과 ) start.do 요청을 컨트롤러에서 받아서 뷰 페이지를 지정해주고
필요한 데이터가 있으면 함께 보내주어 출력한다.
그러나 hello.jsp를 바로 실행할 경우 message 에 들어있는 데이터는 전달되지 않는다.
(mvc 구조, 지정한 경로로 접속하지 않을 경우 데이터를 보여주지 않음)
(14) WEB-INF 밑에 view 폴더를 만든 뒤, hello.jsp 파일을 옮겨온다.
(15) 컨트롤러에서 보여줄 페이지의 경로를 변경한다.
mv.setViewName("/WEB_INF/view/hello.jsp");
( 실행결과 ) WEB-INF 아래의 view 폴더 안에 있어도 정상적으로 컨트롤러에서 읽어올 수 있다.
이후부터는 start.jsp 페이지를 제외한 모든 jsp 파일이 view 폴더 아래에 위치해야 한다.
(16) 이미지 파일은 항상 WebContent 아래에 위치시켜야 한다.
WEB-INF 내에 위치하면 경로로 찾아가서 읽어오지 못 한다.
<!-- 절대경로로 이미지 출력 -->
<img src='/fDynamicWeb/img/icon_01.png' />
<img src='/fDynamicWeb/WEB-INF/icon_02.png'/> --> 출력되지 않음!
<!-- 상대경로로 이미지 출력 -->
<img src='img/icon_01.png' />
( 실행결과 )
(17) springConfig 폴더 안에 스프링 환경설정 파일로 common-servlet.xml 파일을 생성하고 ViewResolver 를 설정한다.
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" /> <!-- 위의 클래스 안에 있는 setPrefix()를 찾음 -->
<property name="suffix" value=".jsp" /> <!-- 위의 클래스에서 setFuffix()를 찾음 -->
</bean>
(18) web.xml 에서 common-servlet.xml도 연결시켜준다.
<param-value>
/WEB-INF/springConfig/springMVC-servlet.xml
/WEB-INF/springConfig/common-servlet.xml
</param-value>
(19) 컨트롤러에서 setViewName( ) 에 들어갈 인자로 페이지 이름만 넣어준다.
mv.setViewName("hello");
( 실행결과 ) 앞으로는 경로나 .jsp 확장자명에 대한 설정을 ViewResolver로 대신할 수 있다.
< 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>fDynamicWeb</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 스프링 서블릿 설정 -->
<servlet>
<servlet-name>servletMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/springConfig/springMVC-servlet.xml
/WEB-INF/springConfig/common-servlet.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servletMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
< springMVC-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 빈설정 -->
<bean class="spring.mvc.sample.HelloController"></bean>
</beans>
<!-- WebContent / WEB-INF / springConfig / springMVC-servlet.xml -->
< HelloController.java 전체 소스 코드 >
package spring.mvc.sample;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class HelloController {
@RequestMapping("start.do")
public ModelAndView test() {
// 1. 컨트롤러까지 왔는지 확인
System.out.println("start 요청입니다.");
// 2. 데이터 & 뷰를 지정
ModelAndView mv = new ModelAndView();
// 보여줄 페이지의 이름
mv.setViewName("hello");
// mv.setViewName("/WEB-INF/view/hello.jsp");
// mv.setViewName("hello.jsp");
// 페이지에 출력될 내용
mv.addObject("message", "오늘은 점심 뭐 드십니까?");
return mv;
}
}
< hello.jsp 전체 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> hello.jsp </title>
</head>
<body>
start.do 요청에 의한 뷰 페이지입니다. <br/>
${message}가 전달되었습니다.
<!-- 이미지 파일이 WEB-INF 안에 있어도 될까? No, 무조건 밖에 있어야 한다.-->
<!-- 절대경로로 이미지 출력 -->
<img src='/fDynamicWeb/img/icon_01.png' />
<img src='/fDynamicWeb/WEB-INF/icon_02.png'/>
<!-- 상대경로로 이미지 출력 -->
<img src='img/icon_01.png' />
</body>
</html>
< common-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- ViewResolver 설정 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" /> <!-- 위의 클래스 안에 있는 setPrefix()를 찾음 -->
<property name="suffix" value=".jsp" /> <!-- 위의 클래스에서 setFuffix()를 찾음 -->
</bean>
</beans>
< Start.jsp 전체 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> start.jsp</title>
</head>
<body>
<a href='start.do'>시작</a>
</body>
</html>
4. 스프링 기반 MVC 직접 만들어보기 (팀플 때 프로젝트 만들기는 이렇게 시작하면 됨)
(1) Dynamic Web Project
- 프로젝트명 : fDynamicTest
- maven 변환
- spring 추가
(2) maven을 통해 라이브러리 관리 : pom.xml
- fDynamicWeb 프로젝트의 pom.xml 복사
(3) 프로젝트 설정 : web.xml
- Spring Servlet 설정
- fDynamicWeb 프로젝트의 web.xml 복사
(4) 스프링 설정
- common-servlet.xml (ViewResolver 설정)
- springMVC-servlet.xml (빈 설정)
(5) 시작 페이지 : main.jsp
<a href="kosmo.do">여기서부터 시작</a>
(6) 뷰 페이지 : /WEB-INF/test/end.jsp
화면에 출력할 내용은 "여기까지 성공"
(7) 컨트롤러 생성
- src에 컨트롤러 생성 : testController.java
(8) "여기까지 성공" 부분을 배경색 및 글자색 변경
<link rel='stylesheet' type='text/css' href='/fDynamicTest/css/Simple.css'/>
< pom.xml 전체 소스 코드 >
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fDynamicWeb</groupId>
<artifactId>fDynamicWeb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- spring web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
< 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>fDynamicWeb</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 스프링 서블릿 설정 -->
<servlet>
<servlet-name>servletMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/springConfig/springMVC-servlet.xml
/WEB-INF/springConfig/common-servlet.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servletMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
< common-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" /> <!-- 위의 클래스 안에 있는 setPrefix()를 찾음 -->
<property name="suffix" value=".jsp" /> <!-- 위의 클래스에서 setsuffix()를 찾음 -->
</bean>
</beans>
< springMVC-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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 빈설정 -->
<bean class="spring.mvc.controller.testController"></bean>
</beans>
< testController.java 전체 소스 코드 >
package spring.mvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class testController {
@RequestMapping("kosmo.do")
public ModelAndView test() {
// 1. 컨트롤러까지 왔는지 확인
System.out.println("main 요청입니다.");
// 2. 데이터 & 뷰를 지정
ModelAndView mv = new ModelAndView();
mv.setViewName("end"); // 보여줄 페이지의 이름
mv.addObject("message", "오늘은 점심 뭐 드십니까?"); // 페이지에 출력될 내용
return mv;
}
}
< main.jsp 전체 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> Main.jsp </title>
</head>
<body>
<a href="kosmo.do">여기서부터 시작</a>
</body>
</html>
< end.jsp 전체 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> end.jsp </title>
<link rel='stylesheet' type='text/css' href='/fDynamicTest/css/Simple.css'/>
</head>
<body>
<span id="test">
여기까지 성공 <br/>
${message}
</span>
</body>
</html>
5. AutoScan
(1) WebContent에 "01_autoScan.jsp" 파일 생성한 뒤
"autoScan.do 요청"이라는 글씨를 클릭하면 "autoScan.do"가 있는 곳으로 이동하도록
<a>태그로 하이퍼링크를 걸어준다.
<a href='autoScan.do'>autoScan.do 요청</a>
(2) spring.mvc.controller 패키지에 AutoScanController.java 생성 후,
컨트롤러 역할을 하고 "autoScan.do" 요청을 받아서 수행하도록 애노테이션을 붙인다.
@Controller
public class AutoScanController {
@RequestMapping("autoScan.do")
public void abc() {
System.out.println("autoScan.do 요청됨");
}
}
(3) 컨트롤러에서 autoScan.do 요청을 수행하는 abc( ) 함수의 리턴형이 void 이므로
뷰 페이지는 자동으로 /WEB-INF/view 안의 같은 이름을 가진 파일로 지정된다.
해당 경로에 autoScan.jsp 파일을 생성한다.
(4) 애노테이션을 읽기 위해 스프링 컨테이너인 springMVC-servlet.xml 에서
Namespaces 탭의 context를 체크한 뒤 <context> 태그를 작성한다.
결과적으로, <bean> 태그를 하나하나 작성해서 빈 설정을 하지 않아도,
스프링 컨테이너가 구동될 때, 기술한 경로상에 있는 애노테이션을 스캔하여 빈을 생성해준다.
<context:component-scan base-package="spring.mvc.controller"></context:component-scan>
(기존 방식)
<bean id='autoScan' class="spring.mvc.controller.AutoscanController"></bean>
※ 빈을 여러개 생성해야 할 때,
기존 방식으로는 <bean> 태그를 필요한 수만큼 반복해서 작성해야 하지만,
오토스캔을 사용하면 단 한 번의 <context> 태그 작성만으로 필요한 모든 빈을 생성할 수 있게 된다.
< 01_autoScan.jsp 전체 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> 01_autoScan.jsp </title>
</head>
<body>
<a href='autoScan.do'>autoScan.do 요청</a>
</body>
</html>
< AutoScanController.java 전체 소스 코드 >
package spring.mvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class AutoScanController {
@RequestMapping("autoScan.do")
public void abc() {
System.out.println("autoScan.do 요청됨");
}
}
< autoScan.jsp 전체 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> autoScan.jsp</title>
</head>
<body>
여기는 뷰 페이지입니다. <hr/>
</body>
</html>
< springMVC-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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 자동 빈 설정 -->
<context:component-scan base-package="spring.mvc.controller"></context:component-scan>
</beans>
6. AutoScan을 사용하여 참조형 변수의 값을 화면에 출력하기 - 스프링 기반 MVC 실습
(1) src에 spring.mvc.model 패키지를 만들고 MemberVO.java 클래스를 만든다.
(2) 변수를 선언하고 setter, getter를 생성한다.
public class MemberVO {
private String id;
private String name;
private int age;
private boolean state;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
(3) springMVC-servlet.xml 에서 빈을 설정한다.
<bean id='memberVO' class="spring.mvc.model.MemberVO">
<!-- 나중에는 DB에서 값을 가져오게 할 것 -->
<property name="id" value='0001' />
<property name="name" value='홍길동' />
<property name="age" value='33' />
</bean>
(4) AutoScanController.xml 에서 멤버변수로 MemberVO 클래스를 지정하고
컨트롤러 구동시 알아서 객체를 가져오도록 @Autowired 애노테이션을 붙인다.
@Controller
public class AutoScanController {
@Autowired
private MemberVO memberVO;
(5) ModelAndView 객체인 mv에 오브젝트를 추가하되,
멤버변수를 memVO라는 이름으로 넣어준다.
mv.addObject("memVO", memberVO);
(6) autoScan.jsp 뷰 페이지에서 memVO라는 이름의 객체에 들어있는 값들을 화면에 출력하도록 작성한다.
여기는 뷰 페이지입니다. <hr/>
아이디 : ${memVO.id}<br/>
이름 : ${memVO.name}<br/>
나이 : ${memVO.age}<br/>
(7) 실행은 01_autoScan.jsp에서 한다.
( 실행결과 )
7. 스프링 기반 MVC 실습
(1) src - spring.mvc.model 패키지에 만든 MemberVO.java 클래스를 그대로 활용한다.
(2) WebContent 아래에 02_request.jsp 파일을 생성하고 폼을 만든다.
→ 웹 페이지에서 입력값을 넣고 전송버튼을 클릭해도 값이 넘어가지 않는다.
→ name이 없기 때문임!
<h2> 폼요청 </h2>
<form action='' >
번호 : <input type="text" /><br/>
이름 : <input type="text" /><br/>
나이 : <input type="text /><br/>
<input type="submit" value="전송" />
</form>
(3) 폼에 name을 부여하되, VO의 멤버이름과 맞추어 동일하게 만든다.
값을 가지고 request.do라는 요청을 하도록 작성한다.
<form action='request.do' >
<!-- name 부여시 VO의 멤버이름과 맞추는 것이 중요! -->
번호 : <input type="text" name='id' /><br/>
이름 : <input type="text" name='name' /><br/>
나이 : <input type="text" name='age' /><br/>
<input type="submit" value="전송" />
</form>
(4) src - spring.mvc.controller 패키지에 RequestController.java 파일 생성 후
컨트롤러가 되도록 @Controller 애노테이션을 붙이고,
"request.do"라는 요청이 들어올 때 request( ) 메소드가 수행되도록 @RequestMapping 애노테이션을 붙여준다.
@Controller
public class RequestController {
@RequestMapping("request.do")
public void request() {
System.out.println("request.do 요청");
// ModelAndView 리턴하지 않기
}
(5) 요청할 때 사용한 이름과 동일한 이름으로,
WEB-INF 아래의 view 폴더 안에 request.jsp 파일을 생성한다.
request.do 요청에 따른 결과 뷰 페이지입니다.
( 실행결과 )
: 함수의 리턴형이 void인 경우, 뷰 페이지가 자동으로 지정되어 페이지가 연결된다.
지정되는 규칙은 다음과 같다.
ex) request . do 요청 → rerquest /WEB-INF/view/ + request + . jsp |
ex) mapTest . do 요청 → mapTest /WEB-INF/view/ + mapTest + . jap |
(6) request.do 요청이 들어올 때 request( ) 메소드 호출하면서
사용자 입력값을 MemberVO 객체 vo에 담아서 가도록 인자를 수정한다.
@Controller
public class RequestController {
@RequestMapping("request.do")
public void request(MemberVO vo) {
(7) 스프링에서 클래스 이름에서 첫 글자만 소문자로 바꿔서 자동으로 객체 memberVO를 생성하면
그 객체 memberVO에 사용자 입력값이 지정된다.
값이 지정된 memberVO를 사용하여 화면에 출력하도록 view 폴더 안의 request.jsp 에서 스크립트를 작성한다.
request.do 요청에 따른 결과 뷰 페이지입니다. <hr/>
번호 : ${memberVO.id}<br/>
이름 : ${memberVO.name}<br/>
나이 : ${memberVO.age}<br/>
<hr/>
( 실행결과 )
(8) 사용자 입력값을 EL (표현언어)을 사용해서도 출력할 수 있다.
번호 : ${param.id}<br/>
이름 : ${param.name}<br/>
나이 : ${param.age}<br/>
( 실행결과 )
(9) 전송방식을 post로 할 경우 한글이 깨지므로 프로젝트 설정 파일인 web.xml 에서 인코딩 설정을 변경해줘야 한다.
<!-- 한글 인코딩 -->
<filter>
<filter-name>characterEncoding</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>characterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(10) 02_request.jsp 에서 폼 요청을 보낼 때
action 속성값을 request.do 에서 board/request.do로 변경하면 동일한 요청값 명이 없어서 수행되지 않는다.
RequestController.java에서 @RequestMapping의 별칭을 ("board/request.do")로 변경해줘야 한다.
이 때 절대 경로 또는 상대경로 둘 중 하나만 선택하여 양 쪽에 부여해줘야 한다.
① 절대경로 사용
: WebContent 에 있는 jsp 파일에서는 프로젝트명에서부터 경로를 작성해야 한다.
: WEB-INF/view 에 있는 jsp 파일에서는 프로젝트명을 제외하고 그 다음부터 경로를 작성해야 한다.
<form action='/fDynamicTest/board/request.do' method="post" >
@Controller
public class RequestController {
// 절대경로 : 프로젝트를 제외하고 그 다음부터 시작
@RequestMapping("/board/request.do")
public void request(MemberVO vo) {
② 상대경로 사용
<form action='board/request.do' method="post" >
@Controller
public class RequestController {
@RequestMapping("board/request.do")
public void request(MemberVO vo) {
( 실행결과 )
(11) 컨트롤러에서 @RequestMapping 애노테이션을 붙일 때 클래스와 메소드를 나누어 붙일 수도 있다.
@Controller
@RequestMapping("/board")
public class RequestController {
@RequestMapping("/request.do")
public void request(MemberVO vo) {
( 실행결과 )
< MemberVO.java 전체 소스 코드 >
package spring.mvc.model;
public class MemberVO {
private String id;
private String name;
private int age;
private boolean state;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isState() {
return state;
}
public void setState(boolean state) {
this.state = state;
}
}
< 02_request.jsp 전체 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> request.jsp </title>
</head>
<body>
<h2> 폼요청 </h2>
<!-- 절대경로 : 프로젝트에서부터 시작 -->
<form action='board/request.do' method="post" >
<!-- name 부여시 VO의 멤버이름과 맞추는 것이 중요! -->
번호 : <input type="text" name='id' /><br/>
이름 : <input type="text" name='name' /><br/>
나이 : <input type="text" name='age' /><br/>
<input type="submit" value="전송" />
</form>
</body>
</html>
< RequestController.java 전체 소스 코드 >
package spring.mvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import spring.mvc.model.MemberVO;
@Controller
// 클래스와 메소드를 나누어 별칭을 지정할 수도 있음
@RequestMapping("/board")
public class RequestController {
// 절대경로 : 프로젝트를 빼고 그 다음부터 시작
// @RequestMapping("board/request.do")
@RequestMapping("/request.do")
public void request(MemberVO vo) {
System.out.println("request.do 요청");
// ModelAndView 리턴하지 않기
}
/********************
* 함수의 리턴형이 void인 경우
* -> 뷰 페이지가 자동으로 지정된다
* ex) request.do 요청 -> request
* /WEB-INF/view/ + request + .jap
* ex) mapTest.do 요청 -> mapTest
* /WEB-INF/view/ + mapTest + .jsp
*/
}
< request.jsp 전체 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> request.jsp </title>
</head>
<body>
request.do 요청에 따른 결과 뷰 페이지입니다. <hr/>
번호 : ${memberVO.id}<br/>
이름 : ${memberVO.name}<br/>
나이 : ${memberVO.age}<br/>
<hr/>
번호 : ${param.id}<br/>
이름 : ${param.name}<br/>
나이 : ${param.age}<br/>
<hr/>
<!-- 외부 CSS 생성하여 글자색과 배경색을 변경 -->
<!-- 이미지 출력 -->
<!-- 단, 상대경로, 절대경로 모두 확인 -->
</body>
</html>
< 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>fDynamicWeb</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 리스너 : 응용프로그램에 적용 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springConfig/common-servlet.xml </param-value>
</context-param>
<!-- 스프링 서블릿 설정 -->
<servlet>
<servlet-name>servletMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/springConfig/springMVC-servlet.xml
/WEB-INF/springConfig/common-servlet.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servletMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 한글 인토딩 -->
<filter>
<filter-name>characterEncoding</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>characterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>