铁手剑谱

上善若水
数据加载中……
Struts秘籍之第2段,第 3.9式,产生动态选择列表项目
最近忙,好久没来这里写东西了。今天抽点时间继续。
上周去北京,坐火车去,在火车上阅读《Core J2EE Patern》,想起再上一次去北京,也是坐火车,也是阅读这本书,不过那次是第1版。
还有巧的是,去时铺位是16车16号,来时居然又买到16车16号,不过是上铺。真是有点意思。

 

 

Recipe 3.9. 产生动态选择列表项目

问题

你想要基于同一个表单中的另一个字段的变化,动态改变一个select元素中显示的项目,而不是非要在客户端使用JavaScript 来处理选项集。

 

这个问题并不会完全避免JavaScript;相反,它展示了如何从客户端JavaScript事件监听器中调用Struts action 的技术。

 

动作要领

使用onchange或者onclick JavaScript 监听器来调用一个将表单提交至一个Struts Action的JavaScript 函数。在Action中,执行必要的业务逻辑来构造一个新的select选项集,并且将控制转发回原来的JSP 页面。Example 3-11就展示了当用户点击一个单选按钮时将表单提交至一个Action的JSP页面。单选按钮的值是作为一个请求参数传递给Action的。

Example 3-11. 使用JavaScript提交表单

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html>
<head>
  
<title>Apache Struts Web Framework - JavaScript Example</title>
  
<script language="JavaScript">
     
function getOptions(control) {
        form 
= control.form;
        form.action 
= "SetOptions.do?someProp=";
        form.action 
+= control.value;
        form.submit( );
     }

   
</script>
</head>
<body>
  
<html:form action="ProcessMyForm">
      
<html:radio property="someProp1" value="val1" 
                   onclick
="getOptions(this);"/> Value 1<br/>
      
<html:radio property="language" value="val2" 
                   onclick
="getOptions(this);"/> Value 2<br/>
      SomeProp2:
      
<html:select property="someProp2">
         
<html:optionsCollection property="prop2Values"/>
      
</html:select>
      
</p>
      
<html:submit/>
  
</html:form>
</body>
</html>

 

动作分解

当一个Web页面的动态交互需求是业务逻辑驱动的时候,那么最好使用一个Action,而不是JavaScript,来执行这个功能。将业务逻辑编码进JavaScript 函数将导致难以维护和不可重用的代码。所以最好在服务器端执行这个行为。

这个技术也可以解决第3.8式中的同一个问题。但是,这个动作却没有依赖于JavaScript 函数中的数据。而是,被onclick时间句柄调用的函数将表单提交到一个与表单的action属性中指定的不同的另一个URL 和Action。这个替换的URL 将控制定向到专门处理显示在select控件中的新的选项集的一个Action。然后这个Action将控制转发回原来的JSP 页面,在其中使用新的值重新组装下拉列表菜单。

创建一个单独的Action来处理HTML 控件中的值的改变好像有些过分。但是,这里展示的技术提供了一个利用了动态HTML背后的服务器端的全部威力的灵活方案。考虑一下你要基于同一个表单中的另一个字段的输入值来计算某个字段的金融数据的情形。执行计算的服务就应该由Action来完成。这里所示的解决方案对这种情形就很好。

对于一个具体的例子,第3.8式所用的方法可以被这里所属的方法代替。这个例子提供了一个输入表单,从其中用户可以输入和选择其钟爱的编程语言和IDE。针对IDE的选项则依赖于编程语言的选择。Example 3-12 显示了现实这个表单的JSP 页面(favorite_language2.jsp)。

Example 3-12. 将表单提交到另一个URL

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html>
<head>
  
<title>Apache Struts Web Framework - JavaScript Example</title>
  
<script language="JavaScript">
     
function getOptions(control) {
        form 
= control.form;
        form.action 
= "GetIdeOptions.do?language=";
        form.action 
+= control.value;
        form.submit( );
     }

   
</script>
</head>
<body>
   
<html:form action="ViewFavoriteLanguage">
      What's your favorite programming language?
<br/>
      
<html:radio property="language" value="Java" 
                   onclick
="getOptions(this);"/> Java<br/>
      
<html:radio property="language" value="C-Sharp" 
                   onclick
="getOptions(this);"/> C-Sharp<br/>
      
<p>What's your favorite development tool?<br/>
      IDE:
      
<html:select property="ide">
         
<html:optionsCollection property="ides"/>
      
</html:select>   
      
</p>
      
<html:submit/>
  
</html:form>
</body>
</html>

 

Apache Struts Web Framework-config.xml中的action元素指定了表单所用的URL 路径。第一个mapping,/FavoriteLanguage2,指定了转发到Example 3-12的JSP的action 。第二个mapping, /GetIdeOptions, 则指定了当用户点击单选按钮时调用的action。最后一个mapping, /ViewFavoriteLanguage, 则指定的是按下Submit 按钮时处理表单的action。

<action    path="/FavoriteLanguage2"
           name
="MyForm"
          scope
="session"
           type
="org.apache.struts.actions.ForwardAction"
      parameter
="/favorite_language2.jsp"/>

<action    path="/GetIdeOptions"
           name
="MyForm"
          scope
="session"
           type
="com.oreilly.strutsckbk.GetIdeOptionsAction">
     
<forward name="success" path="/FavoriteLanguage2.do"/>
</action>

<action    path="/ViewFavoriteLanguage"
           name
="MyForm"
          scope
="session"
           type
="org.apache.struts.actions.ForwardAction"
      parameter
="/view_favorite_language.jsp"/>


最后是GetIdeOptionsAction本身,示于Example 3-13。

Example 3-13. 处理替代URL 的Action

 

package com.oreilly.strutsckbk;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.LabelValueBean;

public final class GetIdeOptionsAction extends Action {

    
public ActionForward execute(ActionMapping mapping,
                 ActionForm form,
                 HttpServletRequest request,
                 HttpServletResponse response)
    throws Exception 
{
        MyForm myForm 
= (MyForm) form;
        String language 
= myForm.getLanguage( );
        ArrayList ides 
= new ArrayList( );
        
if (language.equals("Java")) {
            ides.add(
new LabelValueBean("Net Beans","Net Beans"));
            ides.add(
new LabelValueBean("Eclipse""Eclipse"));
            ides.add(
new LabelValueBean("jEdit""jEdit"));            
        }

        
else if (language.equals("C-Sharp")) {
            ides.add(
new LabelValueBean("Sharp Develop""Sharp Develop"));
            ides.add(
new LabelValueBean("Visual Studio""Visual Studio"));
        }

      myForm.setIdes( ides );

        
// Forward control to the specified success URI
        return (mapping.findForward("success"));
    }

}

 

这个类负责从MyForm中获取选择的编程语言。然后Action设置包含对应的IDE名城的集合到表单中。为了简化,这个Action直接创建了集合。在实际应用中,这些值可能来自于业务层,也许是来自于一个数据库。最后,Action返回success forward,又将控制转到初始Action。

 

使用这个技术的一个后果是你可能需要将ActionForm定义在session范围中。这样可以让主JSP 页面在表单被从预备Action重新提交回原始页面时可以反映修改了的数据。.

 

对这个例子,内置的ForwardAction将处理表单,直接将请求转发至JSP页面。如果你是使用一个定制的Action,请考虑扩展DispatchAction并且实现辅助action 为DispatchAction的一个方法。这种方式将相关代码集中在一起,使应用更易维护。

相关动作

第3.8 式提供了另一个技术,它使用了动态产生JavaScript 数组的方式来解决这个问题。

DispatchAction将在第6.8式讲解。

 

posted on 2005-06-29 10:05 铁手 阅读(3666) 评论(9)  编辑  收藏 所属分类: JavaStruts系列

评论

# re: Struts秘籍之第2段,第 3.9式,产生动态选择列表项目 2005-07-19 09:11 我是一只菠萝

铁手大哥,能不能发一份动态选择项目的完整代码给我回去研究啊..
邮箱:socas@sohu.com
3Q了先
  回复  更多评论    

# re: Struts秘籍之第2段,第 3.9式,产生动态选择列表项目 2005-07-19 09:56 zjmoya

铁手大侠!
我最近也在做一个东西,
由于时间很紧,
学的不扎的!
正好也要产生动态选择列表项目.

我已经把你的所以blog里的关于这方面的原代码试了很久
但是不幸的是没有成功!

铁手大侠!
能不能在你百忙之间抽出点时间把完整的源代码给小弟!

我将不禁感激!!

谢谢!真的有点急
!1!

zjmoya@163.com

  回复  更多评论    

# re: Struts秘籍之第2段,第 3.9式,产生动态选择列表项目 2005-07-19 10:14 铁手

这些都是示例代码,就这些。你可根据你的需要调整。另外,注意版本问题,包括Container, JSP,Servlet和Struts版本。最好使用最新的版本。
  回复  更多评论    

# re: Struts秘籍之第2段,第 3.9式,产生动态选择列表项目 2005-07-19 10:34 zjmoya

view_favorite_language.jsp??


这个文件是哪个???
  回复  更多评论    

# re: Struts秘籍之第2段,第 3.9式,产生动态选择列表项目 2005-07-19 10:45 zjmoya

能不能告诉我啊 !
??

还有Myform
public ArrayList getIdes( )
这个函数是不是应该写上啊 !
  回复  更多评论    

# re: Struts秘籍之第2段,第 3.9式,产生动态选择列表项目 2005-07-19 11:34 铁手

refer to 3.8
  回复  更多评论    

# Struts 秘籍(CookBook)[TrackBack] 2005-11-12 18:29 阿泠

本系列源改编自O'Reily的Strus Cookbook
[引用提示]阿泠引用了该文章, 地址: http://blog.donews.com/inclear/archive/2005/11/12/624363.aspx
  回复  更多评论    

# re: Struts秘籍之第2段,第 3.9式,产生动态选择列表项目 2006-12-04 12:23 mika

formbean里面用ArrayList会报错啊!
  回复  更多评论    

# re: Struts秘籍之第2段,第 3.9式,产生动态选择列表项目 2006-12-04 12:46 mika

而且这样做的话是不是要form嵌套form?否则我真的提交表单的form放在哪里?
  回复  更多评论    

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


网站导航: