也来写个struts2 CURD的例子-Move CRUD Operations into the same Action

 最近读starting struts2 online,里面有一节Move CRUD Operations into the same Action,提供了Move CRUD Operations into the same Action大概的sample,于是进行了补充,记录下来,以备使用。

一、思路

在这本书里,lan roughley提到在结合preparable和ModenDriven拦截器实现Move CRUD Operations into the same Action,采用通配符的方式为所有的crud只写一个action配置,当然,这也要求相关文件的命名和目录组织的时候要遵循一定的要求,示例如下:

 

< action  name ="*/*"  method ="{2}" class ="com.infoq.actions.{1}Action" >
    < result  type ="redirect" > /{1}/view.action </ result >
    < result  name ="view" > /{1}/view.jsp </ result >
    < result  name ="input" > /{1}/edit.jsp </ result >
    < result  name ="home" > /{1}/home.jsp </ result >
</ action >


采用这种方式后,所有的action的url都将是  
 “/{model}/{method}.action”的形式,从层次上看也比较的合理,更重要的是可以大幅度减少action配置的copy and paste

二、实现方式

 具体工作的原理我就不多重复了,主要使用preparable和ModenDriven的拦截器,可以参考starting struts2 online,上面解释得非常清楚,只是我在具体实现的时候,方向采用"*/*" 的形式似乎不行,不得以改成了"*_*"了,哈哈,要是能改成"^_^"就更好了 
注:在struts.xml中增加<constant name="struts.enable.SlashesInActionNames" value="true" />,可以使用"*/*"的方式

下面贴出具体的实现例子,同样了为了简化,在service层面上采取ArrayList模拟的数据库,下面贴代码:

Action 配置文件

因为要用preparable和modendriven,所以需要paramsPrepareParamsStack拦截器栈,下面会专门解释paramsPrepareParamsStack

<? xml version="1.0" encoding="UTF-8"  ?>
<! DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd" >
< struts >
< package  name ="person"  namespace ="/person"
extends ="struts-default" >
< default-interceptor-ref  name ="paramsPrepareParamsStack"   />
<!--  D?3¨¦person/add.action¦Ì¨¨url?¨¢11  -->
< action  name ="*_*"  method ="{2}"
class ="com.work.action.person.{1}Action" >
< result  name ="input" > /pages/{1}/edit.jsp </ result >
< result  type ="redirect" > ListPersons.action </ result >
</ action >
< action  name ="ListPersons"  class ="com.work.action.person.ListPersons" >
< result > /pages/Person/view.jsp </ result >
</ action >
<!--  Add actions here  -->
</ package >
</ struts >

 PersonAction.java

package  com.work.action.person;
import  com.opensymphony.xwork2.ModelDriven;
import  com.opensymphony.xwork2.Preparable;
import  com.work.action.BaseSupport;
import  com.work.model.Person;
import  com.work.service.PersonService;
import  com.work.service.PersonServiceImpl;

public   class  PersonAction  extends  BaseSupport  implements  ModelDriven < Person > ,
        Preparable  {

    private static final long serialVersionUID = 8115088127593809818L;
       // 定义了作为model的person,因为使用了modeldriven,所以jsp中form的值会直接setter到person中     
    private Person person;
       // id 用来保存用户的id,通过paramsPrepareParamsStack中的第一个param拦截器注入到action
    private String id;
    private PersonService service = new PersonServiceImpl();

    public void prepare() throws Exception {
        System.out.println(id);
        if (id == null || id.length() == 0)
            person = new Person();
        else
            person = service.find(id);
    }


    /**
     * delete
     */

    public String delete() throws Exception {
        log.info("delete the person");
        service.deletePerson(id);
        return SUCCESS;
    }


    /**
     * edit
     */

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


    /**
     * add and update
     * 
     * @return
     * @throws Exception
     */

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


    /**
     * ??
     * 
     * @return
     */

    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

这里需要说一下关键的paramsPrepareParamsStack拦截器,其中params拦截器出现了两次,第一次位于servletConfig和prepare之前,更在modelDriven之前,因此会将http://localhost:8080/diseaseMS/person/Person_edit.action?id=202中的参数id注入到action中,而不是model中,之后prepare将根据这个id,从服务层提取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 >

 

三、总结

优点:适用与crud比较的应用程序,大幅减少action的配置信息

其他:

1、也可以不实现modeldriven接口,只不过要在jsp中加上model.properity

2、这种方式在某种程度上透露了action中的方法名称给客户端,是否会带来安全性的问题

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值