UserVO.java

package vo;

import java.io.Serializable;

public class UserVO implements Serializable{
 private String userId = "";
 private String userName = "";
 private String passWord = "";
 private String zipCode = "";
 private String address = "";
 private String email = "";
 private String mobileNumber = "";
 private String birthDay = "";
 private String regiDt = "";
 private String regiId = "";
 private String modiDt = "";
 private String modiId = "";
 
 public String getUserId() {
  return userId;
 }
 public void setUserId(String userId) {
  this.userId = userId;
 }
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 public String getPassWord() {
  return passWord;
 }
 public void setPassWord(String passWord) {
  this.passWord = passWord;
 }
 public String getZipCode() {
  return zipCode;
 }
 public void setZipCode(String zipCode) {
  this.zipCode = zipCode;
 }
 public String getAddress() {
  return address;
 }
 public void setAddress(String address) {
  this.address = address;
 }
 public String getEmail() {
  return email;
 }
 public void setEmail(String email) {
  this.email = email;
 }
 public String getMobileNumber() {
  return mobileNumber;
 }
 public void setMobileNumber(String mobileNumber) {
  this.mobileNumber = mobileNumber;
 }
 public String getBirthDay() {
  return birthDay;
 }
 public void setBirthDay(String birthDay) {
  this.birthDay = birthDay;
 }
 public String getRegiDt() {
  return regiDt;
 }
 public void setRegiDt(String regiDt) {
  this.regiDt = regiDt;
 }
 public String getRegiId() {
  return regiId;
 }
 public void setRegiId(String regiId) {
  this.regiId = regiId;
 }
 public String getModiDt() {
  return modiDt;
 }
 public void setModiDt(String modiDt) {
  this.modiDt = modiDt;
 }
 public String getModiId() {
  return modiId;
 }
 public void setModiId(String modiId) {
  this.modiId = modiId;
 }
 
}



UserRegController.java

package controller;

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import logic.UserInfo;
import org.springframework.dao.DataAccessException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.util.WebUtils;
import vo.UserVO;

public class UserRegController extends SimpleFormController {
 private UserInfo userInfo = null;
 
 public void setUserInfo(UserInfo userInfo) {
  this.userInfo = userInfo;
 }
 
 
 //formBackingObject() / initBinder() / referenceData() : 필요에 따라 오버라이드하여 사용
 @Override
 protected Object formBackingObject(HttpServletRequest request)
   throws Exception {
  // TODO Auto-generated method stub
  
  System.out.println("========== formBackingObject() override ==========");
  System.out.println("화면 표시용의 출력 폼으로서, 사용하는 command를 커스터마이즈할 수 있음");
  return super.formBackingObject(request);
 }
 
 @Override
 protected void initBinder(HttpServletRequest request,
   ServletRequestDataBinder binder) throws Exception {
  // TODO Auto-generated method stub
  
  System.out.println("========== initBinder() override ==========");
  System.out.println("command에 Date형, Number형, Boolean형 등의 프로퍼티가 존재하는 경우에 필요한 변환 처리를 기술");
  super.initBinder(request, binder);
 }
 

  
 //POST
 @Override
 protected ModelAndView onSubmit(HttpServletRequest request,
   HttpServletResponse response, Object command, BindException bindException)
   throws Exception {
  // TODO Auto-generated method stub
  
  System.out.println("========== onSubmit() override ==========");

  UserVO userVo = (UserVO)command;
  
  try{
   userInfo.insertUserInfo(userVo);

   //session에 회원정보 공유
   WebUtils.setSessionAttribute(request, "USER_INFO", userVo);
   
   ModelAndView modelAndView = new ModelAndView(getSuccessView());
   modelAndView.addObject(getCommandName(), userVo);
   
   System.out.println("CommandName : " + getCommandName());
   
   return modelAndView;
   
  }catch(DataAccessException e){
   System.out.println("exception : " + e.toString());
   return showForm(request, response, bindException);
   
  }
 }
 
 
 @Override
 protected Map referenceData(HttpServletRequest request) throws Exception {
  // TODO Auto-generated method stub
  
  System.out.println("========== referenceData() override ==========");
  System.out.println("command 이외의 화면에 표시하기 위하여 모델을 설정할 수 있음");
  return super.referenceData(request);
 }
}


============================== 데이터 처리시 에러가 발생했을 경우 ==============================
========== formBackingObject() override ==========
화면 표시용의 출력 폼으로서, 사용하는 command를 커스터마이즈할 수 있음
========== initBinder() override ==========
command에 Date형, Number형, Boolean형 등의 프로퍼티가 존재하는 경우에 필요한 변환 처리를 기술
========== onSubmit() override ==========
exception : org.springframework.dao.DataIntegrityViolationException: SqlMapClient operation; SQL [];  
--- The error occurred in ../classes/sql/oracle/user.xml. 
--- The error occurred while applying a parameter map. 
--- Check the user.insertUserInfo-InlineParameterMap. 
--- Check the statement (update failed). 
--- Cause: java.sql.SQLException: ORA-00001: 무결성 제약 조건(ANGELOS1981.PK_USER)에 위배됩니다
; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:  
--- The error occurred in ../classes/sql/oracle/user.xml. 
--- The error occurred while applying a parameter map. 
--- Check the user.insertUserInfo-InlineParameterMap. 
--- Check the statement (update failed). 
--- Cause: java.sql.SQLException: ORA-00001: 무결성 제약 조건(ANGELOS1981.PK_USER)에 위배됩니다

========== referenceData() override ==========
command 이외의 화면에 표시하기 위하여 모델을 설정할 수 있음


============================== 데이터 처리시 에러가 없을 경우 ==============================
========== formBackingObject() override ==========
화면 표시용의 출력 폼으로서, 사용하는 command를 커스터마이즈할 수 있음
========== initBinder() override ==========
command에 Date형, Number형, Boolean형 등의 프로퍼티가 존재하는 경우에 필요한 변환 처리를 기술
========== onSubmit() override ==========
CommandName : user

■ SimpleFormController 클래스의 처리 흐름은 이곳을 참고


UserInfo.java

package logic;

import vo.UserVO;

public interface UserInfo {
 void insertUserInfo(UserVO userVo);
}



UserInfoImpl.java

package logic;

import dao.UserRegDao;
import vo.UserVO;

public class UserInfoImpl implements UserInfo {

 private UserRegDao userRegDao = null;
 
 public void setUserRegDao(UserRegDao userRegDao) {
  this.userRegDao = userRegDao;
 }
 
 @Override
 public void insertUserInfo(UserVO userVo) {
  // TODO Auto-generated method stub

  userRegDao.insertUserInfo(userVo);
 }

}



UserRegDao.java

package dao;

import vo.UserVO;

public interface UserRegDao {
 void insertUserInfo(UserVO userVo);
}



UserRegDaoImpl.java

package dao;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import vo.UserVO;

public class UserRegDaoImpl extends SqlMapClientDaoSupport implements
  UserRegDao {

 @Override
 public void insertUserInfo(UserVO userVo) {
  // TODO Auto-generated method stub
  
  //throws DataAccessException

  getSqlMapClientTemplate().insert("user.insertUserInfo", userVo);
 }

}



web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>myHome03</display-name>


 <filter>
  <filter-name>CharacterEncodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>EUC-KR</param-value>
  </init-param>
  <init-param>
   <param-name>forceEncoding</param-name>
   <param-value>true</param-value>
  </init-param>
 </filter>

 <filter-mapping>
  <filter-name>CharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>


 <listener>
  <listener-class>
   org.springframework.web.context.ContextLoaderListener
  </listener-class>
 </listener>

 <context-param>
  <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
 </context-param>


 <servlet>
  <servlet-name>myHome03</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 

 <servlet-mapping>
  <servlet-name>myHome03</servlet-name>
  <url-pattern>*.html</url-pattern>
 </servlet-mapping>


</web-app>



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">

 
 <!-- 1. dataSource 생성 -->
 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
  <property name="url" value="jdbc:oracle:thin:@111.222.333.444:1521:orcl"></property>
  <property name="username" value="xxxxxxx"></property>
  <property name="password" value="yyyyyyy"></property>
 </bean>


 <!-- 2. ibatis 코딩을 지원해주는 SqlMapClient 빈 생성 -->
 <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="dataSource" ref="dataSource"></property>
  <property name="configLocation" value="/WEB-INF/SqlMapConfig.xml"></property>
 </bean>


 <!-- 3. 공통 빈 생성  - 그외의 빈은  myHome02-servlet.xml에서 설정 -->
 
 
</beans>



