`
suliuyes
  • 浏览: 93872 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

SpringSide 3 中的 Struts 2

 
阅读更多

在SpringSide 3 中,使用的MVC框架是Struts 2。Struts 2 向对于Struts 1 来说,具有相当多的优点,有很多人都说,用过Struts 2之后,再也不想看Struts 1了。然而,任何东西都有它的复杂性,Struts 2也不例外,SpringSide 3做了很多工作来简化Struts 2 的使用。

先来说说Struts 2的特点:
1、编写Action变得简单了,Action变成了简单的POJO,再也不用和ActionForm、ActionForward打交道了,返回的时候直接返回字符串即可。如果要访问Servlet API,则直接使用ServletActionContext类的静态方法。
2、Struts 2提供了插件机制,允许我们自己为它编写插件,当然,要我自己写是不现实的,但是面对别人写的琳琅满目的插件,我一样会昏头。再网上随便一搜,就可以发现40多种Struts 2插件。SpringSide 3选择的CodeBehind,就是一种Struts 2插件,它的目的是为了简化配置。
3、Struts 2提供了拦截器机制,之所以编写Action的任务那么简单,靠的都是这些拦截器,比如它们可以自动解析Web表单和URL参数,把它们注入到Action中。
4、Struts 2提供了丰富的taglib,当然,丰富也代表着我们要化更多的时间去学习。
5、Struts 2依然提供了Validator和i18n支持。
等等...

下面,我们来看看SpringSide 3是怎么使用Struts 2的吧。SpringSide 3的主要目标是降低我们使用Struts 2的复杂性,所以,它选择了这些办法:
1、没有使用Validator和i18n,对数据的验证交给了JQuery,这变成了表现层的任务,而且JQuery也可以使用AJAX从服务器端进行验证。至于i18n,江南白衣说小网站用不上。
2、没有使用Struts 2的UI标签,当然也就没有使用FreeMaker或SiteMesh了。

当然,省掉了一些东西,就省掉了我们不少的学习时间。对于Struts 2核心的一些东西,我们看看它是怎么做的:

1、使用CodeBehind插件来简化配置。使用CodeBehind后,我们就可以不用配置result了,它可以根据我们Action的返回值自动猜测返回的视图页面,它猜测的规则是这样的:返回页面的路径为struts.codebehind.pathPrefix + package namespace + action name + action returnvalue + .jsp,action returnvalue为success时,值为空,为其他时,值为"-" + return type。我们来看看SpringSide 3生成的项目中关于Struts 2的配置文件:
001.PNG
其中struts.codebehind.pathPrefix设置为“/WEB-INF/jsp/”,package的namespace没有设置,所以,如果我们的Action为UserAction,则返回success时,就会返回到/WEB-INF/jsp/user.jsp,如果返回input,则返回到/WEB-INF/jsp/user-input.jsp。这里江南白衣玩了一个狡猾,他把所有的jsp页面放到WEB-INF目录中,别人就没有办法直接访问了,这样就可以简化Acegi的配置工作。

2、关于拦截器栈
在上面讲Struts 2的特点时,我已经说了Struts 2中拦截器的重要作用,在上面的截图中,package的配置没有做别的什么事,主要就是配置了拦截器栈。那么拦截器栈是怎么使用的呢?它是在Action类中通过@ParentPackage指定的,如下面的代码:
002.PNG

下面,我来具体说一下拦截器有什么作用。
 例子一、我们知道Struts 2中的Action是和Servlet API解耦的,那么如果我们要在Action中访问Servlet API怎么办呢?一种办法就是使用ServletActionContext,如下图:
003.PNG
另外一种办法,就是让我们的Action实现ServletRequestAware接口,如下代码:

public   class  MyAction  implements  ServletRequestAware {
   
 private  HttpServletRequest request;
   
 public   void  setServletRequest(HttpServletRequest request) {
        
 this .request  =  request;
   }
   
 public  String execute()  throws  Exception {
        
 //  do the work using the request 
         return  Action.SUCCESS;
   }
}
这时候,ServletConfigInterceptor 拦截器就会把request对象注入到我们的Action中。

例子二、ParametersInterceptor 拦截器会自动解析web表单或URL参数,并把它们注入到Action中。但是很多时候,我们不愿意我们的Action具有太多的属性,因为一大堆的get、set方法看起来太乱糟糟,我们希望有一个专门的Model对象来存储这些值,而且刚好我们为Hibernate设计的Entity类用来做Model正合适。这时,我们可以让我们的Action实现ModelDriven接口,让getModel()方法返回我们的entity对象即可。这正是SpringSide 3采取的方法,如下图的代码片断:
004.PNG
这时候,ModelDrivenInterceptor拦截器就会帮助我们把解析的URL参数或表单数据注入到entity的属性中,而不是Action中。

例子三、Preparable 接口联合PrepareInterceptor拦截器一起工作,可以让action在执行execute() 方法前, 执行一个prepare()方法,这也正是SpringSide 3的工作方式。

3、关于Action
有了上面对CodeBehind的理解和对拦截器栈的理解后,再来理解SpringSide 3中的Action就再简单不过了,SpringSide 3中Action的继承树如下:
005.PNG

其中ActionSupport类是Struts 2提供的,另外两个类是白衣自己扩展的。其中SimpleActionSupport主要是提供了一些绕过jsp页面直接输出字符串的方法,不值一谈。而CRUDActionSupport就比较复杂,如下:
public abstract class CRUDActionSupport<T> extends SimpleActionSupport implements ModelDriven<T>, Preparable {
    
/**
     * 进行CUD操作后,以redirect方式重新打开action默认页的result名.
     
*/
    
public static final String RELOAD = "reload";

    
/**
     * Action函数,默认action函数,默认指向list函数.
     
*/
    @Override
    
public String execute() throws Exception {
        
return list();
    }

    
/**
     * Action函数,显示Entity列表.
     * return SUCCESS.
     
*/
    
public abstract String list() throws Exception;

    
/**
     * Action函数,新增或修改Entity. 
     * return RELOAD.
     
*/
    
public abstract String save() throws Exception;

    
/**
     * Action函数,删除Entity.
     * return RELOAD.
     
*/
    
public abstract String delete() throws Exception;

    
/**
     * 在save()前执行二次绑定.
     
*/
    
public void prepareSave() throws Exception {
        prepareModel();
    }

    
/**
     * 在input()前执行二次绑定.
     
*/
    
public void prepareInput() throws Exception {
        prepareModel();
    }

    
/**
     * 屏蔽公共的二次绑定.
     
*/
    
public void prepare() throws Exception {
    }

    
/**
     * 等同于prepare()的内部函数. 
     
*/
    
protected abstract void prepareModel() throws Exception;
}


第一,它做了把CRUD操作放到了同一个Action中的操作,这样可以少写几个Action。这个工作难度不大,我觉得白衣此举,主要是为了规范CRUD函数的命名。在Struts 2中,如果我们要访问的不是默认的excute方法,可以使用如/user!save.action的格式,这样访问的就是UserAction的save方法。
第二,它实现了ModelDriven接口和Preparable接口,关于这两个接口,我在前面讲拦截器的时候已经提到过了,所以很容易理解。我们可以把我们为Hibernate设计的entity类作为Model,也可以把初始化这些entity的工作放到prepareSave()和prepareInput()方法中,这两个方法将会在save()和input()方法执行前自动执行。
第三,它定义了一个静态变量RELOAD,定义这个变量的目的是为了定义一个result的需要。CodeBehind中,大部分的result可以自己猜测,对于不能猜测的,需要使用@Results指定,如下代码:
006.PNG

 

 好了,对SpringSide 3中Struts 2的分析就写到这里了。总之,使用SpringSide 3时,对于Action这一块非常简单,如果不设及到CRUD操作,就继承SimpleActionSupport,如果涉及到CRUD操作,就继承CRUDActionSupport,并在getModel()\save()\prepareSave\input()\prepareInput()等框框中填入适当的代码即可。


评论

# re: SpringSide 3 中的 Struts 2  回复  更多评论   

2008-12-24 15:38 by 虎啸龙吟
非常不错!比看springSide的源码清晰多了。节省了大量的时间。期待有更多的 
springSide的文章。

# re: SpringSide 3 中的 Struts 2  回复  更多评论   

2008-12-24 16:27 by blablalba
Hey,大侠,我从springside的论坛上寻到这儿来。
http://forum.springside.org.cn/viewthread.php?tid=3232&extra=&page=1
是关于配多数据源的,你在回帖中提到的事务配置方面的问题我也碰到了。
<tx:annotation-driven transaction-manager="transactionManager" />

ms不能有多个的<tx:annotation-driven>??

现在提供一个解决方案么?不要JTA咯

# re: SpringSide 3 中的 Struts 2  回复  更多评论   

2008-12-24 17:08 by lx281
谢谢,文章写的很清晰明白,学习struts2中,顺便看看springside

# re: SpringSide 3 中的 Struts 2  回复  更多评论   

2008-12-24 20:11 by 海边沫沫
@blablalba 
等我的下一篇,下一篇我会写关于数据访问方面的内容。

# re: SpringSide 3 中的 Struts 2  回复  更多评论   

2009-01-15 15:19 by 向往蓝天
写的很好啊,谢谢了,我刚开始使用springside
看了你的前一篇文章,觉得思路清晰多了,
我是使用maven 来管理的,但是maven 我刚开始接触
而springside的主页上的文档说的比较凌乱,应该是自己的技术太浅的缘故
能不能麻烦你写便关于maven 结合eclipse3.4的文章啊

# re: SpringSide 3 中的 Struts 2  回复  更多评论   

2009-01-16 11:23 by talangniao
如果我想使用FreeMarker作模板,
怎样配置映射到WEB-INF/ftl/下的.ftl文件?

# re: SpringSide 3 中的 Struts 2  回复  更多评论   

2009-01-16 11:27 by talangniao
使用FreeMarker作模板,是不是要进行配置namespace?
要怎样进行配置?

# re: SpringSide 3 中的 Struts 2[未登录]  回复  更多评论   

2009-02-11 10:49 by sniper
看了文章写的挺详细的,中间有个不明白的地方:prepareSave()和prepareInput()是如何调用的,因为看了Preparable接口只有一个方法prepare(),在实现接口时也只是一个空方法,不知道是如何调用到相应的prepare*方法的,希望能帮忙说明一下。

# re: SpringSide 3 中的 Struts 2[未登录]  回复  更多评论   

2009-02-11 10:57 by sniper
呵呵查看了一些关于PrepareInterceptor的文章,原来是拦截器中处理的。http://willson-tien.javaeye.com/blog/270596

# re: SpringSide 3 中的 Struts 2[未登录]  回复  更多评论   

2009-02-12 22:36 by haha
写得不错,谢谢。springside3还是有很多难点之处。下载的源代码注释不是很清楚,希望楼主能写更详细的springside的说明文档和流程结构图。 
再次感谢!

# re: SpringSide 3 中的 Struts 2  回复  更多评论   

2009-04-28 10:52 by fmq2008
user.action的 url 怎么在ss3中配置成user.html

# re: SpringSide 3 中的 Struts 2  回复  更多评论   

2009-05-06 11:17 by 海边沫沫
@fmq2008 
很简单,在Struts的配置文件中加入: 
<constant name="struts.action.extension" value="html">

# re: SpringSide 3 中的 Struts 2[未登录]  回复  更多评论   

2009-12-31 13:11 by bean
如何在原有的拦截器栈中增加配置一个自己的拦截器?
我添加后,不能起作用,代码如下
<package name="crud-default" extends="convention-default">

<interceptors>
<interceptor name="checkUserAndEncoding"
class="CheckUserAndEncodingIntercept" />

<interceptor-stack name="crudStack">
<interceptor-ref name="checkUserAndEncoding" />
<interceptor-ref name="store">
<param name="operationMode">AUTOMATIC</param>
</interceptor-ref>
<interceptor-ref name="paramsPrepareParamsStack" />

</interceptor-stack>
</interceptors>
<default-interceptor-ref name="crudStack" />
</package>

 

分享到:
评论

相关推荐

    struts2+spring3+hibernate3+jquery+springside 做一个OA2

    标题 "struts2+spring3+hibernate3+jquery+springside 做一个OA2" 提供了一个综合的Web开发框架组合,用于构建一个办公自动化(OA)系统。这个系统基于以下技术栈: 1. **Struts2**: Struts2是一个Java Web MVC...

    springside3与传统ssh区别

    - **Action层:** Springside3中Action层的设计主要依赖于Struts2的Convention插件,该插件能够自动识别和配置Action,使得Action的配置变得更加简洁。 - **示例代码:** ```java @Namespace("/security") public...

    springside3+ext源代码

    在这个名为“springside3+ext源代码”的项目中,开发者基于SpringSide3进行了扩展和改进。SpringSide3的核心价值在于它的模块化设计,这使得开发者可以快速地搭建起符合企业级标准的项目结构。通过引入EXTJS,项目...

    springside3.3完整版

    "ssh3.3"这个文件名暗示了SpringSide 3.3可能集成了Struts2、Hibernate和Spring,也就是常说的SSH框架。这三个框架的整合能够实现高效的MVC开发,Struts2处理请求和展示视图,Hibernate负责持久化操作,Spring则...

    springside框架

    《SpringSide框架详解:整合Spring、Hibernate与Struts2的高效解决方案》 SpringSide框架,作为一款基于Java的开源企业级应用开发框架,是开发者们为了简化开发流程、提高开发效率而精心设计的。它巧妙地融合了...

    springside-springside4-1dff3fc.zip

    在SpringSide 4中,Struts2用于处理HTTP请求,协调前端视图与后端业务逻辑,实现用户界面与应用逻辑的分离。 3. **Hibernate ORM**:Hibernate是一个对象关系映射(ORM)工具,它允许开发者用Java对象来操作数据库...

    springside3.3.4 使用方法

    在本文档中,我们将详细介绍如何使用Springside 3.3.4版本,并特别关注SSH(Spring + Struts + Hibernate)整合的方法。 #### 二、环境配置与准备 1. **安装Java JDK**: - 首先确保已经安装了Java环境,并且设置...

    STRUTS2:零配置插件CodeBehind

    Struts2框架作为Java Web开发中的一款重要工具,在简化Web应用程序开发方面提供了丰富的功能与灵活性。随着框架的发展,Struts2社区不断推出新的插件和技术来进一步简化开发流程。本文将详细介绍Struts2中的两个插件...

    Springside技术参考手册

    在SpringSide 3中,集成的主流技术包括Spring 2.5、Hibernate 3、Struts 2、JSP 2.0、JQuery、JAX-WS 2(通过Apache CXF 2实现)以及SpringSecurity 2.0。这些组件的组合使得SpringSide成为一个强大的开发工具,减少...

    springSide使用手册

    总的来说,SpringSide 提供了一种高效的项目初始化方法,通过 Maven Archetype 和 Velocity 模板,降低了项目创建的复杂度,同时利用 Struts2 的 Convention Plugin 实现了高度自动化配置,提高了开发效率。...

    springSide3框架的笔记参照.pdf

    SpringSide3的主要优点在于其自动化项目生成,能够快速启动新项目,并且支持多种技术栈,包括持久化层的Hibernate和Spring Jdbc,Web MVC的Struts2,视图层的JSP和JQuery,以及企业服务如Web Service(JAX-WS通过CXF...

    SpringSide

    2. **集成多种技术栈**:除了Spring核心框架外,SpringSide还支持如Struts、Hibernate、Spring Security等技术栈,提供了一站式的企业级应用开发解决方案。 3. **简化配置**:SpringSide对Spring框架的配置进行了...

    springside4-master

    在JavaEE领域,SpringSide4-Master涵盖了诸如Hibernate、Struts、JSF等其他主流框架的替代方案,展示了Spring的全面性和兼容性。它还涉及了RESTful API设计、JSON序列化、模板引擎以及前后端分离等现代Web开发技术,...

    springside

    这个压缩包中的springside-3.1.3.1-src是该项目的源代码,是学习和研究Spring框架整合的经典示例。 1. **Spring框架**:Spring是一个开源的Java平台,它为构建企业级应用程序提供了全面的编程和配置模型。其核心...

    springside3.0.4.all.in.one.zip

    它是Struts2框架的核心组成部分之一,在Struts2中用于处理数据模型与视图之间的映射关系。通过OGNL,开发者可以在不编写额外代码的情况下实现对对象属性的灵活访问。 #### Struts2-Core 2.0.11.2 Struts2是一个...

    Spring+Hibernate+Jpa+Struts2整合实例

    在本实例中,我们探讨的是如何将Spring、Hibernate、JPA(Java Persistence API)和Struts2这四个关键的Java Web开发框架进行整合。这些框架的集成为开发高效、可维护的Web应用提供了强大的支持。 首先,Spring是一...

Global site tag (gtag.js) - Google Analytics