iLeichun

当前位置:首页J2EE

通过JVM原理理解字符串的比较

分类:J2EE  来源:网络  时间:2010-10-21 23:23:10

  Java中的字符串也是一连串的字符,但是与许多其他的计算机语言将字符串作为字符数组处理不同,Java将字符串作为String类型对象来处理。将字符串作为内置的对象处理允许Java提供十分丰富的功能特性以方便处理字符串。

  JVM运行时数据区的内存模型由五部分组成:

  (1)方法区

  (2)堆

  (3)JAVA栈

  (4)PC寄存器

  (5)本地方法栈

  对于String s = "haha" ,它的虚拟机指令:

  0: ldc "16; //String haha 2: astore_1 3: return

  ldc指令格式:

  ldc,index

  ldc指令过程:要执行ldc指令,JVM首先查找index所指定的常量池入口,在index指向的JVM常量池入口,JVM将会查找CONSTANT_Integer_info,CONSTANT_Float_info和CONSTANT_String_info入口。如果还没有这些入口,JVM会解析它们。而对于上面的hahaJVM会找到CONSTANT_String_info入口,同时,将把指向被拘留String对象(由解析该入口的进程产生)的引用压入操作数栈。

  astore_1指令格式:

  astore_1

  astore_1指令过程:要执行astore_1指令,JVM从操作数栈顶部弹出一个引用类型或者returnAddress类型值,然后将该值存入由索引1指定的局部变量中,即将引用类型或者returnAddress类型值存入局部变量1。

  return 指令的过程:

  从上面的ldc指令的执行过程可以得出:s的值是来自被拘留String对象(由解析该入口的进程产生)的引用,即可以理解为是从被拘留String对象的引用复制而来的,故我个人的理解是s的值是存在栈当中。上面是对于s值得分析,接着是对于"haha"值的分析,我们知道,对于String s = "haha" 其中"haha"值在JAVA程序编译期就确定下来了的。简单一点说,就是haha的值在程序编译成class文件后,就在class文件中生成了(大家可以用UE编辑器或其它文本编辑工具在打开class文件后的字节码文件中看到这个haha值)。执行JAVA程序的过程中,第一步是class文件生成,然后被JVM装载到内存执行。那么JVM装载这个class到内存中,其中的haha这个值,在内存中是怎么为其开辟空间并存储在哪个区域中呢?

  JVM常量池

  虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集和,包括直接常量(string,integer和floating point常量)和对其他类型,字段和方法的符号引用。对于String常量,它的值是在常量池中的。而JVM常量池在内存当中是以表的形式存在的,对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字字符串值,注意:该表只存储文字字符串值,不存储符号引用。说到这里,对JVM常量池中的字符串值的存储位置应该有一个比较明了的理解了。

  在介绍完JVM常量池的概念后,接着谈开始提到的"haha"的值的内存分布的位置。对于haha的值,实际上是在class文件被JVM装载到内存当中并被引擎在解析ldc指令并执行ldc指令之前,JVM就已经为haha这个字符串在常量池的CONSTANT_String_info表中分配了空间来存储haha这个值。

  既然haha这个字符串常量存储在常量池中,常量池是属于类型信息的一部分,类型信息也就是每一个被转载的类型,这个类型反映到JVM内存模型中是对应存在于JVM内存模型的方法区中,也就是这个类型信息中的JVM常量池概念是存在于在方法区中,而方法区是在JVM内存模型中的堆中由JVM来分配的。所以,haha的值是应该是存在堆空间中的。而对于String s = new String("haha") ,它的JVM指令:


