疑问:关于使用Validator框架后,显示错误信息的问题。

 我发现:使用Validator框架后,

只能使用<html:errors/>显示错误信息,

不能使用诸如:<html:errors property="error1"/>显示指定的错误信息。

我现在需要这样显示错误,

比如:用户名没有填写的话,只在用户名旁边显示错误信息;

如果Email填写不符合标准,只在Email旁边显示错误信息。

我不希望把所有错误都一起显示出来。

可以用Validator实现吗?

因为我不知道如何实现那个目的,

所以,只好把验证的部分放到ActionForm的validate方法中,

这样就可以指定每一个不同的错误信息,以便在错误页面按要求显示了。

可是,每个验证逻辑都需要自己来写,

org.apache.struts.validator.FieldChecks这个类是Validator框架使用的验证类,

里面有很多现成的方法,由于我没有使用这个框架,

所以就无法使用这些现成的方法了(也可能是我不知道如何使用)。

我想知道:有没有现成的验证方法可以下载到?

例如必填、合法日期、合法Email等等。

请前辈指点。

开始Struts的日记。

今天终于对《Jakarta Struts编程》看了一个大概,

准备搭建一个环境进行进一步学习。

我将下载的status-1.2.7.tar.gz解压缩后,

把lib目录中的status.jar、jstl.jar和standard.jar拷贝到了WEB-INF的lib目录中,

起动服务器后,竟然一个劲儿的抛出异常,

郁闷死……

最后,把所有的jar文件都拷贝到WEB-INF的lib目录后,

才解决了问题。

回过头再看书,才发现,

书上已经写的很明白了,只怪当时没有注意到。

看来,看书还是要仔细一些。

又或是,水平不够,所以注意不到书上说的内容的重要性。

(转帖)Struts-menu源码分析

(转自:http://champion.ewuxi.com/old/opensource/struts-new/strutsmenu.htm)

Struts-menu源码分析

        好的代码读起来让人如饮醍醐,读完以后神清气爽。如果你想提高你的编程水平,如果你想提高你的设计能力,如果你也想成为大师,那么就去阅读代码吧。以本人十几年来的编程经验,阅读代码能让你得到的比阅读文章(那怕是大师的文章)得到的更多。优秀而且实用的代码有很多,比如Junit,比如Jive,比如petStore,甚至是tomcat的Example、Log4j的Example。

        一段广告完毕,下面就为大家分析一下struts-menu的源码,作为送给大家的圣诞礼物吧。Struts-Menu也来自一位大师的作品, Matt Raible。有很多优秀的作品,比如使用struts和hibernate的struts-resume。官方网站是http://raibledesigns.com/wiki/Wiki.jsp?page=Main。Struts-Menu的最新版本是2.1。功能是使用struts技术,构建树形菜单。应该说是一个非常实用的技术,极大的方便了广大的开发人员。与此同时,个人认为它的作用还不止于些。比如,同时它也是一个使用Maven和velocity的一个很好的例子。

        首先,我们去看一下它的效果。http://www.raibledesigns.com/struts-menu/。可以看到,如此丰富多彩的菜单效果,都是在演示一个配置文件里的内容。这是一个非常好的数据与表示相分离的实现。我们打开它的源码来看。首先看一下它的包图

共有五个包,其中menu自然是完成数据组织功能,是核心之一,displayer是显示方式包,完成数据显示大部分功能。也是核心之一。taglib意义明显。example自然是一些example。util是读取资源文件的包。因些,我们重点研究的包只有三个menu,displayer和taglib。

首先我们来看menu包的类图

首先是MenuPlugIn这个类。这个类的功能很明显,就是一个struts的plug-in。可以看到,它只有一个参数menuConfig,就是menu的配置文件路径。果然,在struts-conf文件中有这么一段

  <!-- ========== Plug Ins Configuration ================================== -->

<plug-in className="net.sf.navigator.menu.MenuPlugIn">

<set-property property="menuConfig" value="/WEB-INF/menu-config.xml"/>

</plug-in>

 

 

说明配置文件来自于/WEB-INF/menu-config.xml,当然,我们可以找到相应路径下找到这个文件。如果你以前没有做过struts的plug-in,现在该知道怎么做了吧,就这么简单。通过阅读初始化函数,知道它的功能就是调用MenuRepository来建立菜单。因此。我们知道MenuRepository必然是一个组织管理管理菜单的组织类。

public void init(ActionServlet servlet, ModuleConfig config)

throws ServletException {

if (log.isDebugEnabled()) {

log.debug("Starting struts-menu initialization");

}

this.servlet = servlet;

repository = new MenuRepository();

repository.setLoadParam(menuConfig);

repository.setServlet(servlet);

try {

repository.load();

servlet.getServletContext().setAttribute(

MenuRepository.MENU_REPOSITORY_KEY,

repository);

if (log.isDebugEnabled()) {

log.debug("struts-menu initialization successfull");

}

} catch (LoadableResourceException lre) {

throw new ServletException(

"Failure initializing struts-menu: " + lre.getMessage());

}

}

 

打开MenuRepository类,我们可以看到这个类也很简单,不过已经有少可以学习的了。首先是FastHashMap,可以看到,这个类里有三个FastHashMap。顾名思议,是快速HashMap了,再看一下,它来自org.apache.commons.collections.FastHashMap;。看到org.apache.commons这个著名的包了?如果你以前从没使用过它,那么建议你花上一段时间去研究使用它,我保证物有所值。

protected FastHashMap menus = new FastHashMap();

protected FastHashMap displayers = new FastHashMap();

protected FastHashMap templates = new FastHashMap();

接下来我们看到log的定义。对了,log,调试的核心之一。而下面这一句则是commons log的最常用的使用方法。快快让你的程序使用上commons log吧,第一,它功能强大,第二,它使用简单,就是这么简单。

private Log log = LogFactory.getLog(getClass().getName());

下面看一个的函数

 protected Digester initDigester() {

        Digester digester = new Digester();

        digester.setClassLoader(Thread.currentThread().getContextClassLoader());

        digester.push(this);

        //digester.setDebug(getDebug());

        // 1

        digester.addObjectCreate("MenuConfig/Menus/Menu",

            "net.sf.navigator.menu.MenuComponent", "type");

        digester.addSetProperties("MenuConfig/Menus/Menu");

        digester.addSetNext("MenuConfig/Menus/Menu", "addMenu");

        // 2

        digester.addObjectCreate("MenuConfig/Menus/Menu/Item",

            "net.sf.navigator.menu.MenuComponent", "type");

        digester.addSetProperties("MenuConfig/Menus/Menu/Item");

        digester.addSetNext("MenuConfig/Menus/Menu/Item", "addMenuComponent",

            "net.sf.navigator.menu.MenuComponent");

        // 3       

        digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item",

            "net.sf.navigator.menu.MenuComponent", "type");

        digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item");

        digester.addSetNext("MenuConfig/Menus/Menu/Item/Item",

            "addMenuComponent", "net.sf.navigator.menu.MenuComponent");

        // 4

        digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item/Item",

            "net.sf.navigator.menu.MenuComponent", "type");

        digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item/Item");

        digester.addSetNext("MenuConfig/Menus/Menu/Item/Item/Item",

            "addMenuComponent", "net.sf.navigator.menu.MenuComponent");

        // 5

        digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item/Item/Item",

            "net.sf.navigator.menu.MenuComponent", "type");

        digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item/Item/Item");

        digester.addSetNext("MenuConfig/Menus/Menu/Item/Item/Item/Item",

            "addMenuComponent", "net.sf.navigator.menu.MenuComponent");

        // 6

        digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item/Item/Item",

            "net.sf.navigator.menu.MenuComponent", "type");

        digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item/Item/Item");

        digester.addSetNext("MenuConfig/Menus/Menu/Item/Item/Item/Item",

            "addMenuComponent", "net.sf.navigator.menu.MenuComponent");

        // 7

        digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item/Item/Item",

            "net.sf.navigator.menu.MenuComponent", "type");

        digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item/Item/Item");

        digester.addSetNext("MenuConfig/Menus/Menu/Item/Item/Item/Item",

            "addMenuComponent", "net.sf.navigator.menu.MenuComponent");

        digester.addObjectCreate("MenuConfig/Displayers/Displayer",

            "net.sf.navigator.displayer.MenuDisplayerMapping", "mapping");

        digester.addSetProperties("MenuConfig/Displayers/Displayer");

        digester.addSetNext("MenuConfig/Displayers/Displayer",

            "addMenuDisplayerMapping",

            "net.sf.navigator.displayer.MenuDisplayerMapping");

        digester.addSetProperty("MenuConfig/Displayers/Displayer/SetProperty",

            "property", "value");

           

        return digester;

    }

 

这里又是一个经典,digester,Digester的使用,如果你需要读一个XML配置文件,并且不想与DOM直接打交道的话,Digester将是一个很好的选择。实际上我们看到load函数调用一句 digester.parse(input);就已经把menu-config.xml建立到内存里了,就这么简单。如果你想要初始化你的系统,这种方法是不是可以学习呢?"工欲善其事,必先利其器"。我们可以看到Raible是怎么样利用现有的工具来减轻开发量的。

由于MenuRepository举重若轻的初始化过程,甚至都没有让我们看到树形结构是怎么建立到内存里去的。不过不要着急,类图给我们了明示。

看到MenuBase类了吗?对了,看名字就知道是一个Menu的基类。可以看到,它是一个简单的JavaBean。而且相信它的每个属性大家根据名字也能猜出来。所以重点讲解是MenuComponent,一个简化的 "Composite"模式。

如上图所示。由于此处的Leaf没有任何方法,只有属性。因此Leaf和Composite收缩成了一个MenuComponent类。大家都知道,Composite模式是实现树形结构最好的方法。如果你以前没有机会实现或者没有从Composite模式得到好处,那么,从这里看一下用Composite模式得到的好处。首先看它的简单,MenuComponet的实际代码很少,加起来不到十行。

public void addMenuComponent(MenuComponent menuComponent) {

        menuComponents.add(menuComponent);

        menuComponent.setParent(this);

        if ((menuComponent.getName() == null) ||

                (menuComponent.getName().equals(""))) {

            menuComponent.setName(this.name + menuComponents.size());

        }

    }

    public MenuComponent[] getMenuComponents() {

        MenuComponent[] menus =

            (MenuComponent[]) menuComponents.toArray(_menuComponent);

        return menus;

    }

 

如果你用十行来实现一个树型结构(并且还是通用的),你愿不愿意?就是通过简单的这么一些代码,实现的在内存中建立树型结构的目标。

下面我们来看DispLay包,这个包的功能也是很清楚的,就是用来显示啦。这个包的类图非常漂亮,遗憾的是也非常大。只能缩小了给大家看了。

从类图中可以看到一个非常极漂亮的面象对象的设计思路。通过一个接口,利用模板方法。最后具体实现树型结构的显示。其主要方法是displayComponents和display这两方法,init方法则实现了初始化的工作,读取javascript和图片等文件。displayComponents是一个迭代函数。从而可以遍历一个MenuCompont树。并将其显示出来。

应该说,Menu包是一个M层,而Dispplya包是一个view层,而加上TagLib包,就实现了MVC的完整结构。

两个Tag类很清楚,首先我们从怎么使用它来看它们实现的功能

<menu:useMenuDisplayer name="ListMenu"

bundle="org.apache.struts.action.MESSAGE">

        <menu:displayMenu name="ToDoListMenuFile"/>

        <menu:displayMenu name="ToDoListMenuEdit"/>

        <menu:displayMenu name="CaseDetailMenuCase"/>

        <menu:displayMenu name="Standalone"/>

</menu:useMenuDisplayer>

显而易见。useMenuDisplayer这个类是实现使用哪一种显示方式。在menu-config里我们看到ListMenu的定义

<Displayer name="ListMenu"

type="net.sf.navigator.displayer.ListMenuDisplayer"/>

displayMenu则是取得一菜单,并将其显示出来,同样在menu-config也能找到。

<Menu  name="ToDoListMenuEdit"  title="EDIT">         <Item  name="TDLselect" title="SELECT_ALL"       image="images/select-all.png"                    location="index.jsp" width="100" />         <Item  name="TDLprefs"  title="USER_PREFERENCES" image="images/prefs.png"                    location="index.jsp" width="150" />         <Item  title="Action Test" action="setPermissions?displayer=${displayer}"/></Menu>

 

查看 DisplayMenu的代码,可以看到。它完成的功能只是从context里取得MenuComponent对象,然后通过 displayer.display(menu);把它交给一个MenuDisplayer的实例来负责画出来。

因此,Control层很好的完成了控制的功能。

综上所述。通过这样一个优美的设计,把各个功能都他离开来了。如果我们需要增加一种显示方式,只要继承MenuDisplayer或它的一个子类,然后写出我们的方法,而不需要修改系统的其他部分。同样的,如果我们的菜单不准备存放在ServletContext而准备存放在比如Session里了,那么我们也只需要修改control部分和生成部分(即MenuRepository)部分。而不影响Display部分。

OK,对struts-menu的介绍结束了,下一篇文章将是如果使用struts-menu和数据库技术动态生成菜单了。请大家继续关注我的网站。

 

 

紫龙,于12/22/2003 16:45:09

蓝色天空版权所有

 

使用静态常量的注意事项

  两个*.java文件,一个是静态常量,一个是使用静态常量的。含有静态常量的文件在我本地和虚拟空间的内容是不一样的,使用静态常量的文件是一样的。我在本地更新了使用静态常量的那个文件,上传到虚拟空间后发现,这个文件引用的是本地的静态常量。

  反编译使用静态常量的那个*.class文件,发现引用静态常量的变量统统都是本地的静态常量值。

  原来,java中使用的静态常量是编译时就固定了,并不是运行时间的动态调用。看来,有必要学习一下java运行的基本原理。

使用标记的怪现象

       <html:select property="parentID" name="oldAdvice">

         <html:options collection="processGoalsList" property="articleID" labelProperty="articleName"/>

       </html:select>

  上面代码的作用是把一个包含同样对象的List中的对象显示到下拉列表中,其中默认为对象“oldAdvice”,本来这个用法在资料中说得很清楚,我用它却出现了至今也想不通的怪现象两次。就是我按照正确的方法写了代码后,运行中却始终得不到正确的效果。我不知道是eclipse或tomcat的问题。

  以后为了保险起见,遇到自己不熟悉的代码编写后,运行时要:1、删除程序运行的work目录;2、重新编译源程序;3、重新启动tomcat服务器。

  我想,这样总不会再扯拐吧?

疑问:不知道在Struts标签中怎么引用jsp片断里的变量

如下面这段代码:

      <td width = "30%" align="center">

        <%/* pseudo code:

           * get the lastUpdated sub-article of anGoal,called sub-article as:subArt;

           * if (subArt is a goal)

           *   display:Goal:subArt.getArticleName();

           * else if (subArt is a diary)

           *   display:Diary:subArt.getArticleName();

           * else {

           *   if (getTypeIDByID(getParentIDByID(subArt.getArticleID()))==1) 

           *     display:advice for goal:subArt.getArticleName();

           *   else

           *     display:advice for diary:subArt.getArticleName();

           * }       

           */  

           int goalID = anGoal.getArticleID();

   TransContext trans = new TransContext();

           ArticleDB myDB = new ArticleDB(trans);

           ArticleInfo lastUpdatedArt=myDB.getLastArtByID(goalID, Consts.HTML_FLAG);

           int lastArtID=lastUpdatedArt.getArticleID();

           String lastArtName=lastUpdatedArt.getArticleName();

           String lastAuthorName=lastUpdatedArt.getUserName();

           int lastArtTypeID=lastUpdatedArt.getTypeID();

           int lastParentID=lastUpdatedArt.getParentID();

           if (lastArtTypeID==1){

         %>目标:

          <html-el:link action="disGoalContentAction.do?goalID=${anGoal.articleID}&naviStr=${requestScope['naviStr']}" target="_blank">

           <%= lastArtName %>

          </html-el:link><br>

          <%= lastAuthorName %><br>

         <%

           }else if(lastArtTypeID==2){

         %>日记:

          <a href="disDiaryContentAction.do?searchDiaryID=<%= lastArtID %>&goalID=<%= lastArtID %>&naviStr=<%= request.getAttribute("naviStr") %>" target="_blank">

           <%= lastArtName %>

          </a><br>

          <%= lastAuthorName %><br>

         <%

           }else {

               if (myDB.getArtTypeByID(myDB.getParentIDByID(lastArtID))==1){

         %>评论目标:

          <html-el:link action="disGoalContentAction.do?goalID=${anGoal.articleID}&naviStr=${requestScope['naviStr']}" target="_blank">

           <%= lastArtName %>

          </html-el:link><br>

          <%= lastAuthorName %><br>

         <%

           }  else {

         %>评论日记:

          <a href="disDiaryContentAction.do?searchDiaryID=<%= lastParentID %>&goalID=<%= lastParentID %>&naviStr=<%= request.getAttribute("naviStr") %>" target="_blank">

           <%= lastArtName %>

          </a><br>

          <%= lastAuthorName %><br>

         <%

             }

           } 

         %>

        <bean:write name="anGoal" property="lastUpdate" scope="page" filter="false"/>

      </td>

  怎样用Struts的标签完成呢?搞不懂,尤其是: <a href="disDiaryContentAction.do?searchDiaryID=<%= lastArtID %>&goalID=<%= lastArtID %>&naviStr=<%= request.getAttribute("naviStr") %>" target="_blank">

           <%= lastArtName %>

          </a><br>

怎么用<html:link/>来完成这个功能呢?

先记在这里,希望知道的朋友提示一下。

疑问:不知道中value的用法

结果用了下列方法完成功能,真被动。还是要好好的把书看一遍了。

       <c:if test="${param.typeID == 3}">

         <html-el:text value="re:${requestScope['parentName']}" property="articleName" maxlength="60" size="60"/>

       </c:if>

       <c:if test="${param.typeID == 4}">

         <input type="text" name="articleName" maxlength="60" size="60" value="<bean:message key="learndiary.message.defaultName"/>">

       </c:if>

或:

<%@ page pageEncoding="gb2312" %>

...

       <c:if test="${param.typeID == 3}">

         <html-el:text value="re:${requestScope['parentName']}" property="articleName" maxlength="60" size="60"/>

       </c:if>

       <c:if test="${param.typeID == 4}">

         <html:text value="留言" property="articleName" maxlength="60" size="60"/>

       </c:if>

来代替。如果把上面"html:text"换成"html-el:text"在tomcat5.0下正常,但在虚拟空间的resin下面就会报错,不知为什么。

         <c:if test="${param.typeID == 4}">

         <html-el:text value="留言" property="articleName" maxlength="60" size="60"/>

       </c:if>

真是惭愧,至今也没有通读一遍Struts的教程

  电子教程倒是下了好几本,都是临到用时去翻。一些基本的东西的概念也是模糊的。像<html:link/>的用法。我就记不得了。书上说:

  The html:link tag renders an HTML anchor tag (i.e., a hyperlink). This tag uses a lot of the same common

attributes as described earlier.You have multiple options for rendering the URL of a hyperlink. You can use the

href, action, forward, or page attributes to specify the URL.

 The href attribute is used to specify a full

URL without any knowledge of the web context of this web application.

 The page attribute is used to specify a

web context relative link.

 The action attribute is used to specify a link to an action mapping, as described in the

Struts config file.

 The forward attribute is used to specify a link to a global forward, as described in the Struts

config file.

Tip: TIP: If you are following a Model 2/MVC architecture, then you should use the page attribute and

the href attribute sparingly. In fact, you should almost never use the page attribute. The href

attribute should only be used to link to resources that are not in the current web application. This helps

you separate the controller from the View by not letting the View select the next View directly. Only the

controller should select the next View. Using the action and forward attributes instead forces you

to delegate selection of the next View to the controller.

Here is an example of linking to an action (/html-link.do) with the page attribute:

<html:link page="/html-link.do">

Linking with the page attribute.

</html:link>

Notice that you do not have to specify the web context of the web application. Conversely, if you used the href

attribute, you would have to specify the web context as follows (where the context is struts-exercise):

<html:link href="/struts-exercise-taglib/html-link.do">

Using Href

</html:link>

Obviously, it is better to use the page attribute when you are linking to things in the same web application (thus,

the same context). You can also use the href attribute to create links that are not on the same server as follows:

<html:link

href="http://otherserver/strutsTut/html-link.do">

Using Href

</html:link>

Another way to link to the html-link.do action is to use the action attribute as follows:

<html:link action="/html-link">

Using Action attribute

</html:link>

(转帖)web中下拉列表的几种实现

转自:http://www.matrix.org.cn/resource/article/43/43809.html

Matrix首页 Java文栏 业界新闻 部落格 资源下载 Java 论坛 web中下拉列表的几种实现

wldandan 发表于2005-09-23 作者:wldandan 评价:0/0 评论数:4 点击数:1490 [收藏]

摘要:

总结一下关于web上使用下拉框的情况

本文Matrix永久镜像:http://www.matrix.org.cn/resource/article/43/43809.html

说明:本文可能由Matrix原创,也可能由Matrix的会员整理,或者由

Matrix的Crawler在全球知名Java或者其他技术相关站点抓取并永久

保留镜像,Matrix会保留所有原来的出处URL,并在显著地方作出说明,

如果你发觉出处URL有误,请联系Matrix改正.

总结一下关于web上使用下拉框的情况

从数据库中获得数据List,将数据放到Request里面

        使用setAttribute(”AList”,AList)

A中有2个属性(String id,String value)

1.        使用JSTL的forEach方式

<select name=”xx” ……..>

<c:forEach items="${AList}" var="p" >

        <c:choose>

                <c:when test="${xxx == p.id}">

                        <option value='<c:out value="${p.id}"/>' selected="selected">

                                        <c:out value="${p.value}"/>

                        </option>

                </c:when>

        <c:otherwise>

                        <option value='<c:out value="${p.id}"/>'>

                                <c:out value="${p.value}"/>

                        </option>

                </c:otherwise>

        </c:choose>       

<c:forEach>

</select>

2.        使用struts的标签

<html:select property=”xxx”>

<html:options collection="AList" labelProperty="value" property="id" />

</html:select>

查一下struts的api文档,可以看到select 中选项有3 taglib可以使用。

第一种直接使用把所有选项写在中间。

<html:option value="0-15">0-15</html:option> <html:option value="15-20" >15-20</html:option> <html:option value="20-30" >20-30</html:option> <html:option value="20 or above">30 or above</html:option>

第二种:把选项放在一个Collection中(这里使用List).在实际项目中,更多的是可能数据来源于db,文件等。这种情况用得比较多。

<html:options collection="AList" property="value" labelProperty="label"/>把option放在list中的过程在Action中作处理//prepare the age selector list.List ageList =new ArrayList();ageList.add(new LabelValueBean("0-15","0-15"));ageList.add(new LabelValueBean("15-20","15-20"));ageList.add(new LabelValueBean("20-30","20-30"));ageList.add(new LabelValueBean("30 or above","30 or above"));request.setAttribute("AList",AList);

这里使用了LabelValueBean,可以不用的,象

<html:options collection="AList" labelProperty="value" property="id" />

只要在AList中填入的bean有value和id属性就可以

第三种,把此list 作为Form 的一个属性.

<html:optionsCollection property="AList" />

在Form 中添加AList 的setter和getter. Form中作如下处理。

//the list can be a form property.

f.setAgeList(AList);

1.        从数据库中获得数据,你应该在Action里面取得数据后,将数据放到Request里面

2.        数据取出来后放在一个List或Collection或Map里面,我习惯用List

3.        从List或其它的容器中取数据应该用<html:options> 或<html:optionsCollection>

4.        <html:options> 和<html:optionsCollection>外层必须用<html:select property="">,所以这个属性你必须在FormBean里定义

5.        由于你要用到这些标签,所以你必须定义FormBean

6.       

从Action取数据,以List为例

List list = xxxxx;//从数据库中取得下拉列表中的数据

request.setAttribute("list",list);

在页面显示

<html:form action="xxxx">...<html:select property="xxx"><html:options collection="list" labelProperty="下拉框中显示的内容,一般是name或其它相似属性" property="各选项对应的值,一般是id" /></html:select>...</html:form>

补充一点点:

因为数据你要从 数据库去取, 所以一般在 action 里调用 DAO ,作为 request 的一个属性传到页面上; 这时一般用 <html:options .../> 标签

另外,如果数据不从数据库去取,而是代码固定的,则一般把这种放到 ActionForm 里,作为属性在页面上取,这时一般用 <html:optionsCollection ... />

我来评价此文: 非常好 还行 一般 扔鸡蛋 总得分:0 投票人次:0

→用户评论列表

#7269 评论作者: littlebat 发表时间:2005-12-27 10:34

正准备用它,对于我来说,上面的信息足够了。谢谢。

#6861 评论作者: jctr 发表时间:2005-12-09 03:59

还应该有第三种,Tapestry的实现,其实也不只这三种还有很多很多吧

#5288 评论作者:xuerldx 发表时间:2005-10-25 07:37

还是不错,就是 有点肤浅

#4811 评论作者: highfan 发表时间:2005-10-05 04:46

你可以把collection 作为

actionform 的

一个属性,在 actionform 中 初始化 也可以 ,在 action 中

初始化 也可以。这样更简单。同时减少view和 control 直接的命名依赖。