posts - 78, comments - 34, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2010-02-24 传智播客—Struts2

Posted on 2010-02-25 21:32 長城 阅读(569) 评论(0)  编辑  收藏

       Struts2第四天,正如预期Struts2的内容还没有讲完,还需要再加一天课。按照正常的授课方式,Struts2在四天内是可以讲完的,但这可能是老张最后一次讲Struts2,所以他要讲得细致些。

 

       今天的重点内容是Struts2的表单错误信息排版、Struts2中的FreeMark、和Struts2中的UI标签。老张计的比较细致,我做总结就不做的那么细致了。

 

一、Struts2的表单错误信息排版

       Struts2的表单错误信息排版是一个比较常见的问题,但网给所见到的解决方案似乎并不正统。老张给出了他的解决方法。

 

       通过之前的学习,我们知道Struts2中的大部分数据交互操作是由ValueStack来完成的。错误信息也是如此。我们在后台使用配置文件校验或硬编码校验,Struts2将错误信息存放在类型为MapfieldErrors对象中。

 

       我们可以在页面表单字段的后边添加此错误信息,比如在user.name表单字段后边添加<s:property value="fieldErrors['user.name'][0]"/>,这样错误信息可以显示在对应的字段后边。这是针对我们使用非struts2ui标签时(使用提htmlui标签)。但这里有一个问题,如果我的表单字段特别的多,难道我要手动为每个字段添加一个这样的错误信息,这多少有些麻烦,而且以后字段有什么变化还需要行动更改...

 

       Struts2在各方面都做的非常细致和人性化,Struts2UI标签等主要是使用FreeMark来实现的。Struts2使用FreeMar来实现模板和主题,那么我们回显表单数据和错误信息也可以使用FreeMark来实现。此时我们的表单需要使用struts-tags提供的标签来定义,然后我们修改它的ftl模板文件。

 

       下面我们看看一下应该如何修改ftl模板文件,我们以UI标签<s:textarea>为例。Struts2的模板文件存在哪?在Struts2的核心包中的template.xhtml中,textarea.ftl文件内容:

<#include "/${parameters.templateDir}/${parameters.theme}/controlheader.ftl" />

<#include "/${parameters.templateDir}/simple/textarea.ftl" />

<#include "/${parameters.templateDir}/xhtml/controlfooter.ftl" />

      

       我们只需修改 controlheader.ftlcontrolfooter.ftl即可,难道我们需要修改Struts2核心包中的内容?当然不用,这一点Struts2已经为我们考虑到了。我们将这两个文件解压缩并放到WebRoot目录下的”template/xhtml”目录,必须是xhtml目录。看default.properties文件中的这断配置:

### Standard UI theme

### Change this to reflect which path should be used for JSP control tag templates by default

struts.ui.theme=xhtml

struts.ui.templateDir=template

#sets the default template type. Either ftl, vm, or jsp

struts.ui.templateSuffix=ftl

Struts2会先到我们的WebRoot目录搜索相关ftl文件,如果没有才到自己的包中找。

 

       我们的目标,要使用Struts2UI标签并将错误信息显示在标签的旁边。所以我们修改这两个文件的内容为:

controlheader.ftl

<#--

       Only show message if errors are available.

       This will be done if ActionSupport is used.

-->

<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors[parameters.name]??/>

<#if parameters.labelposition?default("") == 'top'>

    <td align="left" valign="top" colspan="2"><#rt/>

<#else>

    <td class="tdLabel"><#rt/>

</#if>

<#if parameters.label??>

    <label <#t/>

<#if parameters.id??>

        for="${parameters.id?html}" <#t/>

</#if>

<#if hasFieldErrors>

        class="errorLabel"<#t/>

<#else>

        class="label"<#t/>

</#if>

    ><#t/>

<#if parameters.required?default(false) && parameters.requiredposition?default("right") != 'right'>

        <span class="required">${stack.findValue("getText('requiredmark')")}</span><#t/>

</#if>

${parameters.label?html}<#t/>

<#if parameters.required?default(false) && parameters.requiredposition?default("right") == 'right'>

 <span class="required"><@s.text name="requiredmark"></@s.text></span><#t/>

</#if>

${parameters.labelseparator?default(":")?html}<#t/>

<#include "/${parameters.templateDir}/xhtml/tooltip.ftl" />

</label><#t/>

</#if>

    </td><#lt/>

<#-- add the extra row -->

<#if parameters.labelposition?default("") == 'top'>

</tr>

<tr>

</#if>

 

controlfooter.ftl

${parameters.after?if_exists}<#t/>

    </td><#lt/>

<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors[parameters.name]??/>

<#if hasFieldErrors>

    <td ><#rt/>

<#list fieldErrors[parameters.name] as error>

        <span class="errorMessage">${error?html}</span><#t/>

</#list>       

    </td><#lt/>

</#if>

<#--

       if the label position is top,

       then give the label it's own row in the table

-->

<tr>   

</tr>

 

至于为什么这么修改,一看便知,我就不多做解释了。

 

二、Struts2如何使用Freemarker

       Struts2是如何使用Freemarker的?在struts2的核心包中有一个default.properties配置文件,Struts2的默认配置都在这个文件中。有一些配置是开启的有一些配置是关闭的。我们要想打开被关闭的配置可以在struts.xml中,添加<constant name="配置项名" value="配置项值"></constant>元素。

 

       default.properties中有一个struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager配置,Struts2是通过FreemarkerManager类来实现对Freemarker的操作的。

 

       通过查看源代码,我们知道通过调用FreemarkerManager类的buildTemplateModel方法生成一个model对象,然后将这个对象放在ValueStack中提供给Freemarker的引擎使用。model中都包含发哪些数据?Freemark的模板信息自然不用说,它还包含RequestApplicationResponse等这些在WEB应用中常用到的对象。具体我就不详细列出了,大家可以查看源代码。我们在上边两个模板文件中使用到的 parameters.name也是存储在model中的。

 

       在此特别提出一个被叫做UIBean的类型,UIBean就是对应Struts2UI标签的对象实体。比如标签有namethemeid等数据,这些都会被封装到UIBean中。Freemarker也正是使用这个东东给我们生成了相应该的页面文件。    

 

三、Struts2中的UI标签

       关于各UI标签的详细使用方式,在此就不做总结了。

 

       在实际开发中有一个重要的问题需要我们解决,比如有一个选择个人喜好的表单。我们需要通过一个Action的方法(likesUI)将喜好列表提供给页面,可以让用户选择。但在应用提交选择进行表单校验时,用户提交的数据不合法,我们需要重新返回到用户选择的界面。此时,我们需要调用 likesUI,获取列表将数据提供给用户选择的界面。

 

       我们可以在Action中添加”<result name="input" type="chain">likesUI</result>”,使其发生错误时直接跳转到likesUI,我们也需要在likesUI中添加一个 名称为inputresult标签,但这个标签的值不能为likesUI,否则会递归调用,直到缓存溢出。我们应将它的值指定为likesUI.jsp页面。但即使指定了这个页面,Struts2的内部实现方式也不会调用likesUI方法从,不会将数据传递给likesUI.jsp页面,而它直接跳转到likesUI.jsp页面。

 

       看来我们不能这么做,通过张老师对源代码的详细解析,我们只需要将likesUIAction中的likesUI的方法命名为input(),并只在likeUIAction中添加”<result name="input">/WEB-INF/pages/user/likesUI.jsp</result>“即可。为什么呢?

 

       在表单校验发生错误并使用 chain进行跳转时,会被chain拦截器给拦截了(ActionChainResult)。然后又会被拦截器validation给拦截了,它再进行表单校验进还是以前的数据,还是会出错然后它就直接跳转到我们指定的页面了。注意配置文件中的validation

<interceptor-ref name="validation">

       <param name="excludeMethods">input,back,cancel,browse</param>

</interceptor-ref>

它忽略请求为 input,back,cancel,browse请求路径。所以我们需要将我们的方法名定义为 input()

 

       我只是泛泛而结,如果想了解Struts2的更多细节请下载老张的视频看吧!

 

       最后送给大家一个Struts2开发用例参考模式图:

clip_image002
       1.用户申请注册,打开注册页面。

       2.用户提交注册申请,表单校验错误。

       3.表单校验错误不要跳转到regUser.jsp页面,而是应该跳转到RegUserUI这个Action方法。

       4.用户提交注册申请,表单校验通过。

       5.表单校验通过,调用RegUser这个Action方法进行注册。

       6.注册成功后,不要跳转到list.jsp页面。而是应该调用ListAction这个Action方法。

       7.ListAction获取所有用户信息后,跳转到list.jsp

 

       一定要记得老张还有一天的Struts2的课程,下一次课程的重点内容应该是Struts2的文件上传与下载,Struts2的防止表单重复提交,Struts2SpringAJAX整合,Struts2的插件。

 

       接下来的课程内容让我等的好久啊——Android!虽然听学习过的同学们说十分简单,但我还是迫不及待的想Android的一睹真容。我想很多人都是这样吧!那就关注我接下来6天课程的总结日志吧!


只有注册用户登录后才能发表评论。


网站导航: