본문 바로가기

카테고리 없음

referenceData()를 이용하여 폼뷰에 회원인증오류 출력하는 예

사용자 삽입 이미지



Spring의 커스텀 태그를 이용하지 않고 회원인증 오류를 폼뷰에 출력하는 예

dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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-2.5.xsd">

<bean name="/hello.htm"
 class="test.HelloController"/>
 
<bean name="authenticator"
 class="test.Authenticator"/>
 
<bean name="/login.htm"
     class="test.LoginFormController"
     p:authenticator-ref="authenticator"
     p:commandClass="test.LoginCommand"
     p:successView="loginSuccess"
     p:formView="loginForm" />

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 <property name="prefix" value="/"/>
 <property name="suffix" value=".jsp"/>       
</bean>

</beans>




LoginFormController.java

package test;

import java.util.*;

import javax.servlet.http.*;

import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.*;
/* SimpleFormController클래스는 속성으로 successView, formView를 가지고 있기 때문에
 * 폼데이터 검증에 성공하면 successView로 등록된 JSP를 출력할 수 있고, 검증에 실패하면
 * formView로 등록된  JSP를 출력하여 다시 폼을 보여 줄 수 있다.
 * 폼 검증에 성공할 시에는 정상적으로 ModelAndView객체를 리턴해 주면 되고,
 * 폼 검증에 실패시에는 showForm()을 호출하여 리턴된 ModelAndView객체(formView가 설정됨)
 * 를 다시 리턴하면 폼이 다시 출력된다.
 */
public class LoginFormController extends SimpleFormController {
 
 /*회원인증을 위해 개발자가 정의한 클래스*/
 private Authenticator authenticator;

 /*DI용 메소드*/
 public void setAuthenticator(Authenticator authenticator) {
  this.authenticator = authenticator;
 }

 @Override
 protected ModelAndView onSubmit(HttpServletRequest request,
   HttpServletResponse response, Object command, BindException errors)
   throws Exception {

  System.out.println("onSubmit()");
  LoginCommand cmd = (LoginCommand) command;
  try{
   /* 회원인증에 실패하면 아래의 메소드는 Exception을 발생하도록 되어있다*/
   authenticator.authenticate(cmd.getId(), cmd.getPwd(), errors); // 회원인즘
   ModelAndView mav = new ModelAndView();
   mav.setViewName(getSuccessView());
   mav.addAllObjects(errors.getModel());
   return mav; // 회원인증에 성공하면 successView가 화면에 출력된다
  }catch(Exception e){
   System.out.println("catch()");
  }

  return showForm(request, response, errors); //회원인증에 실패시 formView가 화면에 출력된다.
 }

 /*
  * (non-Javadoc)
  * @see org.springframework.web.servlet.mvc.SimpleFormController#referenceData(javax.servlet.http.HttpServletRequest, java.lang.Object, org.springframework.validation.Errors)
  * referenceData()메소드는 showForm()에서 formView를 화면에 보여주기 전에
  * 이 메소드를 호출하여 그 결과 리턴되는 Map객체의 내용을 뷰로 포워드해
  * 주기 때문에 폼이 화면에 나타나기 전에 뷰에 보여줄 데이터를 준비하는 용도로 사용하면 된다.
  * 여기서는 인증오류로 인해서 폼뷰가 다시 화면에 출력될 때 인증오류 문장을 출력하기 위해 사용한다.
  */
@Override
protected Map referenceData(HttpServletRequest request, Object command,
  Errors errors) throws Exception {
 Map map = null;
 if(errors.hasFieldErrors()){
  System.out.println("필드오류");
  map = super.referenceData(request, command, errors);
  if(map==null) map = new HashMap();
 
  /* errors.rejectValue("id", null)과 같이 에러를 추가한 경우에는 true*/
  if(errors.getFieldError("id")!=null){
   map.put("loginFail", "아이디, 암호를 확인해 주세요");
   /*jsp에서 ${loginFail}과 같은 방법으로 메시지를 출력할 수 있다 */
  }
 }
 return map;
}

}




Authenticator.java

package test;

import java.sql.*;

import org.springframework.validation.BindException;

public class Authenticator {
 
 public void authenticate(String id, String pwd, BindException errors)throws Exception{

  Connection conn = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;

  String jdbc_driver = "oracle.jdbc.OracleDriver";
  String db_url = "jdbc:oracle:thin:@micropilot.co.kr:1521:ORCL";
 
  try{
    Class.forName(jdbc_driver);
    conn = DriverManager.getConnection(db_url,"scott","tiger");

    String sql = "select * from member where id=? and pwd=?";
    pstmt = conn.prepareStatement(sql);
    pstmt.setString(1, id);
    pstmt.setString(2, pwd);
    rs = pstmt.executeQuery();
    if(!rs.next()) {
     System.err.println("회원인증실패");
     errors.rejectValue("id", null); //폼 필드이름만 사용해야 errors.hasFieldErrors()에서 true가 리턴됨
     throw new Exception("회원인증 실패");
    }
    System.out.println("Authenticate:회원인증성공");
  }catch(SQLException sqle){
  sqle.printStackTrace();
  }finally{
   try{
    if(rs!=null) rs.close();
    if(pstmt!=null) pstmt.close();
    if(conn!=null) conn.close();
   }catch(SQLException e){}
  }
 }
}




loginForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="EUC-KR"%>

<%@ page import="java.util.*"  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>로그인 폼</title>
</head>
<body><center><br></br>

<%-- referenceData()내에서 추가된 Map의 원소 중 loginFail키의 값 --%>
${loginFail}<br>
<form action="login.htm"  method="post"  >
I D: <input type="text"  name="id"   value="${command.id}"><br></br>
PWD: <input type="password"  name="pwd"  value="${command.pwd}"><br></br>
<input type="submit"  value="로그인">
</form>

</center>
</body>
</html>