2014년 11월 19일 수요일

[심심풀이]Struts 더 간단한 로그인 예제[자바JSP/Servlet/JDBC/MiPlatform/XPlatform/교육/JSP/서블릿강좌/Spring교육잘하는곳/자바,JSP/spring/교육추천/JSP/JDBC실무교육]

Struts를 이용한 로그인 예제(2) 

이번에는 이전에 만들어본 로그인 기능에 몇 가지 요소를 붙여 기능을 완성 시켜 보도록 하겠습니다. 우선 개략적인 기능을 살펴 보면… 

먼저 main.jsp로 접근을 합니다. 이때 사용자가 로그인을 이미 한 사용자라면(세션에서 확인) “반갑습니다. ~~~님” 라는 메시지를 출력하고 logout을 하이퍼링크 걸어서 보여주며, 로그인을 하지 않은 사용자라면 단지 “반갑습니다” 메시지를 출력 하면서 login을 하이퍼링크 걸어서 보여 줍니다. 

사용자가 로그인을 하지 않은 상태에서 접근 해 login을 클릭 하면 login화면이 나타나며 이곳에서 로그인 처리를 하게 됩니다. 이때 사용자 ID가 “jclee”라고 입력만 하면 본 예제에서는 인증이 되게 처리를 하였습니다. 

login에서 action의 처리는 LoginAction이 했으며 ogout에 대한 action의 LogoffAction에서 처리를 하였습니다. 물론 인증을 하는 부분은 LoginAction에서 여전히 처리 하고 있습니다. (이 부분은 다음 예제를 할때 모델로 빼 보도록 하겠습니다.) 

아래의 절차대로 하나씩 만들어 보도록 하겠습니다. 

우선 하나씩 따라 하시면서 이해 하도록 하죠^^ 

우선 이클립스에서 Login이라는 톰캣 프로젝트를 하나 만들고 시작 하세요. 

1.        main.jsp 

<%@ page language="java" %> 
<%@ page pageEncoding="euc-kr" %> 
<!-- 최초 사용자가 접속하게 되는 페이지 입니다. --> 
<!-- 아래는 import와 동일한 기능을 하는 태그로 태그 확장을 사용 할 수 있도록 합니다 --> 
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> 
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> 
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> 
<html> 
        <head> 
        <title>환영 합니다</title>                
        
        <!-- HTML의 BASE 태그와 같은 것으로써 이는 JSP에는 이미지나 다른 리소스를 참조하는 경우 
        상대 경로를 기술할 때 BASE가 되는 것입니다. --> 
        <html:base/> 
        
        </head> 
        <body> 
                <!-- 현재 세션에 “user”빈이 저장 되어 있는지 확인을 해 있는 경우엔… --> 
                <logic:present scope="session" name="user"> 
                        <h3>반갑습니다.<bean:write name="user" property="id"/>님!</h3> 
                </logic:present> 
                
                <!-- 현재 세션에 “user”빈이 저장 되어 있는지 확인을 해 없는 경우엔… --> 
                <logic:notPresent scope="session" name="user"> 
                        <h3>반갑습니다! 먼저 로그인을 해주세요~</h3> 
                </logic:notPresent> 
                
                <html:errors/> 
                <ul>        
                <! -- 인증이 된 사용자면 “로그아웃” 버튼을 활성화 하고 인증이 되지 않은 사용자인 경우엔 “로그인” 
                버튼을 활성화 하고 있습니다. --> 
                <logic:present scope="session" name="user"> 
                        <li> 
                            <!-- 로그인을 클릭 하게 되면 이동하게 되는 부분에 대해 기술 한 것인데(하이퍼 링크) 
                            “login”은 struts-cinfig.xml에 Forward로써 정의를 하게 됩니다. 
                                이렇게 Config에서 정의 함으로써 추후 생기게 되는 변화에 유연하게 대처 할 수 있는 것입니다. --> 
                                <html:link forward="logoff">로그아웃</html:link> 
                        </li>                        
                </logic:present> 
                <logic:notPresent scope="session" name="user"> 
                        <li> 
                                <html:link forward="login">로그인</html:link> 
                        </li>                        
                </logic:notPresent> 
                </ul> 
        <body> 
</html> 

        

2.        login.jsp 

<%@ page pageEncoding="euc-kr" %> 
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> 
<html> 
<head> 
<title> Login 화면 </title> 
</head> 
<body> 
<!-- 웹서버가 보내는 응답에 오류가 있다면 출력 --> 
<html:errors/> 

<!-- LoginSummit에 대해서는 struts-config.xml에 Mapping을 하게 된다 --> 
<!-- focus="id" 라는 문법에 의해 자동으로  자바스크립트를 생성 합니다. --> 
<html:form action="/LoginSubmit" focus="id"> 
        <table> 
                <tr> 
                        <th align="right">사용자ID</th> 
                        
                        <!-- 아래는 input type=text 와 동일한 기능을 합니다 --> 
                        <td><html:text property="id"/></td> 
                </tr> 
                <tr> 
                        <th align="right">비밀번호</th> 
                        
                        <!-- 만약 로그인을 실패하여 다시 돌아오는 경우 pwd 항목의 값을 비울때는 redisplay="false" 
                        라고 하면 됩니다. HTML의 password 항목과 유사함  --> 
                        <td><html:password property="pwd"/></td> 
                </tr> 
                <tr> 
                        <!-- Submit 버튼과 Reset 버튼을 생성 --> 
                        <td><html:submit/></td> 
                        <td><html:reset/></td> 
                </tr>                                
        </table> 
</html:form> 
</body> 
</html> 


3.        LoginForm.java (폼빈) 

package login2; 

import javax.servlet.http.HttpServletRequest; 

import org.apache.struts.action.ActionErrors; 
import org.apache.struts.action.ActionError; 
import org.apache.struts.action.ActionForm; 
import org.apache.struts.action.ActionMapping; 

public class LoginForm extends ActionForm { 
        private String id=null; 
        private String pwd=null; 
                
        
        public String getId() { 
                return id; 
        } 
        
        public String getPwd() { 
                return pwd; 
        } 
        
        public void setId(String id) { 
                this.id = id; 
        } 
        
        public void setPwd(String pwd) { 
                this.pwd = pwd; 
        } 
        
        /* struts-config.xml 에서 메핑시 validate="true" 라고 설정 되면 아래의 
        validate 함수가 호출 되어 입력되는 값에 대한 validation check를 하게 됩니다. 
        HTTP 요청으로 부터 해당 폼의 값을 set 한 후 아래 메소드가 호출 됩니다. 
        참고로 validate에 위해 반환되는 ActionErrors 객체 역시 Framework에 관련된 클래스 입니다. 
        만약 validate에서 null이나 empty가 아닌 ActionError 객체를 리턴하게 되면 
        login.jsp에 있는 <html:errors/> 태그는 오류를 출력하고 아니면 넘어가게 됩니다... 
        error.id.required, error.pwd.required는 일종의 키값으로  각 Locale마다 고유한 리소스를 가질 수 
        있으므로 메시지에 대해 손쉬운 관리를 제공 합니다. 
        예를들면 error.id.required = 사용자  ID는 필수 입력 항목 입니다. , 이러한 식으로 설정 합니다. 
        */ 

        public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { 
                ActionErrors errors = new ActionErrors(); 
                
                if((id == null) || (id.length()<1)) { 
                        errors.add("error.id.required", new ActionError("error.id.required")); 
                } 
                
                if((pwd == null) || (pwd.length()<1)) { 
                        errors.add("error.pwd.required", new ActionError("error.pwd.required")); 
                } 
                
                return errors;                        
        } 
        

                
        


4.        LoginActoin.java 

package login2; 

import org.apache.struts.action.Action; 
import java.io.IOException; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpSession; 
import javax.servlet.http.HttpServletResponse; 

import login2.LoginForm; 
import login2.Constants; 

import org.apache.struts.action.Action; 
import org.apache.struts.action.ActionErrors; 
import org.apache.struts.action.ActionError; 
import org.apache.struts.action.ActionForm; 
import org.apache.struts.action.ActionMapping; 
import org.apache.struts.action.ActionForward; 
import org.apache.struts.action.ActionServlet; 

/** 
 * @author 이종철 
 */ 
public class LoginAction extends Action { 
        
