??xml version="1.0" encoding="utf-8" standalone="yes"?> 二、不要让事情复杂化。程序员有时候L对简单问题想出复杂的解决ҎQ比如说Q在只有五个用户的程序中引入EJB、对E序实现了ƈ不需要的框架QframeworkQ,之类的还有属性文件、面向对象解x案、多U程{等。ؓ什么要q样做呢Q也许我们ƈ不知道是否这样会更好Q但q样做也许可以学C些新东西Q或者让自己更感兴趣一些。如果是不知道ؓ什么这样做Q徏议多hl验丰富的程序员Q如果是Z个h的目的,ȝ让自己更专业一炏V?/p>
三、始l牢记—?#8220;即是好QLess is moreQƈ不L对的”。代码效率虽然很重要Q但在许多解x案中Q编写更的代码q不能改善这些代码的效率Q请看下面这个简单的例子Q?/p>
if(newStatusCode.equals("SD") && (sellOffDate == null || 能看明白if条g语句是干什么的吗?能想出来是谁写的q段代码吗?如果把它分成两段独立的if语句Q是不是更容易理解呢Q下面是修改后的代码Q?/p>
if(newStatusCode.equals("SD") && (sellOffDate == null || 是不是读hҎ多了呢,在此只是多加了一个if和两个花括号Q但代码的可L与可理解性就一下子提高了一大截?/p>
四、请不要编码。开发者经常有?#8220;忘记”或忽略掉q点Q因为有些时候开发日E逼得实在太紧。其实,多写一行定义静态变量的代码能花多少旉呢? public class A { 现在Q每ơ需要将“ABC”与其他变量进行比较时Q不必记住实际代码,直接引用A.S_CONSTANT_ABCp了,而且在今后需要进行修ҎQ也可在一处修改,不会遍整个源代码逐个修改了?/p>
五、不?#8220;创?#8221;自己的框ӞframeworkQ。确切来_有数以千计的各种框架存在Q而且大多数是开源的Q这些框枉是优U的解x案,可用于日常程序开发中Q我们只需使用q些框架的最新版本就行了Q至表面上要跟上Ş势吧。被大家qؓ接受的最为明昄一个例子就是Struts了,q个开源web框架非常适合用在Zweb的应用程序中。是不是惛_发出自己的Struts呢,q是省点力气吧,回头看看W二条——不要让事情复杂化。另外,如果正在开发的E序只有3个窗口,׃要用Struts了,对这U程序来_不需要那么多?#8220;控制”?/p>
六、不要用println及字W串q接。通常Z调试方便Q开发者喜Ƣ在可能的所有地斚w加上System.out.printlnQ也许还会提醒自己回q头来再来删除,但有些时候,l常会忘了删除或者不愿意删除它们。既然用System.out.println是ؓ了测试,那么试完之后,Z么还要留着它们呢,因ؓ在删除时Q很可能会删除掉真正有用的代码,所以不能低估System.out.println危害啊,L下面的代码: public class BadCode { 从测试中可以发现Q方法calculationWithOutPrint()执行用了0.001204U,作ؓҎQ方法calculationWithPrint()执行可是用了10.52U?/p>
要避免浪费CPU旉Q最好的Ҏ是引入像如下的包装方法: public class BadCode { 另外Q字W串q接也是费CPU旉的一个大_L下面的示例代码: public static void concatenateStrings(String startingString) { 在测试中可发玎ͼ使用StringBuffer的方法只用了0.01U执行完毕,而用连接的Ҏ则用?.08U,选择显而易见了?/p>
七、多xGUIQ用L面)。再三强调,GUI对商业客h_与程序的功能及效率同{重要,GUI是一个成功程序的最基本部分Q而很多ITl理往往都没注意到GUI的重要性。在现实生活中,许多公司可能Z节省开支,没有雇用那些有着设计“用户友好”界面丰富l验的网设计者,此时Java开发者只能依赖他们自w的HTML基本功及在此领域有限的知识,l果Q很多开发出来的E序都是“计算机友?#8221;甚于“用户友好”。很有开发者同时精通Y件开发及GUI设计Q如果你在公?#8220;不幸”被分配负责程序界面,应该遵守下面三条原则: 1?不要再发明一ơ轮子,即不做无用功。现有的E序可能会有cM的界面需求?br />
2?先创Z个原型。这是非帔R要一步,用户一般想看到他们用的东西Q而且可以先利用这个原型征求用L意见Q再慢慢修改成用h要的样子?br />
3?学会换位思考。换句话来说Q就是从用户的角度来审查E序的需求。D例来Ԍ一个汇ȝH口可以跨页或者不跨页Q作Z个Y件开发者,可能会們于不跨页Q因L单一些。但是,从用L角度来看Q可能不希望看到上百行数据都挤在同一上?/p>
八、文档需求不放松。每个商业需求都必须记录在案Q这可能听上d童话Q似乎在现实生活中很隑֮现。而我们要做的是,不管开发时间多紧迫Q不最l期限多临近Q对每个商业需求都必须记录在案?/p>
九、单元测试、单元测试、单元测试。关于什么是单元试的最好方法,在此不便l说Q只是强调,单元试一定要完成Q这也是~程中最基本的原则。当然了Q如果有人帮你做单元试自然是最好,如果没有Q就自己来做吧,当创Z个单元测试计划时Q请遵守以下三条最基本的原则: 1?先于~写cM码之前编写单元测试?br />
2?记录单元试中的代码注释?br />
3?试所有执行关键功能的公有ҎQ这里不是指set和getҎQ除非它们是以自qҎ式执行set和getҎ?/p>
十、质量,而不是数量。有些时候因Z品问题、期限紧q、或一些预料之外的事情Q导致常怸能按时下班,但一般而言Q公怸会因为雇员经常加班而对之表扬和奖励Q公司只看重高质量的工作。如果遵守了前九条原则,你会发现自己写出的代码bug且可维护性高Q无形中质量提高了一大步?/p>
[mysql] default-character-set=gbk tomcat下jsp出现getOutputStream() has already been called for this response异常的原因和解决Ҏ 在tomcat下jsp中出现此错误一般都是在jsp中用了输出(如输出图片验证码Q文件下载等Q, 然后当然是要提出解决的办法,其实挺简单的Qƈ不是和某些朋友说的那?- 在用完输出以后调用以下两行代码即可: 最后这里是一个输出彩色验证码例子Q这L例子几乎随处可见Q?br />
imag.jsp <%@ page import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %> g.setFont(new Font("Times New Roman",Font.PLAIN,18)); ImageIO.write(image, "JPEG",os);
我们在尝?JDK1.5 的时候,怿不少人遇到过 Unsupported major.minor version 49.0 错误Q当时定会茫然不知所措。因为刚开始那会儿Q网上与此相关的中文资料q不多,现在好了Q网上一扑ְ知道是如何解冻I大多会告诉你要?JDK 1.4 重新~译。那么至于ؓ什么,那个 major.minor I竟Z物呢Q这是本篇来讲的内容,以未错而先知?br />
我觉得我是比较幸q的Q因为在遇到那个错误之前已研读过《深?Java 虚拟机》第二版Q英文原书名为《Inside the Java Virtual Machine? Second Edition)Q看时已知晓 major.minor 藏匿于何处,但没有切w体会,待到?Unsupported major.minor version 49.0 真正会面试,正好是给我验证了一个事实?br />
首先我们要对 Unsupported major.minor version 49.0 建立的直接感觉是QJDK1.5 ~译出来的类不能?JVM 1.4 下运行,必须~译?JVM 1.4 下能q行的类?当然Q也怽用的q是 JVM 1.3 ?nbsp;JVM 1.2Q那么就要编译成目标 JVM 能认可的c?。这也解决问题的方向?br />
二:major.minor 栖n于何?/font>
何谓 major.minorQ且又居w于何处呢?先感性认识ƈ扑ֈ major.minor 来?br />
写一?Java Hello World! 代码Q然后用 JDK 1.5 的编译器~译成,HelloWorld.java
package com.unmi;
2
3public class HelloWorld
4{
5 public static void main(String[] args)
6 {
7 System.out.println("Hello, World!");
8 }
9}
10
从上图中我们看出来了什么是 major.minor version 了,它相当于一个Y件的L版本P只是在这里是标识的一?Java Class 的主版本号和ơ版本号Q同时我们看?minor_version ?0x0000Qmajor_version ?0x0031Q{换ؓ十制数分别ؓ0 ?49Q即 major.minor 是 49.0 了?br />
三:何谓 major.minor 以及何用
Class 文g的第 5-8 字节?minor_version ?major_version。Java class 文g格式可能会加入新Ҏ。class 文g格式一旦发生变化,版本号也会随之变化。对?JVM 来说Q版本号定了特定的 class 文g格式Q通常只有l定ȝ本号和一pdơ版本号后,JVM 才能够读?class 文g。如?class 文g的版本号出?JVM 所能处理的有效范围QJVM 不会处理该 class 文g?br />
?Sun ?JDK 1.0.2 发布版中QJVM 实现支持?45.0 ?45.3 ?class 文g格式。在所?JDK 1.1 发布版中?JVM 都能够支持版本从 45.0 ?45.65535 ?class 文g格式。在 Sun ?1.2 版本?SDK 中,JVM 能够支持从版?45.0 ?6.0 ?class 文g格式?br />
1.0 ?1.2 版本的编译器能够产生版本号ؓ 45.3 ?class 文g。在 Sun ?1.2 版本 SDK 中,Javac ~译器默认生版本号?45.3 ?class 文g。但如果?javac 命o行中指定?-target 1.2 标志Q?.2 版本的编译器生版本号?46.0 ?class 文g?.0 ?1.1 版本?JVM 上不能运行?target 1.2 标志所产生?class 文g?br />
JVM 实现?W二版中修改了对 class 文gȝ本号和次版本L解释。对于第二版而言Qclass 文g的主版本号与 Java q_d布版的版本号保持一?例如Q在 Java 2 q_发布版上Q主版本号从 45 升至 46)Q次版本号与特定d^台发布版的各个发布版相关。因此,管不同?class 文g格式可以׃同的版本可C,但版本号不一样ƈ不代?class 文g格式不同。版本号不同的原因可能只是因?class 文g׃同发布版本的 java q_产生Q可?class 文g的格式ƈ没有改变?br />
上面三段节选自《深?Java 虚拟机》,啰嗦一堆,JDK 1.2 开启了 Java 2 的时代,但那个年代仍然离我们很远Q我们当中很多少直接跛_ JDK 1.4 上的Q我也差不多Q只是项目要求不得不在一D|间里委屈?JDK 1.3 上。不q大致我们可以得到的信息是每个版本?JDK ~译器编译出?class 文g中都带有一个版本号Q不同的 JVM 能接受一个范?class 版本P出范围则要出错。不q一般都是能向后兼容的,知道 Sun 在做 Solaris 的一句口号吗Q保持对先前版本?100% 二进制兼Ҏ,q也是对客户的投资保护?br />
四:其他定 class ?major.minor version 办法
1QEclipse 中查?br />
Eclipse 3.3 加入的新特征Q当某个cL有关联到源代码,打开它会昄比较详细的类信息Q当然还未到源码U别了,看下图是打开 2.0 spring.jar ?ClasspathXmlApplicationContext.class 昄的信?br />
2Q命?javap -verbose
对于~译出的 class 文g?javap -verbose 能显C出cȝ major.minor 版本Q见下图Q?br />
3) MANIFEST 文g
?nbsp;class 打成?nbsp;JAR 包中都会有文?META-INF\MANIFESTQ这个文件一般会有编译器的信息,下面列几个包?META-INF\MANIFEST 文g内容大家看看
·Velocity-1.5.jar ?META-INFO\MANIFEST 部䆾内容
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: Apache Ant
Package: org.apache.velocity
Build-Jdk: 1.4.2_08
Extension-Name: velocity
我们看到是用 ant 打包Q构建用的JDK?1.4.2_08Q用 1.4 ~译的类?1.4 JVM 中当然能q行。如果那人用 1.5 ?JDK 来编译,然后?JDK 1.4+ANT 来打包就太无聊了?br />
·2.0 spring.jar ?META-INFO\MANIFEST 部䆾内容
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_08-b03 (Sun Microsystems Inc.)
Implementation-Title: Spring Framework
q下要注意啦Q它是用?JDK 1.5 来编译的Q那么它是否带了 -target 1.4 ?-target 1.3 来编译的呢?实是的Q可以查看类的二q制文gQ这是最保险的。所?spring-2.0.jar 也可以在 1.4 JVM 中加载执行?br />
·自已一个项目中?ant 打的 jar 包的 META-INFO\MANIFEST
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 1.4.2-b28 (Sun Microsystems Inc.)
用的?JDK 1.4 构徏打包的?br />
W一W二U办法能明确知道 major.minor versionQ而第三种Ҏ应该也没问题Q但是碰到变态构建就难说了,比如谁把那个 META-INFO\MANIFEST 打包后换了也未可知。直接查看类的二q制文g的方法可以万分保证,准确无误Q就是工LҎ也认了?br />
五:~译器比较及症节之所?/font>
现在不妨?JDK 1.1 ?JDK 1.7 ~译器编译出?class 的默?minor.major version 吧。(又走?Sun 的网站上腾出我从来都没用过的古董来Q?br />
JDK ~译器版?/strong>
target 参数
十六q制 minor.major
十进?minor.major
jdk1.1.8
不能?target 参数
00 03 00 2D
45.3
jdk1.2.2
不带(默认?-target 1.1)
00 03 00 2D
45.3
jdk1.2.2
-target 1.2
00 00 00 2E
46.0
jdk1.3.1_19
不带(默认?-target 1.1)
00 03 00 2D
45.3
jdk1.3.1_19
-target 1.3
00 00 00 2F
47.0
j2sdk1.4.2_10
不带(默认?-target 1.2)
00 00 00 2E
46.0
j2sdk1.4.2_10
-target 1.4
00 00 00 30
48.0
jdk1.5.0_11
不带(默认?-target 1.5)
00 00 00 31
49.0
jdk1.5.0_11
-target 1.4 -source 1.4
00 00 00 30
48.0
jdk1.6.0_01
不带(默认?-target 1.6)
00 00 00 32
50.0
jdk1.6.0_01
-target 1.5
00 00 00 31
49.0
jdk1.6.0_01
-target 1.4 -source 1.4
00 00 00 30
48.0
jdk1.7.0
不带(默认?-target 1.6)
00 00 00 32
50.0
jdk1.7.0
-target 1.7
00 00 00 33
51.0
jdk1.7.0
-target 1.4 -source 1.4
00 00 00 30
48.0
Apache Harmony 5.0M3
不带(默认?-target 1.2)
00 00 00 2E
46.0
Apache Harmony 5.0M3
-target 1.4
00 00 00 30
48.0
上面比较?Windows q_下的 JDK ~译器的情况Q我们可以此作些ȝQ?br />
1) -target 1.1 ?有次版本Ptarget ?1.2 及以后都只用ȝ本号了,ơ版本号?0
2) ?1.1 ?1.4 语言差异比较,所?1.2 ?1.4 默认?target 都不是自w相对应版本
3) 1.5 语法变动很大Q所以直接默?target 是 1.5。也因ؓ如此?1.5 ?JDK 要生成目标ؓ 1.4 的代码,光有 -target 1.4 不够Q必d时带?-source 1.4Q指定源码的兼容性,1.6/1.7 JDk 生成目标?1.4 的代码也如此?br />
4) 1.6 ~译器显得较为激q,默认参数׃ؓ -target 1.6。因?nbsp;1.6 ?1.5 的语法无差异Q所以用 -target 1.5 时无需跟着 -source 1.5?br />
5) 注意 1.7 ~译的默?target ?1.6
6) 其他W三方的 JDK 生成?Class 文g格式版本号同对应 Sun 版本 JDK
7) 最后一Ҏ重要的,某个版本?JVM 能接?class 文g的最大主版本号不能超q对?JDK 带相?target 参数~译出来?class 文g的版本号?br />
上面那句话有炚wQ一口气读过M是很好理解,举个例子Q?.4 ?JVM 能接受最大的 class 文g的主版本号不能超q用 1.4 JDK 带参?-target 1.4 时编译出?class 文g的主版本P也就?48?br />
因ؓ 1.5 JDK ~译旉?target ?1.5Q出来的字节?major.minor version ?49.0Q所?1.4 ?JVM 是无法接受的Q只有抛出错误?br />
那么?font color="#800080">Z么从 1.1 ?1.2、从 1.2 ?1.3 或者从 1.3 ?1.4 ?JDK 升不会发生 Unsupported major.minor version 的错误呢Q那是因?1.2/1.3/1.4 都保持了很好的二q制兼容?/font>Q看?1.2/1.3/1.4 的默?target 分别?1.1/1.1/1.2 q道了Q也是默认情况?.4 JDK ~译出的 class 文g?JVM 1.2 下都能加载执行,何况?JVM 1.3 呢?Q当然要去除使用了新版本扩充?API 的因素)
六:扑ֈ问题解决的方?/font>
那么现在如果到q种问题该知道如何解决了吧,q会像我所见到有些兄弟那样Q去找个 1.4 ?JDK 下蝲安装Q然后用光新编译所有的代码吗?其实大可不必如此费神Q我们一定还记得 javac q有?-target 参数Q对啦,可以l箋使用 1.5 JDKQ编译时带上参数 -target 1.4 -source 1.4 ?OK 啦,不过你一定要对哪?API ?1.5 JDK 加入q来的了如指掌,不能你的 class 文g拿到 JVM 1.4 下就?method not found。目?JVM ?1.3 的话Q编译选项q -target 1.3 -source 1.3 了?br />
相应的如果?ant Q它?javac d也可对应的选择 target ?source
<javac target="1.4" source="1.4" ............................/>
如果是在开发中Q可以肯定的是现在真正算得上?JAVA IDE 对于工程也都有编译选项讄目标代码的。例?Eclipse 的项目属性中?Java Compiler 讄Q如?br />
自已讑֮~译选项Q你会看到选择不同?compiler compliance level 是,Generated class files compatibility ?Source compatibility 也在变,你也可以手动调整那两,手动讄后你׃用很在乎用的什么版本的~译器了Q只要求他生成我们希望的字节码就行了Q再引申一下就是即使源代码是用 VB 写的Q只要能~译?JVM 能执行的字节码都不打紧。在其他?IDE 也能扑ֈ相应的设|对话框的?br />
其他时候,你一定要知道当前?JVM 是什么版本,能接受的字节码主版本h多少Q可对照前面那个表)。获息当?JVM 版本有两U途径Q?br />
W一Q如果你是直接用 java 命o在控制台执行E序Q可以用 java -version 查看当前?JVM 版本Q然后确定能接受?class 文g版本
W二Q如果是在容器中执行Q而不能明知道会使用哪个 JVMQ那么可以在容器中执行的E序中加入代码 System.getProperty("java.runtime.version"); ?System.getProperty("java.class.version")Q获?JVM 版本和能接受?class 的版本号?br />
最后一l招Q如果你不想针对低版本的 JVM ?target 参数重新~译所有代码;如果你仍然想l箋在代码中用新?API 的话Q更有甚者,你还用了 JDK 1.5 的新Ҏ,譬如泛型、自动拆装箱、枚丄的话Q那你用 -target 1.4 -source 1.4 没法编译通过Q不得不重新整理代码。那么告诉你最后一招,不需要再从源代码着手,直接转换你所正常~译出的字节码,l箋享用那些新的Ҏ,新的 APIQ那是Q请参考之前的一日志:Retrotranslator让你用JDK1.5的特性写出的代码能在JVM1.4中运?/a>Q我是q么用的Q做好测试就不会有问题的?br />
七:再议一个实际发生的相关问题
q是一个因为拷?Tomcat 而生的 Unsupported major.minor version 49.0 错误。情景是Q我本地安装的是 JDK 1.5Q然后在|上找了一?EXE ?Tomcat 安装文g安装了ƈ且可用。后来同事要一?TomcatQ不想下载或安装Q于是根据我以往的经验是把我?Tomcat 整个目录L他应该就行了Q结果是拿到他那里浏?jsp 文g都出?Unsupported major.minor version 49.0 错误Q可以确定的是他安装的是 1.4 ?JDKQ但我还是有些纳P先前对这个问题还颇有信心的我ȝ了。惯性思维是编译好?class 文g拿到低版本的 JVM 会出现如是异常,可现q没有用?JDK 1.5 ~译好的c要执行啊?br />
后来仔细看异怿息,l于发现?%TOMCAT_HOME%\common\lib\tools.jar q一眉目Q因?jsp 文g需要依赖它来编译,打来q个 tools.jar 中的一?class 文g来看看,49.0Q很快我明白原来这个文件是在我的机器上安装 Tomcat 时由 Tomcat 安装E序?%JDK1.5%\lib 目录拷到 Tomcat ?lib 目录ȝQ造成在同事机器上~译 JSP 时是 1.4 ?nbsp;JVM 配搭着 49.0 ?tools.jarQ那能不出错Q于是找?1.4 JDK ?tools.jar 替换?Tomcat 的就 OK 啦?br />
八:结
其实理解 major.minor 像是我们可以这么想像,同样是微软g的程序,32 位的应用E序不能拿到 16 位系l中执行那样?br />
如果我们发布前了解到目标 JVM 版本Q知道怎么?java class 文g中看?major.minor 版本来,׃用等到服务器报出异常才着手去解决Q也p预知到可能发生的问题?br />
其他时候遇到这个问题应具体解决QM问题的根由是低版本的 JVM 无法加蝲高版本的 class 文g造成的,扑ֈ高版本的 class 文g处理一下就行了?br />
]]>
]]>
todayDate.compareTo(sellOffDate)Q? || (lastUsedDate != null &&
todayDate.compareTo(lastUsedDate)Q?)) ||
(newStatusCode.equals("OBS") && (OBSDate == null ||
todayDate.compareTo(OBSDate)Q?))){
newStatusCode = "NYP";
}
todayDate.compareTo(sellOffDate)Q? || (lastUsedDate != null &&
todayDate.compareTo(lastUsedDate)Q?))){
newStatusCode = "NYP";
}else
if(newStatusCode.equals("OBS") && (OBSDate == null ||
todayDate.compareTo(OBSDate)<0))
{
newStatusCode = "NYP";
}
public static final String S_CONSTANT_ABC = "ABC";
public boolean methodA(String sParam1){
if (A.S_CONSTANT_ABC.equalsIgnoreCase(sParam1)){
return true;
}
return false;
}
}
public static void calculationWithPrint(){
double someValue = 0D;
for (int i = 0; i Q?0000; i++) {
System.out.println(someValue = someValue + i);
}
}
public static void calculationWithOutPrint(){
double someValue = 0D;
for (int i = 0; i Q?10000; i++) {
someValue = someValue + i;
}
}
public static void main(String [] n) {
BadCode.calculationWithPrint();
BadCode.calculationWithOutPrint();
}
}
public static final int DEBUG_MODE = 1;
public static final int PRODUCTION_MODE = 2;
public static void calculationWithPrint(int logMode){
double someValue = 0D;
for (int i = 0; i Q?10000; i++) {
someValue = someValue + i;
myPrintMethod(logMode, someValue);
}
}
public static void myPrintMethod(int logMode, double value) {
if (logMode Q?BadCode.DEBUG_MODE) { return; }
System.out.println(value);
}
public static void main(String [] n) {
BadCode.calculationWithPrint(BadCode.PRODUCTION_MODE);
}
}
for (int i = 0; i Q?20; i++) {
startingString = startingString + startingString;
}
}
public static void concatenateStringsUsingStringBuffer(String startingString) {
StringBuffer sb = new StringBuffer();
sb.append(startingString);
for (int i = 0; i Q?20; i++) {
sb.append(sb.toString());
}
}
主要是根据MLDN的一个实例进行配|的。实例中用的是Tomcat5.5Q所以他的CP配置如下Q?br />
W一Q?/strong>jdbc驱动的jar包,如:MySQL、Oracle的jdbc驱动Q拷贝到tomcat中lib下?br />
注意Q必Ltomcat中lib下,如:D:\Tomcat 6.0\libQ但不能是项目中的WEB-INF/lib下,因ؓq时tomcat解析不到此类目录?br />
W二Q?/strong>在Tomcat的安装目录下conf下找到server.xmlQ在<host></host>之间加上如下代码Q?br />
<Context path="/zhinangtuan" docBase="F:\Eclipse\MyZNTProject\MyZhiNangTuanDemo\WebRoot"
2 debug="5" reloadable="true" crossContext="true">
3
4 <Logger className="org.apache.catalina.logger.FileLogger"
5 prefix="localhost_MysqlTest_log." suffix=".txt"
6 timestamp="true"/>
7
8 <Resource name="jdbc/mldn" auth="Container" type="javax.sql.DataSource"/>
9
10 <ResourceParams name="jdbc/mldn">
11 <parameter>
12 <name>factory</name>
13 <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
14 </parameter>
15 <parameter>
16 <name>maxActive</name>
17 <value>100</value>
18 </parameter>
19 <parameter>
20 <name>maxIdle</name>
21 <value>30</value>
22 </parameter>
23 <parameter>
24 <name>maxWait</name>
25 <value>5000</value>
26 </parameter>
27 <parameter>
28 <name>username</name>
29 <value>root</value>
30 </parameter>
31 <parameter>
32 <name>password</name>
33 <value>mysqladmin</value>
34 </parameter>
35 <parameter>
36 <name>driverClassName</name>
37 <value>org.gjt.mm.mysql.Driver</value>
38 </parameter>
39 <parameter>
40 <name>url</name>
41 <value>jdbc:mysql://localhost:3306/mldn</value>
42 </parameter>
43 </ResourceParams>
44 </Context>
<bean id="dataSource"
2 class="org.springframework.jndi.JndiObjectFactoryBean"
3 destroy-method="close">
4 <property name="jndiName">
5 <value>java:comp/env/jdbc/mldn</value>
6 </property>
7 </bean>
而我用的Tomcat?.0.18Q在Ҏq个配置后就会出现javax.naming.NameNotFoundException: Name jdbc is not bound in this Context的错误。原因是QTomcat5和Tomcat6的配|有所区别Q?br />
W一Q?/strong>jdbc驱动的jar包,拯到Tomcat的lib?br />
W二Q?/strong>在tomcat中conf下的context.xml文g?lt;context>?lt;/context>之间加入以下部分Q?br />
<Resource name="jdbc/mldn"
2 auth="Container"
3 type="javax.sql.DataSource"
4 factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
5 driverClassName="com.mysql.jdbc.Driver"
6 url="jdbc:mysql://localhost:3306/mldn?useUnicode=true&characterEncoding=utf-8"
7 username="root"
8 password="123"
9 maxActive="100"
10 maxIdle="30"
11 maxWait="10000" />
<resource-ref>
2 <description>DB Connection</description>
3 <res-ref-name>jdbc/mldn</res-ref-name>
4 <res-type>javax.sql.DataSource</res-type>
5 <res-auth>Container</res-auth>
6 </resource-ref>
W三Q?/strong>在Spring的配|文件applicationContext.xml中加上如下代码:
<bean id="dataSource"
2 class="org.springframework.jndi.JndiObjectFactoryBean"
3 destroy-method="close">
4 <property name="jndiName">
5 <value>java:comp/env/jdbc/mldn</value>
6 </property>
7 </bean>
q样QTomcat6下的CP才能正常的运行v来?
]]>
package cn.zhang.myznt.filter;
2
3import java.io.IOException;
4
5import javax.servlet.Filter;
6import javax.servlet.FilterChain;
7import javax.servlet.FilterConfig;
8import javax.servlet.ServletException;
9import javax.servlet.ServletRequest;
10import javax.servlet.ServletResponse;
11
12public class EncodingFilter implements Filter {
13 private String charset = null;
14 public void destroy() {
15
16 }
17
18 public void doFilter(ServletRequest request, ServletResponse response,
19 FilterChain chain) throws IOException, ServletException {
20 request.setCharacterEncoding(this.charset);
21 chain.doFilter(request, response);
22
23 }
24
25 public void init(FilterConfig arg0) throws ServletException {
26 this.charset = arg0.getInitParameter("charset");
27 }
28
29}
30
在web.xml中注册这个FilterQ注意他的位|必L在需要调用action及jsp或其他页面声明之?br />
<filter>
2 <filter-name>encoding</filter-name>
3 <filter-class>cn.zhang.myznt.filter.EncodingFilter</filter-class>
4 <init-param>
5 <param-name>charset</param-name>
6 <param-value>UTF-8</param-value>
7 </init-param>
8 </filter>
9 <filter-mapping>
10 <filter-name>encoding</filter-name>
11 <url-pattern>/*</url-pattern>
12 </filter-mapping>
同时在连接mysql数据库的时候也要改为jdbc:mysql://localhost:3306/mldn?useUnicode=true&characterEncoding=utf-8 如果q接在java代码中用,请?amp;Q如果是在xml中用请写成&?br />
关于mysql的collation字符集和mysql的characterSet字符集问题,查了很多资料都说要设|成一P我想那只是针对如果你选GBK作ؓ数据库编码的时候所用,但如果选用UTF8作ؓ数据库编码的时候就不一定正了?br />
今天Ҏ|上的资料将所有的characterSet讄成utf8Q可用mysql> SHOW VARIABLES LIKE 'character_set_%';查看Q,一直在试q问题解决没有。在试q程发现传递的中文都是正确的,可就是在MySQL Client中查看的是ؕ码,所以l找Ҏ解决Q但其实q个时候你插进ȝ中文已经是正常的了,只是在MySQL Client中显C是q。那么ؓ什么会q样QMySQL Client讄成UTF8的时候中文不能正常显C,此时我们应该charact_set_client Q设|成gbkQ这样就可以正常昄中文了?br />
可以在my.ini?
而下面的default-character-set=utf8Q两个default-character-set的设|是不一L。当然如果你选用gbk作ؓ数据库编码,是需要设|成一L?
]]>
没有妥善处理好的原因?br />
具体的原因就?br />
在tomcat中jsp~译成servlet之后在函数_jspService(HttpServletRequest request, HttpServletResponse response)的最?br />
有一D这L代码
finally {
if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
}
q里是在释放在jsp中用的对象Q会调用response.getWriter(),因ؓq个Ҏ是和
response.getOutputStream()相冲H的Q所以会出现以上q个异常?/p>
jsp内的所有空格和回RW号所有都删除掉)Q?/p>
out.clear();
out = pageContext.pushBody();
<%@ page import="java.io.OutputStream" %>
<%!
Color getRandColor(int fc,int bc){
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
%>
<%
try{
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
OutputStream os=response.getOutputStream();
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
String sRand="";
for (int i=0;i<4;i++){
String rand=String.valueOf(random.nextInt(10));
sRand+=rand;
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
g.drawString(rand,13*i+6,16);
}
session.setAttribute("rand",sRand);
g.dispose();
os.flush();
os.close();
os=null;
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
}
catch(IllegalStateException e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}%>
]]>
struts-config.xml
<controller
processorClass="org.springframework.web.struts.DelegatingRequestProcessor">
</controller>
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/classes/applicationContext.xml" />
</plug-in>
开发环境ؓQ?/span>MyEclipse 7.1.1 + Jdk 1.6.0_13 + Tomcat 6.0.18 + MySQL 6.0.10 alpha
所用表Q?/span>test.employee
q个实例主要是实现简单的CRUDҎ。在搭徏环境前,需要处理一个问题:因ؓSpring2.5 AOP Liberaries里的asm2.2.3.jar?/span>Hiberate中的生成代理用的asm.jar冲突Q我们需要删?/span>asm2.2.3.jarQ不然就会发生异常:java.lang.NoClassDefFoundError: org/objectweb/asm/CodeVisitor 。具体的删除ҎQ避免在Tomcat中的lib下删除了Q然后又重新发布目时此jar又重新发不到lib下)Q在MyEclipse中?/span>Window?/span>à?/span>Preferences?/span>à?/span>MyEclipse Enterprise Workbench?/span>à?/span>Project Capabilities?/span>à?/span>Spring】在spring2.5 AOP Libraries中删?/span>asm2.2.3.jar
在开?/span>S2SH架构Ӟ先整?/span>Spring + Hibernate Q然后再整合Struts + Spring 完成S2SH架构的搭建?/span>
一?/span>Srping ?/span> Hibnernate 的整?/span>
Q?/span>1Q添?/span>Hibernate支持
在添?/span>Hibernate支持之前Q我们先在?/span>MyEclipse DataBase Explorer】中讄数据库连接。所用的mysql/jdbc的jar包ؓmysql-connector-java-5.1.8-bin.jar?br />
注意Q?/span>MySQL?/span>URL为:jdbc:mysql://localhost:3306/testQ我所Ҏ学的视频案例是连?/span>oracle的,Ҏ视频中所学的时候,url没有d数据库,在测试过E当中怎么样也扑ֈ实体Q原因就是因为在url中没有添加数据库的选择。)
后面按照默认讄一直到?/span>finish】即可?/span>
Q?/span>aQ在D中找到?/span>MyEclipse】,然后选择?/span>Add Hibernate Capbilities?br />
q里可以直接选择jar包拷贝到lib下面Q也可以先不拯Q到时?/span>MyEclipse会自动拷贝到lib下?/span>
Q?/span>bQ由?/span>Hibernate要与Spring整合Q所以在q一步无需再配|更详细?/span>hibernate.cfg.xml
在这个按列中Q我们?/span>JDBC Driver模式?/span>
Q?/span>cQ不创徏sessionFactory。然后?/span>finish?br />
Q?/span>2Q添?/span>Spring支持
Q?/span>aQ在D中找到?/span>MyEclipse】,然后选择?/span>Add Spring Capbilities?/span>
d5个类库?br />
Q?/span>bQ生?/span>applicationContext.xmlQ徏议将其放?/span>WEB-INF下面?br />
Q?/span>cQ创?/span>sessionFactory。然后?/span>finish?br />
Q?/span>3Q整?/span>Spring?/span>Hibernate
打开applicationContextQ在当中增加DataSource?/span>SessionFactory
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml"> </property> </bean> |
先将原先自动生成的上qC码删除?br />
然后?/span>Outline的导航中选择?/span>New DataSource and SessionFactory?br />
后面要用?/span>Mapping ResourcesQ所以你可以在这里随便填一个D厅R?br />
最后添加部分属性(d?/span>hibernate.show_sqlQ后形成代码如下Q?/span>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"> </property> <property name="url" value="jdbc:mysql://localhost:3306/test"></property> <property name="username" value="root"></property> <property name="password" value="123"></property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <property name="mappingDirectoryLocations"> <list> <value>file:src</value> </list> </property> </bean> |
自此已经完成?/span>Spring?/span>Hibernate的整合?/span>