BeanNameUrlHandlerMapping말고 다른 HandlerMapping ( SimpleUrlHandlerMapping ) 을 덧붙여보자.
AbstractCommandController 도 테스트해보자. (Spring 3.0에서는 주로 AbstractController와 @를 사용)
AbstractCommandController는 페이지에(form 태그에) 값을 넘기는데 유용해.
그러니까..
SimpleUrlHandlerMapping, AbstractCommandController, iBatis를 사용해서 간단하게 사원정보(t_emp)를 입력하게 해보자.
먼저 mapping.xml로 파일을 분리하고 HandlerMapping 를 이용해보자.
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- BeanNameUrlHandlerMapping : 원래 이렇게 지정해주는거야. 안하면 Default로 이게 있는거지. --> <bean id="beanNameUrlHandler" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="order" value="1" /> <!-- 여러 handlerMapping간에 우선 순위줄때.. --> </bean> <!-- simpleUrlHandlerMapping --> <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/registerForm.do">RegisterForm</prop> </props> </property> <property name="order" value="2" /> </bean> </beans>
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 멀티액션 2.5 버전 --> <bean id="paramResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"> <property name="paramName" value="genre" /> </bean> <bean name="/music.do" class="test.MusicController" > <property name="methodNameResolver" ref="paramResolver" /> </bean> <!-- 원래 이렇게 지정해주는거야. 안하면 Default로 이게 있는거지. --> <bean id="beanNameUrlHandler" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="order" value="1" /> <!-- 여러 handlerMapping간에 우선 순위줄때.. --> </bean> <!-- bean을 다른 파일로 분리해보자 --> <import resource="hello.xml" /> <import resource="mapping.xml" /> <!-- viewResolver 추가 : P 옵션 추가 후 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/" p:suffix=".jsp" /> <!-- simpleUrlHandlerMapping 사용 --> <bean id="RegisterForm" class="test.EmployeeRegister" /> </beans>
위에서 설정한 클래스(test.EmployeeRegister)구현한다. 우선 기존의 AbstractController를 사용한다. 그냥 입렵폼만 띄울거야.
package test; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; public class EmployeeRegister extends AbstractController { @Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { // TODO Auto-generated method stub //입력폼만 띄울거야.. return new ModelAndView("view/empinsert"); } }
입력폼(empinsert.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="registerAction.do" method="post"> <table> <caption>사원등록</caption> <tr> <th>사원이름</th> <td><input type="text" name="ename" /></td> </tr> <tr> <th>급여</th> <td><input type="text" name="sal" /></td> </tr> <tr> <th>부서번호</th> <td><select name="deptno"> <option value="10">운영부</option> <option value="20">영업부</option> <option value="30">개발부</option> </select></td> </tr> <tr> <td colspan="2"><input type="submit" value="등록" /></td> </tr> </table> </form> </body> </html>
EmpDto 구현
package test; public class EmpDto { private int empno; private String ename; private int sal; private int deptno; public int getEmpno() { return empno; } public void setEmpno(int empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public int getSal() { return sal; } public void setSal(int sal) { this.sal = sal; } public int getDeptno() { return deptno; } public void setDeptno(int deptno) { this.deptno = deptno; } }
Database는 iBatis를 이용해서 구현하기로 했으니 ( 참고 : http://capricasix.tistory.com/entry/120510-2 )
spring-framework-2.5.6.SEC01\lib\ibatis\ibatis-2.3.4.726.jar를 /springmvc/WebContent/WEB-INF/lib에 가져와.
혹시 Database Pool사용할 지 모르니 다음 세 개도 가져와.
- sw\spring-framework-2.5.6.SEC01\lib\jakarta-commons\commons-pool.jar
- sw\spring-framework-2.5.6.SEC01\lib\jakarta-commons\commons-dbcp.jar
- sw\spring-framework-2.5.6.SEC01\lib\jakarta-commons\commons-collections.jar
ibatis-2.3.4.726\simple_example\com\mydomain\data 파일3개(Account.xml,SimpleExample.java,SqlMapConfig.xml) 를
src\ibatis package 만들어서 넣고 수정하자.
database.properties파일 만들고
driver=oracle.jdbc.OracleDriver url=jdbc:oracle:thin:@localhost:1521:xe username=oraclejava password=oraclejava
SqlMapConfig.xml을 수정한다.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <properties resource="ibatis/database.properties" /> <transactionManager type="JDBC" commitRequired="false"> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="${driver}" /> <property name="JDBC.ConnectionURL" value="${url}" /> <property name="JDBC.Username" value="${username}" /> <property name="JDBC.Password" value="${password}" /> </dataSource> </transactionManager> <sqlMap resource="ibatis/emp.xml" /> </sqlMapConfig>
위에서 설정한대로 Account.xml을 emp.xml로, SimpleExample는 QueryHandler로 rename해놓는다.
이제 insert하는거 만들어보면..
EmpDao Interface를 만들고 insertEmp 메서드를 정의해놔.
package test; public interface EmpDao { public Boolean insertEmp(EmpDto empDto); }
이를 implements하는 EmpDaoImpl을 구현한다.
package test; import ibatis.QueryHandler; import java.sql.SQLException; public class EmpDaoImpl implements EmpDao{ @Override public Boolean insertEmp(EmpDto empDto) { // TODO Auto-generated method stub try { QueryHandler.insertEmp(empDto); return true; } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } } }
QueryHandler에 insertEmp를 구현한다. 예외처리 해주고.
package ibatis; import java.io.IOException; import java.io.Reader; import java.sql.SQLException; import test.EmpDto; import com.ibatis.common.resources.Resources; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; public class QueryHandler { private static SqlMapClient sqlMapper; static { try { Reader reader = Resources.getResourceAsReader("ibatis/SqlMapConfig.xml"); sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader); reader.close(); } catch (IOException e) { // Fail fast. throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e); } } public static void insertEmp(EmpDto empDto) throws SQLException { // TODO Auto-generated method stub sqlMapper.insert("insertEmp", empDto); } }
emp.xml에 insertEmp를 구현한다.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="emp"> <insert id="insertEmp" parameterClass="test.EmpDto" > INSERT INTO T_EMP(empno, ename, sal, deptno) VALUES(empseq.nextVal, #ename#, #sal#, #deptno#) </insert> </sqlMap>
여기까지 DB에 넣는 것은 됐고..
다시 EmpRegister의 흐름을 보면 emplist.jsp에서 입력하고 registerAction.do가 호출되면 BeanNameUrlHandlerMapping에서 못찾고 simpleUrlHandlerMapping에서 찾겠지.
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- BeanNameUrlHandlerMapping : 원래 이렇게 지정해주는거야. 안하면 Default로 이게 있는거지. --> <bean id="beanNameUrlHandler" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="order" value="1" /> <!-- 여러 handlerMapping간에 우선 순위줄때.. --> </bean> <!-- simpleUrlHandlerMapping --> <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/registerForm.do">RegisterForm</prop> <prop key="/registerAction.do">RegisterAction</prop> </props> </property> <property name="order" value="2" /> </bean> </beans>
그럼 이제 RegisterAction을 찾으니 등록해줘야지.
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 멀티액션 2.5 버전 --> <bean id="paramResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"> <property name="paramName" value="genre" /> </bean> <bean name="/music.do" class="test.MusicController" > <property name="methodNameResolver" ref="paramResolver" /> </bean> <!-- 원래 이렇게 지정해주는거야. 안하면 Default로 이게 있는거지. --> <bean id="beanNameUrlHandler" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="order" value="1" /> <!-- 여러 handlerMapping간에 우선 순위줄때.. --> </bean> <!-- bean을 다른 파일로 분리해보자 --> <import resource="hello.xml" /> <import resource="mapping.xml" /> <!-- viewResolver 추가 : P 옵션 추가 후 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/" p:suffix=".jsp" /> <!-- simpleUrlHandlerMapping 사용 --> <bean id="RegisterForm" class="test.EmployeeRegister" /> <bean id="RegisterAction" class="test.EmployeeRegisterAction" /> </beans>
그런데 test.EmployeeRegisterAction를 만들자. 이번에는 AbstractCommandController 를 사용 할거야.
package test; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.validation.BindException; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractCommandController; public class EmployeeRegisterAction extends AbstractCommandController{ public EmployeeRegisterAction() { setCommandClass(EmpDto.class); //생성자에서 command객체생성 setCommandName("EmpDto"); } //EmpDao도 사용해야 하는데 주입받으면 되겠지. //주입받기위해 private로 선언하고 setter만들어주자. private EmpDao empDao; public void setEmpDao(EmpDao empDao) { this.empDao = empDao; } @Override protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException bindException) throws Exception { // TODO Auto-generated method stub /* 넘어오는 Object를 바로 받아들일 수 있어. 전 페이지에서 넘긴 것이 무조건 upcasting되서 Object command에 들어가.. 그럼 컬럼 이름만 일치하면 downcasting으로 dto로 바로 받을 수 있어. */ EmpDto empDto = (EmpDto) command; //받아온dto로 insert작업 boolean result = empDao.insertEmp(empDto); ModelAndView mav= new ModelAndView(); if (result == true) { mav.setViewName("view/empview"); mav.addObject("empDto", empDto); } else { mav.setViewName("view/result"); mav.addObject("msg", "입력에러"); } return mav; } }
EmployeeRegisterAction에 EmpDao를 주입
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 멀티액션 2.5 버전 --> <bean id="paramResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"> <property name="paramName" value="genre" /> </bean> <bean name="/music.do" class="test.MusicController" > <property name="methodNameResolver" ref="paramResolver" /> </bean> <!-- 원래 이렇게 지정해주는거야. 안하면 Default로 이게 있는거지. --> <bean id="beanNameUrlHandler" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="order" value="1" /> <!-- 여러 handlerMapping간에 우선 순위줄때.. --> </bean> <!-- bean을 다른 파일로 분리해보자 --> <import resource="hello.xml" /> <import resource="mapping.xml" /> <!-- viewResolver 추가 : P 옵션 추가 후 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/" p:suffix=".jsp" /> <bean id="EmpDao" class="test.EmpDaoImpl" /> <!-- simpleUrlHandlerMapping 사용 --> <bean id="RegisterForm" class="test.EmployeeRegister" /> <bean id="RegisterAction" class="test.EmployeeRegisterAction" > <property name="empDao" ref="EmpDao" /> </bean> </beans>
성공,실패 시 각 view를 구현한다.
<%@ 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> <table> <caption>사원정보</caption> <tr> <th>사원이름</th> <td><input type="text" name="ename" value="${empDto.ename}" /></td> </tr> <tr> <th>급여</th> <td><input type="text" name="sal" value="${empDto.sal}" /></td> </tr> <tr> <th>부서번호</th> <td>${empDto.deptno}</td> </tr> </table> </body> </html>
<%@ 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> <script type="text/javascript"> alert('${msg}'); location.href = '${url}' </script> </body> </html>
실행하기 편하게 하나 만들어놔..
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <%-- <% response.sendRedirect("HelloWorld.do"); %> --%> <%-- <% response.sendRedirect("music.do?genre=jazz"); %> --%> <ol> <li><a href="HelloWorld.do">Hello World</a></li> <li><a href="music.do?genre=rock">rock</a></li> <li><a href="music.do?genre=funk">funk</a></li> <li><a href="music.do?genre=jazz">jazz</a></li> <li><a href="registerForm.do">SimpleUrlHandlerMapping : AbstractCommandController</a></li> </ol> </body> </html>
정상적으로 실행됨을 확인
.
.
.
.
springweb3에서 EmpDao, EmpDaoImpl, EmpDto 복사해와.