2014년 11월 19일 수요일

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

Struts를 이용한 인증 예제(3) 

이번 예제는 이전 예제의 기능을 개선한 예제인데 바뀐 부분은 대체로 아래와 같습니다. 

Struts를 이용한 인증 예제(3) 

이번 예제는 이전 예제의 기능을 개선한 예제인데 바뀐 부분은 아래와 같습니다. 

1.        사용자가 main.jsp를 호출 하면 인증을 하지 않은 사용자는 자동으로 login.jsp로 보내어 버립니다. 물론 인증을 이미 한 사용자라면 환영 인사와 로그아웃을 활성화 합니다. 

2.        main.jsp에서 인증이 되었는지 안되었는지의 여부는 사용자 정의 태그(Custom Tag Library)를 이용하였으며 중추적인 역할을 하는 Tag Handler 클래스는 IsLogin.java 입니다. 

3.        login.jsp, main.jsp 에서 화면 UI의 구성을 위해 화면에 뿌리는 텍스트 등을 message 처리 했습니다.(application.properties) 

4.        기존 예제의 LoginAction에 있던 인증 기능을 LoginDAO.java라는 Model을 이용하여 처리 했으며 인증이 성공적으로 끝난 후 사용자의 정보를 UserInfoVO라는 자바 빈에 저장 해 놓고 이를 이용 하였습니다. (비즈니스 로직을 분리 했습니다.) 

[실행 화면] 

  

  

  



---------------- 
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" %> 
<%@ taglib uri="/WEB-INF/app.tld" prefix="login" %> 

<!-- 인증이 안된 사용자는 login.jsp로 보내 버립니다. --> 
<login:IsLogin/> 

<html> 
<head> 
    <title><bean:message key="main.title" /></title> 
    <html:base/> 
</head>        
        <body>                
            <h3>반갑습니다.<bean:write name="user" property="id"/>님!</h3>                                        
                <ul>                        
                        <li>                            
                                <html:link forward="logoff">로그아웃</html:link> 
                        </li>                        
                </ul> 
        <body> 
</html> 

------------- 
2.        login.jsp 
------------- 

<%@ page pageEncoding="euc-kr" %> 
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> 
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> 
<html> 
<head> 
    <title><bean:message key="login.title" /></title> 
    <html:base/> 
</head> 

<body> 
<!-- 웹서버가 보내는 응답에 오류가 있다면 출력 --> 
<html:errors/> 

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

-------------------------------------------------- 
3.        application.properties (/WEB-INF/src/resources/ 에 위치) 
-------------------------------------------------- 


login.title = LogIn 
login.login = Login 
login.reset = Cancel 

prompt.id= User ID : 
prompt.password=Password : 

main.title=Main 


###############################################3 
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> 

----------------------------- 
4.        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;                        
        } 
        

                
        



------------------------------- 
5.        LoginAction.java(Action) 
------------------------------- 

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 ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) { 
                String id = ((LoginForm)form).getId(); 
                String pwd = ((LoginForm)form).getPwd(); 
                
                //Model을 이용하기 이용하여 인증부분의 처리를 합니다. 
                LoginDAO loginDAO = new LoginDAO(); 
                UserInfoVO userinfo = loginDAO.authUser(id, pwd); 
                
                //에러 내용을 담을 ActionErrors 객체를 생성 
                ActionErrors errors = new ActionErrors(); 
                
                if (userinfo==null) { 
                        //인증 실패                        
                        errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.login.invalid"));                        
                } 
                else { 
                        //사용자 아이디와 비밀번호가 틀릴경우 비밀번호가 틀리다는 에러 메세지 출력 
                        if ( !id.equals(userinfo.getPwd()) ) { 
                              errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("error.login.invalid")); 
                        } 
                } 
                
                //로그인 과정에서 에러가 있을 경우 Action클래스의 saveErrors 메소드를 이용해  에러를 저장하고 
                //이전의 로그인 페이지로 돌려 보내면 login.jsp의 <html:errors/> 태그에 의해 오류가 출력됨 
                //mapping의 getInputForward()에서 반환하게 되는 정보는 struts-config.xml의 action태그의 
                //input 속성에  정의된 페이지로 이동하게 됩니다. 
                if (!errors.isEmpty()) { 
                    saveErrors(request, errors); 
                  return (mapping.getInputForward()); 
                }        
                                
                //인증 성공한 경우 세션에 UserInfoVO(로그인한 사용자 정보를 담은 객체)저장 
                HttpSession session = request.getSession(); 
                session.setAttribute(Constants.USER_KEY, userinfo); 
                
                //로그를 남기자. 
                StringBuffer buf = new StringBuffer("LoginAction : User --> "); 
                buf.append(id + "logged in session"); 
                servlet.log(buf.toString()); 
                                
                return (mapping.findForward(Constants.SUCCESS));                        
                
        } 

        


------------------------------------------------------------------- 
6.        LoginDAO.java (인증을 하기 위한 비즈니스 로직을 담고 있는 Model) 
------------------------------------------------------------------- 

package login2; 

public class LoginDAO { 
        
        public UserInfoVO authUser(String id, String pwd) { 
                /** 
                * 이부분은 실제 DB에서 ID와 PASWORD로 인증을 해야 하는 부분 입니다. 
                * 예제를 간략히 하기 위해 이 부분의 처리는 생략 했으며 ID가 "jclee", Password가 "jclee" 인 경우엔 
                * 인증을 허용 합니다. 
                */ 
                
                if ( id.equals("jclee")&& pwd.equals("jclee")) { 
                        //ID:jclee, PASSWORD:jclee인 경우 인증이 성공, 사용자의 정보(아이디, 패스워드)를 저장 합니다. 
                        return new UserInfoVO(id, pwd); 
                } else { 
                        return null; 
                }                
        } 



----------------------------------------------------------------- 
7.        UserInfoVO.java (인증이 성공되면 사용자의 정보를 담아 두기 위한 Model) 
----------------------------------------------------------------- 

package login2; 
/** 
 * 로그인이 정상적으로 이루어진 경우 사용자의 정보등을 저장 하는 빈 
 * 본 예제에서는 ID와 PASSWORD를 저장 합니다. 
 */ 
public class UserInfoVO { 
        private String id = null; 
        private String pwd = null; 
        
        //LoginDAO에서 인증이 성공인 경우 아래의 생성자를 불러 값을 setting 합니다. 
        public UserInfoVO(String id, String pwd){ 
                this.id = id; 
                this.pwd = pwd; 
        } 
        
        public  String getId() { 
                return id; 
        } 

        public  String getPwd() { 
                return pwd; 
        } 



------------------------------------------------------- 
8.        Constants.java (LoginAction등에서 사용 될 상수를 정의) 
------------------------------------------------------- 



package login2; 


public class Constants { 
        /** 
        * 로그인한 사용자의 LoginForm이 저장될 세션 범위의 Attribute 이름 
        */ 
        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"; 
        
        



--------------------------------------------------- 
9.        LogoffAction.java (로그오프 처리를 위한 ActionBean) 
--------------------------------------------------- 


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(); 
                UserInfoVO userinfo = (UserInfoVO)session.getAttribute(Constants.USER_KEY); 
                
                if (userinfo != null) { 
                        //로그를 남기자 
                        StringBuffer buf = new StringBuffer("User Logout : " + userinfo.getId()); 
                        servlet.log(buf.toString());                                        
                }                
                
                //사용자의 로그인을 삭제, session.invaidate() 의 경우 션의 모든 것을 무효화 시킴. 
                session.removeAttribute(Constants.USER_KEY); 
                
                //성공적으로 처리 되었음을 알림 
                return (mapping.findForward(Constants.SUCCESS)); 
                
        } 

        


-------------------------------------------------------------------- 
10.        IsLogin.java (커스텀 태그를 처리 하기 위한 핸들러, main.jsp에서 인증이 되었는지 안되었는지 검사하는 기능을 수행하며 인증이 안된 경우라면 login.jsp로 보냄) 
-------------------------------------------------------------------- 

package login2; 


import javax.servlet.http.HttpSession; 
import javax.servlet.jsp.JspException; 
import javax.servlet.jsp.tagext.TagSupport; 

import login2.Constants; 


public final class IsLogin extends TagSupport { 
        private String name = Constants.USER_KEY; 
        private String page = "/login.jsp"; 

        public String getName() { 

                return (this.name); 

        } 

        public void setName(String name) { 

                this.name = name; 

        } 

        public String getPage() { 
                return (this.page); 
        } 

        public void setPage(String page) { 
                this.page = page; 
        } 

        public int doStartTag() throws JspException { 

                return (SKIP_BODY); 

        } 

        public int doEndTag() throws JspException { 

                // Is there a valid user logged on? 
                boolean valid = false; 
                HttpSession session = pageContext.getSession(); 
                if ((session != null) && (session.getAttribute(name) != null)) 
                        valid = true; 

                // Forward control based on the results 
                if (valid) 
                        return (EVAL_PAGE); 
                else { 
                        try { 
                                pageContext.forward(page); 
                        } catch (Exception e) { 
                                throw new JspException(e.toString()); 
                        } 
                        return (SKIP_PAGE); 
                } 

        } 

        /** 
        * Release any acquired resources. 
        */ 
        public void release() { 

                super.release(); 
                this.name = Constants.USER_KEY; 
                this.page = "/login.jsp"; 

        } 



------------------------------------------------------------------ 
11.        app.tld (/WEB-INF/에 위치) 앞의 커스템 태그 핸들러 및 커스텀 태그를 사용 하기 위한 tld 파일 
------------------------------------------------------------------ 

<?xml version="1.0" encoding="ISO-8859-1" ?> 

<!DOCTYPE taglib  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" 
  "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> 
<taglib> 

  <tlibversion>1.0</tlibversion> 
  <jspversion>1.1</jspversion> 
  <shortname>Application Tag Library</shortname> 
  <uri>http://jakarta.apache.org/taglibs/struts-example-1.0</uri> 
  <info> 
    Example Application. 
  </info> 
  <tag> 

    <name>IsLogin</name> 

    <tagclass>login2.IsLogin</tagclass> 

    <bodycontent>empty</bodycontent> 

    <info> 

      Validate that there is a currently logged on user, by checking for 

      the existence of a session-scope bean under the specified name. 

      If there is no such bean, forward control to the specified page, 

      which will typically be a logon form. 

      name - Name of the session-scope bean to check for [user] 
      page - Context-relative path to the logon page [/logon.jsp] 

    </info> 

    <attribute> 

      <name>name</name> 

      <required>false</required> 

      <rtexprvalue>true</rtexprvalue> 

    </attribute> 

    <attribute> 

      <name>page</name> 

      <required>false</required> 

      <rtexprvalue>true</rtexprvalue> 

    </attribute> 

  </tag> 
</taglib> 

--------------------------- 
12.        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> 


 [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

댓글 없음:

댓글 쓰기