⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jakarta struts简介.txt

📁 一些自己平时积累的小知识点, java 的 javaee 的
💻 TXT
📖 第 1 页 / 共 4 页
字号:
        再次重复一遍,本文需要读者有如下几方面的知识和经验:JSP,Servlets,自定义标签库(Custom Tag libraries)和XML。此外,在本文中,我还会用到Jakarta项目组其他一些好东东,比如Tomcathttp://jakarta.apache.org/tomcat/index.html(实现Java Servlet和JSP官方标准的Servlet容器,通俗的讲就是一个JSP的Web Server啦)和Anthttp://jakarta.apache.org/ant/index.html(基于Java的自动编译发布工具,这可是好东东啊)。
        作为一名一直使用前沿技术开发了诸多应用的技术人员,我一直坚信掌握新技术,理解该技术开发的逻辑是至关重要的。但这往往就是陷住我们学习步伐的泥潭,正因如此,我打算将利用Struts开发的一套完整流程作为我们教学的案例。该流程的这个案例可谓“麻雀虽小、五脏据全”,你完全可以将这个流程应用到你手头那些复杂庞大的项目中,至少在我们的大项目中应用这个流程效果不错。
        有开发复杂商业应用的开发人员都知道,客户的需求总是在不停变幻,所以如果有一套规范的开发流程来遵循,当客户提出新的需求时,我们至少可以明确哪些“无理”需求其实是合理可行的。好,接下里我将在我的这个例子中向各位展示和应用整个流程。
        本文中的示例代码是StrutsSample应用中的一部分,包括build.xml的完整代码可以到此处http://www.onjava.com/onjava/2001/10/31/examples/StrutsPartII.jar下载。

Struts开发过程
        从Struts发布的版本号可以看出,Struts是个新玩意,她有好几个部分组成,明智的你如果搞清楚了何时该开发完成合适的部分,那将会更好的利用我们的开发时间。从我所开发的几个利用Struts应用中,我大致总结出如下这个比较有效的开发步骤:
1,明确应用需求;
2,由用户输入和获取数据的角度出发,明确和设计出每一个用户界面;
3,确定用户界面的进入路径;
4,由应用逻辑信息确定动作映射表(ActionMapping);
5,由设计完成的用户界面开发其所用到的类和应用函数;
6,由用户界面中的数据信息开发ActionForm和相应的数据校验方法;
7,ActionMapping中将会被调用相应的Action或转到相应的JSP页面,这一步我们先开发这些Action;
8,开发商业应用逻辑,就是相应的JavaBean、EJB或其他东东;
9,开发由ActionMapping定义的系统工作流程完成对应的JSP页面;
10,完成系统配置文件:struts-config.xml和web.xml;
11,编译/测试/发布。

明确应用需求
        开发任何应用系统的第一步就是收集用户需求信息。不管一个用户逻辑初看上去多么合理,但总有可能在开发时才发现它比看上去要难得多。所以,建议拟一份明确的用户需求列表,这不只是出于开发的目的,还能通过该表分析用户需求以确定哪些地方可能需要花更多的精力。
        在我们这个StrutsSample项目中,应用需求就是:
        作为一个展示Struts框架应用的完整例子,本示例完成的功能是用户登录。目的只为明确Struts的应用,本示例将不会涉及到一般复杂应用系统中可能应用的安全、数据库、EJB开发等等相关技术。

设计用户界面
        这个应用中,包括如下三个用户界面:
1)登录界面,用于用户名和密码输入;
2)当登录用户为合法用户时的欢迎界面; 
3)当登录失败时的错误提示界面。

确定用户界面的进入路径
1)登录界面作为这个应用的默认页面;
2)欢迎界面只有当成功登录后才能进入;
3)任何可能发生错误的页面能可以进入错误提示界面;

由应用逻辑信息确定ActionMapping
        ActionMapping为整个应用确定的“线路图”,在配置文件struts-config.xml对ActionMapping进行定义,通过转发请求(forward)来理顺应用的处理流程,确定应用中每个用户请求对应的动作。
        通常我们在开发过程中就逐步确定了ActionMapping所需的信息,开发代码的过程就是在由草稿开始一步步完善struts-config.xml的过程。当Action类处理完用户请求后,其返回的的forward就是在ActionMapping中定义的一个。一个Action返回的forward完全有多种可能,尽管一个Action一般只定义其相关的几个forward。那么,如果有多个Action都可能返回的同一个forward,那么就可以将其定义为全局转发(global forward)。这类似于C中的头文件中全局变量,如果在struts-config.xml描述信息中,某一个forward并不是在当前Action描述中定义的而是全局定义的,那么这个全局的将起作用,同样,一个Action中当前定义的forward将覆盖全局定义。在我们所给的这个简单实例中,我们定义了全局forward――“error”,当某Action返回的forward是“error”这个映射,那么Errorpage.jsp页面将会显示给用户,尽管当前Action并没有对其定义。
        我们继续不断的开发,项目日渐完善,项目相关的配置文件也会越来越详细。在下面的例子中,我们将以StrutsSample中用到的struts-confug.xml文件为例,学习global forward和一个Action中相关映射的定义。下面定义了一个名为“login”的Action,其为com.oreilly.actions.LoginAction的实例,当Action处理用户登录成功后将一个名为"success"的forward返回,用户也就会看到Welcome.jsp页面,如果登录失败,Action将返回对应的forward以再显示Login.jsp给用户,而如果处理过程中发生其他错误,Action将返回全局定义的forward――“error”,用户也就会看到错误提示页面Errorpage.jsp。

<!-- ========== Global Forward 定义 -->
<global-forwards>
<forward name="login" path="/Login.jsp"/>
<forward name="error" path="/Errorpage.jsp"/>
</global-forwards>

<!-- ========== Action Mapping 定义 -->
<action-mappings>
<!-- <action>元素的相关属性 -->
<!--
以下只列出常用属性,其他请参考org.apache.struts.action.ActionMapping的相关文档

path - 当前Action对应的用户请求URI路径

type - 实现当前Action的Java class的完整名字

name - 当前Action中用到的ActionForm的名字,其具体信息在配置文件其他地方另有详细定义

unknown - 如果将该属性设置为true,那么就是声明这个Action将处理整个应用中所有未找到相应处理Action的请求,当然,一个应用系统中也只会有一个Action的unknown属性可以设为true

scope - Action中所用到的ActionForm的生存期,可以为“request”或“session”,随着生存期的设置,该Action也会在相应的时间被创建

input - 该Action中相关ActionForm获取用户输入的输入页面,当将ActionForm设为自动验证输入数据,发现不合法数据返回错误时,将返回该页面

validate - 如果本属性为true则在Action动作之前其对应的ActionForm的validate方法会自动被调用,一般用以验证用户输入的数据

forward 元素 - 定义当前Action相关的ActionForward
-->

<!-- =================== -->
<!-- O&#39;Reilly Struts Sample Main Actions -->
<!-- =================== --> 
<action path="/login"
type="com.oreilly.actions.LoginAction"
name="loginForm"
scope="request"
input="/Login.jsp">
<forward name="success" path="/Welcome.jsp"/>
<forward name="failure" path="/Login.jsp"/>
</action>
</action-mappings>        

        在前一篇文章中,我们曾说过,struts-config.xml就是MVC模式的的Controller。在确定struts-config.xml中的配置信息时,应该多花些时间精力在上面,以保证每一个Action定义及其相关定义是符合应用的需求的。如果在项目开始没有详细的设计其定义,当将所有代码和配置集成到一起的时候,我们将不可避免的将各部分的代码和配置完全重新组织一遍。
        我们当前的例子StrusSample因为只是处理用户登录,所以只需要一个Action。一个应用系统中所要用到的Action的多少完全依应用的大小而定。一旦整套Action的映射完全的定义出来后,我们就可以一个一个开发其具体实现的Action和ActionForm类,并逐渐将完成的部分一点一点集成起来。

由设计完成的用户界面开发其所用到的类和应用函数
        所有ActionForm的实现类都是org.apache.struts.ActionForm的子类。一个ActionForm是与页面上的输入表单相关联的,而且ActionForm的实现还可以对用户输入数据的合法性进行验证。作为一个Java Bean,ActionForm有Set和Get方法,当一个页面中表单被提交时,系统将自动调用Set方法将数据放入ActionForm中,而Get方法将为在Action中操作这些数据所提供。一般来说,处理表单中的所有数据,并进行合法性验证都完全可以交由ActionForm来完成。在应用中,就我个人而言,倾向于将ActionForm和Action划分到不同的包中,因为当一个页面中要用到几对ActionFrom和Action时,都放在一个包内会混淆的。下面的代码,就是实例中登录页面用到的ActionForm的代码。

/*
* LoginForm.java
*/
package com.oreilly.forms;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

/**
* 验证用户要用到的两个数据
*
* username - 登录用户名
* password - 用户密码
* 
*/
public final class LoginForm extends ActionForm {
        private String userName = null;
        private String password = null;

        /**
        * userName的Get方法
        * @return String 
        */
        public String getUserName() {
                return (userName);
        }

        /**
        * userName的Set方法
        * @param userName 
        */
        public void setUserName(String newUserName) {
                userName = newUserName;
        }

        /**
        * password的Get方法
        * @return String 
        */
        public String getPassword() {
                return (password);
        }

        /**
        * password的Set方法
        * @param password 
        */
        public void setPassword(String newPassword) {
                password = newPassword;
        }

        /**
        * 重置所有数据
        *
        * @param mapping 当前的ActionMapping
        * @param request 当前Server正在处理的HttpServletRequest
        */
        public void reset(ActionMapping mapping, HttpServletRequest request) {
                userName = null;
                password = null;
        }

        /**
        * 验证当前HTTP请求提交上来的数据
        * 如果数据验证发现不合法数据,将返回一个封装
          * 所有验证错误的ActionErrors对象
        * 如果数据验证通过,该方法返回null或者一个
          * 没有封装任何验证错误的ActionErrors对象
        *
        * @param mapping 当前的ActionMapping
        * @param request 当前Server正在处理的HttpServletRequest
        */
        public ActionErrors validate(ActionMapping mapping,
                                     HttpServletRequest request) {
                ActionErrors errors = new ActionErrors(); 
                // 当前ActionForm中,只需要检查用户输入的用户名数据
                if( userName == null || userName.length()==0 ){
                        errors.add("userName",new ActionError("error.userName.required"));
                }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -