`
cats_tiger
  • 浏览: 276488 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

终于发现struts2 Annotation的用处了——验证

阅读更多
struts2提供了annotation来代替配置文件,并且说:"It is great start."。我试用了Annoation风格的Action配置,感觉并不是很好用,尤其在比较复杂的Action中,反而不如XML直观明了。甚至,我不喜欢使用带有{}的简化配置,还是传统的方式更加一目了然。尤其是配置配置Action的时候需要在web.xml中注明packages,简直是...
今天终于找到了Struts2 Annotation的用途——验证。
下面代码是在一个Action中使用CRUD、ModelDriven的情况下利用Annotation验证的方式,Action使用了springside风格,父类提供了基本的CRUD能力:

//这是父类代码
@SuppressWarnings( { "serial", "unchecked" })
public abstract class AbstractCrudAction<T, M extends Manager>
    extends BaseAction implements Preparable, ModelDriven {
  /**
   * 定义显示单个实体的页面
   */
  public static final String VIEW = "view";

  /**
   * 定义显示实体列表的页面
   */
  public static final String INDEX = "index";

  /**
   * Action所使用的Manager类
   */
  private M manager;

  /**
   * Action所管理的Entity
   */
  private T model;

  /**
   * Action所管理的实体的类型
   */
  private Class entityClass;
  
   /**
   * 用于保存查询结果。
   */
  protected Collection<T> items;

  /**
   * 用于对应页面上CheckBox,List等组件的选择值.
   */
  protected Serializable[] selectedItems;

  /**
   * 用于保存分页查询结果
   */
  private Page page;

  /**
   * 创建一个新的实体,如果成功,返回index页面,如果失败,返回输入页面.
   */
  public String create() {
    //代码略
  }

  /**
   * <B>创建或更新</B>一个实体,如果成功,返回index页面,如果失败,返回输入页面.
   *  <code>save()</code>相当于调用{@link create()}和{@link update()},
   * 为了简化jsp编码,可以将新建和编辑页面合二为一,此时,<code>save()</code>方法.
   * 
   */
  public String save() {
    //代码略
  }

  /**
   * @see {@link #save()}
   */
  public String update() {
    return SUCCESS;
  }

  /**
   * 列出实体
   */
  @SkipValidation
  public String index() {
     //代码略
  }

  /**
   * 根据<code>Id</code>查询单个<code>model</code>并定向到显示它的页面.
   */
  @SkipValidation
  public String view() {
    return VIEW;
  }

  /**
   * 重定向到编辑页面。为了简化页面编程,将新建和编辑和为一个页面。
   */
  @SkipValidation
  public String edit() {
    return INPUT;
  }

  /**
   * 重定向到新建页面。为了简化页面编程,将新建和编辑和为一个页面。
   */
  @SkipValidation
  public String editNew() {
    return INPUT;
  }

  /**
   * 如果<code>id != null</code>,则删除ID所代表的Entity, 否则,如果<code>selectedItems.length > 0</code>则删除
   * <code>selectedItems</code>所代表的所有Entities.
   * @return
   */
  @SkipValidation
  public String remove() {
    //代码略
  }

  // Method from Preparable
  /**
   * @see com.opensymphony.xwork2.Preparable#prepare()
   */
  public void prepare() {
    if (model == null || extractId(model) == null) {
      model = (T) ReflectUtil.newInstance(getEntityClass());
    } else {
      model = (T) manager.get(extractId(model));
    }
  }
  
  /**
   * 从{@link #model}中取得ID
   * @param model 给定Model
   * @return 实体对象的ID值
   */
  protected abstract Serializable extractId(T model);
  /**
   * 将{@link #id}转换为实际的类型,子类必须根据持久化标识的类型实现,例如:<br>
   * <pre>
   * protected Serializable convertId(Serializable id) {
   *     return (id == nul) ? null : Integer.valueOf(id.toString());
   * }
   * </pre> 
   */
  protected abstract Serializable convertId(Serializable id);
  

  // Protected methods

  protected Class getEntityClass() {
    if (entityClass == null) {
      entityClass = GenericsUtil.getGenericClass(getClass(), 0);
    }
    return entityClass;
  }

  
  //Method from ModelDriven
  /**
   * @see com.opensymphony.xwork2.ModelDriven#getModel()
   */
  public T getModel() {
    if(model == null) {
      model = (T) ReflectUtil.newInstance(getEntityClass());
    }
    return model;
  }

  // Getters and setters.
  public void setModel(T model) {
    this.model = model;
  }
  
  public void setManager(M manager) {
    this.manager = manager;
  }
  
  protected M getManager() {
    return manager;
  }
  
  public Collection<T> getItems() {
    return items;
  }

  public Serializable[] getSelectedItems() {
    return selectedItems;
  }
  
  public void setSelectedItems(Serializable[] selectedItems) {
    this.selectedItems = selectedItems;
  }


  public Page getPage() {
    return page;
  }
}

这是子类的代码:
//少了中间的DefaultCrudAction
@Validation
public class DeptAction extends DefaultCrudAction<Dept, DeptManager> {
  /**
   * 当前上级部门ID
   */
  private Integer parentId;

  /**
   * 部门序列号管理器
   */
  private DeptSerialNoManager serialNoManager;

  /**
   * 用于查询的部门名称
   */
  private String deptName = StringUtils.EMPTY;

 
  @Override
  @SkipValidation
  public String index() {
    
    return INDEX;
  }


  @Override
  @Validations(requiredStrings = { @RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "model.name", message = "部门名称是必须的.")})
  public String save() {
    
  }

  /**
   * 处理parentDept为null的情况
   */
  @Override
  @SkipValidation
  public String edit() {
    
  }

  /**
   * 重置所有部门编号
   */
  @SkipValidation
  public String updateSerialNo() {
    serialNoManager.updateAllSerialNo();
    return SUCCESS;
  }

  public DeptSerialNoManager getSerialNoManager() {
    return serialNoManager;
  }

  public void setSerialNoManager(DeptSerialNoManager serialNoManager) {
    this.serialNoManager = serialNoManager;
  }
}


这是Struts的配置文件
<package name="admin.dept" extends="struts-default" namespace="/admin/dept">
		 <action name="index" class="deptAction" method="index">
		     <result name="index" type="dispatcher">/pages/admin/dept/index.jsp</result>
		 </action>
		 <action name="editNew" class="deptAction" method="editNew">
		     <result name="input">/pages/admin/dept/edit.jsp</result>
		 </action>
		 <action name="edit" class="deptAction" method="edit">
		     <result name="input">/pages/admin/dept/edit.jsp</result>
		 </action>
		 <action name="remove" class="deptAction" method="remove">
		     <result name="success" type="redirect">index.do</result>
		 </action>
		 <action name="save" class="deptAction" method="save">
		     <result name="success" type="redirect">index.do</result>
		     <result name="input">/pages/admin/dept/edit.jsp</result>
		 </action>
		 <action name="updateDeptSerialNo" class="deptAction" method="updateSerialNo">
		     <result name="success" type="redirect">index.do</result>
		 </action>
	</package>
<!--如果使用{},这个配置文件会更简单一些.-->

说明一下:
1.不必在web.xml的添加任何代码,struts会自动根据Annotation进行验证。
2.在需要验证的方法前加@SkipValidation,如果你采用了SpringSide风格的Action,那么在父类的方法前加@SkipValidation即可。但是如果子类覆盖了父类的方法,子类方法前也需要用@SkipValidation标注。感觉Struts2好像弄反了,实际应用中,需要验证的方法要少于不需要验证的方法,如果缺省的方法都不验证,只有标注了@Validations的方法验证就更好了。
3.一直感觉struts2 的XML验证方式比较难以维护,Annotation的使用解决了这个问题。
分享到:
评论
5 楼 slaser 2008-04-07  
我还是喜欢写代码进行验证。annotation和代码差别也不大了。
4 楼 cats_tiger 2008-03-20  
to Fly_m:
哦,原来如此。Ths
3 楼 Fly_m 2008-03-19  
<p>晚上回去搞了半天,还专门下了xwork的源代码来看,结果发现是struts2默认是全局验证了.解决方法就是重写struts2的默认拦截器,在引用validatio拦截器时,加入新的param,如下</p><p> </p><pre name='code' class='xml'>&lt;interceptor-ref name="validation"&gt;
<br/> &lt;param name="excludeMethods"&gt;input,back,cancel,browse&lt;/param&gt;
<br/> &lt;param name="validateAnnotatedMethodOnly"&gt;true&lt;/param&gt;
<br/> &lt;/interceptor-ref&gt;</pre><p>  这样就可以达到单个方法级别的Annotation验证了.</p><p>以后可要好好看看别人的代码了,本来还以为是xwork没提供这个功能呢,结果是自己小白了.</p><p>不过好像下载xwork2.1的代码好像跟struts2有冲突吧,都无法启动了,最后又换回2.04的了.</p>
2 楼 ygxdha 2008-03-18  
struts2验证的内核还是common-validator吧。
annotation不过是把需要在common-validator所需要的配置信息转移到java代码中的annotation中去。如果struts2的校验annotion对一些common-validator的支持不够,可以自己添加annotation的实现。只要把common-valitor这个核心搞清楚就ok了
1 楼 Fly_m 2008-03-18  
你这个例子不够全面,你只验证了一个方法.我刚也试了下你的方法,发现其中有一个问题是值得注意的,就是一个类中出现两个方法都需要验证,且两个验证都是不同的验证,如A方法验证a,B方法验证b.当同时出现两个方法验证不同的东西时,错误就出现了.
B方法在验证b的同时,会同时尝试去验证a(即会叠加另一个方法的验证),这样,本来不需要验证a方法的B方法,就已经出现验证错误了.不知道关于这个问题你发现没.如果有相应的解决方法,请与告知.

相关推荐

    struts2 使用Annotation 配置的小例子

    在这个小例子中,我们将深入探讨如何利用Struts2的Annotation配置来构建一个简单的应用。 首先,让我们了解什么是Annotation。在Java中,Annotation是一种元数据,它提供了一种安全的方式向编译器、JVM或者第三方...

    在嵌入式jetty环境下运行struts2Annotation项目

    在嵌入式Jetty环境下运行Struts2 Annotation项目是一个常见的任务,特别是在开发和测试阶段,因为这种方式能够快速启动服务,而无需依赖大型服务器容器。本文将深入探讨如何配置和执行这个过程,以及涉及的关键技术...

    struts2annotation json

    标题“struts2annotation json”暗示我们将探讨如何在Struts2中使用注解来处理JSON相关的功能。首先,让我们深入理解Struts2的注解系统。 1. **Struts2注解**: - `@Action`: 这个注解用于标记一个方法为处理HTTP...

    使用struts2的annotation验证

    博文链接:https://flym.iteye.com/blog/174358

    Struts2之Annotation注解配置使用案例struts013

    在Struts2中,Annotation注解的引入为开发者提供了更加灵活和便捷的配置方式,使得无需在XML配置文件中进行繁琐的设置,可以直接在类或方法上通过注解来进行配置。本文将深入探讨Struts2中的Annotation配置,以及...

    struts2 annotation 批量下载

    在Struts2框架中,使用注解(Annotation)可以极大地简化控制器类的配置,提高代码的可读性和维护性。本文将深入探讨如何利用Struts2的注解功能实现批量下载功能,并通过创建临时文件来处理下载请求,同时确保在下载...

    struts2 annotation 文件下载

    import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spring...

    struts2 hibernate3 spring2.5 annotation 整合

    Struts2、Hibernate3和Spring2.5是Java Web开发中的三大框架,它们各自负责不同的职责,但可以协同工作以构建高效的企业级应用。这里主要讨论的是如何将这三者结合,并利用注解(Annotation)进行配置,以简化开发...

    struts2 Annotation 版本学习心得与例子

    Struts2的“零配置”特性是Struts2的新功能,可能会出现一些小Bug,所以企业开发者请慎重使用该特性, ...如果用的是Annotation的Struts2,就要将struts.xml去掉,否则即使将struts.xml中的内容注销,也会报错;

    struts2-Annotation

    在给定的“struts2-Annotation”主题中,重点是Struts2框架如何利用注解(Annotation)来增强其功能和简化配置。注解是一种元数据,可以在代码中嵌入,提供有关类、方法或字段的额外信息,而无需编写XML配置文件。 ...

    struts2利用注解annotation实现文件下载

    ### Struts2 使用注解(Annotation)实现文件下载 在Web开发中,文件上传与下载是常见的需求之一。Struts2框架提供了强大的功能来支持这一需求。本文将详细介绍如何使用Struts2框架结合注解(Annotation)的方式...

    struts2 interceptor annotation plugin

    而"struts2 interceptor annotation plugin"则是Struts2框架提供的一种使用注解来配置拦截器的方式,这种方式更加简洁、直观,减少了XML配置文件的复杂性。 注解(Annotation)是Java编程语言的一个重要特性,它...

    struts annotation Hello World

    此外,Struts 2还提供了其他注解,例如`@Namespace`用于定义Action的命名空间,`@ParentPackage`用于继承现有的配置包,`@SkipValidation`用于跳过特定Action的方法验证等。 为了运行这个"Hello World"应用,你需要...

    Struts2使用Annotation返回Json

    在Struts2中,使用注解(Annotation)可以简化配置,提高开发效率。本篇文章将深入探讨如何在Struts2中通过注解实现返回JSON数据的功能。 首先,让我们理解JSON(JavaScript Object Notation)是一种轻量级的数据...

    struts annotation.ppt

    Struts2注解是Java开发框架Struts2中的一种特性,它引入了JDK1.5及更高版本的注解(Annotation)概念,使得开发者能够更简洁地配置Struts2框架,减少XML配置文件的使用,提高开发效率。注解提供了一种方式,将元数据...

Global site tag (gtag.js) - Google Analytics