Table of Contents
- 설정 및 구현
- 생명주기(Life Cycle) : afterPropertiesSet(), destroy(), init-method, destroy-method
- @Annotation을 이용한 스프링 설정 (.xml to .java) : @Configuration, @Bean
- @Annotation을 이용한 스프링 설정 (분리) : @import
- Spring MVC Web Service I : Tomcat, STS 설치
- Spring MVC Web Service II : 프로젝트 전체 구조, Controller 생성
- Web Project Without STS : pom.xml, web.xml, servlet-context.xml, root-context.xml
- Service&Dao 객체구현 : @Service, @Component, @Repository
- Controller 객체 구현 I : @RequestMapping
- Controller 객체 구현 II : @ModelAttribute, Model&ModelAndView
설정-및-구현
생명주기(Life-Cycle)
빈 객체의 생명주기는 스프링 컨테이너의 생명주기와 같음
GenericXmlApplicationContext를 이용한 스프링 컨테이너 초기화(생성)
- 스프링 컨테이너와 Bean 객체의 생성 시점은 동일
- 빈 객체 생성 및 주입
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtx.xml");
- 스프링 컨테이너와 Bean 객체의 생성 시점은 동일
getBean()을 이용한 Bean객체 이용
BookRegisterService bookRegisterService = ctx.getBean("bookRegisterService", BookRegisterService.class); BookSearchService bookSearchService = ctx.getBean("bookSearchService", BookSearchService.class); MemberRegisterService memberRegisterService = ctx.getBean("memberRegisterService", MemberRegisterService.class); MemberSearchService memberSearchService = ctx.getBean("memberSearchService", MemberSearchService.class);
close()를 이용한 스프링 컨테이너 종료
- 스프링 컨테이너 소멸(안에 있는 Bean 객체들도 자동 소멸)
ctx.close();
Bean 객체 Interface를 이용한 동작
InitializingBean Interface : afterPropertiesSet()
- Bean 객체 생성시점에 호출
DisposableBean Interface : destroy()
Bean 객체 소멸시점에 호출
Ex)
public class BookRegisterService implements InitializingBean, DisposableBean{ @Autowired private BookDao bookDao; public BookRegisterService() { } public void register(Book book) { bookDao.insert(book); } @Override public void afterPropertiesSet() throws Exception { // bean 객체 생성 시점 동작 // (DB connet, 특정 네트워크 자원 사용 등..) System.out.println("빈(Bean)객체 생성 단계"); } @Override public void destroy() throws Exception { // bean 객체 소멸 시점 동작 System.out.println("빈(Bean)객체 소멸 단계"); } }
속성(init-method, destroy-method)을 이용한 동작
- init-method, destroy-method Method 설정
<bean id="bookRegisterService" class="com.brms.book.service.BookRegisterService"
init-method="initMethod" destroy-method="destroyMethod"/>
속성 값과 똑같은 method 생성
public class BookRegisterService { @Autowired private BookDao bookDao; public BookRegisterService() { } public void register(Book book) { bookDao.insert(book); } public void initMethod() { System.out.println("빈(Bean)객체 생성 단계"); } public void destroyMethod() { System.out.println("빈(Bean)객체 소멸 단계"); } }
@Annotation을-이용한-스프링-설정-I
.xml 파일을 .java 파일로 변경
applicationContext.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 id="studentDao" class="ems.member.dao.StudentDao" ></bean> <bean id="registerService" class="ems.member.service.StudentRegisterService"> <constructor-arg ref="studentDao" ></constructor-arg> </bean> <bean id="modifyService" class="ems.member.service.StudentModifyService"> <constructor-arg ref="studentDao" ></constructor-arg> </bean> <bean id="deleteService" class="ems.member.service.StudentDeleteService"> <constructor-arg ref="studentDao" ></constructor-arg> </bean> <bean id="selectService" class="ems.member.service.StudentSelectService"> <constructor-arg ref="studentDao" ></constructor-arg> </bean> <bean id="allSelectService" class="ems.member.service.StudentAllSelectService"> <constructor-arg ref="studentDao" ></constructor-arg> </bean> <bean id="dataBaseConnectionInfoDev" class="ems.member.DataBaseConnectionInfo"> <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe" /> <property name="userId" value="scott" /> <property name="userPw" value="tiger" /> </bean> <bean id="dataBaseConnectionInfoReal" class="ems.member.DataBaseConnectionInfo"> <property name="jdbcUrl" value="jdbc:oracle:thin:@192.168.0.1:1521:xe" /> <property name="userId" value="masterid" /> <property name="userPw" value="masterpw" /> </bean> <bean id="informationService" class="ems.member.service.EMSInformationService"> <property name="info"> <value>Education Management System program was developed in 2015.</value> </property> <property name="copyRight"> <value>COPYRIGHT(C) 2015 EMS CO., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION.</value> </property> <property name="ver"> <value>The version is 1.0</value> </property> <property name="sYear"> <value>2015</value> </property> <property name="sMonth"> <value>1</value> </property> <property name="sDay"> <value>1</value> </property> <property name="eYear" value="2015" /> <property name="eMonth" value="2" /> <property name="eDay" value="28" /> <property name="developers"> <list> <value>Cheney.</value> <value>Eloy.</value> <value>Jasper.</value> <value>Dillon.</value> <value>Kian.</value> </list> </property> <property name="administrators"> <map> <entry> <key> <value>Cheney</value> </key> <value>cheney@springPjt.org</value> </entry> <entry> <key> <value>Jasper</value> </key> <value>jasper@springPjt.org</value> </entry> </map> </property> <property name="dbInfos"> <map> <entry> <key> <value>dev</value> </key> <ref bean="dataBaseConnectionInfoDev"/> </entry> <entry> <key> <value>real</value> </key> <ref bean="dataBaseConnectionInfoReal"/> </entry> </map> </property> </bean> </beans>
MemberConfig.java
- @Configuration : 이 .java 파일은 스프링 컨테이너를 만드는데 사용
- @Bean : 메소드를 이용하여 Bean 객체 생성
package ems.member.configration; // ... @Configuration public class MemberConfig { @Bean public StudentDao studentDao() { return new StudentDao(); } @Bean public StudentRegisterService registerService() { return new StudentRegisterService(studentDao()); } @Bean public StudentModifyService modifyService() { return new StudentModifyService(studentDao()); } @Bean public StudentSelectService selectService() { return new StudentSelectService(studentDao()); } @Bean public StudentDeleteService deleteService() { return new StudentDeleteService(studentDao()); } @Bean public StudentAllSelectService allSelectService() { return new StudentAllSelectService(studentDao()); } @Bean public DataBaseConnectionInfo dataBaseConnectionInfoDev() { DataBaseConnectionInfo infoDev = new DataBaseConnectionInfo(); infoDev.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:xe"); infoDev.setUserId("scott"); infoDev.setUserPw("tiger"); return infoDev; } @Bean public DataBaseConnectionInfo dataBaseConnectionInfoReal() { DataBaseConnectionInfo infoReal = new DataBaseConnectionInfo(); infoReal.setJdbcUrl("jdbc:oracle:thin:@192.168.0.1:1521:xe"); infoReal.setUserId("masterid"); infoReal.setUserPw("masterpw"); return infoReal; } @Bean public EMSInformationService informationService() { EMSInformationService info = new EMSInformationService(); info.setInfo("Education Management System program was developed in 2015."); info.setCopyRight("COPYRIGHT(C) 2015 EMS CO., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION."); info.setVer("The version is 1.0"); info.setsYear(2015); info.setsMonth(1); info.setsDay(1); info.seteYear(2015); info.seteMonth(2); info.seteDay(28); ArrayList<String> developers = new ArrayList<String>(); developers.add("Cheney."); developers.add("Eloy."); developers.add("Jasper."); developers.add("Dillon."); developers.add("Kian."); info.setDevelopers(developers); Map<String, String> administrators = new HashMap<String, String>(); administrators.put("Cheney", "cheney@springPjt.org"); administrators.put("Jasper", "jasper@springPjt.org"); info.setAdministrators(administrators); Map<String, DataBaseConnectionInfo> dbInfos = new HashMap<String, DataBaseConnectionInfo>(); dbInfos.put("dev", dataBaseConnectionInfoDev()); dbInfos.put("real", dataBaseConnectionInfoReal()); info.setDbInfos(dbInfos); return info; } }
Main.java
// Using .xml GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationContext.xml"); // Using .java AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MemberConfig.class);
@Annotation을-이용한-스프링-설정-II
코드가 길어지면 유지보수에 어려움이 생기므로 파일을 분리해주는 것이 편리
(참고 : Ctrl + Shift + o : 참조되지 않는 패키지 정리)
- 보통 기능별로 분리
- Dao (Data Access Object)
- Service
- DataBase 관련 기능
- Utility
.java 파일 분리
MemberDaoConfig.java
// ... @Configuration public class MemberDaoConfig { @Bean public DataBaseConnectionInfo dataBaseConnectionInfoDev() { DataBaseConnectionInfo infoDev = new DataBaseConnectionInfo(); infoDev.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:xe"); infoDev.setUserId("scott"); infoDev.setUserPw("tiger"); return infoDev; } @Bean public DataBaseConnectionInfo dataBaseConnectionInfoReal() { DataBaseConnectionInfo infoReal = new DataBaseConnectionInfo(); infoReal.setJdbcUrl("jdbc:oracle:thin:@192.168.0.1:1521:xe"); infoReal.setUserId("masterid"); infoReal.setUserPw("masterpw"); return infoReal; } }
MemberServiceConfig.java
// ... @Configuration public class MemberServiceConfig { @Bean public StudentDao studentDao() { return new StudentDao(); } @Bean public StudentRegisterService registerService() { return new StudentRegisterService(studentDao()); } @Bean public StudentModifyService modifyService() { return new StudentModifyService(studentDao()); } @Bean public StudentSelectService selectService() { return new StudentSelectService(studentDao()); } @Bean public StudentDeleteService deleteService() { return new StudentDeleteService(studentDao()); } @Bean public StudentAllSelectService allSelectService() { return new StudentAllSelectService(studentDao()); } }
MemberUtilConfig.java
@Configuration public class MemberUtilConfig { // dbInfos 객체에서 필요한 DataBaseConnectionInfo 객체를 @Autowired 로 생성 @Autowired DataBaseConnectionInfo dataBaseConnectionInfoDev; @Autowired DataBaseConnectionInfo dataBaseConnectionInfoReal; @Bean public EMSInformationService informationService() { EMSInformationService info = new EMSInformationService(); info.setInfo("Education Management System program was developed in 2015."); info.setCopyRight("COPYRIGHT(C) 2015 EMS CO., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION."); info.setVer("The version is 1.0"); info.setsYear(2015); info.setsMonth(1); info.setsDay(1); info.seteYear(2015); info.seteMonth(2); info.seteDay(28); ArrayList<String> developers = new ArrayList<String>(); developers.add("Cheney."); developers.add("Eloy."); developers.add("Jasper."); developers.add("Dillon."); developers.add("Kian."); info.setDevelopers(developers); Map<String, String> administrators = new HashMap<String, String>(); administrators.put("Cheney", "cheney@springPjt.org"); administrators.put("Jasper", "jasper@springPjt.org"); info.setAdministrators(administrators); Map<String, DataBaseConnectionInfo> dbInfos = new HashMap<String, DataBaseConnectionInfo>(); dbInfos.put("dev", dataBaseConnectionInfoDev); dbInfos.put("real", dataBaseConnectionInfoReal); info.setDbInfos(dbInfos); return info; } }
Main.java
AnnotationConfigApplicationContext ctx = // spring 설정 파일을 나열 new AnnotationConfigApplicationContext(MemberServiceConfig.class, MemberDaoConfig.class, MemberUtilConfig.class);
@import Annotation
하나의 파일에 분리된 설정 파일을 import하는 방법
MemberServiceConfig.java 에 다른 설정 파일들을 import
// ... @Configuration @Import({MemberDaoConfig.class, MemberUtilConfig.class}) public class MemberServiceConfig { @Bean public StudentDao studentDao() { return new StudentDao(); } @Bean public StudentRegisterService registerService() { return new StudentRegisterService(studentDao()); } // ... }
Main.java
AnnotationConfigApplicationContext ctx = // 다른 설정 파일들을 import한 파일만 명시 new AnnotationConfigApplicationContext(MemberServiceConfig.class);
Spring-MVC-Web-Service-I
- 웹 서버(Tomcat) 다운로드 : 서버와 웹 컨테이너를 동시에 제공
- 웹 서버(Tomcat)와 이클립스 연동
Window
->Show View
->Other
에서 새로운 Server를 만들거나- 하단 Server console 에서 Click this link를 눌러주고, 자신의 Tomcat 서버를 선택한 후 installation directory를 설정.
- 서버 설정에서 Server Location, Server Options, Ports를 변경. Port는 DB와 충돌 고려
- http://localhost:8090 OR http://127.0.0.1 로 접속하여 확인 가능
- 이클립스에 STS(Spring Tool Suit) 설치
Help
->Eclipse Marketplace
->sts 검색 후 설치
- STS를 이용하여 웹 프로젝트를 생성하기 위해
New
->Other
->Spring Legacy Project
->spring MVC Project
선택
Spring-MVC-Web-Service-II
프로젝트 전체 구조
java파일 : java파일들이 위치. 주로 패키지로 묶어서 관리
웹 애플리 케이션에서 사용되는 Controller, Service, DAO객체들이 위치
- webapp : 웹과 관련된 파일들(스프링 설정파일, JSP파일, HTML파일 등..)이 위치
- resources : JSP파일을 제외한 html, css, js파일등이 위치
- spring폴더 : 스프링 컨테이너를 생성하기 위한 스프링 설정파일이 위치
- views 폴더 : View로사용될 JSP파일이 위치
- pom.xml파일 : 메인 레파지토리에서 프로젝트에 필요한 라이브러리를 내려받 기위한 메이븐 설정 파일
새로운 Controller 생성
src
>main
>java
>com
>bs
>lec14
> Login.java// ... @Controller public class Login { // 메소드와 매핑 설정 (/login 요청이 들어왔을 때, login 메소드 실행하도록 매핑 설정) // @RequestMapping(value = "/login", method = RequestMethod.GET) @RequestMapping("/login") public String login(Model model) { model.addAttribute("loginKey", "loginValue"); return "login"; // login.jsp (View의 이름을 return 값으로 설정) } }
src
>main
>webapp
>WEB-INF
>views
> login.jsp<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ page session="false" %> <html> <head> <title>Login</title> </head> <body> <h1> Hello world! </h1> <P> loginKey is ${loginKey}. </P> </body> </html>
Web-Project-Without-STS
스프링MVC 웹애플리케이션제작을위한폴더생성
C:\spring\pjt\lec16Pjt001\src
C:\spring\pjt\lec16Pjt001\src\main
C:\spring\pjt\lec16Pjt001\src\main\java
- 여기까지 Spring Framework을 이용한 java Application을 만드는 구조
C:\spring\pjt\lec16Pjt001\src\main\webapp
C:\spring\pjt\lec16Pjt001\src\main\webapp\resources
- html, css, js, img 등의 리소스 파일 위치
C:\spring\pjt\lec16Pjt001\src\main\webapp\WEB-INF
- 웹 설정파일 위치
C:\spring\pjt\lec16Pjt001\src\main\webapp\WEB-INF\spring
- Spring 관련 설정 파일 위치(servlet-context, xml 등의 파일)
C:\spring\pjt\lec16Pjt001\src\main\webapp\WEB-INF\views
JSP 파일 위치
pom.xml 작성 및 이클립스 import
import
->import
->Existing Maven Projects
->프로젝트 선택
->Finish
web.xml 작성
src
->main
->webapp
->WEB-INF
-> web.xml
스프링 설정 파일(servlet-context.xml) 작성
src
->main
->webapp
->WEB-INF
->spring
->appServlet
-> servlet-context.xml
- root-context.xml 작성
src
->main
->webapp
->WEB-INF
->spring
-> root-context.xml
Controller와 View 작성
src
->main
->java
->com
->bs
->lecTest
-> HomeController.java@Controller public class HomeController { @RequestMapping("/") public String home(Model model) { return "home"; } @RequestMapping("/login") public String login(Model model) { model.addAttribute("key", "value"); return "login"; } @RequestMapping("/success") public String success(Model model) { return "success"; } @RequestMapping(value = "/fail", method = RequestMethod. GET ) public String fail(Model model) { return "fail"; } }
src
->main
->webapp
->WEB-INF
->views
-> home.jsp<%@ taglib uri= "http://java.sun.com/jsp/jstl/core" prefix = "c" %> <%@ page session= "false" language = "java" contentType = "text/html; charset=UTF - 8" pageEncoding= "UTF - 8" %> <html> <head> <title>Home</title> </head> <body> <h1> Hello world! </br> Key is ${key} </h1> </body> </html>
Service&Dao-객체구현
- Web Application 준비
New
->Project
->Spring Legacy Project
->Spring MVC Project
한글 처리
src
->main
->webapp
->WEB-INF
-> 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> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- ... -->
- CharacterEncodingFilter 를 encodingFilter 라는 이름으로 이용
- encodingFilter 는 모든 경로(/*)에 대하여 이 필터를 거쳐 동작하도록 설정
서비스 객체 구현
new 연산자를 이용한 service 객체 생성 및 참조
MemberService service = new MemberService();
스프링 설정파일을 이용한 서비스 객체 생성 및 의존 객체 자동 주입
<beans:bean id="service" class="com.bs.lec17.member.service.MemberService"></beans:bean>
@Autowired MemberService service;
Annotation을 이용해서 서비스 객체 생성 및 의존 객체 자동 주입
실무에서도 자주 쓰이는 좋은 방법
@Service
OR@Component
OR@Repository
- Service 객체에 Annotation 명시(Service Annotation이 가독성이 좋음)
// Service.java @Service @Component @Repository public class MemberService implements IMemberService { }
// Controller.java @Autowired MemberService service;
@Repository 특정이름 지정하는 방법
// Service.java @Repository("memService") public class MemberService implements IMemberService { }
// Controller.java @Resource(name="memService") MemberService service;
DAO 객체 구현
어노테이션을 이용해서 DAO 객체 생성 및 의존 객체 자동 주입
@Component
OR@Repository
를 이용해서 자동으로 Spring Contatiner에 생성되도록 명시// Dao.java @Component @Repository public class MemberDao implements IMemberDao { }
// Controller.java @Autowired MemberDao dao;
Controller-객체-구현-I
Web Application
@RequestMapping을 이용한 URL 맵핑
메소드에 @RequestMapping Annotation 적용 시
http://localhost:8090/lec18/memJoin
->memJoin()
실행
요청 파라미터
// MemberController.java @RequestMapping(value="/memJoin", method=RequestMethod.POST) /////////////////////////////////////// // :star2:. 커멘드 객체를 이용한 HTTP 전송 정보 얻기 /* 사용자가 html에서 정보를 날리면 Member.java 커멘드 객체의 setter가 작동하여 setter 메소드가 실행되고, property에 값이 들어가게 됨. 코드 양이 많이 줄어들어서 많이 사용되는 방법. 자동으로 getter, setter 가 작동하고, Controller, View 단에서 모두 사용 가능 */ public String memJoin(Member member) {} service.memberRegister(member.getMemId(), member.getMemPw(), ...); return "memJoinOk"; } /* 단, 이 경우 .jsp 에서도 커멘드 객체를 이용하여 값을 받아오도록 설정이 필요(getter 작동) memJoinOk.jsp <h1> memJoinOk </h1> ID : ${member.memId}<br /> PW : ${member.memPw}<br /> <!-- --> */ /////////////////////////////////////// // 1. HttpServletRequest 객체를 이용한 HTTP 전송 정보 얻기 // HttpServletRequest 객체를 이용하여 HTTP 전송 정보를 얻을 수 있음(.getParameter()) public String memJoin(Model model, HttpServletRequest request) { String memId = request.getParameter("memId"); String memPw = request.getParameter("memPw"); String memMail = request.getParameter("memMail"); String memPhone1 = request.getParameter("memPhone1"); String memPhone2 = request.getParameter("memPhone2"); String memPhone3 = request.getParameter("memPhone3"); service.memberRegister(memId, memPw, memMail, memPhone1, memPhone2, memPhone3); model.addAttribute("memId", memId); model.addAttribute("memPw", memPw); model.addAttribute("memMail", memMail); model.addAttribute("memPhone", memPhone1 + " - " + memPhone2 + " - " + memPhone3); return "memJoinOk"; } /////////////////////////////////////// // 2. 요청 파라미터에 @RequestParam Annotation을 이용한 HTTP 전송 정보 얻기 public String memJoin(Model model, @RequestParam("memId") String memId, @RequestParam("memPw") String memPw ...) { service.memberRegister(memId, memPw, memMail, memPhone1, memPhone2, memPhone3); model.addAttribute("memId", memId); model.addAttribute("memPw", memPw); model.addAttribute("memMail", memMail); model.addAttribute("memPhone", memPhone1 + " - " + memPhone2 + " - " + memPhone3); return "memJoinOk"; } /////////////////////////////////////// // 3. @RequestParam 세부 속성을 이용한 HTTP 전송 정보 얻기 /* @RequestParam Annotation 의 required 속성은 값이 넘어어지 않더라도 exception이 발생하지 않 고, defaultValue는 값이 넘어오지 않았을 때, 기본적으로 사용되는 값을 명시(보통 JSP 단에서 처리하므 로 서버에서는 잘 사용되지 않음) */ public String memJoin(Model model, @RequestParam("memId") String memId, @RequestParam(value = "memPw", required = false, defaultValue = "1234") String memPw .. ) { service.memberRegister(memId, memPw, memMail, memPhone1, memPhone2, memPhone3); model.addAttribute("memId", memId); model.addAttribute("memPw", memPw); model.addAttribute("memMail", memMail); model.addAttribute("memPhone", memPhone1 + " - " + memPhone2 + " - " + memPhone3); return "memJoinOk"; }
<!-- memJoin.html --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>Member Join</h1> <form action="/lec17/memJoin" method="post"> ID : <input type="text" name="memId" ><br /> PW : <input type="password" name="memPw" ><br /> MAIL : <input type="text" name="memMail" ><br /> PHONE : <input type="text" name="memPhone1" size="5"> - <input type="text" name="memPhone2" size="5"> - <input type="text" name="memPhone3" size="5"><br /> <input type="submit" value="Join" > <input type="reset" value="Cancel" > </form> <a href="/lec17/resources/html/login.html">LOGIN</a> <a href="/lec17/resources/html/index.html">MAIN</a> </body> </html>
Controller에 중복되는 공통된 경로(/member)가 있을 경우
Class에도 @RequestMapping Annotation 적용 가능
Before
<!-- memJoin.html --> <!DOCTYPE html> <!-- ... --> <body> <h1>Member Join</h1> <form action="/lec17/member/memJoin" method="post"> <!-- ... --> </body> </html>
// MemberController.java // ... @Controller public class MemberController { @Resource(name="memService") MemberService service; @RequestMapping(value="/member/memJoin", method=RequestMethod.POST) // ... } @RequestMapping(value="/member/memLogin", method=RequestMethod.POST) public String memLogin(Model model, HttpServletRequest request) { // ... }
After
```java // MemberController.java
// …
@Controller
@RequestMapping("/member")
public class MemberController {
@Resource(name="memService")
MemberService service;
@RequestMapping(value="/memJoin", method=RequestMethod.POST)
// ...
}
@RequestMapping(value="/memLogin", method=RequestMethod.POST)
public String memLogin(Model model, HttpServletRequest request) {
// ...
}
```
Controller-객체-구현-II
@ModelAttribute
커맨드 객체 이름변경
@ModelAttribute Annotation을 이용하면 커멘드 객체의 이름을 변경할 수 있고,
이렇게 변경된 이름은 뷰에서 커멘드 객체를 참조할 때 사용
- Before
// MemberController.java (Controller) public String memJoin(Member member) { }
<!-- memJoinOk.jsp (View) --> <!-- ... --> <body> <h1> memJoinOk </h1> ID : ${member.memId} <br /> PW : ${member.memPw} <br /> Mail : ${member.memMail} <br /> PHONE : ${member.memPhone1}-${member.memPhone2}-${member.memPhone1} <br /> <!-- ... -->
- After
// MemberController.java (Controller) public String memJoin(@ModelAttribute("mem") Member member) {}
<!-- memJoinOk.jsp (View) --> <!-- ... --> <body> <h1> memJoinOk </h1> ID : ${mem.memId} <br /> PW : ${mem.memPw} <br /> Mail : ${mem.memMail} <br /> PHONE : ${member.memPhone1}-${member.memPhone2}-${member.memPhone1} <br /> <!-- ... -->
공통적으로 무조건 실행되는 method
- @ModelAttribute Annotation이 적용된 method는 공통적으로 무조건 실행
- 다른 method가 호줄되더라도 같이 호출 (View에서 같이 써먹을 수 있음)
// MemberController.java (Controller) // ... @ModelAttribute("serverTime") public String getServerTime(Locale locale) { Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale); return dateFormat.format(date); } // ..
<!-- memRemoverOk.jsp --> <body> <h1> memRemoveOk </h1> ID : ${mem.memId}<br /> <P> The time on the server is ${serverTime}. </P> <!-- ... -->
Model & ModelAndView
컨트롤러에서 뷰에 데이터를 전달하기 위해 사용되는 객체로 Model과 ModelAndView가 있음
Model
객체의 차이점에서 Model은 뷰에 데이터만을 전달하기 위한 객체
Model에 데이터를 추가하는 방식, Data Type은 String, View 이름을 return에 명식
MemberController.java
// ... @RequestMapping(value = "/memModify", method = RequestMethod.POST) public String memModify(Model model, Member member) { Member[] members = service.memberModify(member); model.addAttribute("memBef", members[0]); model.addAttribute("memAft", members[1]); return "memModifyOk"; } // ...
memModifyOk.jsp
<!-- ... --> ID : ${memBef.memId} <br /> PW : ${memBef.memPw} <br /> ID : ${memAft.memId} <br /> PW : ${memAft.memPw} <br /> <!-- ... -->
ModelAndView
ModelAndView는 데이터와 뷰의 이름을 함께 전달하는 객체
ModelAndView 객체 생성, 객체에 데이터와 View 이름 추가, Data Type은 ModelAndView, ModelAndView 이름을 return에 명시
MemberController.java
// ... @RequestMapping(value = "/memModify", method = RequestMethod.POST) public ModelAndView memModify(Member member) { Member[] members = service.memberModify(member); ModelAndView mav = new ModelAndView(); mav.addObject("memBef", members[0]); mav.addObject("memAft", members[1]); mav.setViewName("memModifyOk"); return mav; } // ...
memModifyOk.jsp (View는 Model과 동일)
<!-- ... --> ID : ${memBef.memId} <br /> PW : ${memBef.memPw} <br /> ID : ${memAft.memId} <br /> PW : ${memAft.memPw} <br /> <!-- ... -->