久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

struts2中action實(shí)現(xiàn)Preparable接口

 昵稱15698534 2015-10-02
 

struts2中action實(shí)現(xiàn)Preparable接口

 3956人閱讀 評論(0) 收藏 舉報
 最近在學(xué)習(xí)struts2,發(fā)現(xiàn)了很多驚喜,,在設(shè)計上,,確實(shí)很優(yōu)秀,這兩天在研究怎么做出一個好的架構(gòu),,以后好用,。
    今天看了包中的showcase例子,發(fā)現(xiàn)了一種新的配置action方法:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->        <action name="edit-*" class="org.apache.struts2.showcase.action.EmployeeAction">
      <param name="empId">{1}</param>
            <result>/empmanager/editEmployee.jsp</result>
            <interceptor-ref name="crudStack">
                <
param name="validation.excludeMethods">execute</param>
            </
interceptor-ref>
        </action>
    當(dāng)時昏了一下,,用過這么多MVC的框架,,第一次看到action還可以用*配的,很牛啊,,自己配了一個,,不好使,找原因,,發(fā)現(xiàn)這里的EmployeeAction實(shí)現(xiàn)了com.opensymphony.xwork2.Preparable接口,,并實(shí)現(xiàn)了prepare()方法,再試,,成功,。但發(fā)現(xiàn)個問題,如果這個action中還有其它的控制處理,,而配置文件用的不是這種*形式,,比如我的例子:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><action name="BookAction" class="com.sigon.crud.action.BookAction">
            <result type="redirect">List.action</result>
        </action>
<action name="Edit*" class="com.sigon.crud.action.BookAction" method="load">
            <param name="isbn">{1}</param>
            <result>Edit.jsp</result>
        </action>
    這里兩個action用的是一個action類文件,而且BookAction實(shí)現(xiàn)了上面所說的Preparable接口,,這時就需要將BookAction中的isbn初始化,,否則在頁面調(diào)用BookAction時出空指針異常
    而在實(shí)際項目中,一個Action處理多個控制邏輯是家常便飯,,如果還想用這種形式,,就要在聲明isbn時賦初值,本例中是
private String isbn = "2";
    很明顯,,不穩(wěn)妥,。所以如何取舍,頗為困擾,。
    如果有哪位大俠有好的方法,,敬請賜教,。

Struts2的Preparable接口

分類: Struts2 940人閱讀 評論(1)收藏舉報

Struts2的Action在實(shí)現(xiàn)com.opensymphony.xwork2.Preparable接口后,就可以重寫prepare()方法
此時在Action中,,prepare()方法的執(zhí)行點(diǎn)是在:setXxx()execute()的執(zhí)行之前


比如需求:在執(zhí)行Action的方法前,,接收前臺隱藏域傳過來的值,再根據(jù)該值執(zhí)行相應(yīng)邏輯
如前臺傳過來ID,,我們根據(jù)ID查找數(shù)據(jù)庫對應(yīng)的用戶信息,,再跳轉(zhuǎn)到modify()中修改信息
但實(shí)際的運(yùn)行過程中發(fā)現(xiàn),通過Debug斷點(diǎn)調(diào)試得知prepare()方法接收到的ID值是零
即前臺隱藏域中的ID值沒有傳過來,,事實(shí)上問題就出在默認(rèn)的defaultStack攔截器棧
其實(shí)defaultStack無法接收prepare()需要的數(shù)據(jù),,而應(yīng)借助paramsPrepareParamsStack攔截器棧
事實(shí)上使用prepare攔截器之前,應(yīng)先調(diào)用params攔截器,,prepare()才能接收到表單數(shù)據(jù)
基于這個思路,,于是可以通過各種手段將params攔截器放置在prepare攔截器之前即可
比如將defaultStack中的所有攔截器拷貝struts.xml的我們自定義的myStack攔截器棧
再按照paramsPrepareParamsStack攔截器棧中的paramsprepare順序修改二者位置即可

最近讀starting struts2 online,里面有一節(jié)Move CRUD Operations into the same Action,,提供了Move CRUD Operations into the same Action大概的sample,,于是進(jìn)行了補(bǔ)充,記錄下來,,以備使用,。

一、思路
在這本書里,,lan roughley提到在結(jié)合preparable和ModenDriven攔截器實(shí)現(xiàn)Move CRUD Operations into the same Action,,采用通配符的方式為所有的crud只寫一個action配置,當(dāng)然,,這也要求相關(guān)文件的命名和目錄組織的時候要遵循一定的要求,,示例如下:

<action name="**" 的形式似乎不行,不得以改成了"*_*"了,,哈哈,,要是能改成"^_^"就更好了
注:在struts.xml中增加<constant name="struts.enable.SlashesInActionNames" value="true" />,可以使用"*
    public String delete() throws Exception {
        log.info("delete the person");
        service.deletePerson(id);
        return SUCCESS;
    }

   
    public String edit() {
        return "input";
    }

   
    public String update() throws Exception {
        if (id == null || id.length() == 0) {
            log.info("add the person");
            service.addPerson(person);
        } else {
            log.info("update the person");
            service.updatePerson(person);
        }
        return SUCCESS;
    }

   
    public String view() {
        return SUCCESS;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public PersonService getService() {
        return service;
    }

    public void setService(PersonService service) {
        this.service = service;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Person getModel() {
        return person;
    }
}
 

PersonListAction.java  :


package com.work.action.person;

import java.util.List;

import com.work.action.BaseSupport;
import com.work.model.Person;
import com.work.service.PersonService;

public class PersonListAction extends BaseSupport {
    private static final long serialVersionUID = 1810482163716677456L;
    private List<Person> people;
    private PersonService service=new PersonServiceImpl(); ;

    public String execute() throws Exception {
        log.info("list persons");
        people = service.getAllPersons();
        return SUCCESS;
    }

    public List<Person> getPeople() {
        return people;
    }

    public void setPeople(List<Person> people) {
        this.people = people;
    }

    public PersonService getService() {
        return service;
    }

    public void setService(PersonService service) {
        this.service = service;
    }
}

paramsPrepareParamsStack
這里需要說一下關(guān)鍵的paramsPrepareParamsStack攔截器,,其中params攔截器出現(xiàn)了兩次,,第一次位于servletConfig和prepare之前,更在modelDriven之前,,因此會將http://localhost:8080/diseaseMS/person/Person_edit.action?id=202中的參數(shù)id注入到action中,,而不是model中,之后prepare將根據(jù)這個id,,從服務(wù)層提取model,。

下面是paramsPrepareParamsStack的英文注釋:

An example of the params-prepare-params trick. This stack  is exactly the same as the defaultStack, except that it  includes one extra interceptor before the prepare interceptor:the params interceptor.
This is useful for when you wish to apply parameters directly to an object that you wish to load externally (such as a DAO or database or service layer), but can't load that object  until at least the ID parameter has been loaded. By loadingthe parameters twice, you can retrieve the object in the prepare() method, allowing the second params interceptor toapply the values on the object.

 


<interceptor-stack name="paramsPrepareParamsStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="params"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel</param>
</interceptor-ref>
</interceptor-stack>
PersonServiceImpl.java

package com.work.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.work.model.Person;

public class PersonServiceImpl implements PersonService {
   
    private List<Person> personList;

    public PersonServiceImpl() {
        personList = new ArrayList<Person>();
        Person p1 = new Person("202", "name1", "beijing");
        Person p2 = new Person("203", "name2", "beijing");
        Person p3 = new Person("204", "name3", "tianjing");
        personList.add(p1);
        personList.add(p2);
        personList.add(p3);

    }

    public void addPerson(Person person) {
        if (person == null) {
            throw new RuntimeException("add kong");
        }
        person.setId(getID(200));
        personList.add(person);
    }

    public void deletePerson(String personID) {
        int target = findLocation(personID);
        if (target != -1)
            personList.remove(target);
    }

    public List<Person> getAllPersons() {
        return personList;
    }

    public void updatePerson(Person person) {
        if (person == null) {
            throw new RuntimeException("update kong");
        }
        int target = findLocation(person.getId());
        personList.remove(target);
        personList.add(person);
       
    }

    private int findLocation(String personID) {
        int target = -1;
        for (int i = 0; i < personList.size(); i++) {
            if (personID.equals(personList.get(i).getId())) {
                target = i;
                break;
            }
        }
        return target;
    }

    public Person find(String personID) {
        Person person = null;
        int target = findLocation(personID);
        if (target != -1) {
            person = personList.get(target);
        }
        return person;
    }
   
    private String getID(int round) {
        Random rand = new Random();
        int needed = rand.nextInt(round) + 1; // 1-linesum+1
        return needed+"";
    }

}

下面就是jsp文件了,就只貼部分了:edit.jsp:
<s:form action="Person_update.action" >
    <s:textfield label="your ID" name="id" readonly="true"/>
    <s:textfield label="Please enter your name" name="name" required="true"  />
    <s:textfield label="Please enter your homeaddr" name="homeAddr" required="true"/>   
    <s:submit />
</s:form>

view.jsp

 

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<title>person view</title>
</head>

<body>
<s:actionerror />
<table>
    <tr>
        <td>id</td>
        <td>name</td>
        <td>address</td>
        <td></td>
        <td></td>
    </tr>
    <s:iterator value="people">
        <tr>
            <td><s:property value="id" /></td>
            <td><s:property value="name" /></td>
            <td><s:property value="homeAddr" /></td>
            <td><s:url id="update" action="Person_edit.action" >
                <s:param name="id">
                    <s:property value="%{id}" />
                </s:param>
            </s:url> <s:a href="%{update}">修改</s:a>
            </td>

            <td><s:url id="delete" action="Person_delete.action">
                <s:param name="id">
                    <s:property value="%{id}" />
                </s:param>
            </s:url> <s:a href="%{delete}">刪除</s:a>
            </td>
        </tr>
    </s:iterator>
</table>
<ul>
    <li><a href="<s:url action="Person_input"/>">Create a new person</a></li>

</ul>
</body>
</html>
 

三,、總結(jié)
優(yōu)點(diǎn):適用與crud比較的應(yīng)用程序,,大幅減少action的配置信息

其他:

1,、也可以不實(shí)現(xiàn)modeldriven接口,只不過要在jsp中加上model.properity

2,、這種方式在某種程度上透露了action中的方法名稱給客戶端,,是否會帶來安全性的問題

 

使用場景:
如果action針對每次請求都要執(zhí)行一些相同的業(yè)務(wù)邏輯, 那么可以實(shí)現(xiàn)Preparable接口,, 將預(yù)處理業(yè)務(wù)邏輯寫在prepare()方法里


Preparable 接口定義:
public interface Preparable {
    void prepare() throws Exception;
}


prepare何時被執(zhí)行:
prepare方法由PrepareInterceptor攔截器調(diào)用執(zhí)行


com.opensymphony.xwork2.interceptor.PrepareInterceptor
    public String doIntercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();

        if (action instanceof Preparable) {
            try {
                String[] prefixes;
                if (firstCallPrepareDo) {
                    prefixes = new String[] {ALT_PREPARE_PREFIX, PREPARE_PREFIX};
                } else {
                    prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX};
                }
                PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);
            }
            catch (InvocationTargetException e) {
                // just in case there's an exception while doing reflection,
                // we still want prepare() to be able to get called.
                LOG.warn("an exception occured while trying to execute prefixed method", e);
            }
            catch (IllegalAccessException e) {
                // just in case there's an exception while doing reflection,
                // we still want prepare() to be able to get called.
                LOG.warn("an exception occured while trying to execute prefixed method", e);
            } catch (Exception e) {
                // just in case there's an exception while doing reflection,
                // we still want prepare() to be able to get called.
                LOG.warn("an exception occured while trying to execute prefixed method", e);
            }

            // 必須執(zhí)行或初始化的一些業(yè)務(wù)操作 action prepare()方法
            if (alwaysInvokePrepare) {
                ((Preparable) action).prepare();
            }

        }

        return invocation.invoke();
    }


使用方法:

使用basicStack攔截器棧
<action name="list" class="org.apache.struts2.showcase.action.SkillAction" method="list">
 <result>/empmanager/listSkills.jsp</result>
 <interceptor-ref name="basicStack" />    <!-- 使用basicStack攔截器棧, 該攔截器棧在 struts-default.xml 已配置, 包括了prepare -->
</action>

(注: struts-default.xml  里定義的 basicStack攔截器棧

       <!-- Basic stack -->
            <interceptor-stack name="basicStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="multiselect"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params">
                    <param name="excludeParams">dojo\..*,^struts\..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
            </interceptor-stack>

)

或者直接指定prepare攔截器

<action name="list" class="org.apache.struts2.showcase.action.SkillAction" method="list">
 <result>/empmanager/listSkills.jsp</result>
 <interceptor-ref name="prepare" />   <!-- 直接指定prepare攔截器 -->
</action>


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多