免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1118 | 回复: 0
打印 上一主题 下一主题

strust学习心得 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-04-15 16:48 |只看该作者 |倒序浏览

/*****************************************************************************
第一式:学习使用DispatchAction
DispatchAction继承自Action类,它是一个抽象类,封装了一些基础方法,来解决使用一个Action处理多个操作的能力,
这就是DispatchAction最大的用途,它可以帮助我们用一个Action类,封装一套类似的操作方法,节省了类的数目,同时也减轻了后期维护的困难。
*/
DispatchAction中主要包括一下几个方法:
protected ActionForward dispatchMethod
protected java.lang.reflect.Method getMethod
protected java.lang.String getMethodName
DispatchAction在配置上于标准的Action稍有不同,就是要在Action配置中多一个parametr属性,这个属性将指导DispatchAction找到
对应的方法,
例如这样配置:
parameter的属性值是可以任意起的,只要你记得在传参数的时候统一就可以了。比如我写了一个类似这样的Action,它继承自DispatchAction类,
包含了三个操作方法,有Add(),Update(),Delete()。(在这个action里不必覆盖execute()方法,只需要包含与execute()方法有相同的签名并
同样声明抛出Exception异常的方法即可),而当我想要调用这个Action的Update操作时,提交的URL应该类似这样的:
"
http://localhost:8080/myapp/saveSubscription.do?method=update&id=2
"
就是这么简单,不过非常方便程序员,开发中的确省了好多代码,至少以前的三个类文件变成了现在一个类了,而且在后期维护的时候感觉也会方便很多。
需要注意的是:在调用DispatchAction的时候method参数是不能为空的,如果空,DispatchAction会调用unspecified方法并抛出异常。
实例代码如下:
/******************************************************************************
第二式:学习使用DynaActionForm
DynaActionForm列举编写过程中遇到的与普通ActionForm的不同:
1.最大的不同就是动态ActionForm是配置出来的(在struts-config.xml中),而不是通过编写.java文件;
2.  中的type属性设置为"org.apache.struts.action.DynaActionForm"或者其子类;
3.  在中添加子元素设置动态ActionForm的字段(对应于视图组件中的表项),其name属性制定字段名,
  type指定属性类型;
4.  在处理该form的action类中,execute方法中的“ActionForm form”参数的类型仍然保持为其默认的ActionForm,而不是
  DynaActionForm,尽管DynaActionForm是从ActionForm继承而来,否则action不会执行任何逻辑。在这一点上,我用了一天多的时间才
  发现,不过其深层次的缘由还未发现;
访问动态ActionForm的时候只需要对form进行类型转换即可,但其访问表项的方法要调用public Object get(String name)
和 public void set(String name,Object value),这一点亦和普通ActionForm的访问方式不一样,DynaActionForm是把所有的属性
保存在一个Map类对象中;
另外一种声音:
  接触Struts久了不免会对其有这样或那样的看法,前阶段潜心研究Struts,对其中的动态ActionForm的使用就有一些意见,在这里跟大家
说道说道,希望大家能够给点意见。
一、用途
  动态ActionForm与标准的Form的用途如出一辙,都是为了能够作为DTO(Data Transfer Object)对向来与Action做数据传递,所不同的
是动态ActionForm并没有一个专门的类作为DTO对象的载体,取而代之的是在Struts配置文件FormBean中增加属性配置项,来达到与DTO对象
相同的作用。下面我们以用户登陆的应用为例,讨论一下普通的ActionForm与动态ActionForm的区别。
用户通过输入用户名和密码后经过校验进入系统。过程描述的很简单,ActionForm设计起来也不复杂,我们只需要设定一下两个属性就可以了:
  private String userID;
  private String userPwd;
最后,我们为着两个属性加上get和set方法就完成了普通ActionForm的设计。如果需要的话,我们还可以在这个Formli覆盖validate()方法
来对用户输入的信息进行简单的校验。
下面,我们就来看看动态ActionForm是通过怎样的设计来达到和上面同样的效果的吧!
我们在struts-config文件中的标签中定义我们的动态Form,代码如下。

   
   
   
   
   

这样便完成了一个动态ActionForm的定义,我们不需要定义get和set方法来设置或者获得Form属性的值,我们只需要在我们的Action中使用:
String userID=(String)form.get(“userID”);
这样的方法获得Form中的数据,或者是通过form.set(“userID”,”001318”);这样的方法设置Form中的属性值。
从上面的论述不难看出两种ActionForm的用途与使用差别不是很大,都可以完成对视图的数据传递的作用。而从便捷角度来看动态FormBean显得
优势明显,因为他的设计更为简单,而且由于具有可配置的优势,使其在实际操作方面显得跟为灵活!
二、差异
上面的论述能够突出动态ActionForm的优势,下面我们来看看动态ActionForm的“致命伤”。
1、数据验证
  细心的读者会发现我在提及普通的ActionForm的时候我曾经讲到过可以在ActionForm中的validate()方法对用户输入的信息进行简单的
  校验,而在动态ActionForm中却从未提到。这是因为如果想要实现动态ActionForm的校验我们必须做很多工作。首先我们必须引入
  Validator验证框架来帮助我们完成数据校验工作,其次由于某些数据的校验,我们还有可能为其编写数据校验项来帮助Validator框架完成
  数据校验工作。这与普通的ActionForm相比,动态ActionForm显得繁琐而笨拙。
2、可配置
  动态ActionForm的可配置型无疑是其存在优势之一,,但笔者发现,其可配置性的作用可谓捉襟见肘。因为可配置的FormBean与Action的
  耦合度还是相当大的。也就是说,由于Action类李引用了如“String userID=(String)form.get(“userID”);”这样的代码,那么当
  我们增加或删除Form中的属性的时候就必须更改我们的Action类,这与普通的ActionForm的作法是一样的,失去了其可配置的优势所在。
综上,笔者推荐使用普通的ActionForm去履行DTO的职责,因为那样会更方便解决应用问题。动态ActionForm只是一点小尝试,不推荐使用。
以上观点均属个人看法,不妥之处还望各位能够批评指正!
第三种声音:DynaActionForm的使用:
一直以来对actionForm很有意见,因为总感觉actionForm类是多余的.可能struts组织也意识到了这方面的不足于是有了
DynaValidatorForm(动态actionForm).下面我来介绍DynaValidatorForm的使用.
以用户注册的例子简单介绍
首先创建用户类 (User.java)
属性为 userName
   userPass
第二创建动态ActionForm
在Struts-config中加入
  
   
   
   
  
第三在页面里对应属性
  
  
第四在action中使用
  DynaActionForm userForm = (DynaActionForm) form;
  User user=userForm .get("user");
而在编辑的时候则可以用
  userForm.set("user",user)
总结:通过动态actionForm,减少了大量 get set 代码,以及actionForm类
*/
/********************************************************************************
第三式:Strus开发实践备忘录
一、struts使用小贴士(mainly from《struts in action》)
1. 在actionForm中使用array以匹配重复的变量。例如在使用multibox时,相对应的可以在form中定义array。
2.使用显示collection的记录总数。
  eg:。如果resultList有两条记录,则显示2。
3. 显示循环序号标记:
  
   
  
4.使用检查对象是否存在。使用检查属性是否存在。
5.相对稳定的下拉列表数据集使用scope=”application”。(这个方法一直想用,但是具体上仍不太清楚,是否在系统登陆的时候获得
  这个数据集,以后就可以直接用了)。
6.使用设置css,js文件的路径。(这一点看不出来与直接使用有什么区别)。
7.javascript与form值的交互:这一点使用很频繁
  eg:)’>
8.使用DispatchAction将几个相关的操作放在一起,例如将save,delete操作放在一个action中。DispatchAction的使用需要
  在struts-config.xml中的action-mapping中设置parameter,具体可以参考
9. 在使用javascript的页面中,不能出现两个Form对象的名称相同。特别是submit按钮我们常常会不写name,缺省name都为submit,
  这时如果有onclick事件触发,就会出错。
10. 几个ActionForm公用的属性,可以在ActionForm中定义一个子类。
  eg: Class BasicInfo  implement Serializable {};
    在ActionForm中需定义BasicInfo basicInfo = new BasicInfo();
   在jsp页面中的property="basicInfo.a"
二、上传文件
1. 在actionForm中需定义FormFile类型字段。eg:FormFile myphoto
2. 在jsp页面中
  
  
3.在submit以后可能会出现一下错误:no multipart request date sent”
  解决方案:
   1.将struts-config.xml中redirect树性置为true。
   2.如果是带参数的跳转,采用以下方法:
   ActionForward forward = mapping.findForward("success");
   StringBuffer bf = new StringBuffer(forward.getPath());
   bf.append("?id=1");//参数
   return new ActionForward(bf.toString(),true);
三、图片的显示
1.写一个显示图片的Action,代码结构如下:
public class PhotoAction extends Action
{
  private static final String CONTENT_TYPE = "image/gif";
  public ActionForward perform(
         ActionMapping mapping,
         ActionForm actionForm,
         HttpServletRequest request,
         HttpServletResponse response)throws ServletException, IOException
  {
   response.setContentType(CONTENT_TYPE);
   ...//GET PARAM employeeId
   ServletOutputStream out = response.getOutputStream();
   InputStream in =null;
   try
   {
    in = ...//get blob pic
   }
   catch (Throwable e)
   {
    e.printStackTrace();
   }
   if(in!=null)
   {
    try {
      int len;
      byte buf[] = new byte[4096];
      while ( (len = in.read(buf, 0, 4096)) != -1)
      {
       out.write(buf, 0, len);
      }
     }
    catch (IOException ioe)
    {
     ioe.printStackTrace();
    }
   }
   return null;
   }
}
2.在显示图片的jsp页面写如下代码:
  
四、使ApplicationResources.properties支持中文显示:
进入命令提示符页面,进入jdk安装路径下的bin目录,执行一下命令:
native2ascII - encoding gb2312 ApplicationResources_ISO.properties(原文件)
AllicationResources.properties(新生成文件)
即可在jsp页面显示中文。但是,目前还有一点问题没解决,就是在jsp页面显示的内容为“null error ”,你出现过相同问题吗?怎么解决的?
五:Action中的文件路径问题:
在Action中需要调用一个xml文件,是用相对路径在本地编译没有问题,但是一放在服务器上执行就找不到文件路径。找了很多解决方法,最后
调用了request.getRealPath("/")方法,行的通,但是这个方法已经不被建议使用了。你有更好的方法吗?
六:jsp页面显示字符串数组:



七:如何定义自己的jsp文件发布路径(windows2000环境下实践通过):
打开tomcat目录下conf文件夹下的server.xml文件,找到标签
在其标签后,添加自己的发布路径,如下:

重启tomcat,访问:/localhost:8080/mybwebapps/,ok!
八:如何解决偏僻难字的显示问题:
使用大字符集,将所有jsp页面字符集设置如下:注意:GBK一定得大写。
九:页面刷新数据重复提交问题:
解决的方法就是采用重定向。与二的解决方法相同:
  1.将struts-config.xml中redirect属性置为true。
  2.如果是带参数的跳转:
  ActionForward forward = mapping.findForward("success");
  StringBuffer bf = new StringBuffer(forward.getPath());
  bf.append("?id=1");//参数
  return new ActionForward(bf.toString(),true);
十:其他:
编程规范建议:
数据库接口类命名:*DAO.JAVA
逻辑类命名:*BO.JAVA
ACTION命名:*Action.JAVA
ACTIONFORM命名:*Form.JAVA
然后一个功能模块的文件放在一个包内。
*/
/****************************************************************************************
第四式:让初学者理解Struts
新手学习struts可以更加好的理解面向对象开发的方法、3层结构的优势、模型驱动等概念。
Struts是一个不错的java框架,但是它包含的内容也相当多,对于初次接触它的人,特别是java新手,可能有很多不明白的地方。
根据我自己的理解和实践,觉得struts还是相当容易上手,网上能找到很多例子。但是这些例子又讲的比较浅,没有涉及到实际项目的应用,
比如如何连接数据库,如何实现应用。
简单的讲,要应用Struts,就是建立对应的actionForm、action、jsp页面,并配置web.xml, struts-config.xml。如果利用JBuilder,
则可以很方便的建立和管理这些文件了,当然等你以后经验丰富了也可以全凭记事本来处理。
配置struts-config.xml相当比较简单,记得添加对应的form-beans, action-mappings即可。而如果不涉及更高级的开发,则几乎无需重新
配置web.xml。建立actionForm也很简单,只需把所需的对象属性都set、get进去即可。在jsp页面中,可以用到一些tags以使你的代码跟清晰,
或者仍旧使用传统jsp写法慢慢改进也行。最关键的就是action的写法,如果理解了action的工作原理,那么对于进一步掌握struts有很大帮助。
action中常用的对象有actionForm、request(httpServletRequest),常用的session对象来自于request.getSession()。从页面传递
过来的参数有两种方法获取,如果是表单数据,就是actionForm.getXXXX();,另外表单数据和url参数都可以
用request.getParameter(name);获取。要往页面输出信息,如果是actionForm里有的,就是actionForm.setXXX();,
另外一种方法是request.setAttribute(name,arg);传递到内容,从页面中request.getAttribute(name)读取。
很多时候都要用后面这种方法把对象数据传递给页面,你应该理解并记住。
另外出错提示信息(不是指程序异常)一般是通过actionErrors对象
处理,稍微有点麻烦,以后再讲。
*/
/***********************************************************************************************
第五式:使用LookupDispatchAction类
  这个Action类可以将据有类似功能的Action合并到一起。它与DispatchAction类的作用差不多,唯一不同的是:这个类是通过资源包中
的key作为请求参数来进行对方法的映射,而DispatchAction是通过请求参数来选择方法,即,SUBMIT的value与方法名必须一致。如果
使用这个类,SUBMIT的value是资源包中key所对应的值,而根据这个key是如何选择运行方法的,下面就来介绍一下。
步骤一:扩展一个LookupDispatchAction的子类。
  注意:1)每个方法必须是public的,为了向外面提供调用接口;
  2)不能包括execute方法,这个方法使用LookupDispatchAction的默认方法;
  3)每个方法的返回值与参数应该与普通Action类的execute方法一样;
  4)每个方法代表一个功能,就相当于合并以前各个普通Action子类的execute方法。
步骤二:在这个子类中实现个体KeyMethodMap方法,实现“键--方法”的映射。
例子:
  public Map getKeyMethodMap()
  {
   Map map = new HashMap();
   map.put("save","saveStatus");
   map.put("load","loadStatus");
   return map;
  }
步骤三:在资源包中定义“键”对应的“值”,用于表示在SUBMIT按钮上。
例子:
  save=save this status;
  load=load this status;
步骤四:配置struts-config.xml。
例子:
  input = "/www.jsp"
  parameter = "method"
  scope = "request"
  type = "com.sinpool.strtus.QQQAction"
其中parameter="method",指定的字符串是method,说明SUBMIT的property(name)就应该是method。
步骤五:在JSP中的代码。
例子:
必须用设置SUBMIT应该显示的值,这段代码提交请求时,应该类似这个样子:
http://localhost:8080/qqq?method="save
this status"。
参数名“method”应该与步骤四中的action标签中的parameter一样。
总结:虽然在提交请求时,仍将SUBMIT的value("save this status")提交了,但是,可以按照getKeyMethodMap()方法的定义,通过
资源包的key映射到具体的方法名上。所以,这个请求实际调用了save方法。
另一种声音:解决LookupDispatchAction使用中对中文信息支持的问题
关于这个问题,首先得明白jsp页面数据----到----ActionForm----到----Action的顺序,
一般来说jsp页面的数据提交无非是get方式或者post方式,通过request都可以得到,所以,
凡是使用LookupDispatchAction时出现中文信息支持问题的,均是出在这个中间环节
----formbean上了。
        出现这个问题的原因是request默认的编码是iso,而从jsp传入的数据包括了gbk,所以,
到Action中后,因为LookupDispatchAction要根据Value找key,而value它不认识,所以就出现
了错误。
        解决方案是:为这种Action专门写一个ActionForm,这个ActionForm中要专门设置request的
编码类型,这样,传到后台的数据和资源文件保持了一致,所以还是能被识别的。
       下面是例子:
    1、struts-config.xml中对FormBean的定义
   
    2、Action的配置:
   
    3、RequestForm
   package com.frame.webFrame.portal;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class RequestForm extends ActionForm{
  Log log = LogFactory.getLog(RequestForm.class);
  public void reset(ActionMapping mapping,
                       HttpServletRequest request) {
      try {
        request.setCharacterEncoding("GBK");
      }
      catch (UnsupportedEncodingException ex) {
        log.error("encoding error! ",ex);
      }
  }
}
4、资源文件一例(为上述的GBK编码)
CreateApplyForm.saveApplyForm=\u4fdd\u5b58\u7533\u8bf7\u5355
有了上面的例子,你使用LookupDispatchAction就更顺手了
*/
package com.lxx.flypig.web.action;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.LookupDispatchAction;
public class ModelqxAction extends LookupDispatchAction
//public class ModelqxAction extends AdminBaseAction
{
private String url = "";
public Map getKeyMethodMap()
{
Map map = new HashMap();
map.put("button.save","save");
map.put("button.save1","save1");
map.put("button.save2","save2");
return map;
}
public ActionForward save(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
System.out.println("2222222222222222->>>创建");
return (mapping.findForward(url));
}
public ActionForward save1(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
System.out.println("2222222222222222->>>创建1");
return (mapping.findForward(url));
}
public ActionForward save2(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
System.out.println("2222222222222222->>>创建2");
return (mapping.findForward(url));
}
}
ApplicationResources.properties.GBK配置:
button.save=save
button.save1=提交
button.save2=提交
如果是中文还需要ApplicationResources.properties编码文件
button.save=save
button.save1=\u63d0\u4ea4
button.save2==\u63d0\u4ea4
页面:
  
/**************************************************************************
第六式:Validator验证框架
1.要使用validator验证框架,首先要采用插件机制把validator加入到框架中去。
在struts配置文件中配置ValidatorPlugIn插件,代码如下:
     
2.validator框架不能用于验证标准的org.apache.struts.action.ActionForm类。要使用validator框架,
应该采用ActionForm的两个子类:org.apache.struts.validator.DynaValidatorForm和
org.apache.struts.validator.ValidatorForm。
3.DynaValidatorForm和ValidatorForm都实现了validate()方法,所以,在创建他们的子类时,不必覆盖
validate()方法;具体做法是将validate()和reset()方法删除。
4.编写validation.xml文件,这个文件很重要哦!
在这个文件中设置各种验证规则,可以是validator框架自带的,也可以是自定义的规则!
5.如果有自定义的规则,首先要添加到validator-rules.xml文件中。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/55983/showart_538152.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP