`
wangpan80
  • 浏览: 104891 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Struts原理与实践(2)

阅读更多

下面,我们就从一个最简单的登录例子入手,以对Struts的主要部分有一些直观而清晰的认识。这个例子功能非常简单,假设有一个名为lhb的用户,其密码是awave,程序要完成的任务是,呈现一个登录界面给用户,如果用户输入的名称和密码都正确返回一个欢迎页面给用户,否则,就返回登录页面要求用户重新登录并显示相应的出错信息。这个例子在我们讲述Struts的基础部分时会反复用到。之所以选用这个简单的程序作为例子是因为不想让过于复杂的业务逻辑来冲淡我们的主题。

因为Struts是建立在MVC设计模式上的框架,你可以遵从标准的开发步骤来开发你的Struts Web应用程序,这些步骤大致可以描述如下:
1定义并生成所有代表应用程序的用户接口的Views,同时生成这些Views所用到的所有ActionForms并将它们添加到struts-config.xml文件中。
2在ApplicationResource.properties文件中添加必要的MessageResources项目
3生成应用程序的控制器。
4在struts-config.xml文件中定义Views与 Controller的关系。
5生成应用程序所需要的model组件
6编译、运行你的应用程序.

下面,我们就一步步按照上面所说的步骤来完成我们的应用程序:

第一步,我们的应用程序的Views部分包含两个.jsp页面:一个是登录页面logon.jsp,另一个是用户登录成功后的用户功能页main.jsp,暂时这个页面只是个简单的欢迎页面。

其中,logon.jsp的代码清单如下:

  1. <%@ page contentType="text/html; charset=UTF-8" %>  
  2. <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>  
  3. <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>  
  4. <HTML>  
  5. <HEAD>  
  6. <TITLE><bean:message key="logon.jsp.title"/>TITLE>  
  7. <html:base/>  
  8. HEAD>  
  9. <BODY>  
  10. <h3><bean:message key="logon.jsp.page.heading"/>h3>  
  11. <html:errors/>  
  12. <html:form action="/logonAction.do" focus="username">  
  13. <TABLE border="0" width="100%">  
  14. <TR>  
  15. <TH align="right"><bean:message key="logon.jsp.prompt.username"/>TH>  
  16. <TD align="left"><html:text property="username"/>TD>  
  17. TR>  
  18. <TR>  
  19. <TH align="right"><bean:message key="logon.jsp.prompt.password"/>TH>  
  20. <TD align="left"><html:password property="password"/>TD>  
  21. TR>  
  22. <TR>  
  23. <TD align="right">  
  24.   <html:submit><bean:message key="logon.jsp.prompt.submit"/>html:submit>  
  25. TD>  
  26. <TD align="left">  
  27.   <html:reset><bean:message key="logon.jsp.prompt.reset"/>html:reset>  
  28. TD>  
  29. TR>  
  30. TABLE>  
  31. html:form>  
  32. BODY>  
  33. HTML>  



main.jsp的代码清单如下:

  1. <%@ page contentType="text/html; charset=UTF-8" %>  
  2. <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>  
  3. <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>  
  4.   
  5. <HTML>  
  6. <HEAD>  
  7. <TITLE><bean:message key="main.jsp.title"/>TITLE>  
  8. <html:base/>  
  9. HEAD>  
  10. <BODY>  
  11. <logic:present name="userInfoForm">  
  12. <H3>  
  13.   <bean:message key="main.jsp.welcome"/>    
  14.   <bean:write name="userInfoForm" property="username"/>!   
  15. H3>  
  16. logic:present>  
  17. BODY>  
  18. HTML>  



首先,我们看一下logon.jsp文件,会发现它有这么两个鲜明的特点:一是文件头部有诸如:
<!---->
<!---->

这样的指令代码,他们的作用就是指示页面要用到struts的自定义标签,标签库uri是一个逻辑引用,标签库的描述符(tld)的位置在web.xml文件中给出,见上篇文章的配置部分。struts的标签库主要由四组标签组成,它们分别是:

  • bean标签,作用是在jsp中操纵bean
  • logic标签,作用是在jsp中进行流程控制
  • html标签,作用是显示表单等组件
  • template标签,作用是生成动态模板

    关于每类标签的具体作用及语法,因受篇幅限制,不在这里详细讨论,大家可参考struts手册之类的资料。只是心里要明白所谓标签其后面的东西就是一些类,这点与bean有些相似,它们在后端运行,生成标准的html标签返回给浏览器。

    要使用它们显然要把它们的标签库描述文件引入到我们的系统中,这是些以.tld为扩展名的文件,我们要把它们放在/webapps/mystruts/WEB-INF/目录下。引入struts标签后原来普通的html标签如文本框的标签变成了这样的形式。

    Jsp文件的第二个特点,就是页面上根本没有直接写用于显示的文字如:username,password等东西,而是用这种形式出现。这个特点为国际化编程打下了坚实的基础,关于国际化编程后面的文章还会专门讨论。

    这个简单的应用所用到的ActionForm为UserInfoForm,代码清单如下:
    java 代码
    1. package entity;   
    2. import org.apache.struts.action.ActionForm;   
    3. import org.apache.struts.action.ActionMapping;   
    4. import javax.servlet.http.HttpServletRequest;   
    5.   
    6. public class UserInfoForm extends ActionForm{   
    7.   
    8.   private String username;   
    9.   private String password;   
    10.   
    11.   
    12.   public String getUsername() {   
    13.     return (this.username);   
    14.   }   
    15.   public void setUsername(String username) {   
    16.     this.username = username;   
    17.   }   
    18.   
    19.   public String getPassword() {   
    20.     return (this.password);   
    21.   }   
    22.   public void setPassword(String password) {   
    23.     this.password = password;   
    24.   }   
    25. }  


    在你的应用程序的WEB-INF目录下再建一个classes目录,在新建的这个classes目录下再建如下几个目录entity(用于存放ActionForm类)、action目录(用于存放Action类)、bussness目录(用于存放作为Model的业务对象类)。Classes目录下的子目录就是所谓的包,以后,还会根据需要增加相应的包。

    现在,将UserInfoForm.java保存到entity目录中。

    把如下代码添加到/webapps/mystruts/WEB-INF/struts-config.xml文件中
    xml 代码
    1. <form-beans>  
    2.     <form-bean name="userInfoForm" type="entity.UserInfoForm" />  
    3.  form-beans>  


    特别要提醒一下的是:关于ActionForm的大小写,一定要按照上面的写,以免造成不必要的麻烦。

    到此,我们完成了第一步工作。

    第二步,我们建一个名为ApplicationResource.properties的文件,并把它放在/webapps/mystruts/WEB-INF/classes目录下。它在struts-config.xml的配置信息我们已在第一篇文章的末尾说了,就是:


    目前我们在ApplicationResource.properties文件中加入的内容是:
    1. #Application Resource for the logon.jsp   
    2. logon.jsp.title=The logon page   
    3. logon.jsp.page.heading=Welcome World!   
    4. logon.jsp.prompt.username=Username:   
    5. logon.jsp.prompt.password=Password:   
    6. logon.jsp.prompt.submit=Submit  
    7. logon.jsp.prompt.reset=Reset  
    8.   
    9. #Application Resource for the main.jsp   
    10. main.jsp.title=The main page   
    11. main.jsp.welcome=Welcome:  


    到此,我们已完成了第二个步骤。

    第三步,我们开始生成和配置Controller组件。

    在前面我们已经提到,Struts应用程序的控制器由org.apache.struts.action.ActionServlet和org.apache.struts.action.Action类组成,其中,前者已由Struts准备好了,后者Struts只是为我们提供了个骨架,我们要做的是为实现应用程序的特定功能而扩展Action类,下面是实现我们登录程序的Action类的代码清单:
    java 代码
    1. package action;   
    2. import java.io.IOException;   
    3. import javax.servlet.ServletException;   
    4. import javax.servlet.http.HttpServletRequest;   
    5. import javax.servlet.http.HttpSession;   
    6. import javax.servlet.http.HttpServletResponse;   
    7. import org.apache.struts.action.Action;   
    8. import org.apache.struts.action.ActionError;   
    9. import org.apache.struts.action.ActionErrors;   
    10. import org.apache.struts.action.ActionForm;   
    11. import org.apache.struts.action.ActionForward;   
    12. import org.apache.struts.action.ActionMapping;   
    13. import org.apache.struts.action.ActionServlet;   
    14. import bussness.UserInfoBo;   
    15. import entity.UserInfoForm;   
    16. public final class LogonAction extends Action {   
    17.      
    18.   public ActionForward execute(ActionMapping mapping,   
    19.          ActionForm form,   
    20.          HttpServletRequest request,   
    21.          HttpServletResponse response)   
    22.          throws IOException, ServletException {   
    23.     UserInfoForm userInfoForm = (UserInfoForm) form;           
    24.     //从web层获得用户名和口令   
    25.     String username = userInfoForm.getUsername().trim();   
    26.     String password = userInfoForm.getPassword().trim();   
    27.     //声明错误集对象   
    28.     ActionErrors errors = new ActionErrors();   
    29.     //校验输入   
    30.     if(username.equals("")){   
    31.       ActionError error=new ActionError("error.missing.username");   
    32.       errors.add(ActionErrors.GLOBAL_ERROR,error);   
    33.     }   
    34.     if(password.equals("")){   
    35.       ActionError error=new ActionError("error.missing.password");   
    36.       errors.add(ActionErrors.GLOBAL_ERROR,error);   
    37.     }   
    38.        
    39.     //调用业务逻辑   
    40.     if(errors.size()==0){   
    41.       String validated = "";   
    42.       try{   
    43.         UserInfoBo userInfoBo=new UserInfoBo();   
    44.         validated =userInfoBo.validatePwd(username,password);   
    45.         if(validated.equals("match")){   
    46.           //一切正常就保存用户信息并转向成功的页面    
    47.           HttpSession session = request.getSession();   
    48.           session.setAttribute("userInfoForm", form);             
    49.           return mapping.findForward("success");   
    50.         }    
    51.       }   
    52.          
    53.       catch(Throwable e){   
    54.         //处理可能出现的错误   
    55.         e.printStackTrace();   
    56.         ActionError error=new ActionError(e.getMessage());   
    57.         errors.add(ActionErrors.GLOBAL_ERROR,error);   
    58.       }   
    59.     }     
    60.     //如出错就转向输入页面,并显示相应的错误信息   
    61.     saveErrors(request, errors);       
    62.     return new ActionForward(mapping.getInput());       
    63.   }    
    64. }  


    这个action类中有两个错误消息键要加到ApplicationResource.properties文件中,清单如下:
    1. #Application Resource for the LogonAction.java   
    2. error.missing.username=<li><font color="red">missing usernamefont>li>  
    3. error.missing.password=<li><font color="red">missing passwordfont>li>>  


    第四步:在struts-config.xml文件中定义Views与 Controller的关系,也就是配置所谓的ActionMapping。它们在struts-config.xml中的位置是排在 … 标签后,我们的登录程序的配置清单如下:
    1. <action-mappings>  
    2.     <action input="/logon.jsp" name="userInfoForm" path="/logonAction" 
    3.     scope="session"    
    4.     type="action.LogonAction" validate="false">  
    5.       <forward name="success" path="/main.jsp" />         
    6.     action>  
    7. action-mappings>    


    第五步:生成应用程序所需要的model组件,该组件是完成应用程序业务逻辑的地方,现在我的登录程序的业务逻辑很简单,就是判断用户是不是lhb并且其口令是不是awave如果是就返回一个表示匹配的字符串"match",否则,就抛出出错信息。其代码清单如下:
    java 代码
    1. package bussness;   
    2.   
    3. import entity.UserInfoForm;   
    4.   
    5. public class UserInfoBo {   
    6.   
    7.   public UserInfoBo(){   
    8.        
    9.   }        
    10.   
    11.   public String validatePwd(String username,String password){   
    12.            
    13.     String validateResult="";    
    14.           
    15.     if(username.equals("lhb")&&password.equals("awave")){   
    16.       validateResult="match";   
    17.     }   
    18.     else{   
    19.          
    20.       throw new RuntimeException("error.noMatch");   
    21.     }          
    22.        
    23.     return validateResult;      
    24.        
    25.   }   
    26. }  


    将其放在bussness包中。

    我们同样要将其表示错误信息的键值设置在ApplicationResource.properties文件中,清单如下:
    1. #Application Resource for the UserInfoBo.java   
    2. error.noMatch=<li><font color="red">no matched userfont>li>  


    到此为止,我们已经完成了这个简单登录程序的所有组件。下面就可以享受我们的劳动成果了。

    第六步、编译运行应用程序。

    常规的做法是用Ant来装配和部署Struts应用程序,如果按这个套路,这篇文章就会显得十分冗长乏味,同时也没有太大的必要,因为,用一个IDE一般可以很方便地生成一个应用。因此,我们采用简便的方法,直接编译我们的.java文件。不过这里要注意一点的是:实践证明,要使得编译过程不出错,还必须将struts.jar文件放一份拷贝到/common/lib目录中,并在环境变量中设置CLASSPATH 其值是/common/lib/struts.jar;配置好后就可以分别编译entity、bussness及action目录下的.java文件了。编译完成后:打开/conf目录下的server.xml文件,在前加上如下语句为我们的应用程序建一个虚拟目录:
    xml 代码
    1. <Context path="/mystruts" docBase="mystruts" debug="0"  
    2.                  reloadable="true">                    
    3. Context>  
    4.     


    启动,tomcat。在浏览器中输入:http://localhost:8080/mystruts/logon.jsp
    如果前面的步骤没有纰漏的话,一个如图所示的登录画面就会出现在你的眼前。



    如果,不输入任何内容直接点击Submit按钮,就会返回到logon.jsp并显示missing username和missing password错误信息;如果输入其他内容,则会返回no matched user的错误;如果输入的用户名是lhb且口令是awave则会显示表示登录成功的欢迎页面。

    上面虽然是一个功能很简单的应用程序,但麻雀虽小,五脏俱全,基本涉及到了struts的主要组成部分。下面我们就来分析一下程序的特点和基本的工作原理。

    首先,我们在浏览器中输入.jsp文件时,后台将struts的自定义标签"翻译"成普通的html标签返回给浏览器,而一些提示信息如作为输入框label的username、password还有按钮上提示信息还有错误信息等都来自MessageResources即ApplicationResource.properties文件中对应的键值。当我们点击Submit按钮时,从web.xml的配置可以看出,请求将被ActionServlet截获。它通过表单中提供的action参数在struts-config.xml文件中查找对应的项目,如果有对应的ActionForm,它就用表单中数据填充ActionForm的对应属性,本例中的ActionForm为userInfoForm,相应的属性是username和password,这就是所谓的实例化ActionForm。然后,将控制交给对应的Action,本例中是LogonAction,它做的主要工作是对ActionForm中取出的username和password做了一下校验,这里只是简单检验它们是否为空(这些简单的格式化方面的校验应该放在客户端进行,而且struts也为我们提供了一个很好的模式,后面如果有可能会详细介绍)。如果不为空则调用判断用户及口令是否正确的业务逻辑模块UserInfoBo,同时,它会捕获可能出现的错误,然后根据业务逻辑返回的结果将程序导向不同的页面,本例中如果业务逻辑返回的结果是"match"则依据中的返回main.jsp页面给浏览器同时在session对象中保存了用户的登录信息;否则,返回输入页面并显示相应的出错信息,完成了上篇文章所说的它的四个主要职责。

    大家一定注意到了,在本例的业务逻辑模块UserInfoBo中,将用户与密码是写死在程序中的,在一个真实的应用程序中是不会这样做的,那些需要永久保存的信息如,username及口令等都会保存在数据库文件之类的永久介质中,下一篇文章我们将介绍在struts中如何访问数据库。

  • 分享到:
    评论

    相关推荐

      Struts原理与实践(罗会波)

      Struts原理与实践罗会波Struts原理与实践罗会波

      Struts原理与实践.mht

      Struts原理与实践(1) - Java - New - JavaEye论坛.mht

      Struts原理与实践

      Struts原理与实践,我也不想要大家的分,我实在是没分了。谢谢

      Struts原理与实践(一) .rar

      Struts原理与实践(一) .rar

      Struts原理与实践(三).rar

      Struts原理与实践(三).rar

      Struts原理与实践(五).rar

      Struts原理与实践(五).rar

      Struts原理与实践(二).rar

      Struts原理与实践(二).rar

      struts2 原理与实践

      struts2 原理与实践 值得收藏

      Struts+spring+hibernate学习笔记! - Struts原理与实践 - JavaEye知识库.files

      Struts+spring+hibernate学习笔记! - Struts原理与实践

      Struts原理与实践 ——

      下面,我们讨论一下最后一个问题,就是读写数据库时出现乱码。 现在一些常用的数据库都支持数据库encoding,也就是说在创建数据库时可以指定它自己的字符集设置, 数据库数据以指定的编码形式存储。...

      struts原理与实践+指导JAVA学习阶段需研究的开源项目

      主要讲解struts原理及实践应用和指导JAVA学习阶段需要研究的开源项目struts初学者及Java进阶学者

      struts原理与实践(一)

      很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:) 本节介绍了struts的基本原理,流程图看起来很直接的哦..

      struts原理与实践(三)

      很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:) 本节介绍了Struts JDBC的工作原理和数据库的连接配置..

      struts原理与实践二)

      很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:) 本节介绍了Struts Web应用程序的开发步骤和一个简单例子的详细过程,...

      struts原理与实践(四)

      本节介绍了struts的国际化编程问题.. 很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:)

      struts原理与实践(六)

      本节介绍了采用Struts中的输入校验问题.. 很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:)

      struts原理与实践(七)

      本节介绍了如何实现一个文章发布系统.. 很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:)

      初探Struts原理与实践.doc

      Struts作为一个开放原代码的应用框架,在最近几年得到了飞速的发展,在JSP Web应用开发中应用得非常广泛,有的文献上说它已经成为JSP Web应用框架的事实上的标准。那么,究竟什么是Struts呢?

    Global site tag (gtag.js) - Google Analytics