        public boolean authUser(String id, String pwd) { 
                //이곳에서 디비에 접속해서 ID와 Password가 맞는지 확인 한다. 
                //본 예제에서는 ID가 "jclee"인 경우 무조건 인증이 된다고 보고  true를 리턴 합니다 
                if (id.equals("jclee")) { 
                        return true; 
                } 
                else { 
                        return false; 
                } 
                
        } 
        
        public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) { 
                String id = ((LoginForm)form).getId(); 
                String pwd = ((LoginForm)form).getPwd(); 

                boolean isOK = authUser(id, pwd); 
                
                if (!isOK) { 
                        //인증 실패 
                        ActionErrors errors = new ActionErrors(); 
                        errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.login.invalid")); 
                        saveErrors(request,errors); 
                        return (new ActionForward(mapping.getInput())); 
                } 
                
                
                //인증 성공한 경우 세션에 로그인한 사용자를 저장 
                HttpSession session = request.getSession(); 
                session.setAttribute(Constants.USER_KEY, form); 
                
                //로그를 남기자. 
                StringBuffer buf = new StringBuffer("LoginAction : User --> "); 
                buf.append(id + "logged in session"); 
                servlet.log(buf.toString()); 
                                
                return (mapping.findForward(Constants.SUCCESS));                        
                
        } 

        


5.        LogoffAction.java 


package login2; 

import org.apache.struts.action.Action; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpSession; 
import javax.servlet.http.HttpServletResponse; 

import login2.LoginForm; 

import org.apache.struts.action.ActionForm; 
import org.apache.struts.action.ActionForward; 
import org.apache.struts.action.ActionMapping; 

public class LogoffAction extends Action {        
        
        public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { 
                
                //필요한 어트리뷰트를 뽑아 냅니다. 
                //LoginAction에서 사용자의 로그온개체를 Consants.USER_KEY라는 이름으로 세션에 저장 
                HttpSession session = request.getSession(); 
                LoginForm user = (LoginForm)session.getAttribute(Constants.USER_KEY); 
                
                if (user!= null) { 
                        //로그를 남기자 
                        StringBuffer buf = new StringBuffer("User Logout : " + user.getId()); 
                        servlet.log(buf.toString());                                        
                }                
                
                //사용자의 로그인을 삭제, session.invaidate() 의 경우 션의 모든 것을 무효화 시킴. 
                session.removeAttribute(Constants.USER_KEY); 
                
                //성공적으로 처리 되었음을 알림 
                return (mapping.findForward(Constants.SUCCESS)); 
                
        } 

        



6.        Constants.java (상수 값을 설정 한 곳) 


package login2; 


public class Constants { 
        /** 
        * 로그인한 사용자의 LoginForm이 저장될 세션 범위의 Attriute 이름 
        */ 
        public static final String USER_KEY = "user"; 
        
        /** 
        * ActionForward에서 사용되는 값        
        */ 
        public static final String SUCCESS = "success"; 
        
        /** 
        * ActionForward 로그인 동작을 나타내는 Tocken        
        */ 
        public static final String LOGIN = "login"; 
        
        /** 
        * ActionForward welcome 동작을 나타내는 Tocken        
        */ 
        public static final String WELCOME = "welcome"; 
        
        



7.        application.properties(/WEB-INF/src/resources 에 위치) 
(애플리케이션 전에에 사용될 메시지들을 정리해 놓은 것) 

error.id.required=<li>ID REQUIRED.</li> 
error.pwd.required=<li>PASSWORD REQUIRED</li> 
error.login.invalid=<li>ID/PASSWORD NOT CORRECT</li> 

errors.header=<h3><font color="red">ERROR!</font></h3> 
                  You must correct the following error(s) before proceeding:<UL> 
errors.footer=</ul><hr> 


8.        struts-config.xml 

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> 
<struts-config> 
      
