Stripes是一个以让程序员的web开发简单而高效为准则来设计的基于动作的开源Java web框架。本文将介绍Stripes与其它如Struts之类基于动作的框架的区别和其提供的一些存在于Ruby on Rails之中的简单性。
Stripes是一个以让程序员的web开发简单而高效为准则来设计的基于动作的开源Java web框架。传统的Java
web开发着眼于借去耦(Decoupling)来实现其灵活性,但导致多个的配置文件,额外的对象,和其他资源的分散。这些困难造成相当多的程序员的更
高的学习时间和低下的效率。其结果是有些Java程序员被一些非Java的框架所吸引去了:Ruby on Rails或者Django。一些Java
web框架,如Stripes,正在开始从这些非Java框架中汲取其成功经验:简单而高效的开发。本文将介绍Stripes与其它如Struts之类基
于动作的框架的区别和其提供的一些存在于Ruby on Rails之中的简单性。
图1是典型的用Stripes写的应用程序中的正常事件流程和组件。
图 1 典型Stripes流程
|
如你所见,其流程基本上就是一个MVC框架。Stripes和其他的基于动作的框架的一个主要的区别是没有一个外部的配置文件。我们随后将看到,Stripes用annotation和约定而非配置来提高产出和减少杂乱。
编写你的第一个Stripe动作(Action)
让我们现在就开始通过创建Hello World例程来了解Stripes框架和理解其运作。HelloWorldAction类将提示
用户输入姓氏和名字然后在另一个View
里面显示,首先我们来编写controller类。
public class HelloWorldAction implements ActionBean
{
@ValidateNestedProperties(
{
@Validate(field = "firstName", required = true, on = {"hello"}),
@Validate(field = "age", required = true, minvalue = 13, on = {"hello"})
})
private Person person;
private ActionBeanContext context;
@DefaultHandler public Resolution index()
{
return new ForwardResolution("Hello.jsp");
}
public Resolution hello()
{
return new ForwardResolution("SayHello.jsp");
}
public void setPerson(String person) {this.person = person;}
public String getPerson() { return person;}
public void setContext(ActionBeanContext c) {this.context = c; }
public ActionBeanContext getContext() {return context; }} |
Controller类是一个实现了Stripes特有接口ActionBean的POJO(Plain Old Java
Object,译注:读破粥)。所有的Stripes动作类都要实现这一接口以让StripesDispatcher
servlet在运行服务时为其注入一个ActionBeanContext对象。ActionBeanContext对象可以让你存取的对象如
request、response、和servlet context等servlet
API。大多数时候在Stripes应用中是不用读取这些底层API对象的。
ActionBeanContext类还提供当前动作的状态并可以添加信息消息和错误消息到当前动作中。ActionBeanContext的变量和其读写方法可以放在一个基类里面,因为所有的Stripes动作都要实现之。
Controller类的其他部分对于任何Java程序员来说都是很面熟的。有一个Person对象和其读写方法是用来读写用户的姓名给view的。虽
然这仅仅是一个简单的嵌套对象,Stripes可以通过Java集合、泛型支持、和下标化的属性来实现更复杂完善的数据捆绑。因为Stripes可以处理
复杂数据捆绑,你的领域对象(Domain
Object)可以在其他需要它们的层重用。例如:通过Stripes你可以很容易的收集一个领域对象的信息,然后用其他的POJO框架,如
Hibernate或者EJB3来对其进行持久化。
Person对象变量上有一个Stripes验证annotation用来保证用
户在激活hello方法的时候已经输入了姓名。如果用户没有输入这两个必需的变量,原始页会被返回,并显示一个相关的错误消息。该验证只有在hello事
件被申请的时候才会被激活,因为annotation的属性中指定了(on =
{"hello"})。Stripes还会使用实用默认法则,根据验证方法和变量名称产生一个错误信息。例如,如果Person类的firstName变
量在提交的时候没有提供,用户将看到:
Person First Name is
a required field.
这条消息是通过将Person.firstName进行刻读化处理后得到的。如果有必要,这些错误消息可以被重载来提供更多的客户自定义功能。
另外还有一个Integer类型的变量age,是Person对象的一个属性。Stripes首先试图对request中命为person.age的
parameter转换为Integer类型,并将其捆绑到Person对象上。在Person对象的age变量被付值以后,Stripes将验证该
Integer值是否小于13。如果用户输入了一个字符串而非整数,用户得到这个消息:
The value (Mark) entered in field Person Age must be a
valid number.
若是用户输入了一个小于13的整数,用户将看到这个消息:
The minimum allowed value for Age is 13.
同样地,我们没有必要为这些错误消息提供任何外部的配置文件。Annotation提供的验证与你的变量在同一个位置上,使得程序员定位验证、理解验证的内容、和对验证进行维护变动更容易。
这个Stripes动作还有两个可被激活的方法(称为事件)。事件是ActionBean类中有如下特征的方法:
public Resolution eventName
请注意index方法被标注为@DefaultHandler
annotation。因为在本动作中有多个事件,其中一个必须被指定为默认事件。如果调用本动作的URL没有指定哪个事件,Stripes则查找标注有
@DefaultHandler annotation的事件,并执行。
显示层(View)
现在让我们给Hello
World例程加上显示层的逻辑。Stripes默认支持JSP为显示层的标准技术,不过你也可以用其他的显示层技术,比如FreeMaker。除了
Stripes的tag库以外,没有什么新的东西要学。Hello.jsp是初始的显示,可以让用户输入和提交姓名。
<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld" %>
......
<stripes:errors/>
<stripes:form beanclass="com. myco. web. stripes. action. example. HelloWorldAction"> Say hello to: <br> First name:
<stripes:text name="person.firstName"/> <br> Age:<stripes:text name="person.age"/><br>
<stripes:submit name="hello" value="Say Hello"/>
</stripes:form>
...... |
这个JSP易读易维
护。
而Stripes用于form和input的tag跟对应的HTML代码非常相似。stripes:form
tag包含一个beanclass属性,其值为我们前面定义的controller类的完整类名。我们可以用stripes:form中的action属
性来替换beanclass属性,但是beanclass属性可以让你在以后对Stripes动作进行重构的时候更加方便。如果你要用在
stripes:form tag中使用action属性,方法如下:
<stripes:form action="/example/HelloWorld.action"> |
有一个stripes:input
tag指定了一个名为person.firstName属性,其作用是将其储存的输入值付给controller的Person对象的firstName
变量中。最后,stripes:submit tag指定一个name属性来告诉Stripes的HelloWorldAction类使用哪一个事件。
我们现在已经完成了提交姓名的值给HelloWorldAction,剩下的就是在另一个view中将其反馈给用户了。
<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld" %>
......
<stripes:errors/>
<h2>Hello ${actionBean.person.firstName} your age is ${actionBean.person.age} </h2> <p/>
<stripes:link beanclass="com.myco.web.stripes.action. example.HelloWorldAction"> Say Hello Again
</stripes:link>
...... |
本JSP将自己通过一个对动作的引用读取person的姓名信息并显示。为达到这一目的,Stripes自动在request的属性中添加一个名为
actionBean动作对象,以供JSTL存取。最后,我们用了一个strips:link
tag来建立一个返回HelloWorldAction地链接从而可以让我们输入不同的姓名。我们以可以通过如下办法显式地创建一个指向index事件的
stripes:link:
<stripes:link beanclass="com.myco.web.stripes.action. example.HelloWorldAction" event="index">
Say Hello Again
</stripes:link> |
因为我们已经用annotation把index方法标记为@DefaultHandler,Stripes无须event属性也知道要执行哪一个方法。
用约定、不用配置文件
我们现在有了Java组件,我们该做配置了,把动作映射的一个URL上,并将其连接到我们的两个view
上面去。等一下!我们在用Stripes,我们不需要外部配置文件!
虽然这听来好像好得不像是真的,但这的确是Stripes的一项最具生产效率的功能。Stripes使用约定而非配置文件来映射动作到URL上。我们也
无须使用一个外部配置文件来把view映射到一个个标记名字上。这意味着程序员不用再为了一个标记名字——比方说SUCCESS——的实际来源,而在配置
文件中跳来跳去了。没有必要在Java和view组件的外部进行配线,因而导致更好地维护性和更高的生产率。
Stripes是如何提
供隐式的URL映射而无需在外部配置每一个动作或者而外的annotation呢?这个可以从Stripes在web.xml中的配置以及它是如何通过实
用默认法建立URL映射来解释。首先,我们来看看Servlet过滤器:StripesFilter。其在web.xml中的默认配置如下:
<filter>
<display-name>Stripes Filter</display-name>
<filter-name>StripesFilter</filter-name>
<filter-class> net.sourceforge.stripes.controller.StripesFilter </filter-class>
<init-param>
<param-name>ActionResolver.UrlFilters</param-name>
<param-value>/WEB-INF/classes</param-value>
</init-param>
</filter> |
当Servlet容器启动的时候,StripesFilter对其init-param元素执行初始化。其中最重要的init-param元素就是
ActionResolver.UrlFilters参数。这个参数告诉Stripes到哪里查找跟Stripes有关的类。这个例子里
面,Stripes将查找/WEB-INF/classes目录下的所有实现ActionBean接口的类。每一个被找到的类和其绑定的URL都将被加入
一个Map
中。
让我们来看看Stripes是如何处理我们的HelloWorldAction动作为例子吧。因为HelloWorldAction类位于/WEB-
INF/classes目录下,所以会被认为是一个Stripes
servlet。在我们的例子当中,其完整类名是
com.myco.web.stripes.action.example.HelloWorldAction。随后,其完整类名将按照如下法则被翻译成
一个URL绑定。
1. 将含有www、web、stripes、和action的部分及其以前的内容删掉。在我们的例子有三个上述单词,所以我们得到了example.HelloWorldAction。
2. 如果类名中包涵带Action或Bean的尾巴,删掉。因为我们的类名以Action结尾,我们得到了example.HelloWorld。
3. 将.替换为/,我们得到了example/HelloWorld。
4. 最后,添加上一个尾缀(默认是.action)从而完成了URL绑定。最后的结果是example/HelloWorld.action。
现在Stripes找到了ActionBean类并为其创建了一个URL绑定,然后存放在一个java.util.Map<String,
Class<? extends
ActionBean>>之中。其中key参数是URL绑定,value参数是实现ActionBean的类名。下面是我们的例子中的Map:
URL绑定:/example/HelloWorld.action
ActionBean类:com.myco.web.stripes.action.example.HelloWorldAction
我们要看的第二个组件是Stripes如何把URL绑定翻译成你正在做的这个ActionBean类。这是Stripes调度servlet的职责,在web.xml中的配置如下:
<servlet>
<servlet-name>StripesDispatcher</servlet-name>
<servlet-class>
net.sourceforge.stripes.controller.DispatcherServlet </servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>StripesDispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping> |
StripesDispatcher的一个职责就是将URL解析为Stripes的ActionBean类。当用户激活URL
http://host/uri/example/HelloWorld.action的时候,Stripes调度servlet将在URL映射表中查询
并找到com.myco.web.stripes.action.example.HelloWorldAction类,并实例化产生该类的一个实例。最
后,index方法被激活,因为在annotation中它被定义为默认局柄而在该URL中并没有指定一个事件。
如果我们想要直接执行HelloWorldAction中的hello方法怎么办?应该象下面这个URL这样把事件的名字放在request的参数中:
http://host/uri/example/HelloWorld.action?hello=&firstName=Mark&age=13
请注意我们没有给hello这个request参数名指定任何值。在这个情况下,StripesDispatcher会把hello这个这个
request参数名和HelloWorldAction类中个一个带有public Resolution
hello()签名的函数识别并映射。该方法名城在初始化的时候为了性能而缓存在另一个Map中。
我们已经看到Stripes的基础
以及如果创建简单的动作和一些该框架是如何运作的细节。通过在web.xml中的初始化,我们能够避免用多个单独的XML配置文件来把我们的显示层组建写
在一起。这很重要,原因如下:首先,如果你需要任何改动,你可以看到一个URL就立即知道你该查看哪一个类。其次,我们不需要任何单独的工具来在你的配置
文件过大而且不可管理的时候帮助你。通过消除掉配置文件,我们不再需要给框架一大堆的metadata。最后,我们不再需要为一个独立的用来描述我们的组
件是如果相互关联的文件来一刻不停维护了。
Ajax
要不要更高级的功能?那我们就来看看Stripes是怎么处理Ajax的。我们将把先前的Hello World例程改成使用Ajax调用Stripes动作。本例子的源代码
可以在本文资源中找到。首先,我们对Hello.jsp作改动使其引用Prototype JavaScript函数库。我们还要为Ajax调用增加一个JavaScript函数,并更改提交按钮为其添加一个onclick事件:
<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld" %>
......
<script src="${pageContext.request.contextPath}/js/prototype.js" type="text/javascript">
</script>
<script type="text/javascript">
function sayHelloAjax(){
var myAjax = new Ajax.Updater('hello', "<stripes:url beanclass="com.
myco. web. stripes. action. example. HelloWorldAction"
event="sayHelloAjax"/>", { method: 'get', parameters:
Form.serialize('helloForm') });
}
</script>
......
<stripes:errors/>
<stripes:form beanclass="com. myco. web. stripes. action. example. HelloWorldAction" id="helloForm">
Say hello to:
<br> First name:
<stripes:text name="person.firstName"/><br>
Age:<stripes:text name="person.age"/><br>
<stripes:button name="helloAjax" value="Say Hello" onclick="sayHelloAjax()"/>
<div id="hello"></div>
</stripes:form> ...... |
stripes:button有一个onclick事件将会调用HelloWorldAction类中的sayHelloAjax方法并将其结果返回在一个叫hello的div tag中。下面是我们要在HelloWorldAction中介绍的一个新方法:
public Resolution sayHelloAjax()
{
return new ForwardResolution("SayHelloAjax.jsp");
} |
这个方法没有多少工作,因为Stripes已经承担了姓名内容的绑定。因此,本方法唯一的责任就是转发到一个叫SayHelloAjax.jsp的页面片断上去。该叶面片段的内容如下:
<h2>Hello ${actionBean.person.firstName} your age is ${actionBean.person.age}!</h2> |
Spring整合
Stripes还内置了对Spring支持。你可以自动地将Spring bean诸如到你的动作中。按照Stripes的风格,除了Spring上下文配置文件以外不需要任何外部配置文件。如果我们Spring的配置文件如下:
<bean id="personService" parent="abstractTxDefinition">
<property name="target">
<bean class="com.myco.service.impl.PersonServiceImpl"/>
</property>
</bean> |
要把person服务注入到一个Stripes动作中,得增加一个跟Spring
bean的名字一致的属性和setter。Stripes提供了@SpringBean annotation来查询正确的Spring
bean以注入到动作之中。下面是我们要在动作类中包含的例子:
private PersonService personService;
@SpringBeanpublic void setBlogService(BlogService blogService)
{
this.blogService = blogService;
} |
本文无法囊括Stripes的所有高级功能。但是,Stripes有非常完整的文档。Stripes还包含了一个与Tiles类似但无需外部配置文件的layout管理器。另外,拦截器还可以用于生命周期事件的各处、文件上载等等等等。
结论
Stripes是一个既强大又简单的Java web框架。Stripes利用了Java 5
的annotation和泛型功能,从而使得Java程序员避免维护外部配置文件并增加工作效率。Stripes可以简化困难的web开发工作,并使得简单的工作更加简单!
分享到:
相关推荐
2. **简单的MVC模式**:Stripes实现了Model-View-Controller(MVC)架构模式,Action类代表控制器,负责处理用户请求,与模型交互,并将结果传递给视图进行展示。 3. **事件处理**:Stripes通过事件驱动的方式来...
5. **RESTful支持**:通过使用ActionBean和URL映射,Stripes可以轻松实现RESTful接口,支持HTTP动词如GET、POST、PUT、DELETE等,使得Web服务更加标准化。 6. **Servlet集成**:Stripes是一个Servlet过滤器,可以与...
总的来说,Stripes框架通过Java注解简化了Web开发的配置,使得开发者能够更专注于业务逻辑的实现。它提供了一个务实的开发理念,既适合新手也适合有经验的开发者。《Stripes and Java Web Development Is Fun Again...
### 在Stripes中实现Excel表格下载的关键技术点 #### 一、Stripes框架简介 Stripes是一个基于Java的Web应用开发框架,它采用MVC(Model-View-Controller)架构模式设计,旨在简化Web应用程序的开发流程。相较于...
Stripes框架的核心理念是“约定优于配置”(Convention over Configuration),这意味着开发者可以通过遵循框架提供的约定来减少不必要的配置工作,从而更加专注于业务逻辑的实现而非繁琐的配置细节。这一特点使得...
Ajax技术的集成也是Stripes的一大特点,Stripes简化了Ajax调用的实现,提供了示例来展示如何使用Ajax进行即时检测账号的合法性,或者重新获取验证码等。 最后,Stripes支持单元测试,这包括使用TestNG进行测试,...
1. **ActionBeans**:Stripes 中的动作类被称为 ActionBeans,它们是实现了特定接口的 POJO(Plain Old Java Object),用于处理来自用户的请求。 2. **ActionBeanContext**:这是一个由 Stripes Dispatcher Servlet...
Stripes-Components利用React的生命周期方法、状态管理和props机制,实现了组件的可复用性和可扩展性。同时,React的单向数据流和声明式编程方式使得代码更易于理解和调试。 三、组件库的构建 Stripes-Components...
【标题】"Python-d3stryr3stripes的Python3实现"主要涉及到的是一个Python3版本的项目,该项目可能是对某个特定算法或工具的实现,名为d3stryr3stripes。在Python社区中,这样的项目通常是由开发者分享的代码库,...
例如,表单中的输入字段可以直接映射到Action Bean的属性,通过`@Bind`注解实现。 3. **URL映射**:Stripes使用简单的URL结构,通过Action Bean的类名和方法名来映射URL。这使得URL更易读,也便于搜索引擎优化(SEO...
9. **Ajax支持**:通过ActionBean和事件机制,Stripes可以轻松地与Ajax技术结合,实现页面的部分更新,提供更流畅的用户体验。 10. **JSP和FreeMarker视图**:Stripes可以与JSP或FreeMarker模板引擎配合使用,方便...
这些例子通常包括ActionBean的实现、JSP页面以及可能的配置文件(如web.xml和Stripes.xml)。通过分析和运行这些示例,你可以了解如何设置事件、如何处理用户输入、如何进行验证,以及如何与视图进行交互。 总之,...
4. Stripes框架在Ajax中的应用:Stripes框架可以和Ajax技术结合,实现快速简洁的Ajax开发,提高用户体验和数据传输速度。 5. Ajax数据传输格式和方案:文中提出了多种Ajax数据传输格式,例如JSON、XML等,并提出了...
此外,可能还需要配置一些基本设置,如菜单、小工具和页面模板,以实现模板的全部功能。 总的来说,Wordpress Blue Stripes模板提供了一个优雅的蓝色条纹设计,结合了易用性和灵活性,为WordPress用户打造一个既...
本项目——"stripes+spring+mybatis项目源码下载",便是一个将条纹(Stripes)、Spring和MyBatis三大框架融合的实例,旨在实现一个简洁的网上宠物商店应用。接下来,我们将深入探讨这三个技术的核心概念以及它们在...
改写至mybaits提供的示例程序,将Stripes实现改为maven管理的,mybatis+spring mvc项目,使用sitemesh装饰。提供完整的宠物商店,支持开发模式和应用模式,只需要修改web.xml文件中的spring.profiles.active属性为...
条纹核心版权所有 (C) 2016-2019 开放图书馆基金会该软件是根据 Apache 许可证 2.0 版的条款分发... 通过示例展示了件——有些是连接的,有些不是——如何协同工作以实现应用程序的一部分。 请注意,这有点过时,但仍然
首先,"Table Stripes"是指在HTML表格中实现的一种视觉设计技巧,通过为交替的行添加不同的背景色,使得表格内容更易于阅读和理解。这通常通过CSS(层叠样式表)来实现,使用`nth-child`选择器或者`odd`和`even`伪类...
然而,JSF也存在一些不足,如过多依赖JSP标签,对于RESTful架构和安全功能的支持不足,以及不同实现之间的差异(如SUN的实现和Apache的MyFaces实现)。 **Spring MVC** Spring MVC以其强大的生命周期管理和与多种...