- 浏览: 42543 次
- 性别:
- 来自: 山东->北京
最新评论
-
lancezhcj:
我的配置文件在WEB-INF下的config文件夹下
配置文件在WEB-INF下的读取方式 -
davidx:
正则表达式
判断字符是否为中文
J2ee的开源框架很多,笔者只能介绍自己熟悉的几个,其他的目前在中国IT行业应用得不是很多。希望大家对新出的框架不要盲目的推崇,首先一定要熟悉它比旧的到底好在哪里,新的理念和特性是什么?然后再决定是否要使用它。
这期的主题是Struts,直译过来是支架。Struts的第一个版本是在2001年5月发布的,它提供了一个Web应用的解决方案,如何让Jsp和servlet共存去提供清晰的分离视图和业务应用逻辑的架构。在Struts之前,通常的做法是在Jsp中加入业务逻辑,或者在Servlet中生成视图转发到前台去。Struts带着MVC的新理念当时退出几乎成为业界公认的Web应用标准,于是当代IT市场上也出现了众多熟悉Struts的程序员。即使有新的框架再出来不用,而继续用Struts的理由也加上了一条低风险,因为中途如果开发人员变动,很容易的招进新的会Struts的IT民工啊,^_^!
笔者之前说的都是Struts-1,因为新出了Struts-2,使得每次谈到Struts都必须注明它是Struts-1还是2。笔者先谈比较熟悉的Struts-1,下次再介绍一下与Struts-2的区别:
1. Struts框架整体结构
Struts-1的核心功能是前端控制器,程序员需要关注的是后端控制器。前端控制器是是一个Servlet,在Web.xml中间配置所有Request都必须经过前端控制器,它的名字是ActionServlet,由框架来实现和管理。所有的视图和业务逻辑隔离都是应为这个ActionServlet, 它就像一个交通警察,所有过往的车辆必须经过它的法眼,然后被送往特定的通道。所有,对它的理解就是分发器,我们也可以叫做Dispatcher,其实了解Servlet编程的人自己也可以写一个分发器,加上拦截request的Filter,其实自己实现一个struts框架并不是很困难。主要目的就是让编写视图的和后台逻辑的可以脱离紧耦合,各自同步的完成自己的工作。
那么有了ActionServlet在中间负责转发,前端的视图比如说是Jsp,只需要把所有的数据Submit,这些数据就会到达适合处理它的后端控制器Action,然后在里面进行处理,处理完毕之后转发到前台的同一个或者不同的视图Jsp中间,返回前台利用的也是Servlet里面的forward和redirect两种方式。所以到目前为止,一切都只是借用了Servlet的API搭建起了一个方便的框架而已。这也是Struts最显著的特性——控制器。
那么另外一个特性,可以说也是Struts-1带来的一个比较成功的理念,就是以xml配置代替硬编码配置信息。以往决定Jsp往哪个servlet提交,是要写进Jsp代码中的,也就是说一旦这个提交路径要改,我们必须改写代码再重新编译。而Struts提出来的思路是,编码的只是一个逻辑名字,它对应哪个class文件写进了xml配置文件中,这个配置文件记录着所有的映射关系,一旦需要改变路径,改变xml文件比改变代码要容易得多。这个理念可以说相当成功,以致于后来的框架都延续着这个思路,xml所起的作用也越来越大。
大致上来说Struts当初给我们带来的新鲜感就这么多了,其他的所有特性都是基于方便的控制转发和可扩展的xml配置的基础之上来完成它们的功能的。
下面将分别介绍Action和FormBean, 这两个是Struts中最核心的两个组件。
2. 后端控制器Action
Action就是我们说的后端控制器,它必须继承自一个Action父类,Struts设计了很多种Action,例如DispatchAction、DynaValidationAction。它们都有一个处理业务逻辑的方法execute(),传入的request, response, formBean和actionMapping四个对象,返回actionForward对象。到达Action之前先会经过一个RequestProcessor来初始化配置文件的映射关系,这里需要大家注意几点:
1) 为了确保线程安全,在一个应用的生命周期中,Struts框架只会为每个Action类创建一个Action实例,所有的客户请求共享同一个Action实例,并且所有线程可以同时执行它的execute()方法。所以当你继承父类Action,并添加了private成员变量的时候,请记住这个变量可以被多个线程访问,它的同步必须由程序员负责。(所有我们不推荐这样做)。在使用Action的时候,保证线程安全的重要原则是在Action类中仅仅使用局部变量,谨慎的使用实例变量。局部变量是对每个线程来说私有的,execute方法结束就被销毁,而实例变量相当于被所有线程共享。
2) 当ActionServlet实例接收到Http请求后,在doGet()或者doPost()方法中都会调用process()方法来处理请求。RequestProcessor类包含一个HashMap,作为存放所有Action实例的缓存,每个Action实例在缓存中存放的属性key为Action类名。在RequestProcessor类的processActionCreate()方法中,首先检查在HashMap中是否存在Action实例。创建Action实例的代码位于同步代码块中,以保证只有一个线程创建Action实例。一旦线程创建了Action实例并把它存放到HashMap中,以后所有的线程会直接使用这个缓存中的实例。
3) <action> 元素的 <roles> 属性指定访问这个Action用户必须具备的安全角色,多个角色之间逗号隔开。RequestProcessor类在预处理请求时会调用自身的processRoles()方法,检查配置文件中是否为Action配置了安全角色,如果有,就调用HttpServletRequest的isUserInRole()方法来判断用户是否具备了必要的安全性角色,如果不具备,就直接向客户端返回错误。(返回的视图通过 <input> 属性来指定)
3. 数据传输对象FormBean
Struts并没有把模型层的业务对象直接传递到视图层,而是采用DTO(Data Transfer Object)来传输数据,这样可以减少传输数据的冗余,提高传输效率;还有助于实现各层之间的独立,使每个层分工明确。Struts的DTO就是ActionForm,即formBean。由于模型层应该和Web应用层保持独立。由于ActionForm类中使用了Servlet API, 因此不提倡把ActionForm传递给模型层, 而应该在控制层把ActionForm Bean的数据重新组装到自定义的DTO中, 再把它传递给模型层。它只有两个scope,分别是session和request。(默认是session)一个ActionForm标准的生命周期是:
1) 控制器收到请求 ->
2) 从request或session中取出ActionForm实例,如不存在就创建一个 ->
3) 调用ActionForm的reset()方法 ->
4) 把实例放入session或者request中 ->
5) 将用户输入表达数据组装到ActionForm中 ->
6) 如眼张方法配置了就调用validate()方法 ->
7) 如验证错误就转发给 <input> 属性指定的地方,否则调用execute()方法
validate()方法调用必须满足两个条件:
1) ActionForm 配置了Action映射而且name属性匹配
2) <aciton> 元素的validate属性为true
如果ActionForm在request范围内,那么对于每个新的请求都会创建新的ActionForm实例,属性被初始化为默认值,那么reset()方法就显得没有必要;但如果ActionForm在session范围内,同一个ActionForm实例会被多个请求共享,reset()方法在这种情况下极为有用。
4. 验证框架和国际化
Struts有许多自己的特性,但是基本上大家还是不太常用,说白了它们也是基于JDK中间的很多Java基础包来完成工作。例如国际化、验证框架、插件自扩展功能、与其他框架的集成、因为各大框架基本都有提供这样的特性,Struts也并不是做得最好的一个,这里也不想多说。Struts的验证框架,是通过一个validator.xml的配置文件读入验证规则,然后在validation-rules.xml里面找到验证实现通过自动为Jsp插入Javascript来实现,可以说做得相当简陋。弹出来的JavaScript框不但难看还很多冗余信息,笔者宁愿用formBean验证或者Action的saveErrors(),验证逻辑虽然要自己写,但页面隐藏/浮现的警告提示更加人性化和美观一些。
至于Struts的国际化,其实无论哪个框架的国际化,java.util.Locale类是最重要的Java I18N类。在Java语言中,几乎所有的对国际化和本地化的支持都依赖于这个类。如果Java类库中的某个类在运行的时候需要根据Locale对象来调整其功能,那么就称这个类是本地敏感的(Locale-Sensitive), 例如java.text.DateFormat类就是,依赖于特定Locale。
创建Locale对象的时候,需要明确的指定其语言和国家的代码,语言代码遵从的是ISO-639规范,国家代码遵从ISO-3166规范,可以从
http://www.unicode.org/unicode/onlinedat/languages.html
http://www.unicode.org/unicode/onlinedat/countries.htm
Struts的国际化是基于properties的message/key对应来实现的,笔者曾写过一个程序,所有Jsp页面上没有任何Text文本串,全部都用的是 <bean:message> 去Properties文件里面读,这个时候其实只要指定不同的语言区域读不同的Properties文件就实现了国际化。需要注意的是不同语言的字符写进Properties文件的时候需要转化成Unicode码,JDK已经带有转换的功能。JDK的bin目录中有native2ascii这个命令,可以完成对*.txt和*.properties的Unicode码转换。
OK,今天就说到这里,本文中的很多内容也不是笔者的手笔,是笔者一路学习过来自己抄下来的笔记,希望对大家有帮助!Java杂谈一路走来,感谢大家持续的关注,大概再有个2到3篇续篇就改完结了!笔者尽快整理完成后续的写作吧……^_^
发表评论
-
日期操作函数
2008-12-04 15:16 1405import java.util.Date; import j ... -
判断字符是否为中文
2008-12-04 15:07 1118package cn.wangy.test; import ... -
System.getProperties()参数列表
2008-12-04 14:44 1456JAVA.version :JAVA运行时环境版本JAVA.v ... -
Class.forName()详解
2008-12-04 14:35 1606Class.forName(xxx.xx.xx) 返回的是一个 ... -
Java中日期操作函数
2008-12-04 14:25 9671.计算某一月份的最大天数 Calendar time = C ... -
Java中使用MD5加密
2008-12-04 14:12 1118在各种应用系统的开发 ... -
Java文件操作大全
2008-12-04 13:50 841一.获得控制台用户输入的信息 /**获得控制台用户输入的信 ... -
泛型与反射
2008-12-04 13:31 1056我们知道,反射和泛型都是Java的一种动态技术。而不像继承和多 ... -
Java的多线程
2008-12-04 13:09 942一.实现多线程1. 虚假的多线程例1: public clas ... -
线程的wait(),notify()例子
2008-12-04 13:01 2384package cn.wangy; class Produc ... -
共5次每隔2秒检查指定文件是否存在 读取并强制删除
2008-12-04 12:56 1587package cn.wangy.io; import ja ... -
String和InputStream的转换
2008-12-04 12:33 19151. String --> InputStream I ... -
Java学习杂谈(10)
2008-12-04 12:28 832今天的主题是目前很流行也很好的一个开源框架-Spring。 ... -
Java学习杂谈(8)
2008-12-04 12:25 803终于正式进入J2ee的细节部分了,首当其冲的当然是Servle ... -
Java学习杂谈(7)
2008-12-04 12:24 695终于又静下来继续写这 ... -
Java学习杂谈(6)
2008-12-04 12:18 5141. Java中的RMI机制 RMI的全称是远程方法调 ... -
Java学习杂谈(5)
2008-12-04 12:13 7081. Java关于XML的解析 ... -
java的几种对象(PO,VO,DAO,BO,POJO)解释
2008-12-04 12:10 456一、PO:persistant object 持 ... -
Java学习杂谈(4)
2008-12-04 12:06 732第三篇讲的是反射机制集合框架之类的,这次打算讲讲自己对反序 ... -
Java学习杂谈(3)
2008-12-04 12:05 7791. 关于Object类理解 ...
相关推荐
Java学习杂谈系列涵盖了许多关于Java编程的基础概念和机制,以下是对这些知识点的详细解读: 1. **动态加载机制**: 动态加载机制是Java语言的一个关键特性,它使得程序在运行时才能确定哪些类需要加载。当你声明...
### Java学习杂谈:深入解析Java的动态加载机制、类搜索原理及JDK与JRE的区别 #### 动态加载机制解析 Java的学习者往往在掌握面向对象编程(OOP)概念时,会遇到“动态加载机制”这一关键点。相较于C++中面向过程...
"主流编程语言的选择和学习杂谈" 本文主要介绍了当前主流编程语言的特点、发展趋势和学习方法,为新手提供了学习参考。 一、Java 语言 Java 语言是由 Sun 公司开发的,目前由 Java Community Process 控制。Java ...
[学习资料] 09年Java认证考试:我的Java学习道路 [学习资料] 09年Java认证考试:学好java开发的关键七步 [学习资料] 09年Java认证考试:JAVA求素数算法实现 [学习资料] 09年Java认证考试:java类的构造方法 [学习...
此外,随着Java版本的更新,一些机制可能会有所变化,例如类加载器的工作方式在JDK 1.4到1.6之间可能有所调整,因此持续学习和跟踪Java的最新发展也是必要的。 总之,Java的动态加载机制、类加载器的工作原理以及...
例如,Python有PEP 8,Java有Google Java Style Guide,这些都是值得遵循的编码规范。 最后,项目管理在大型项目中扮演着重要角色。了解敏捷开发理念,如Scrum或Kanban,可以帮助团队有效地组织和管理任务。同时,...
总的来说,《Java陈国君(第二版)课件》是一个全面的Java学习资源,无论你是零基础的新手,还是希望进一步提升的开发者,都能从中受益匪浅。通过深入学习和实践,你将能够掌握Java编程的核心技能,为未来的编程生涯...
### Java框架知识学习 #### Struts 1.x **手写MVC框架** - **概念理解**:在探讨Struts框架之前,先了解MVC(Model-View-Controller)架构模式的基本原理。这是一种广泛应用于软件工程的设计模式,尤其是用于Web...
**1.6 JAVA面试题解惑系列(六)——字符串(String)杂谈** - **知识点**:深入探讨字符串处理技术,包括字符串拼接、比较、格式化等常见操作的内部实现,以及性能优化建议。 **1.7 JAVA面试题解惑系列(七)——...
- 发布工具:Jenkins是自动发布工具的首选,它既关乎管理人员的经验,也关系到开发人员的学习与适应能力。Jenkins能够在持续集成中发挥关键作用,提高软件交付的速度和质量。 - Bug管理:合理的Bug管理能够确保软件...
【JAVA面试题解惑系列】是一系列专门...以上只是《JAVA面试题解惑系列》中部分主题的简要介绍,每篇文章都深入探讨了相关主题,为面试者提供了丰富的学习资料。掌握这些知识点,将有助于在面试中表现出扎实的Java基础。
9. **性能优化**:了解如何通过代码优化、数据库查询优化、内存管理等方式提高系统性能,是高级程序员的必备技能。 10. **跨平台与兼容性**:随着多平台开发的需求增加,理解不同操作系统和浏览器的特性,以及如何...
“JAVA面试题解惑系列(六)——字符串(String)杂谈”可能涉及到String池的概念,即JVM会缓存重复的字符串,以提高性能。此外,String的equals()和==的区别也常常是面试的焦点,前者比较内容,后者比较对象引用。 ...
在IT行业中,J2EE(Java 2 Platform, Enterprise Edition)是一个广泛使用的开源企业级应用开发平台,由Oracle...通过深入学习和实践这两个技术,开发者可以更好地应对复杂的业务场景,打造健壮、可维护的Java应用。
这篇"Android开发杂谈"涵盖了从系统组成、启动过程到关键组件的解析,旨在为初学者提供一个全面的理解框架。 Android系统是由多个层次构成的,包括Application、Framework、Native Libraries、Userspace Drivers...
Swing是Java编程语言中用于构建图形用户界面(GUI)的一个工具包,它是Java Foundation Classes ...通过学习和理解这个初版本的源码,开发者能够更好地掌握Swing的使用,并在此基础上构建更复杂的Java GUI应用程序。
深入浅出 例子实用 代码丰富 是java程序人员学习和深入数据结构和算法的实用读物 由于资源过大,分两部分上传 本资源为第二部分
综上所述,“java俄罗斯方块”项目涵盖了Java编程中的许多核心概念和技术,是学习和实践Java GUI编程、多线程、游戏开发和数据处理的绝佳案例。通过这个项目,开发者不仅可以掌握Java编程基础,还能深入理解游戏开发...