2015年7月2日 星期四

Struts Hello World(Struts一)

首先了解一下
ActinServlet:Struts的Controller
struts-config.xml:struts主要的設定檔
ActionForm:負責處理Controller中接收、驗證、轉換資料的功能
Action:處理Controller呼叫Model和根據Model執行結果導向下一個View的功能

1.放jar,注意jstl.jar和standard.jar版本較舊,用maven下載是個不錯的選擇
  我是將 jstl-1.0.2.jar 換 jstl-1.2.jar;standard-1.0.6.jar 換 standard-1.1.2.jar
2.設定web.xml-->從blank去copy
3.加入struts-config.xml-->放在WEB-INF裡,從blank去copy
4.加入properties(放在/WEB-INF/classes,也就是src下),並設定struts-config.xml,從blank去copy

功能:
頁面如果不輸入,就會出現錯誤訊息
如果帳號是aaa而且密碼是111就跳成功頁,不然就跳失敗頁(模擬資料庫)

struts-config.xml
<struts-config>
    <form-beans>
        <form-bean name="ooo" type="controller.LoginActionForm">
            <form-property name="username" type="java.lang.String" />
            <form-property name="password" type="java.lang.String" />
        </form-bean>
    </form-beans>

    <action-mappings>
        <action path="/xxx" type="controller.LoginAction" name="ooo"
            scope="request" validate="true" input="/index.jsp">
            <forward name="success" path="/s.jsp" />
            <forward name="fail" path="/f.jsp" />
        </action>
    </action-mappings>

    <message-resources parameter="MessageResources" />
</struts-config>
path:和html的.do一樣,但不用.do
type:action的家
name:和form-bean name一樣
scope:就是scope
validate:是否驗證
input:錯誤跳轉

ActionForm.java
public class LoginActionForm extends ActionForm {
    private String username;
    private String password;

    //setter/getter...

    @Override
    public ActionErrors validate(ActionMapping mapping,
            HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();
        System.out.println("username=" + this.getUsername());
        System.out.println("password=" + this.getPassword());

        if (this.getUsername().trim().isEmpty()) {
            errors.add("user", new ActionMessage("username"));
        }
        if (this.getPassword().trim().isEmpty()) {
            errors.add("pass", new ActionMessage("password"));
        }
        return errors;
    }
}

Action.java
public class LoginAction extends Action {
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        LoginActionForm laf = (LoginActionForm) form;
        
        if(laf.getUsername().trim().equals("aaa") && laf.getPassword().trim().equals("111")){
            return mapping.findForward("success");
        } else {
            return mapping.findForward("fail");
        }
    }
}

index.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>
<html:errors/>
<form action="<c:url value="/xxx.do"/>">
    帳:<input type="text" name="username" /><html:errors property="user" />
    密:<input type="password" name="password" /><html:errors property="pass" />
    <input type="submit" value="送出" />
    <input type="reset" value="重置" />
</form>

s.jsp
<h1>Login Success</h1>

f.jsp
<h1>Login Fail</h1>

MessageResources.properties
username=username can't empty
password=password can't empty 


※如果Action要顯示錯誤訊息也可以

// action想存錯誤訊息可用這兩行
ActionErrors errors = new ActionErrors();
request.setAttribute(Globals.ERROR_KEY, errors);

if (laf.getUsername().trim().equals("aaa") && laf.getPassword().trim().equals("111")) {
    return mapping.findForward("success");
} else {
    errors.add("user", new ActionMessage("actionUP"));
    return mapping.findForward("fail");
}

struts-config.xml修改fail路徑
<forward name="fail" path="/index.jsp" />

properties也增加一行
actionUP=please Enter legal username and password!

※注意:如果有「No bean specified」錯誤訊息,通常都是formbean有集合,此時集合要實體化,如:
private List<Student> students; --> private List<Student> students = new ArrayList<>();
如果Student類別還有集合,也要實體化


※DispatchAction

是 Action 的子類
controller 若繼承 DispatchAction 這個類,然後裡面寫很多方法,然後 struts-config.xml 的 action標籤,有個 parameter 屬性,通常喜歡設定成 method,這樣子就可以用 xxx.do?method=方法名,此方法名會對應你寫的方法名

注意:
.4 個參數都不能變,否則會 500;而回傳值我寫 void 是可以的
.如果在此類別覆寫 execute 方法,那執行時會呼叫到 execute 方法,其他都不會呼叫
.如果繼承一個父類,此父類繼承 DispatchAction  且覆寫 execute 方法,那執行時會先呼叫 execute 方法,然後再呼叫 method=xxx 的方法
.GET、POST 都可以

沒有留言:

張貼留言