2015年6月27日 星期六

Struts簡單入門 - 簡易身份認證(使用NetBeans)

Struts是一個基於MVC(Model-View-Control)架構的Java Web框架,今天要以一個簡單的身份認證例子來初步地了解Struts的MVC概念精神。

下圖為一個Struts的簡單原理流程圖,其中在web.xml中會設定什麼樣的url要交由ActionServlet來轉發給處理邏輯(例如 *.do),JSP File相當於View的可視化介面,當JSP File要把表單(Form)中的參數傳給商業邏輯處理時,ActionServlet會去struts-config.xml中尋找對應Form裡指定目標url的Action(相當於Control)和相應要物件實例化Form的Bean類別,ActionForm(相當於Model)。之後在Action中處理商業邏輯,並指定一個轉送目標url,這時就會轉送到struts-config.xml中對應轉送標的JSP或Action等。

我們的範例專案檔案配置如下:

  1. login.jsp                  : 身份認證的輸入畫面。
  2. loginSuccess.jsp     : 認證成功的畫面。
  3. struts-config.xml    : Struts的配置設定。
  4. LoginCheckAction : 處理身份認證商業邏輯的Action。
  5. LoginFormBean     : 用來實例物件Form的Bean類別。



以下為程式碼,相關的解釋都在註解裡:



一、首先是login.jsp的程式碼:

<%@page contentType="text/html" pageEncoding="UTF-8"%>

<%-- 引進Struts的bean及html標籤庫 --%>

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<!DOCTYPE html>

<html>

    <head>

        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        <title>登入頁面</title>

    </head>

    <body>

        <h1>請輸入名字</h1>       

        <%-- 使用html:form來建立一個form,action為資料要送往的url --%>

        <html:form action="/loginCheckAction">

            <%-- 使用bean:write來從名為LoginFormBean的Bean類別中取得名為errorMessage的資 --%>

            <%-- 料,如找不到則忽略 --%>

            <bean:write name="LoginFormBean" property="errorMessage" filter="false"/>

            <%-- 使用html:text來紀錄為name的值,之後利用html:submit來將name值傳給action指定的url --%>

            請輸入名字:<html:text property="name" />

            <html:submit value="登入" />

        </html:form>

    </body>

</html>

二、再來是loginSuccess.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%-- 引進Struts的bean及html標籤庫 --%>

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<!DOCTYPE html>

<html>

    <head>

        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        <title>登入成功</title>

    </head>

    <body>

        <h1>登入成功!</h1>

        <%-- 將LoginFormBean物件中名為name的屬性顯示出來 --%>

        您好:<bean:write name="LoginFormBean" property="name" filter="false"/>

    </body>

</html>

三、接著實作用來實例物件Form的Bean類別,LoginFormBean,其中的name屬性對應到login.jsp中<html:form>裡<html:text>的name property:

package com.myapp.struts;



import javax.servlet.http.HttpServletRequest;



import org.apache.struts.action.ActionErrors;

import org.apache.struts.action.ActionMapping;

import org.apache.struts.action.ActionMessage;



public class LoginFormBean extends org.apache.struts.action.ActionForm {

   

    private String name;

    private String errorMessage;

   

    public String getName() {

        return name;

    }



    /**

     * @param string

     */

    public void setName(String string) {

        name = string;

    }



    public String getErrorMessage() {

        return errorMessage;

    }

    //設置名字錯誤的errorMessage之html

    public void setNameErrorMessage() {

        this.errorMessage = "<span style='color:red'>名字錯誤!你是誰?</span></br>";

    }

   

    public void clearErrorMessage(){

       this.errorMessage = null;

    }

   

    public LoginFormBean() {

        super();

        // TODO Auto-generated constructor stub

    }

    //用於驗證Form參數的method

    public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {

        ActionErrors errors = new ActionErrors();

        if (getName() == null || getName().length() < 1) {

            errors.add("name", new ActionMessage("error.name.required"));

            //驗證有無輸入name的參數,如果沒有則加入顯示相應錯誤的html到errorMessage中

            this.errorMessage = "<span style='color:red'>你沒輸入任何名字!</span></br>";

            // TODO: add 'error.name.required' key to your resources

        }

        return errors;

    }

}

四、這裡我們在LoginCheckAction設計了簡單的身份認證商業邏輯:

package com.myapp.struts;



import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;



public class LoginCheckAction extends org.apache.struts.action.Action {

    @Override

    public ActionForward execute(ActionMapping mapping, ActionForm form,

            HttpServletRequest request, HttpServletResponse response)

            throws Exception {

        //獲得由Form實例化的物件,LoginFormBean,其中包含了對應到<html:form>裡<html:text>中的name參數

        LoginFormBean loginFormBean = (LoginFormBean) form;

        //如果是表單輸入的名字是Hugo的話,轉送"success"對應的JSP或Action

        if ("Hugo".equals(loginFormBean.getName())) {

            return mapping.findForward("success");

        } else {           

            //如果是表單輸入的名字不是Hugo的話,轉送"failure"對應的JSP或Action

            loginFormBean.setNameErrorMessage();

            return mapping.findForward("failure");

        }

    }

}

五、最後,我們要在struts-config.xml裡進行設定,將以上的各檔關係聯繫起,在struts-config.xml中,我們要加上以下片段程式碼,其中在<action>中,scope為處理的domain、path為要處理轉送的url路徑、type為要從JSP送到哪個Action或JSP、name為要實例物件化Form的Bean類別、validate為參數要不要在Bean類別中執行validate()方法來進行先行驗證、input為指定validate()不通過時要返回的JSP。而在<action>中可以設定<forward>標籤,用來設定從Action中要利用mapping.findForward()轉送時,不同的輸入參數要送到哪個目標:
<action-mappings>

        <action name="LoginFormBean" input="/login.jsp" path="/loginCheckAction" scope="request" type="com.myapp.struts.LoginCheckAction" validate="true">

            <forward name="success" path="/WEB-INF/loginSuccess.jsp"/>

            <forward name="failure" path="/login.jsp"/>

        </action>

    </action-mappings>


成品展示:
一開始的網頁如下圖:
如果沒有輸入任何名字並按下鈃入按鈕後,會出現相應的提示訊息:

如果輸入錯誤的名字的話(非Hugo時),也會出現相應的提示訊息:

如果輸入正確的名字的話(輸入Hugo),將會被導向loginSuccess.jsp頁面:



最後附上源始碼:
MyStrutsWebApp.7z



沒有留言 :

張貼留言