myHome03-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">

 
 <!-- HandlerMapping 설정 : SimpleUrlHandlerMapping -->
 <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="/userReg.html">userRegController</prop>
   </props>
  </property>
 </bean>


 <!-- ViewResolver 설정 : ResourceBundleViewResolver -->
 <!-- ResourceBundleViewResolver 클래스는 view의 인터페이스의 구현 클래스의 지정과 이동장소 view의 url맵핑을 프로퍼티 파일에서 관리 --> 
 <bean id="resourceBundleViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
  <property name="basename">
   <value>myhome03_view</value>
  </property>
 </bean>

 
 <!-- 각종 bean 설정 -->
 <bean id="userRegController" class="controller.UserRegController">
  <property name="commandName"><value>user</value></property>
  <property name="commandClass"><value>vo.UserVO</value></property>
  <property name="formView"><value>userReg</value></property>
  <property name="successView"><value>userRegSuccess</value></property>

  <property name="userInfo" ref="userInfo"></property>
 </bean>

 <bean id="userInfo" class="logic.UserInfoImpl">
  <property name="userRegDao" ref="userRegDao"></property>
 </bean>
 
 <bean id="userRegDao" class="dao.UserRegDaoImpl">
  <property name="sqlMapClient" ref="sqlMapClient"></property>
 </bean>


</beans>

■ ResourceBundleViewResolver 클래스
  - view 인터페이스의 구현 클래스의 지정과 이동장소 view의 url의 맵핑을 프로퍼티 파일에서 관리
  - ResourceBundleViewResolver 클래스에서 사용하는 프로퍼티 파일명은 basename 프로퍼티로 지정


myhome03_view.properties

#userRegist View
userReg.class=org.springframework.web.servlet.view.JstlView
userReg.url=/WEB-INF/jsp/userReg.jsp

#userRegSuccess View
userRegSuccess.class=org.springframework.web.servlet.view.JstlView
userRegSuccess.url=/WEB-INF/jsp/userRegSuccess.jsp



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>

 <settings useStatementNamespaces="true"/>

   <sqlMap resource="../classes/sql/oracle/user.xml"/>

</sqlMapConfig>



user.xml

<?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">

<!-- Mapper 파일 -->

<!--
 이름 충돌을 방지하기 위해 namespace를 사용
 SqlMapConfig.xml에 <settings useStatementNamespaces="true"/> 설정이 지정되어 있는 경우
 sql구문을 찾을 때 반드시 namespace값을 포함해야 한다.
-->
<sqlMap namespace="user">

 <insert id="insertUserInfo" parameterClass="vo.UserVO">
  INSERT
  INTO USERS(USERID, USERNAME, PASSWORD, ZIPCODE, ADDRESS, EMAIL, MOBILENUMBER, BIRTHDAY, REGIDT, REGIID, MODIDT, MODIID)
  VALUES(#userId#, #userName#, #passWord#, #zipCode#, #address#, #email#, #mobileNumber#, #birthDay#, SYSDATE, 'ADMIN', SYSDATE, 'ADMIN')
 </insert>
   
</sqlMap>



userReg.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ page session="false" %>   
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<html>
<head>
<title>User Reg Page</title>
</head>
<body>
 <div align="center">
  <h2>회원 가입</h2>
  <form action="userReg.html" method="post">
  <table border="1">
   <tr height="30px">
    <td>ID</td>
    <td>
     <spring:bind path="user.userId"><input type="text" name="userId" value=""/></spring:bind>
    </td>
   </tr>
   <tr height="30px">
    <td>PW</td>
    <td>
     <spring:bind path="user.passWord"><input type="password" name="passWord" value=""/></spring:bind>
    </td>
   </tr>
   <tr height="30px">
    <td>성명</td>
    <td>
     <spring:bind path="user.userName"><input type="text" name="userName" value=""/></spring:bind>
    </td>
   </tr>
   <tr height="30px">
    <td>주소</td>
    <td>
     <spring:bind path="user.address"><input type="text" name="address" value=""/></spring:bind>
    </td>
   </tr>
  </table>
  <table>
   <tr>
    <td><input type="submit" name="submit" value="reg"></input></td>
    <td><input type="reset" name="reset" value="reset"></input></td>
   </tr>
  </table>
  </form>
 </div>
</body>
</html>


userRegSuccess.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ page session="true" %>   
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<html>
<head>
<title>User Reg Success</title>
</head>
<body>
 <div align="center">
  <b>회 원 가 입 완 료</b>
  
  <table border="1">
   <tr>
    <td>ID</td>
    <td><c:out value="${user.userId}"></c:out> </td>
   </tr>
   <tr>
    <td>이름</td>
    <td><c:out value="${user.userName}"></c:out> </td>
   </tr>
  </table>
 </div>
</body>
</html>




[참고자료] Spring 2.5 실무 프로그래밍(성윤정)

+ Recent posts