0:   new             "16; //class String   
3:   dup   
4:   ldc             "18; //String haha   
6:   invokespecial   "20; //Method java/lang/String."":(Ljava/lang/String;)V   
9:   astore_1   
10:  return 

  new指令格式:new indexbyte1,indexbyte2

  new指令过程:

  要执行new指令,Jvm通过计算(indextype1<<8)|indextype2生成一个指向常量池的无符号16位索引。然后JVM根据计算出的索引查找JVM常量池入口。该索引所指向的常量池入口必须为CONSTANT_Class_info。如果该入口尚不存在,那么JVM将解析这个常量池入口,该入口类型必须是类。JVM从堆中为新对象映像分配足够大的空间,并将对象的实例变量设为默认值。最后JVM将指向新对象的引用objectref压入操作数栈。

  dup指令格式:dup

  dup指令过程:

  要执行dup指令,JVM复制了操作数栈顶部一个字长的内容,然后再将复制内容压入栈。本指令能够从操作数栈顶部复制任何单位字长的值。但绝对不要使用它来复制操作数栈顶部任何两个字长(long型或double型)中的一个字长。上面例中,即复制引用objectref,这时在操作数栈存在2个引用。

  ldc指令格式:ldc,index

  ldc指令过程:

  要执行ldc指令,JVM首先查找index所指定的常量池入口,在index指向的JVM常量池入口,JVM将会查找CONSTANT_Integer_info,CONSTANT_Float_info和CONSTANT_String_info入口。如果还没有这些入口,JVM会解析它们。而对于上面的haha,JVM会找到CONSTANT_String_info入口,同时,将把指向被拘留String对象(由解析该入口的进程产生)的引用压入操作数栈。

  invokespecial指令格式:invokespecial,indextype1,indextype2

  invokespecial指令过程:对于该类而言,该指令是用来进行实例初始化方法的调用。上面例子中,即通过其中一个引用调用String类的构造器,初始化对象实例,让另一个相同的引用指向这个被初始化的对象实例,然后前一个引用弹出操作数栈。

  astore_1指令格式:astore_1

  astore_1指令过程:

  要执行astore_1指令,JVM从操作数栈顶部弹出一个引用类型或者returnAddress类型值,然后将该值存入由索引1指定的局部变量中,即将引用类型或者returnAddress类型值存入局部变量1。

  return 指令的过程:

  从方法中返回,返回值为void,要执行astore_1指令,JVM从操作数栈顶部弹出一个引用类型或者returnAddress类型值,然后将该值存入由索引1指定的局部变量中,即将引用类型或者returnAddress类型值存入局部变量1。

  通过上面6个指令,可以看出,String s = new String("haha");中的haha存储在堆空间中,而s则是在操作数栈中。上面是对s和haha值的内存情况的分析和理解;那对于String s = new String("haha");语句,到底创建了几个对象呢?这里"haha"本身就是JVM常量池中的一个对象,而在运行时执行new String()时,将JVM常量池中的对象复制一份放到堆中,并且把堆中的这个对象的引用交给s持有。所以这条语句就创建了2个String对象。下面是一些String相关的常见问题:

  String中的final用法和理解

  final StringBuffer a = new StringBuffer("111"); final StringBuffer b = new StringBuffer("222"); a=b;//此句编译不通过 final StringBuffer a = new StringBuffer("111"); a.append("222");//编译通过

  可见,final只对引用的"值"(即内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。

  String 常量池问题的几个例子

  下面是几个常见例子的比较分析和理解:


final StringBuffer a = new StringBuffer("111");   
final StringBuffer b = new StringBuffer("222");   
a=b;//此句编译不通过   
final StringBuffer a = new StringBuffer("111");   
a.append("222");//编译通过 

 

  分析:JVM对于字符串常量的"+"号连接,将程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,拿"a" + 1来说,经编译器优化后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序最终的结果都为true。


String a = "ab";
String bb = "b"; String b = "a" + bb; 
System.out.println((a == b)); 
//result = false

  分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。


String a = "ab"; 
final String bb = "b"; 
String b = "a" + bb; 
System.out.println((a == b));
 //result = true

  分析:和[3]中唯一不同的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。故上面程序的结果为true。


String a = "ab"; final String bb = getBB(); 
String b = "a" + bb; 
System.out.println((a == b)); 
//result = false private static String getBB() { return "b"; }

  分析:JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b,故上面程序的结果为false。通过上面4个例子可以得出得知:


String s = "a" + "b" + "c"; 
就等价于String s = "abc"; 
String a = "a"; String b = "b"; 
String c = "c"; 
String s = a + b + c;

  这个就不一样了,最终结果等于:


StringBuffer temp = new StringBuffer(); 
temp.append(a).append(b).append(c); 
String s = temp.toString();

  由上面的分析结果,可就不难推断出String 采用连接运算符(+)效率低下原因分析,形如这样的代码:


public class Test { public static void main(String args[]) {
 String s = null; 
for(int i = 0; i < 100; i++) { s += "a"; } } }

  每做一次 + 就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后 append 字符串,如此循环直至结束。 如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来进行append操作。String对象的intern方法理解和分析:


public class Test4 {   
private static String a = "ab";    
public static void main(String[] args){   
String s1 = "a";   
String s2 = "b";   
String s = s1 + s2;   
System.out.println(s == a);//false   
System.out.println(s.intern() == a);//true     
}   

  这里用到Java里面是一个常量池的问题。对于s1+s2操作,其实是在堆里面重新创建了一个新的对象,s保存的是这个新对象在堆空间的的内容,所以s与a的值是不相等的。而当调用s.intern()方法,却可以返回s在JVM常量池中的地址值,因为a的值存储在常量池中,故s.intern和a的值相等。

J2EE开发中几个主流框架的简短使用总结

分类:J2EE  来源:网络  时间:2010-10-21 23:21:24

  spring,SSH框架处于一个难于撼动的地位,spring以其轻量级,易操作的,开发高效等优点,被业界内广泛应用。IOC及AOP是spring被重要应用的两点,由于struts,struts2,webword等一系列view框架的存在,springMVC的应用显得有些力不从心,不能被广为推广使用。AOP使用中目前主要用,配置ehcache的时候用到过一次,其它地方应用不是太多,更多的是IOC的操作。与hibernate,struts结合使用,采用不同的设计模式,面向接口编程,已经成为业界公认的框架模式。struts的action交由spring配置bean文件来完成,由spring代理其action的操作,数据源/数据库连接池也在其配置文件里完成。

  spring更重要的是完成了应用间的解耦,更加有利于程序的维护,扩展。

  hibernate,ORM领域中的经典之作。OO与关系型数据库处于不协调发展的局面,数据库如今却成了OO编程路上的绊脚石,阻碍着OO向前发展,ORM于此解决了关系型数据库与对象间的映射。hibernate自动生成sql语句封装在内部,开发人员无须写SQL语句,HQL语法又相当简单,大大简化了开发的步骤。由于hibernate处理持久层的角色,只要数据库设计合理,更多的是利用IDE(MyEclipse)就可以生成相对的持久类POJO以及映射配置文件,与数据库关联起来,操作POJO类即操作数据库。spring对hibernate提供了很好的兼容性,在hibernate配置二级缓存,可以对系统应用起到良好的效果。

  Ibatis,ORM领域中一个框架,相对hibernate而言,ibatis更加小巧,更易于学习,对数据库设计不太友好的,使用IBATIS比hibernate更合适。ibatis不会像hibernate一样生成SQL,而是需要开发人员自己去写SQL语句,这一点也给于了开发人员更灵活的设计与操作。hibernate相对来说,在一些复杂的数据处理方,并不如IBATIS灵活。struts+ibatis+spring与SSH相比,也是一种不错的组合,巧手(7iaoshou)就是基于此框架组合。

  struts,MVC经典的一个实现,近阶段依然于其它框架无法超载的地位,不是说struts有多强大,完美,而是struts似乎成为了MVC开发的标准。主要应用有以下这些:对于大中型的企业级应用,多模块开发必然应用到,很多模块只有分开在不同的配置文件里写,才能更有利于书写,维护;自身FORM的验证,validate;struts丰富的页面标签书写页面更加灵活强大;与spring,hibernate完美的结合在一起使用,快速高效开发。

  其它WEB开发框架还有JSF,Struts 2.0,webwork等等,由于只是简单了解,并未投入生产使用,只能由读者自己去体会了。

JNDI 在 J2EE 中的角色收藏

分类:J2EE  来源:网络  时间:2010-10-21 23:20:35

  掌握 J2EE 是件令人生畏的事,因为它包含的技术和缩略语在不断地增长。Java 命名和目录接口(Java Naming and Directory Interface,JNDI)从一开始就一直是 Java 2 平台企业版(JEE)的核心,但是 J2EE 开发新手经常用不好它。本文将消除 JNDI 在 J2EE 应用程序中所扮演角色的神秘性,并展示它如何帮助应用程序从部署细节中解脱出来。

  虽然 J2EE 平台提高了普通企业开发人员的生活水平,但是这种提高是以不得不学习许多规范和技术为代价的,这些规范和技术则是 J2EE 为了成为无所不包的分布式计算平台而整合进来的。Dolly Developer 是众多开发人员中的一员,她已经发现了一个特性,该特性有助于缓解随企业级应用程序部署而带来的负担,这个特性就是 JNDI,即 Java 命名与目录接口(Java Naming and Directory Interface)。让我们来看看 Dolly 在没有 JNDI 的时候是怎么做的,以及她是如何正确地应用 JNDI 来改善其状况的。

  所有人都非常熟悉的旅程

  Dolly Developer 正在编写使用 JDBC 数据源的 Web 应用程序。她知道自己正在使用 MySQL,所以她将一个对 MySQL JDBC 驱动程序类的引用进行了编码,并通过使用适当的 JDBC URL 连接到其 Web 应用程序中的数据库。她认识到数据库连接池的重要性,所以她包含了一个连接池包,并把它配置成最多使用 64 个连接;她知道数据库服务器已经被设置成最多允许 128 台客户机进行连接。

  Dolly 在走向灾难

  在开发阶段,每件事都进行得很顺利。但是,在部署的时候,开始失控。Dolly 的网络管理员告诉她,她不能从她的桌面机访问生产服务器或登台服务器(staging server),所以她不得不为每个部署阶段开发不同的代码版本。因为这种情况,她需要一个新的 JDBC URL,所以还要为测试、阶段和生产进行独立的部署。(一听到要在每个环境中建立单独部署,熟悉配置管理的人会战战兢兢的,但是既然这是种非常普遍的情况,所以他们也只好硬着头皮上了。)

  就在 Dolly 认为通过不同的 URL 建立彼此独立的部署已经解决了自己的配置问题时,她发现她的数据库管理员不想在生产环境中运行 MySQL 实例。他说,MySQL 用作开发还可以,但是对于任务关键型数据而言,业务标准是 DB2®。现在她的构建不仅在数据库 URL 方面有所不同,而且还需要不同的驱动程序。

  事情越变越糟。她的应用程序非常有用,并且变得非常关键,以致于它从应用服务器那里得到了故障恢复的能力,并被复制到 4 个服务器集群。但是数据库管理员提出了抗议,因为她的应用程序的每个实例都要使用 64 个连接,而数据库服务器总共只有 200 个可用连接 —— 全部都被 Dolly 的应用程序占用了。更麻烦的是,DBA 已经确定 Dolly 的应用程序只需要 32 个连接,而且每天只有一个小时在使用。随着她的应用程序规模扩大,应用程序遇到了数据库级的争用问题,而她的惟一选择就是改变集群的连接数量,而且还要做好准备,在集群数量增长或者应用程序复制到另一个集群时再重复一次这样的操作。看来她已经决定了如何配置应用程序,应用程序的配置最好是留给系统管理员和数据库管理员来做。

Eclipse e4 M5发布 新功能及特性一览

分类:J2EE  来源:网络  时间:2010-8-28 1:28:18

  被称为下一代Eclipse平台的Eclipse e4近日传来消息,Eclipse e4 M5版本正式发布了,该版本提供了集成包,同时集成了Eclipse 4.0 SDK,包含Eclipse,EMF,XML Editors and Tools,用户可以直接下载Eclipse e4。

  关于Eclipse e4更多内容,请参阅下一代Eclipse平台:Eclipse e4全面介绍 下一代Eclipse平台7月推出 抢先版已可下载

  Eclipse e4 M5版本新功能与值得关注的特性:

  ◆可兼容性并使用Eclipse 4.0 SDK平台。在兼容性这一具有里程碑意义的重大成果包括了对按键绑定的支持、工具栏、主要性能的改进、细化了控制台的布局等。

  使用Eclipse 4.0 SDK平台

  ◆“Part”功能已经完成。在这个新版本中,调色板工具的“Part”已经完成,它将给开发人员带来更多的创造性。

  “Part”功能

  ◆XWT的输入部分。一个输入部分,包括读取数据源,比如文件的根数据,另一个则为“分配部分输入”。根据提供的EMF数据创建选项对话框中的文件,我们可以选择的根对象,如客户。通过数据结构和用户的选择,我们能够在部分用户界面形式中产生XWT。

  XWT的输入部分

  ◆XWT的选项部分。一个“选项部分”是显示Eclipse服务选项的一部分,我们可以在“选择部分”中使用调色板,选择对话框中显示的“选择部分数据”的工具,同时我们需要建立一个数据类型。

  XWT的选项部分

  ◆先进的控制台模型编辑器。这是一个全新的控制台模型编辑器,它的主要特点是:(1)我们能够在设计时方便的进行编辑;(2)我们能够同时在e4运行一个应用程序实例的同时,来编辑一个模型。

  先进的控制台模型编辑器

  e4 SDK压缩包下载地址:http://download.eclipse.org/e4/downloads/drops/S-1.0M5-201004111600/

  新功能与值得关注的特性(英文原文):http://download.eclipse.org/e4/downloads/drops/S-1.0M5-201004111600/e4-news-M5.html

  wiki:http://wiki.eclipse.org/E4

  e4 general build page:http://download.eclipse.org/e4/downloads/

JSP与Servlet

分类:J2EE  来源:网络  时间:2010-8-22 12:50:46

在使用JSP技术开发网站时,不强调使用Servlet。,这是为什么呢?Servlet的应用是没有问题的,它非常适合服务器端的处理和编程。但是如果用Servlet处理大量的HTML文本,那么将是一件及其繁琐的事情。这种事情更适合机器去做,否则就是浪费程序员的体力。所以Servlet更适合处理后端的事务,前端的效果用JSP来实现更为合适。

  早期的JSP标准给出了两种使用JSP的方式。这些方式都可以归纳为JSP模式1和JSP模式2,主要的差别在于处理大量请求的位置不同。在模式1中,JSP页面独自响应请求并将处理结果返回客户。这里仍然有视图和内容的分离,因为所有的数据都依靠bean来处理。尽管模式1可以很好的满足小型应用的需要,但却不能满足大型应用的需要。大量使用模式1,常常会导致页面被嵌入大量的Script和Java代码。特别是当需要处理的商业逻辑很复杂时,情况会变得很严重。也许这对于Java程序员来说,这不是大问题。但是如果开发者是前台界面设计人员,在大型项目中,这是很常见的,则代码的开发和维护将出现困难。在任何项目中,这样的模式多少总是会导致定义不清的响应和项目管理的困难。下图是模式1的示意图:


  JSP模式2是一种面向动态内容的实现,结合了Servlet和JSP技术。它利用两种技术原有的优点,采用JSP来表现页面,采用Servlet来完成大量的处理,Servlet扮演一个控制者的角色,并负责响应客户请求。接着,Servlet创建JSP需要的Bean和对象,再根据用户的行为,决定将哪个JSP页面发送给用户。特别要注意的是,JSP页面中没有任何商业处理逻辑,它只是简单的检索Servlet先前创建的Beans或者对象,再将动态内容插入预定义的模板。

  从开发的观点来看,这一模式具有更清晰的页面表现,清楚的开发者角色划分,可以充分的利用开发小组中的界面设计人员。事实上,越是复杂的项目,使用模式2的好处就越突出。

  使用模式2,JSP和Servlet可以在功能最大幅度的分开。正确的使用模式2,导致一个中心化的控制Servlet,以及只完成显示的JSP页面。另一方面,模式2的实现很复杂,因此,在简单应用中,可以考虑使用模式1。下面是模式2的示意图:


  在Web的建设中到底使用哪一种模式是很重要的事前规划,只有积累了大量的经验才能作出正确而有效的选择。总之网站建设不光是技术的问题,总体的规划是很重要的,读者在学习JSP和Servlet的同时更应该注意从中吸取思想的精华,技术是会过时的,而思想却是永远有价值的。
 

tomcat下配置jsp、servlet、JavaBean连接池

分类:J2EE  来源:网络  时间:2010-8-22 12:49:45

经常看到jsp的初学者问tomcat下如何配置jsp、servlet和bean,数据库连接池,虚拟目录等问题,于是总结了一下如何tomcat下配置jsp、servlet和bean,连接池,虚拟目录希望对那些初学者有所帮助。
  
   一、开发环境配置
  
   第一步:下载j2sdk和tomcat:到sun官方站(http://java.sun.com/j2se/1.5.0/download.jsp)下载j2sdk,注意下载版本为Windows Offline Installation的SDK,同时最好下载J2SE 1.5.0 Documentation,然后到tomcat官方站点(http://jakarta.apache.org/site/downloads/downloads_tomcat-5.cgi)下载tomcat(下载最新5.5.9版本的tomcat);
  
   第二步:安装和配置你的j2sdk和tomcat:执行j2sdk和tomcat的安装程序,然后按默认设置进行安装即可。
  
   1.安装j2sdk以后,需要配置一下环境变量,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量(假定你的j2sdk安装在c:j2sdk1.5.0):
  
JAVA_HOME=c:j2sdk1.5.0
classpath=.;%JAVA_HOME%libdt.jar;%JAVA_HOME%lib    ools.jar;(.;一定不能少,因为它代表当前路径)
path=%JAVA_HOME%in
   接着可以写一个简单的java程序来测试J2SDK是否已安装成功:
  
public class Test{
  public static void main(String args[]){
   System.out.println("This is a test program.");
  }
}  
   将上面的这段程序保存为文件名为Test.java的文件。
  
   然后打开命令提示符窗口,cd到你的Test.java所在目录,然后键入下面的命令
  
javac Test.java
java Test 
   此时如果看到打印出来This is a test program.的话说明安装成功了,如果没有打印出这句话,你需要仔细检查一下你的配置情况。
  
   2.安装Tomcat后,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量(假定你的tomcat安装在c:    omcat):
  
   CATALINA_HOME=c:    omcat
   CATALINA_BASE=c:    omcat
  
   然后修改环境变量中的classpath,把tomat安装目录下的commonlib下的(可以根据实际追加)servlet.jar追加到classpath中去,修改后的classpath如下:
  
classpath=.;%JAVA_HOME%libdt.jar;%JAVA_HOME%lib    ools.jar;%CATALINA_HOME%commonlibservlet.jar;  
   接着可以启动tomcat,在IE中访问http://localhost:8080,如果看到tomcat的欢迎页面的话说明安装成功了。
  
   第三步:建立自己的jsp app目录
  
   1.到Tomcat的安装目录的webapps目录,可以看到ROOT,examples, tomcat-docs之类Tomcat自带的的目录;
   2.在webapps目录下新建一个目录,起名叫myapp;
   3.myapp下新建一个目录WEB-INF,注意,目录名称是区分大小写的;
   4.WEB-INF下新建一个文件web.xml,内容如下:
  

     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
   "http://java.sun.com/dtd/web-app_2_3.dtd";>
 
   My Web Application
  
    A application for test.

   5.在myapp下新建一个测试的jsp页面,文件名为index.jsp,文件内容如下:

   Now time is:

   6.重启Tomcat
  
   7.打开浏览器,输入http://localhost:8080/myapp/index.jsp ;看到当前时间的话说明就成功了。
  
  第四步:建立自己的Servlet:
  
   1.用你最熟悉的编辑器(建议使用有语法检查的java ide)新建一个servlet程序,文件名为Test.java,文件内容如下:
  
package test;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
  public class Test extends HttpServlet {
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
    PrintWriter out=response.getWriter();
    out.println( "

This is a servlet test.

");
    out.flush();
   }
  }
}
   2 .编译
  将Test.java放在c:    est下,使用如下命令编译:
  
   C:Test>javac Test.java
  
  然后在c:Test下会产生一个编译后的servlet文件:Test.class
  
   3 .将结构testTest.class剪切到%CATALINA_HOME%webappsmyappWEB-INFclasses下,也就是剪切那个test目录到classes目录下,如果classes目录不存在,就新建一个。 现在webappsmyappWEB-INFclasses下有testTest.class的文件目录结构
  
   4 .修改webappsmyappWEB-INFweb.xml,添加servlet和servlet-mapping
  
  编辑后的web.xml如下所示,红色为添加的内容:
  

   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
   "http://java.sun.com/dtd/web-app_2_3.dtd";>

My Web Application

  A application for test.


  Test
  Test
  A test Servlet
  test.Test


  Test
  /Test


  这段话中的servlet这一段声明了你要调用的Servlet,而servlet-mapping则是将声明的servlet "映射"到地址/Test上
  
   5 .好了,重启动Tomcat,启动浏览器,输入http://localhost:8080/myapp/Test ;如果看到输出This is a servlet test.就说明编写的servlet成功了。
  
  注意:修改了web.xml以及新加了class,都要重启Tomcat
  
  第四步:建立自己的Bean:
  
   1.用你最熟悉的编辑器(建议使用有语法检查的java ide)新建一个java程序,文件名为TestBean.java,文件内容如下:
  
package test;
  public class TestBean{
   private String name = null;
   public TestBean(String strName_p){
    this.name=strName_p;
   }
   public void setName(String strName_p){
    this.name=strName_p;
   }
   public String getName(){
    return this.name;
  }
} 
   2 .编译
  
  将TestBean.java放在c:    est下,使用如下命令编译:
  
   C:Test>javac TestBean.java
  
  然后在c:Test下会产生一个编译后的bean文件:TestBean.class
  
   3 .将TestBean.class文件剪切到 %CATALINA_HOME%webappsmyappWEB-INFclasses    est下,
  
   4 .新建一个TestBean.jsp文件,文件内容为:


 
  Java bean name is:



   5 .好了,重启Tomcat,启动浏览器,输入http://localhost:8080/myapp/TestBean.jsp ;如果看到输出Java bean name is: This is a test java bean.就说明编写的Bean成功了。
  
  这样就完成了整个Tomcat下的jsp、servlet和javabean的配置。接下来需要做的事情就是多看书、多读别人的好代码,自己多动手写代码以增强自己在这方面开发的能力了。

配置TOMCAT5.5.X连接池(sqlserver版)

1. 进入tomcat目录下的conf文件夹目录里,找到Server.xml
在tomcat的Server.xml文件中在标签与标签里,定议连接语句,格式如下;
debug="5" reloadable="true" crossContext="true">
maxActive="100" maxIdle="30" maxWait="10000"
username="javauser" password="javadude"
driverClassName=" com.microsoft.jdbc.sqlserver.SQLServerDriver "
url=" jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=KB_Rate""/>
 

 

配置完成后,在DBTest目录下添加一个Test文件,如下:
<%
Connection conn = null;
Context initCtx = new InitialContext();
if (initCtx == null)
throw new Exception("不能获取Context!");
Context ctx = (Context) initCtx.lookup("java:comp/env");
Object obj = (Object) ctx.lookup("/Default_JDBC ");//获取连接池对象
javax.sql.DataSource ds = (javax.sql.DataSource) obj; //类型转换
conn = ds.getConnection();
Statement stmt = conn.createStatement();
PreparedStatement ps=conn.prepareStatement("select * from FinalOrderdata");
ResultSet rs=ps.executeQuery();
while(rs.next()){
out.println(rs.getString(1)+"
");
i++;
}
rs.close();
stmt.close();
conn.close();
out.println("连接池测试成功"+i);

到于TOMCAT5.0版本的设置也是差不多,不过在Server.xml中添加连接池设置语句上有所有不,可参考
http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html
其它操作也是差不多,
debug="5" reloadable="true" crossContext="true">
debug="5" reloadable="true" crossContext="true">
prefix="localhost_DBTest_log." suffix=".txt"
timestamp="true"/>
auth="Container"
type="javax.sql.DataSource"/>

factory
org.apache.commons.dbcp.BasicDataSourceFactory

maxActive
100

maxIdle
30

maxWait
10000

username
javauser

password
javadude

driverClassName
com.mysql.jdbc.Driver

url
jdbc:mysql://localhost:3306/javatest?autoReconnect=true

有不足的地方,请各为指正!

如何配置Tomcat的虚拟目录

ROOT是tomcat的默认虚拟目录,如果要改成自己的虚拟目录怎么办呢?请继续往下看吧。
要改成自己的虚拟目录,就要请出server.xml来了,该文件是一个配置文件,在Tomcatconf目录下,使用任何文本编辑软件都能打开它,我们先找到下面一句:
port="8080" minProcessors="5" maxProcessors="75"
enableLookups="true" redirectPort="8443"
acceptCount="100" debug="0" connectionTimeout="20000"
useURIValidationHack="false" disableUploadTimeout="true" />
这里的port="8080"就是端口,我们完全可以用别的端口来代替,但不能是被系统占用的端口(0--1023),这里简单提一下。
下面我们再往下找,会发现以下的语句:

我们就应该找到这两个语句,如果不懂E文,您就认定这两个语句好了。然后我们将该语句更改如下:

这里的path="/myjsp"就是我们就配置的虚拟目录了,以后在地址栏中输入http://localhost:8080/myjsp即可。而docBase="e:/myjsp" 则是机器本地路径,他们通过这个语句形成一个映射关系,其它照抄。
将上面的First.jsp文件放到e:/myjsp目录下,输入http://localhost:8080/myjsp/First.jsp,是不是有一种喜上眉梢的感觉?
在论坛里我见得最多的就是很多人不知道javaBean文件放到哪里,老实说开始我也不知道,更令人不解的是,十个人有九种不同的说法,这更让我们茫然。其实这问题也不是我们想像的那么复杂,我们以一个例子说明:
先建立一个java程序,代码如下:
package hall;
public class SimpleBean {
private String message = "No message specified";
public String getMessage() {
return(message);
}
public void setMessage(String message) {
this.message = message;
}
}
保存为SimpleBean.java,编译后会生成一个包,其实就相当于一个目录,也就是SimpleBean.class会存放在hall目录中,暂且保存起来,将来备用。
再输入以下代码:
 

Message:

保存在我们刚才建立的虚拟目录e:/myjsp下面,并命名为:BeanTest.jsp。
现在我们应该将hall(包)目录放在哪儿呢?别急,我们先在e:/myjsp下建立一个文件夹WEB-INF,然后再在WEB-INF下建立一个classes文件夹,最后将hall目录放到classes下,当然,hall下的字节码文件SimpleBean.class也一并要移过来,而SimpleBean.java就和BeanTest.jsp放到同一目录吧(可以不需要放的,自己试试)。
好了,大功告成了,重新启动机器(如果您试了好多次都不行,这一步一定要做),在浏览器中输入:http://localhost:8080/myjsp/BeanTest.jsp,您看到了什么?呵,别告诉我您什么都没看到,那肯定是您设置的问题了。
 

解决中文乱码问题

分类:J2EE  来源:网络  时间:2010-8-22 12:45:47

由于近来在本站看见N人问中文问题,为了帮大家解决。现将解决中文问题方法列出如下,*注:并非原创,此乃平时用时收集*。
一、中文问题的来源
    计算机最初的操作系统支持的编码是单字节的字符编码,于是,在计算机中一切处理程序最初都是以单字节编码的英文为准进行处理。随着计算机的发展,为了适应世界其它民族的语言(当然包括我们的汉字),人们提出了UNICODE编码,它采用双字节编码,兼容英文字符和其它民族的双字节字符编码,所以,目前,大多数国际性的软件内部均采用UNICODE编码,在软件运行时,它获得本地支持系统(多数时间是操作系统)默认支持的编码格式,然后再将软件内部的UNICODE转化为本地系统默认支持的格式显示出来。Java的JDK和JVM即是如此,我这里说的JDK是指国际版的JDK,我们大多数程序员使用的是国际化的JDK版本,以下所有的JDK均指国际化的JDK版本。我们的汉字是双字节编码语言,为了能让计算机处理中文,我们自己制定的gb2312、GBK、GBK2K等标准以适应计算机处理的需求。所以,大部分的操作系统为了适应我们处理中文的需求,均定制有中文操作系统,它们采用的是GBK,GB2312编码格式以正确显示我们的汉字。如:中文Win2K默认采用的是GBK编码显示,在中文WIN2k中保存文件时默认采用的保存文件的编码格式也是GBK的,即,所有在中文WIN2K中保存的文件它的内部编码默认均采用GBK编码,注意:GBK是在GB2312基础上扩充来的。
    由于Java语言内部采用UNICODE编码,所以在JAVA程序运行时,就存在着一个从UNICODE编码和对应的操作系统及浏览器支持的编码格式转换输入、输出的问题,这个转换过程有着一系列的步骤,如果其中任何一步出错,则显示出来的汉字就会出是乱码,这就是我们常见的JAVA中文问题。
    同时,Java是一个跨平台的编程语言,也即我们编写的程序不仅能在中文windows上运行,也能在中文Linux等系统上运行,同时也要求能在英文等系统上运行(我们经常看到有人把在中文win2k上编写的JAVA程序,移植到英文Linux上运行)。这种移植操作也会带来中文问题。
    还有,有人使用英文的操作系统和英文的IE等浏览器,来运行带中文字符的程序和浏览中文网页,它们本身就不支持中文,也会带来中文问题。
    有,几乎所有的浏览器默认在传递参数时都是以UTF-8编码格式来传递,而不是按中文编码传递,所以,传递中文参数时也会有问题,从而带来乱码现象。
    总之,以上几个方面是JAVA中的中文问题的主要来源,我们把以上原因造成的程序不能正确运行而产生的问题称作:JAVA中文问题。
2、JAVA编码转换的详细过程
    我们常见的JAVA程序包括以下类别:
     *直接在console上运行的类(包括可视化界面的类)
     *JSP代码类(注:JSP是Servlets类的变型)
     *Servelets类
     *EJB类
     *其它不可以直接运行的支持类
    这些类文件中,都有可能含有中文字符串,并且我们常用前三类JAVA程序和用户直接交互,用于输出和输入字符,如:我们在JSP和Servlet中得到客户端送来的字符,这些字符也包括中文字符。无论这些JAVA类的作用如何,这些JAVA程序的生命周期都是这样的:
    *编程人员在一定的操作系统上选择一个合适的编辑软件来实现源程序代码并以.java扩展名保存在操作系统中,例如我们在中文win2k中用记事本编辑一个java源程序;
     *编程人员用JDK中的javac.exe来编译这些源代码,形成.class类(JSP文件是由容器调用JDK来编译的);
     *直接运行这些类或将这些类布署到WEB容器中去运行,并输出结果。
    那么,在这些过程中,JDK和JVM是如何将这些文件如何编码和解码并运行的呢?
    这里,我们以中文win2k操作系统为例说明JAVA类是如何来编码和被解码的。
    第一步,我们在中文win2k中用编辑软件如记事本编写一个Java源程序文件(包括以上五类JAVA程序),程序文件在保存时默认采用了操作系统默认支持GBK编码格式(操作系统默认支持的格式为file.encoding格式)形成了一个.java文件,也即,java程序在被编译前,我们的JAVA源程序文件是采用操作系统默认支持的file.encoding编码格式保存的,java源程序中含有中文信息字符和英文程序代码;要查看系统的file.encoding参数,可以用以下代码:
public class ShowSystemDefaultEncoding {
public static void main(String[] args) {
String encoding = System.getProperty("file.encoding");
System.out.println(encoding);
}}
    第二步,我们用JDK的javac.exe文件编译我们的Java源程序,由于JDK是国际版的,在编译的时候,如果我们没有用-encoding参数指定我们的JAVA源程序的编码格式,则javac.exe首先获得我们操作系统默认采用的编码格式,也即在编译java程序时,若我们不指定源程序文件的编码格式,JDK首先获得操作系统的file.encoding参数(它保存的就是操作系统默认的编码格式,如WIN2k,它的值为GBK),然后JDK就把我们的java源程序从file.encoding编码格式转化为JAVA内部默认的UNICODE格式放入内存中。然后,javac把转换后的unicode格式的文件进行编译成.class类文件,此时.class文件是UNICODE编码的,它暂放在内存中,紧接着,JDK将此以UNICODE编码的编译后的class文件保存到我们的操作系统中形成我们见到的.class文件。对我们来说,我们最终获得的.class文件是内容以UNICODE编码格式保存的类文件,它内部包含我们源程序中的中文字符串,只不过此时它己经由file.encoding格式转化为UNICODE格式了。
    这一步中,对于JSP源程序文件是不同的,对于JSP,这个过程是这样的:即WEB容器调用JSP编译器,JSP编译器先查看JSP文件中是否设置有文件编码格式,如果JSP文件中没有设置JSP文件的编码格式,则JSP编译器调用JDK先把JSP文件用JVM默认的字符编码格式(也即WEB容器所在的操作系统的默认的file.encoding)转化为临时的Servlet类,然后再把它编译成UNICODE格式的class类,并保存在临时文件夹中。如:在中文win2k上,WEB容器就把JSP文件从GBK编码格式转化为UNICODE格式,然后编译成临时保存的Servlet类,以响应用户的请求。
    第三步,运行第二步编译出来的类,分为三种情况:
    A、 直接在console上运行的类
    B、 EJB类和不可以直接运行的支持类(如JavaBean类)
    C、 JSP代码和Servlet类
    D、 JAVA程序和数据库之间
    下面我们分这四种情况来看。
    A、直接在console上运行的类
    这种情况,运行该类首先需要JVM支持,即操作系统中必须安装有JRE。运行过程是这样的:首先java启动JVM,此时JVM读出操作系统中保存的class文件并把内容读入内存中,此时内存中为UNICODE格式的class类,然后JVM运行它,如果此时此类需要接收用户输入,则类会默认用file.encoding编码格式对用户输入的串进行编码并转化为unicode保存入内存(用户可以设置输入流的编码格式)。程序运行后,产生的字符串(UNICODE编码的)再回交给JVM,最后JRE把此字符串再转化为file.encoding格式(用户可以设置输出流的编码格式)传递给操作系统显示接口并输出到界面上。
    以上每一步的转化都需要正确的编码格式转化,才能最终不出现乱码现象。
    B、EJB类和不可以直接运行的支持类(如JavaBean类)
    由于EJB类和不可以直接运行的支持类,它们一般不与用户直接交互输入和输出,它们常常与其它的类进行交互输入和输出,所以它们在第二步被编译后,就形成了内容是UNICODE编码的类保存在操作系统中了,以后只要它与其它的类之间的交互在参数传递过程中没有丢失,则它就会正确的运行。
    C、JSP代码和Servlet类
    经过第二步后,JSP文件也被转化为Servlets类文件,只不过它不像标准的Servlets一校存在于classes目录中,它存在于WEB容器的临时目录中,故这一步中我们也把它做为Servlets来看。
    对于Servlets,客户端请求它时,WEB容器调用它的JVM来运行Servlet,首先,JVM把Servlet的class类从系统中读出并装入内存中,内存中是以UNICODE编码的Servlet类的代码,然后JVM在内存中运行该Servlet类,如果Servlet在运行的过程中,需要接受从客户端传来的字符如:表单输入的值和URL中传入的值,此时如果程序中没有设定接受参数时采用的编码格式,则WEB容器会默认采用ISO-8859-1编码格式来接受传入的值并在JVM中转化为UNICODE格式的保存在WEB容器的内存中。Servlet运行后生成输出,输出的字符串是UNICODE格式的,紧接着,容器将Servlet运行产生的UNICODE格式的串(如html语法,用户输出的串等)直接发送到客户端浏览器上并输出给用户,如果此时指定了发送时输出的编码格式,则按指定的编码格式输出到浏览器上,如果没有指定,则默认按ISO-8859-1编码发送到客户的浏览器上。
    D、Java程序和数据库之间
    对于几乎所有数据库的JDBC驱动程序,默认的在JAVA程序和数据库之间传递数据都是以ISO-8859-1为默认编码格式的,所以,我们的程序在向数据库内存储包含中文的数据时,JDBC首先是把程序内部的UNICODE编码格式的数据转化为ISO-8859-1的格式,然后传递到数据库中,在数据库保存数据时,它默认即以ISO-8859-1保存,所以,这是为什么我们常常在数据库中读出的中文数据是乱码。
    3、分析常见的JAVA中文问题几个必须清楚的原则
    首先,经过上面的详细分析,我们可以清晰地看到,任何JAVA程序的生命期中,其编码转换的关键过程是在于:最初编译成class文件的转码和最终向用户输出的转码过程。
    其次,我们必须了解JAVA在编译时支持的、常用的编码格式有以下几种:
    *ISO-8859-1,8-bit, 同8859_1,ISO-8859-1,ISO_8859_1等编码
    *Cp1252,美国英语编码,同ANSI标准编码
    *UTF-8,同unicode编码
    *GB2312,同gb2312-80,gb2312-1980等编码
    *GBK , 同MS936,它是gb2312的扩充
    及其它的编码,如韩文、日文、繁体中文等。同时,我们要注意这些编码间的兼容关体系如下:
    unicode和UTF-8编码是一一对应的关系。GB2312可以认为是GBK的子集,即GBK编码是在gb2312上扩展来的。同时,GBK编码包含了20902个汉字,编码范围为:0x8140-0xfefe,所有的字符可以一一对应到UNICODE2.0中来。
    再次,对于放在操作系统中的.java源程序文件,在编译时,我们可以指定它内容的编码格式,具体来说用-encoding来指定。注意:如果源程序中含有中文字符,而你用-encoding指定为其它的编码字符,显然是要出错的。用-encoding指定源文件的编码方式为GBK或gb2312,无论我们在什么系统上编译含有中文字符的JAVA源程序都不会有问题,它都会正确地将中文转化为UNICODE存储在class文件中。
    然后,我们必须清楚,几乎所有的WEB容器在其内部默认的字符编码格式都是以ISO-8859-1为默认值的,同时,几乎所有的浏览器在传递参数时都是默认以UTF-8的方式来传递参数的。所以,虽然我们的Java源文件在出入口的地方指定了正确的编码方式,但其在容器内部运行时还是以ISO-8859-1来处理的。
4、中文问题的分类及其建议最优解决办法
    了解以上JAVA处理文件的原理之后,我们就可以提出了一套建议最优的解决汉字问题的办法。
    我们的目标是:我们在中文系统中编辑的含有中文字符串或进行中文处理的JAVA源程序经编译后可以移值到任何其它的操作系统中正确运行,或拿到其它操作系统中编译后能正确运行,能正确地传递中文和英文参数,能正确地和数据库交流中英文字符串。
    我们的具体思路是:在JAVA程序转码的入口和出口及JAVA程序同用户有输入输出转换的地方限制编码方法使之正确即可。
    具体解决办法如下:
    1、 针对直接在console上运行的类
    对于这种情况,我们建议在程序编写时,如果需要从用户端接收用户的可能含有中文的输入或含有中文的输出,程序中应该采用字符流来处理输入和输出,具体来说,应用以下面向字符型节点流类型:
    对文件:FileReader,FileWrieter
        其字节型节点流类型为:FileInputStream,FileOutputStream
    对内存(数组):CharArrayReader,CharArrayWriter
        其字节型节点流类型为:ByteArrayInputStream,ByteArrayOutputStream
    对内存(字符串):StringReader,StringWriter
    对管道:PipedReader,PipedWriter
        其字节型节点流类型为:PipedInputStream,PipedOutputStream
    同时,应该用以下面向字符型处理流来处理输入和输出:
    BufferedWriter,BufferedReader
        其字节型的处理流为:BufferedInputeStream,BufferedOutputStream
    InputStreamReader,OutputStreamWriter
    其字节型的处理流为:DataInputStream,DataOutputStream
    其中InputStreamReader和InputStreamWriter用于将字节流按照指定的字符编码集转换到字符流,如:
    InputStreamReader in = new InputStreamReader(System.in,"GB2312");
    OutputStreamWriter out = new OutputStreamWriter (System.out,"GB2312");
    例如:采用如下的示例JAVA编码就达到了要求:
//Read.java
import java.io.*;
public class Read {
public static void main(String[] args) throws IOException {
String str = " 中文测试,这是内部硬编码的串"+" test english character";
String strin= "";
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in,"gb2312")); //设置输入接口按中文编码
BufferedWriter stdout = new BufferedWriter(new OutputStreamWriter(System.out,"gb2312")); //设置输出接口按中文编码
stdout.write("请输入:");
stdout.flush();
strin = stdin.readLine();
stdout.write("这是从用户输入的串:"+strin);
stdout.write(str);
stdout.flush();
}}
    同时,在编译程序时,我们用以下方式来进行:
    javac -encoding gb2312 Read.java
    2、 针对EJB类和不可以直接运行的支持类(如JavaBean类)
    由于这种类它们本身被其它的类调用,不直接与用户交互,故对这种类来说,我们的建议的处理方式是内部程序中应该采用字符流来处理程序内部的中文字符串(具体如上面一节中一样),同时,在编译类时用-encoding gb2312参数指示源文件是中文格式编码的即可。
    3、 针对Servlet类
    针对Servlet,我们建议用以下方法:
    在编译Servlet类的源程序时,用-encoding指定编码为GBK或GB2312,且在向用户输出时的编码部分用response对象的setContentType("text/html;charset=GBK");或gb2312来设置输出编码格式,同样在接收用户输入时,我们用request.setCharacterEncoding("GB2312");这样无论我们的servlet类移植到什么操作系统中,只有客户端的浏览器支持中文显示,就可以正确显示。如下是一个正确的示例:
//HelloWorld.java
package hello;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet
{
public void init() throws ServletException { }
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
request.setCharacterEncoding("GB2312"); //设置输入编码格式
response.setContentType("text/html;charset=GB2312"); //设置输出编码格式
PrintWriter out = response.getWriter(); //建议使用PrintWriter输出
out.println("


");
out.println("Hello World! This is created by Servlet!测试中文!");
out.println("


");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
request.setCharacterEncoding("GB2312"); //设置输入编码格式
response.setContentType("text/html;charset=GB2312"); //设置输出编码格式
String name = request.getParameter("name");
String id = request.getParameter("id");
if(name==null) name="";
if(id==null) id="";
PrintWriter out = response.getWriter(); //建议使用PrintWriter输出
out.println("


");
out.println("你传入的中文字串是:" + name);
out.println("


你输入的id是:" + id);
out.println("


");
}
public void destroy() { }
}
    请用javac -encoding gb2312 HelloWorld.java来编译此程序。
    测试此Servlet的程序如下所示:

Servlet入门实例

分类:J2EE  来源:网络  时间:2010-8-22 12:44:24

1.在tomcat下的webapps目录下新建一个文件夹java

2.在java下建立一个新文件夹WEB-INF(不能自定义)

3.在WEB-INF下建立一个新文件夹classes(不能自定义),这个目录下专门存放编译好的class文件,包括servlet

4.编写servlet
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws IOException, ServletException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("");
        out.println("");
        out.println("Hello World!");
        out.println("");
        out.println("");
    }
}    
保存为HelloWorld.java

5.编译HelloWorld.java
使用命令javac HelloWorld.java,把编译好的class文件放到webappsjavaWEB-INFclasses目录下

6.编写web.xml文件

"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

    
        HelloWorld
        HelloWorld        
    

    
        HelloWorld
        /hello
    

保存为web.xml(不能自定义),把web.xml文件放到webappsjavaWEB-INF目录下

7.运行
启动tomcat服务器,在地址栏中输入http://localhost:8080/java/hello
 

JEE环境下各类开发架构简介

分类:J2EE  来源:网络  时间:2010-8-22 12:41:34

如今,各种可用的Web框架如雨后春笋般林立。把浏览器指向Java技术网站时,常会看到新版的Web框架发布的消息,这些新框架意图改变现代世界。虽然有些人认为这是坏事,把Java群体分解得支离破碎,但事实是,不断冒出的新框架只是演化的过程而已。
通过这样的演化过程,有些框架成为目前几种主流的Web框架。本文着重讨论几种主流框架的原理,尤其详细讲解Structs框架,各框架之间的比较,及这些框架在未来发展的趋势。它们包括Structs框架,JavaServer Faces(JSF)框架,Spring框架。
这些框架几乎都是Model-View-Controller(MVC)模式的实现,所以本文先介绍了MVC的工作模式及其原理。Struts框架实质上就是在JSP Model2的基础上实现的一个MVC框架。在下面的章节中将详细介绍Struts框架的工作原理及流程。JSF是对Struts的升级。不过不同于Struts的开放源代码模式,它是Sun制定的一个规范。本文除了介绍JSF的工作原理,还有很大的篇幅对JSF,Struts的模式应用进行比较。Spring是另一个解决了许多在J2EE开发中常见的问题的强大框架。Spring的架构基础是基于使用JavaBean属性的Inversion of Control容器。然而,这仅仅是完整图景中的一部分:Spring在使用IoC容器作为构建所有架构层的完整解决方案方面是独一无二的。 Spring提供了唯一的数据访问抽象,包括简单和有效率的JDBC框架,极大的改进了效率并且减少了可能的错误。Spring的数据访问架构还集成了Hibernate和其他O/R mapping解决方案。
 

struts和hibernate整合的一种方式(hibernate作为struts插件)

分类:J2EE  来源:网络  时间:2010-8-17 0:51:04

把hibernate用到的包全部放进web应用程序的lib里面,然后定义hibernate.cfg.XML,也就是插件的配置信息,如下

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"                                         "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"><hibernate-configuration>    <session-factory>        <property name="show_sql">false</property>        <property name="use_outer_join">true</property>        <property name="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</property>        <property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>        <property name="hibernate.connection.url">jdbc:mysql:///test</property>        <property name="hibernate.connection.username">root</property>        <property name="hibernate.connection.password"></property>        <property name="hibernate.connection.pool.size">20</property>        <property name="session_factory_name">hibernate/session_factory</property>        <!-- Mapping files -->    <mapping resource="/homepage/Artical.hbm.xml"/>

    </session-factory></hibernate-configuration>信息很清楚的,就是配置数据库等信息,我们利用jndi来查找SessionFactory,下面是插件程序,HibernatePlugIn.Java

import org.apache.struts.action.PlugIn;import org.apache.struts.action.ActionServlet;import org.apache.struts.config.ModuleConfig;import javax.servlet.ServletException;import javax.servlet.ServletContext;import net.sf.hibernate.SessionFactory;import net.sf.hibernate.cfg.Configuration;public class HibernatePlugIn    implements PlugIn {  public void destroy() {  }  public void init(ActionServlet servlet, ModuleConfig config) throws      ServletException {    try {      ServletContext context = servlet.getServletContext();      SessionFactory sf = new Configuration().configure().buildSessionFactory();      context.setAttribute("net.sf.hibernate.SessionFactory",sf);    }    catch (Exception ex) {      ex.printStackTrace();    }  }}相应的,要在struts-config.xml配置插件信息,大概如下,注意路径

 <plug-in className="homepage.HibernatePlugIn">    <set-property property="configFilePath" value="/WEB-INF/classes/hibernate.cfg.xml" />    <set-property property="storeInServletContext" value="true" />  </plug-in>

以后就可以利用java.naming.Context,java.naming.InitiaContext来查找

      Context ct = new InitialContext();      sessions=(SessionFactory) ct.lookup("hibernate/session_factory");      session=sessions.openSession();

当然,还有另外两种整合方式,我认为这种方法更为灵活,也比较容易掌握