    <!-- ========== Form Bean Definitions ================================== --> 
    <form-beans> 
        <form-bean name="loginForm" type="login2.LoginForm">                  
            <form-property name="pwd" type="java.lang.String" /> 
            <form-property name="id" type="java.lang.String" />            
        </form-bean>            
    </form-beans> 
    
  
    <!-- ========== Global Forward Definitions =============================== --> 
    <global-forwards> 
        <forward name="success" path="/main.jsp" /> 
        <forward name="logoff" path="/logoff.do" /> 
        <forward name="login" path="/login.jsp" /> 
    </global-forwards> 
    
    <!-- ========== Action Mapping Definitions =============================== --> 
    <!-- valiedate를 true라고 함으로써 LoginForm의 validate가 호출 됩니다.            --> 
    <action-mappings> 
            <!-- loginAction에 대한 정의 --> 
        <action          
                path="/LoginSubmit" 
                type="login2.LoginAction" 
            name="loginForm"                        
            validate="true" 
            input="/login.jsp" 
        /> 
        
        <!-- logoffAction에 대한 정의 --> 
        <action          
                path="/logoff" 
                type="login2.LogoffAction"                              
            validate="false"          
        />                      
    </action-mappings>  
    
    <!-- ========== 아래는 스트러츠 Application에서 사용할 Message Resource들을 설정 ====== --> 
    <!-- 확장자가 properties인 application.properties를 만들어 넣으면 된다 ============ --> 
    <message-resources parameter="resources.application"/> 
    
</struts-config> 

요기까지 입니다. 

http://localhost/Login/main.jsp 라고 실행 하세요~ 

1. 이 예제에서는 LoginAction.java에 AuthUser라는 메소드를 통해서  인증을 하고 있는데 이 부분을 Model로 빼서 테스트 해 보시기 바랍니다. 

2. main.jsp에서 인증을 한 경우와 인증을 하지 않은 경우를 세션에서 빈을 통해 확인 하는 데 이 부분을 간단한 커스텀 태그를 이용하여 인증이 안된 사용자가 접근을 하면 곧장 login.jsp로 보내버리고 인증을 한 사용자만 main.jsp로 들어 올 수 있도록 수정 해 보세요~ 

 [100%환급,개발자전문]빅데이터/SQL/자바/스프링/안드로이드/닷…오라클자바…12-272539
 [채용확정무료교육]오라클자바개발잘하는신입뽑기2개월과정,교육…오라클자바…12-111860
53 [평일100%환급7건]Spring,자바&JSP,안드로이드,웹퍼블리싱,C#닷… 오라클자바…03-151664
52 [주말]C#,ASP.NET마스터 오라클자바…01-311757
51 [기업100%환급,평일주간]SQL기초에서스키마오브젝트,PLSQL,힌트… 오라클자바…01-312531
50 [평일주간야간,주말]C기본&자료구조,알고리즘 오라클자바…01-311397
49 [평일주간,평일야간,주말]Spring,MyBatis,Hibernate개발자과정-… 오라클자바…01-191701
48 [평일야간,주말]안드로이드개발자과정(Android기초실무) 오라클자바…01-111584
47 [평일야간,주말주간야간]JAVA,Network&JSP&Spring,MyBatis,Hiber… 오라클자바…01-032101
46 [100%환급,개발자전문]빅데이터/SQL/자바/스프링/안드로이드/닷… 오라클자바…12-272539
45 [평일주간]NoSQL,MongoDB,빅데이터기초과정 오라클자바…12-191813
44 [평일주간야간, 주말]웹퍼블리싱 마스터(HTML5,CSS3,jQUERY,AJAX… 오라클자바…12-141796
43 [채용확정무료교육]오라클자바개발잘하는신입뽑기2개월과정,교육… 오라클자바…12-111860
42 [평일주간]빅데이터하둡기초과정(BigData Hadoop) 오라클자바…12-091457
41 [평일야간]닷넷(C#,Network,ADO.NET,ASP.NET)마스터 오라클자바…12-011683
40 [기업100%환급]오라클&자바웹스프링신입과정3주(SQL,JAVA,JSP,Se… 오라클자바…12-011853
39 [평일야간,주말]SQL기초에서실무까지(SQL기초,PLSQL,힌트,튜닝) 오라클자바…12-011330

댓글 없음:

댓글 쓰기