??xml version="1.0" encoding="utf-8" standalone="yes"?> 单地_(d) Clone 是对于l定的一个对象实?/span> o Q得到另一个对象实?/span> o’ Q?/span> o ?/span> o’ c?/span> 型相同( o.getClass() == o’.getClass() Q,内容相同Q对?/span> o/o’ 中的字段 f Q如?/span> f 是基本数据类型,?/span> o.f == o’.f Q如?/span> f 是对象引用,?/span> o.f == o’.f ?/span> o.f 指向的对象与 o’.f 指向的对象的内容相同Q。通常U?/span> o’ ?/span> o 的克隆或副本?/span> 直观上看Q似乎很Ҏ(gu)Z个类加上 clone Ҏ(gu)Q?/span> class A { private Type1 field1; private Type2 field2; ….. public Object clone() { A a = new A(); a.field1 = a.getField1(); a.field2 = a.getField2(); …… return a; } } 然而,E加推敲Q就?x)发现这L(fng)实现Ҏ(gu)有两个问题:(x) 1. 要想某个cL clone 功能Q必d独ؓ(f)其实?/span> clone() 函数Q函数实C码与该类定义密切相关?/span> 2. 即基类 A 已有 clone() 函数Q其子类 ExtendA 若要具备 clone 功能Q则必须 override 其基c?/span> A ?/span> clone() 函数。否则,对类型ؓ(f) ExtendA 的对?/span> ea ?/span> clone() Ҏ(gu)的调用,?x)执行于c?/span> A 中定义的 clone() Ҏ(gu)而返回一个类型ؓ(f) A 的对象,它显然不?/span> ea 的克隆?/span> 万类之初?/span> Object cL clone() Ҏ(gu)Q?/span> protected native Object clone() throws CloneNotSupportedException; 该方法是 protected 的,昄是留待被子类 override 的。该Ҏ(gu)又是 native 的,必然做了(jin) 与具体^台相关的底层工作?/span> 事实上,c?/span> Object ?/span> clone() Ҏ(gu)首先?x)检?/span> this.getClass() 是否实现?/span> Cloneable 接口?/span> Cloneable 只是一个标志接口而已Q用来标志该cL否有克隆功能?/span> public interface Cloneable { } 如果 this.getClass() 没有实现 Cloneable 接口Q?/span> clone() ׃(x)?/span> CloneNotSupportedException q回。否则就?x)创Z个类型ؓ(f) this.getClass() 的对?/span> other Qƈ?/span> this ?/span> field 的D值给 other 的对?/span> field Q然后返?/span> other ?/span> 如此一来,我们要定义一个具?/span> Clone 功能的类q当方便:(x) 1. 在类的声明中加入“ implements Cloneable ”Q标志该cL克隆功能Q?/span> 2. Override c?/span> Object ?/span> clone() Ҏ(gu)Q在该方法中调用 super.clone() Q?/span> class CloneableClass implements Cloneable { …… public Object clone() { try { return super.clone(); // 直接?/span> Object.clone() 为我们代劳一?/span> } catch (CloneNotSupportedException e) { throw new InternalError(); } } } 一个具有克隆功能的c,如果有可变( Mutable Q类cd的字D?/span> field Q如何ؓ(f)其克隆(?/span> 本)(j)对象 o’ 中的 field 赋| Ҏ(gu)一、如 Object ?/span> clone() Ҏ(gu)所实现Q设原始对象?/span> o Q其克隆对象?/span> o’ Q执?/span> o’.field = o.field 。这P o’.field ?/span> o.field 指向同一个可变对?/span> m ?/span> o ?/span> o’ 可能?x)相互?jing)响(一个对象的状态可能会(x)随着另一个对象的状态的改变而改变)(j)。这L(fng) Clone UCؓ(f) Shallow Clone 。这也是 Object ?/span> clone() Ҏ(gu)的实现方式?/span> Ҏ(gu)二、将 o.field 指向的可变对?/span> m 克隆Q得?/span> m’ Q将 m’ 的引用赋值给 o’.field 。这?/span> o’ ?/span> o 内容相同Q且怺之间无媄(jing)响(一个对象状态的改变?sh)?x)影响另一个对象的状态)(j)。这L(fng) Clone UCؓ(f) Deep Clone ?/span> Java Collection cd中具体数据结构类Q?/span> ArrayList/LinkedList Q?/span> HashSet/TreeSet Q?/span> HashMap/TreeMap {)(j)都具有克隆功能,且都?/span> Shallow Clone Q这栯计是合理的,因ؓ(f)它们不知道存攑օ中的每个数据对象是否也有克隆功能?/span> System.arrayCopy() 的实现采用的也是 Shallow Clone ?/span> Deep Clone 对于实现不可变( Immutable Q类很有帮助。设一个类包含可变c?/span> M cd?/span> field Q如何将其设计ؓ(f)不可变类呢?先ؓ(f) M 实现 Deep Clone 功能Q然后这栯计类 ImmutableClass Q?/span> class ImmutableClass { MutableClass m; ImmutableClass(MutableClass m) { this.m = m.clone(); // 传入的 m ?/span> clone 赋值给内部 m } public MutableClass getM() { return this.m.clone(); // 内?/span> m ?/span> clone q回l外?/span> } } (g)查类有无可变cȝ型的字段。如果无Q返?/span> super.clone() 卛_Q?/span> 如果有,保包含的可变类本n都实C(jin) Deep Clone Q?/span> Object o = super.clone(); // 先执行浅克隆Q确保类型正和基本cd?qing)非可变cȝ型字D内Ҏ(gu)?/span> 对于每一个可变类cd的字D?/span> field Q?/span> o.field = this.getField().clone(); q回 o ?/span> Z么不?/span>System.out.println()? Z么同时?/span>commons-logging?/span>Log4j?Z么不仅用其中之一Q?br />
Commons-loggin的目的是?#8220;所有的Java日志实现”提供一个统一的接口,它自w的日志功能q_弱(只有一个简单的SimpleLog?Q,所以一般不?x)单独用它?/span> Log4j的功能非常全面强大,是目前的首选。我发现几乎所有的Java开源项目都?x)用?/span>Log4jQ但我同时发玎ͼ所有用?/span>Log4j的项目一般也同时?x)用?/span>commons-loggin。我惻I大家都不希望自己的项目与Log4jl定的太紧密吧。另外一个我能想到的“同时使用commons-logging?/span>Log4j”的原因是Q简化用和配置?/span> 一点,“同时使用commons-logging?/span>Log4j”Q与“单独使用Log4j”相比Qƈ不会(x)带来更大的学?fn)、配|和l护成本Q反而更加简化了(jin)我们的工作?/span>我想q也是ؓ(f)什?#8220;所有用?/span>Log4j的项目一般也同时?x)用?/span>commons-loggin”的原因之一吧?/span> Commons-logging能帮我们做什么? q里看一下它怎么“‘很脓(chung)?j)?#8217;帮我?#8216;自动选择’‘适当?#8217;日志实现pȝ”Q?/span> 可见Q?/span>commons-loggingL能找C个日志实现类Qƈ且尽可能扑ֈ一?#8220;最合?#8221;的日志实现类。我说它“很脓(chung)?#8221;实际上是因ؓ(f)Q?/span>1、可以不需要配|文Ӟ2、自动判断有没有Log4j包,有则自动使用之;3、最(zhn)观的情况下也总能保证提供一个日志实玎ͼSimpleLogQ?/span> Z(jin)化配|?/span>commons-loggingQ一般不使用commons-logging的配|文Ӟ也不讄?/span>commons-logging相关的系l环境变量,而只需?/span>Log4j?/span>Jar包放|到classpash中就可以?jin)。这样就很简单地完成?/span>commons-logging?/span>Log4j的融合?/span>如果不想?/span>Log4j?jin)怎么办?只需?/span>classpath中的Log4j?/span>Jar包删除即可?br />
代码应该怎么写? 我们在需要输出日志信息的“每一?#8221;cM做如下的三个工作Q?/span> 如果愿意化的话,q可以两行合Z行:(x) 2、在自己的类中定义一?/span>org.apache.commons.logging.LogcȝU有?rn)态类成员Q?/span> 注意q里定义的是static成员Q以避免产生多个实例?/span> LogFactory.getLog()Ҏ(gu)的参C用的是当前类?/span>classQ这是目前被普通认为的最好的方式。ؓ(f)什么不写作LogFactory.getLog(this.getClass())Q因?/span>staticcL员访问不?/span>this指针Q?/span> 3、?/span>org.apache.commons.logging.Logcȝ成员Ҏ(gu)输出日志信息Q?/span> q里?/span>logQ就是上面第二步中定义的cL员变量,其类型是org.apache.commons.logging.LogQ通过该类的成员方法,我们可以将不同性质的日志信息输出到目的圎ͼ目的地是哪里Q视配置可定Q可能是stdoutQ也可能是文Ӟq可能是发送到邮gQ甚臛_送短信到手机……详见下文?/span>log4j.properties的介l)(j)Q?/span> Ҏ(gu)不同的性质Q日志信息通常被分成不同的U别Q从低到高(sh)ơ是Q?#8220;调试Q?/span>DEBUGQ?#8221;“信息Q?/span>INFOQ?#8221;“警告Q?/span>WARNQ?#8221;“错误Q?/span>ERRORQ?#8221;“致命错误Q?/span>FATALQ?#8221;?/span>Z么要把日志信息分成不同的U别呢?q实际上是方便我们更好的控制它。比如,通过Log4j的配|文Ӟ我们可以讄“输出‘调试’?qing)以上别的日志信?#8221;Q即“调试”“信息”“警告”“错误”“致命错误”Q,q对目开发h员可能是有用的;我们q可以设|?#8220;输出“警告”?qing)以上别的日志信?#8221;Q即“警告”“错误”“致命错误”Q,q对目最l用户可能是有用的?/span> 从上面三个步骤可以看出,使用commons-logging的日志接口非常的单,不需要记忆太多东西:(x)仅仅用到?jin)两个?/span>Log, LogFactoryQƈ且两个类的方法都非常(后者只用到一个方法,前者经常用到的也只是上面第三步中列出的几个Q,同时参数又非常简单?/span> 上面所介绍的方法是目前被普通应用的Q可以说是被标准化了(jin)的方法,几乎所有的人都是这么用。如果不信,或想认一下,去下蝲几个知名?/span>Java开源项目源代码看一下吧?/span> 下面l出一个完整的Javacȝ代码Q?/span> public class TestLog { public static void main(String[] args) { 只要保证commons-logging?/span>jar包在classpath中,上述代码肯定可以很顺利的~译通过。那它的执行l果是怎么L(fng)呢?恐怕会(x)有很大的不同Q请l箋往下看?/span> Log4j在哪里呢Q它发挥作用?jin)吗Q?/span> 应该注意刎ͼ我们上面l出的源代码Q完全没有涉?qing)?/span>Log4j——这正是我们所希望的,q也正是commons-logging所要达到的目标之一?/span> 可是Q怎么才能?/span>Log4j发挥它的作用呢?{案很简单,只需满“classpath中有Log4j?/span>jar?#8221;。前面已l说q了(jin)Q?/span>commons-logging?x)自动发现ƈ应?/span>Log4j。所以只要它存在Q它?yu)发挥作用。(它不存在呢?自然׃发挥作用Q?/span>commons-logging?x)另行选择其它的日志实现类。)(j) 注意Q配|文?/span>log4j.properties?/span>Log4j来说是必ȝ。如?/span>classpath中没有该配置文gQ或者配|不对,会(x)引发q行时异常?/span> q样Q要正确地应?/span>Log4j输出日志信息Q?/span>log4j.properties的作用就很重要了(jin)。好在该文g有通用的模板,复制一份(E加修改Q就可以使用。几乎每一?/span>Java目目录内都?x)有一?/span>log4j.properties文gQ可下蝲几个Java开源项目源代码查看。本文最后也附一个模板性质?/span>log4j.properties文gQ直接复制过d可以用,或者根据自q需要稍加修攏V后文将?/span>log4j.properties文g适当作一些介l?/span> LOG4J的配|之单它遍?qing)于来多的应用中了(jin)?x)Log4J配置文g实现?jin)输出到控制台、文件?/span> 回滚文g、发送日志邮件、输出到数据库日志表、自定义标签{全套功能。择其一二用就够用?/span> log4j.rootLogger=DEBUG,CONSOLE,A1,im # 应用于控制台 Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1545873
关于“vsftpd 部分本地用户不能dQ部分可?#8221;的问题,我重新做?jin)一些实验,我把q个问题l合实验的结果再重新描述一下,请各位高?sh),帮忙看看可能的原因?谢谢?jin)?br />
pȝ中原来就有的本地帐号都不能登录,我的/etc/vsftpd/vsftpd.conf文g的配|如下:(x)
local_enable=YES
write_enable=YES
chroot_local_user=YES
pam_service_name=vsftpd
/etc/pam.d/vsftpd存在且正常?br />
d旉误信息都是一L(fng)Q?br />
500 OOPS: cannot change directory:/home/xxxx
Login failed.
421 Service not available, remote server has closed connection
他们的home目录都是/home/xxxx?home?home/xxxx的权限都?55?br />
以上q些帐号都不能ftpdQ这些都是^常经怋用的Q可以用shelld的?br />
我新创徏?jin)一个usr1帐号Q?br />
# useradd -G test -d /tmp/usr1 usr1
能ftpdQ他的home?tmp/usr1,?分区上。?home我是mount?dev/hda9上的?br />
#mount
/dev/hdb1 on / type ext3 (rw)
/dev/hda9 on /home type ext2 (rw)
所以,我猜惻I(x)是否是由?home分区的原因,而造成“ȝ录在/home分区的帐?#8221;都不能登录呢Q?br />
Z(jin)验证以上设想Q我试着再创Z(jin)一个帐P
useradd -G test -d /home/usr3 usr3
/home, /home/usr3 的权限都?55?br />
usr3 ftpdp|?
500 OOPS: cannot change directory:/home/usr3
Login failed.
421 Service not available, remote server has closed connection
x(chng)Q我觉得可以定是由?home分区的原因,而造成“ȝ录在/home分区的帐?#8221;都不能登录?br />
参考文章:(x)
-----------------------------------------------------------------------------------------
I finished my second upgrade to Fedora Core 4. Not everything is ironed out yet with the build of course. But one thing is for sure a lot has happened to the RedHat I knew before.
I must say of all the changes, for me the nicest addition is the new SELinux extensions. For deep background on the reasons for and theory of SELinux read, The Inevitability of Failure: The Flawed Assumption of Security in Modern Computing Environments
The more I work with SELinux the more I realize I need to know about it, and how exactly it does all its stuff. It certainly changes things relating to users, directories and access. As I am starting to learn it, I'm sure I'm doing things the hard-way. :)
The major difference, so far for me, in Red Hat's SELinux is the way ftp is handled. vsftpd is still the server which is great. However, it seems to be designed to run as a daemon rather than invoked via xinet.d. If you grab a working copy of the xinet.d file for vsftpd you can invoke it via xinet.d wrapper. I did my first server upgrade in this manner. The current one I am trying as a daemon. I certainly think I will miss some of the features that the xinet.d wrapper brings, and may yet return to it.
Of all the issues I saw most notable is if you want to enable chroot directory's outside of the normal /home/xxx vsftpd. These will fail with a
500 OOPS: cannot change directory: /mnt/xxxxx
I was able to use ftp if I logged in with an account with a directory in /home, but once I set a user account to have a home drive outside of /home (in this case on a mounted secondary disk) vsftpd barfs the above.
I found information at the NSA that indicates you can disable SELinux protection of the ftp daemon.
setsebool -P ftpd_disable_trans 1
This seems a bit drastic. It certainly works for now though.
I think ultimately the issue resides with policies, but as SELinux policies are new to me, it will take time before it all gets sorted out. As I spend time with the new SELinux extensions in Fedora Core 4 I will keep you updated on my thoughts and configuration lessons.
---------------------------------------------------------------------------------------
解决办法Q?br />
--------------------------------------------------------------------------------------
# setsebool ftpd_disable_trans 1
# service vsftpd restart
我用的是FC4Q按照你上一帖子里的Ҏ(gu)试了(jin)Q马上就解决?jin)。所以,可以定原因在SELinux?br />
------------------------------------------------------------------------------------
1 什么是 Clone Q容易实现吗Q?/span>
2 Java ?/span> clone 的支?/span>
3 Shallow Clone ?/span> Deep Clone
3.1 Shallow ?/span> Deep 从何而来
3.2 如何实现 Deep Clone
q个……׃必说?jin)吧?/span>
功能太弱Q不易于控制。如果暂时不惌Z(jin)怎么办?如果惌出到文g怎么办?如果想部分输出怎么办?……
l 提供一个统一的日志接口,单了(jin)操作Q同旉免项目与某个日志实现pȝ紧密a耦合
l 很脓(chung)?j)的帮我们自动选择适当的日志实现系l(q一炚w常好Q)(j)
l 它甚至不需要配|?/span>
1) 首先?/span>classpath下寻找自q配置文gcommons-logging.propertiesQ如果找刎ͼ则用其中定义的Log实现c;
2) 如果找不?/span>commons-logging.properties文gQ则在查找是否已定义pȝ环境变量org.apache.commons.logging.LogQ找到则使用其定义的Log实现c;
3) 否则Q查?/span>classpath中是否有Log4j的包Q如果发玎ͼ则自动?/span>Log4j作ؓ(f)日志实现c;
4) 否则Q?/span>JDK自n的日志实现类Q?/span>JDK1.4以后才有日志实现c)(j)Q?/span>
5) 否则Q?/span>commons-logging自己提供的一个简单的日志实现c?/span>SimpleLogQ?/span>
Q以上顺序不保证完全准确Q请参考官Ҏ(gu)档)(j)
可以看到Q?/span>commons-logging对编E者和Log4j都非常友好?/span>
p么简单!
1、导入所有需?/span>commongs-loggingc:(x)
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.*;
private static Log log = LogFactory.getLog(YouClassName.class);
log.debug("111");
log.info("222");
log.warn("333");
log.error("444");
log.fatal("555");
l debug() 输出“调试”U别的日志信息;
l info() 输出“信息”U别的日志信息;
l warn() 输出“警告”U别的日志信息;
l error() 输出“错误”U别的日志信息;
l fatal() 输出“致命错误”U别的日志信息;
仅从字面上理解,也可以大致得出结论:(x)最常用的应该是debug()?/span>info()Q?/span>warn()?/span>error()?/span>fatal()仅在相应事g发生后才使用?/span>
package liigo.testlog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private static Log log = LogFactory.getLog(TestLog.class);
public void test() {
log.debug("111");
log.info("222");
log.warn("333");
log.error("444");
log.fatal("555");
}
TestLog testLog = new TestLog();
testLog.test();
}
} 关于Log4j比较全面的配|?/h5>
log4j.addivity.org.apache=true
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
#应用于文?/font>
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis
# 应用于文件回?/font>
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#应用于socket
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
# 发送日志给邮g
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# 用于数据?/font>
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
#自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
requestQ?/strong>
好处Q用完就仍,不会(x)D资源占用的无限增ѝ?
弊处Q每ơ要用都从数据库中抓Q多做操作,自然?x)对性能有一些媄(jing)响?
sessionQ?/strong>
好处Q不用每ơ都L据库抓,做操作?
弊处Q每个客户都有一个sessionQ只能自׃用,不同session可能保存大量重复数据Q?
可能耗费大量服务器内存;
另外session构徏在cookie和url重写的基上,所以用session实现?x)话跟踪Q会(x)用掉一点点服务器带宽和客户端保持联l,
当然session多Q耗费的带宽越多,理论上也?x)对性能造成影响?
集群的session同步?x)是个问题?
servletContextQ?/strong>
好处Q不用每ơ都L据库抓,做操作?
存储的数据所有客户都可以用?
可减重复在内存?sh)存储数据造成的开销?
弊处Q很多时候相同的数据可能不多(相当于cache的命中率很低Q?
其实以上3中方法都有利有弊Q各自的好处在某U条件下Q也都会(x)转变?sh)弊处。所以不妨综合用,相当于一?#8220;W三方用?#8221;Q只讲一下思\Q否则太q繁琐,涉及(qing)到的相关技术点请参考有x(chng)术资料)(j)Q?
request不说?jin),重点说说session和servletContextQ?
--session的可控应?/strong>
session的最大问题是资源回收Q两cd收方?
d回收Q浏览器被关闭,而ؓ(f)提交触发清理动作的请求时Q该Ҏ(gu)失效Q而且很常见?
时回收Q设|session的setMaxInactiveInterval属性或在web.xml中配|超时时_(d)然后交给jvm的垃圑֤理器处理?
不过不要报太大希望,jvm的垃圾收集器q不灵光?
可以用另一U替代方法缓解该问题Q比如限制session的数量,可以用HttpSessionListener实现Q这样可以缓解session带来的吃内存问题Q当然这U做法每ơ都需要判断session数量Q当session辑ֈ限定数量时还必须用其他方法处理了(jin)Q这些细节繁琐,而且要}慎处理?
--servletContext
如果说session是一?#8220;局部缓?#8221;Q那servletContext是一?#8220;全局~存”?jin),不妨把它当作cacheQ这里不讲究用词的严谨性,仅ؓ(f)?jin)更好说明问题?j)。cache的大是当前应用可用的最大内存。cache的最大问题是提高命中率,命中率高Q内存占用少Q效率高Q命中率低,则内存占用多而且效率低。这U应用的技术实现比“session的可I应?#8221;要简单,适用于相同数据多的地方,q个要事先有所判断Q如果用不好则有弊无利?
如果仅用servlet规范l出?U机ӞM一U都达不到好处兼收的效果Q所以要发挥3U方法的好处、摒弃弊处,必须l合q用Q做一些技术框架的构徏工作Q而且有些地方q比较繁琐(q好框架是可重用的)(j)?/span>
有时候寻求或实现“q”Q或者说取其利而摒其害Q,要付出很大代PҎ(gu)不同的情况,q些代h(hun)或是值得Q或是不值得。也可以“两害相权取其?#8221;Q或许是最便捷的方法?/span>
你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握?jin)Java的异常处理机Ӟ在下面这D代码中Q你能够q速找出异常处理的六个问题吗?
1 OutputStreamWriter out = ... 2 java.sql.Connection conn = ... 3 try { // ? 4 Statement stat = conn.createStatement(); 5 ResultSet rs = stat.executeQuery( 6 "select uid, name from user"); 7 while (rs.next()) 8 { 9 out.println("IDQ? + rs.getString("uid") // ? 10 "Q姓名:(x)" + rs.getString("name")); 11 } 12 conn.close(); // ? 13 out.close(); 14 } 15 catch(Exception ex) // ? 16 { 17 ex.printStackTrace(); //_(d)? 18 } |
作ؓ(f)一个JavaE序员,你至应该能够找Z个问题。但是,如果你不能找出全部六个问题,L(fng)l阅L文?
本文讨论的不是Java异常处理的一般性原则,因ؓ(f)q些原则已经被大多数人熟知。我们要做的是分析各U可UCؓ(f)“反例”Qanti-patternQ的q背优秀~码规范的常见坏?fn)惯Q帮助读者熟(zhn)这些典型的反面例子Q从而能够在实际工作中敏锐地察觉和避免这些问题?
反例之一Q丢弃异?
代码Q?5?18行?
q段代码捕获?jin)异常却不作M处理Q可以算得上Java~程中的杀手。从问题出现的频J程度和害E度来看Q它也许可以和C/C++E序的一个恶名远播的问题相提q论??不检查缓冲区是否已满。如果你看到?jin)这U丢弃(而不是抛出)(j)异常的情况,可以癑ֈ之九(ji)十九(ji)地肯定代码存在问题(在极数情况下,q段代码有存在的理由Q但最好加上完整的注释Q以免引起别解)(j)?
q段代码的错误在于,异常Q几乎)(j)L意味着某些事情不对劲了(jin)Q或者说臛_发生?jin)某些不d的事情,我们不应该对E序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace不?#8220;处理异常”。不错,调用printStackTrace对调试程序有帮助Q但E序调试阶段l束之后QprintStackTrace׃应再在异常处理模块中担负主要责Q?jin)?
丢弃异常的情形非常普遍。打开JDK的ThreadDeathcȝ文档Q可以看C面这D说明:(x)“特别圎ͼ虽然出现ThreadDeath是一U?#8216;正常的情?#8217;Q但ThreadDeathcLError而不是Exception的子c,因ؓ(f)许多应用?x)捕h有的Exception然后丢弃它不再理睬?#8221;q段话的意思是Q虽然ThreadDeath代表的是一U普通的问题Q但鉴于许多应用?x)试图捕h有异常然后不予以适当的处理,所以JDK把ThreadDeath定义成了(jin)Error的子c,因ؓ(f)ErrorcM表的是一般的应用不应该去捕获的严重问题。可见,丢弃异常q一坏习(fn)惯是如此常见Q它甚至已经影响C(jin)Java本n的设计?
那么Q应该怎样Ҏ(gu)呢?主要有四个选择Q?
1、处理异常。针对该异常采取一些行动,例如修正问题、提醒某个h或进行其他一些处理,要根据具体的情Ş定应该采取的动作。再ơ说明,调用printStackTrace不上已l?#8220;处理好了(jin)异常”?
2、重新抛出异常。处理异常的代码在分析异怹后,认ؓ(f)自己不能处理它,重新抛出异常也不׃ؓ(f)一U选择?
3、把该异常{换成另一U异常。大多数情况下,q是指把一个低U的异常转换成应用的异常(其含义更Ҏ(gu)被用户了(jin)解的异常Q?
4、不要捕获异常?
l论一Q既然捕获了(jin)异常Q就要对它进行适当的处理。不要捕获异怹后又把它丢弃Q不予理睬?
反例之二Q不指定具体的异?
代码Q?5行?
许多时候h们会(x)被这样一U?#8220;妙?#8221;x(chng)吸引Q用一个catch语句捕获所有的异常。最常见的情形就是用catch(Exception ex)语句。但实际上,在绝大多数情况下Q这U做法不值得提倡。ؓ(f)什么呢Q?
要理解其原因Q我们必d一下catch语句的用途。catch语句表示我们预期?x)出现某U异常,而且希望能够处理该异常。异常类的作用就是告诉Java~译器我们想要处理的是哪一U异常。由于绝大多数异帔R直接或间接从java.lang.ExceptionzQcatch(Exception ex)q当于说我们想要处理几乎所有的异常?
再来看看前面的代码例子。我们真正想要捕L(fng)异常是什么呢Q最明显的一个是SQLExceptionQ这是JDBC操作中常见的异常。另一个可能的异常是IOExceptionQ因为它要操作OutputStreamWriter。显?dng)在同一个catch块中处理q两U截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOExceptionp好多?jin)。这是_(d)catch语句应当量指定具体的异常类型,而不应该指定늛范围太广的ExceptioncR?
另一斚wQ除?jin)这两个特定的异常,q有其他许多异常也可能出现。例如,如果׃某种原因QexecuteQueryq回?jin)nullQ该怎么办?{案是让它们l箋抛出Q即不必捕获也不必处理。实际上Q我们不能也不应该去捕获可能出现的所有异常,E序的其他地方还有捕获异常的Z(x)??直至最后由JVM处理?
l论二:(x)在catch语句中尽可能指定具体的异常类型,必要时用多个catch。不要试囑֤理所有可能出现的异常?
反例之三Q占用资源不释放
代码Q??14行?
异常改变?sh)(jin)程序正常的执行程。这个道理虽然简单,却常常被Z忽视。如果程序用C(jin)文g、Socket、JDBCq接之类的资源,即遇到?jin)异常,也要正确释放占用的资源。ؓ(f)此,Java提供?jin)一个简化这cL作的关键词finally?
finally是样好东西:(x)不管是否出现?jin)异常,Finally保证在try/catch/finally块结束之前,执行清理d的代码L有机?x)执行。遗憄是有些h却不?fn)惯使用finally?
当然Q编写finally块应当多加小?j),特别是要注意在finally块之内抛出的异常??q是执行清理d的最后机?x),量不要再有难以处理的错误?
l论三:(x)保证所有资源都被正释放。充分运用finally关键词?/span>
反例之四Q不说明异常的详l信?
代码Q??18行?
仔细观察q段代码Q如果@环内部出C(jin)异常Q会(x)发生什么事情?我们可以得到_的信息判断@环内部出错的原因吗?不能。我们只能知道当前正在处理的cd生了(jin)某种错误Q但却不能获得Q何信息判断导致当前错误的原因?
printStackTrace的堆栈跟t功能显C出E序q行到当前类的执行流E,但只提供?jin)一些最基本的信息,未能说明实际D错误的原因,同时也不易解诅R?
因此Q在出现异常Ӟ最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一U更适合阅读的方式整理和l织printStackTrace提供的信息?
l论四:(x)在异常处理模块中提供适量的错误原因信息,l织错误信息使其易于理解和阅诅R?
反例之五Q过于庞大的try?
代码Q??14行?
l常可以看到有h把大量的代码攑օ单个try块,实际上这不是好习(fn)惯。这U现象之所以常见,原因在于有些h囄事,不愿花时间分析一大块代码中哪几行代码?x)抛出异常、异常的具体cd是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大子Q虽然东西是带上?jin),但要扑և来可不容易?
一些新手常常把大量的代码放入单个try块,然后再在catch语句中声明ExceptionQ而不是分d个可能出现异常的D落q分别捕获其异常。这U做法ؓ(f)分析E序抛出异常的原因带来了(jin)困难Q因Z大段代码中有太多的地方可能抛出Exception?
l论五:(x)量减小try块的体积?
反例之六Q输出数据不完整
代码Q??11行?
不完整的数据是JavaE序的隐形杀手。仔l观察这D代码,考虑一下如果@环的中间抛出?jin)异常,会(x)发生什么事情。@环的执行当然是要被打断的Q其ơ,catch块会(x)执行??p些,再也没有其他动作?jin)。已l输出的数据怎么办?使用q些数据的h或设备将收到一份不完整的(因而也是错误的Q数据,却得不到M有关q䆾数据是否完整的提C。对于有些系l来_(d)数据不完整可能比pȝ停止q行带来更大的损失?
较ؓ(f)理想的处|办法是向输?gu)备写一些信息,声明数据的不完整性;另一U可能有效的办法是,先缓冲要输出的数据,准备好全部数据之后再一ơ性输出?
l论六:(x)全面考虑可能出现的异总?qing)这些异常对执行程的?jing)响?
改写后的代码
Ҏ(gu)上面的讨论,下面l出改写后的代码。也许有Z(x)说它E微有点?嗦,但是它有?jin)比较完备的异常处理机制?
OutputStreamWriter out = ... java.sql.Connection conn = ... try { Statement stat = conn.createStatement(); ResultSet rs = stat.executeQuery( "select uid, name from user"); while (rs.next()) { out.println("IDQ? + rs.getString("uid") + "Q姓? " + rs.getString("name")); } } catch(SQLException sqlex) { out.println("警告Q数据不完整"); throw new ApplicationException("d数据时出现SQL错误", sqlex); } catch(IOException ioex) { throw new ApplicationException("写入数据时出现IO错误", ioex); } finally { if (conn != null) { try { conn.close(); } catch(SQLException sqlex2) { System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连? " + sqlex2.toString()); } } if (out != null) { try { out.close(); } catch(IOException ioex2) { System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文g" + ioex2.toString()); } } } |
术异常c:(x)ArithmeticExecption
I指针异常类QNullPointerException
cd强制转换异常QClassCastException
数组负下标异常:(x)NegativeArrayException
数组下标界异常QArrayIndexOutOfBoundsException
q背安全原则异常QSecturityException
文g已结束异常:(x)EOFException
文g未找到异常:(x)FileNotFoundException
字符串{换ؓ(f)数字异常QNumberFormatException
操作数据库异常:(x)SQLException
输入输出异常QIOException
Ҏ(gu)未找到异常:(x)NoSuchMethodException
java.lang.AbstractMethodError
抽象Ҏ(gu)错误。当应用试图调用抽象Ҏ(gu)时抛出?/span>
java.lang.AssertionError
断言错。用来指CZ个断ap|的情c(din)?/span>
java.lang.ClassCircularityError
cd@环依赖错误。在初始化一个类Ӟ若检到cM间@环依赖则抛出该异常?/span>
java.lang.ClassFormatError
cL式错误。当Java虚拟图从一个文件中dJavac,而检到该文件的内容不符合类的有效格式时抛出?/span>
java.lang.Error
错误。是所有错误的基类Q用于标识严重的E序q行问题。这些问题通常描述一些不应被应用E序捕获的反常情c(din)?/span>
java.lang.ExceptionInInitializerError
初始化程序错误。当执行一个类的静(rn)态初始化E序的过E中Q发生了(jin)异常时抛出。静(rn)态初始化E序是指直接包含于类中的static语句Dc(din)?/span>
java.lang.IllegalAccessError
q法讉K错误。当一个应用试图访问、修Ҏ(gu)个类的域QF(tun)ieldQ或者调用其Ҏ(gu)Q但是又q反域或Ҏ(gu)的可见性声明,则抛?gu)异常?/span>
java.lang.IncompatibleClassChangeError
不兼容的cd化错误。当正在执行的方法所依赖的类定义发生?jin)不兼容的改变时Q抛?gu)异常。一般在修改?jin)应用中的某些类的声明定义而没有对整个应用重新~译而直接运行的情况下,Ҏ(gu)引发该错误?/span>
java.lang.InstantiationError
实例化错误。当一个应用试N过Java的new操作W构造一个抽象类或者接口时抛出该异?
java.lang.InternalError
内部错误。用于指CJava虚拟机发生了(jin)内部错误?/span>
java.lang.LinkageError
链接错误。该错误?qing)其所有子cLC某个类依赖于另外一些类Q在该类~译之后Q被依赖的类改变?sh)(jin)其cd义而没有重新编译所有的c,q而引发错误的情况?/span>
java.lang.NoClassDefFoundError
未找到类定义错误。当Java虚拟机或者类装蝲器试囑֮例化某个c,而找不到该类的定义时抛出该错误?/span>
java.lang.NoSuchFieldError
域不存在错误。当应用试图讉K或者修Ҏ(gu)cȝ某个域,而该cȝ定义中没有该域的定义时抛?gu)错误?/span>
java.lang.NoSuchMethodError
Ҏ(gu)不存在错误。当应用试图调用某类的某个方法,而该cȝ定义中没有该Ҏ(gu)的定义时抛出该错误?/span>
java.lang.OutOfMemoryError
内存?sh)错误。当可用内存?sh)以让Java虚拟机分配给一个对象时抛出该错误?/span>
java.lang.StackOverflowError
堆栈溢出错误。当一个应用递归调用的层ơ太p导致堆栈溢出时抛出该错误?/span>
java.lang.ThreadDeath
U程l束。当调用ThreadcȝstopҎ(gu)时抛?gu)错误Q用于指C线E结束?/span>
java.lang.UnknownError
未知错误。用于指CJava虚拟机发生了(jin)未知严重错误的情c(din)?/span>
java.lang.UnsatisfiedLinkError
未满的链接错误。当Java虚拟机未扑ֈ某个cȝ声明为nativeҎ(gu)的本a定义时抛出?/span>
java.lang.UnsupportedClassVersionError
不支持的cȝ本错误。当Java虚拟图从d某个cLӞ但是发现该文件的丅R次版本号不被当前Java虚拟机支持的时候,抛出该错误?/span>
java.lang.VerifyError
验证错误。当验证器检到某个cL件中存在内部不兼Ҏ(gu)者安全问题时抛出该错误?/span>
java.lang.VirtualMachineError
虚拟机错误。用于指C拟机被破坏或者l执行操作所需的资源不的情况?/span>
java.lang.ArithmeticException
术条g异常。譬如:(x)整数除零{?/span>
java.lang.ArrayIndexOutOfBoundsException
数组索引界异常。当Ҏ(gu)l的索引gؓ(f)负数或大于等于数l大时抛出?/span>
java.lang.ArrayStoreException
数组存储异常。当向数l中存放非数l声明类型对象时抛出?/span>
java.lang.ClassCastException
c造型异常。假设有cA和BQA不是B的父cL子类Q,O是A的实例,那么当强制将O构造ؓ(f)cB的实例时抛出该异常。该异常l常被称为强制类型{换异常?/span>
java.lang.ClassNotFoundException
找不到类异常。当应用试图Ҏ(gu)字符串Ş式的cd构造类Q而在遍历CLASSPAH之后找不到对应名U的class文gӞ抛出该异常?/span>
java.lang.CloneNotSupportedException
不支持克隆异常。当没有实现Cloneable接口或者不支持克隆Ҏ(gu)?调用其clone()Ҏ(gu)则抛?gu)异常?/span>
java.lang.EnumConstantNotPresentException
枚D帔R不存在异常。当应用试图通过名称和枚丄型访问一个枚丑֯象,但该枚D对象q不包含帔RӞ抛出该异常?/span>
java.lang.Exception
根异常。用以描q应用程序希望捕L(fng)情况?/span>
java.lang.IllegalAccessException
q法的访问异常。当应用试图通过反射方式创徏某个cȝ实例、访问该cd性、调用该cL法,而当时又无法讉Kcȝ、属性的、方法的或构造方法的定义时抛?gu)异常?/span>
java.lang.IllegalMonitorStateException
q法的监控状态异常。当某个U程试图{待一个自己ƈ不拥有的对象QOQ的监控器或者通知其他U程{待该对象(OQ的监控器时Q抛?gu)异常?/span>
java.lang.IllegalStateException
q法的状态异常。当在Java环境和应用尚未处于某个方法的合法调用状态,而调用了(jin)该方法时Q抛?gu)异常?/span>
java.lang.IllegalThreadStateException
q法的线E状态异常。当县城未处于某个Ҏ(gu)的合法调用状态,而调用了(jin)该方法时Q抛出异常?/span>
java.lang.IndexOutOfBoundsException
索引界异常。当讉K某个序列的烦(ch)引值小?或大于等于序列大时Q抛?gu)异常?/span>
java.lang.InstantiationException
实例化异常。当试图通过newInstance()Ҏ(gu)创徏某个cȝ实例Q而该cL一个抽象类或接口时Q抛?gu)异常?/span>
java.lang.InterruptedException
被中止异常。当某个U程处于长时间的{待、休眠或其他暂停状态,而此时其他的U程通过Thread的interruptҎ(gu)l止该线E时抛出该异常?/span>
java.lang.NegativeArraySizeException
数组大小值异常。当使用负数大小值创建数l时抛出该异常?/span>
java.lang.NoSuchFieldException
属性不存在异常。当讉K某个cȝ不存在的属性时抛出该异常?/span>
java.lang.NoSuchMethodException
Ҏ(gu)不存在异常。当讉K某个cȝ不存在的Ҏ(gu)时抛?gu)异常?/span>
java.lang.NullPointerException
I指针异常。当应用试图在要求用对象的地方使用?jin)nullӞ抛出该异常。譬如:(x)调用null对象的实例方法、访问null对象的属性、计null对象的长度、用throw语句抛出null{等?/span>
java.lang.NumberFormatException
数字格式异常。当试图一个String转换为指定的数字cdQ而该字符串确不满x(chng)字类型要求的格式Ӟ抛出该异常?/span>
java.lang.RuntimeException
q行时异常。是所有Java虚拟机正常操作期间可以被抛出的异常的父类?/span>
java.lang.SecurityException
安全异常。由安全理器抛出,用于指示q反安全情况的异常?/span>
java.lang.StringIndexOutOfBoundsException
字符串烦(ch)引越界异常。当使用索引D问某个字W串中的字符Q而该索引值小?或大于等于序列大时Q抛?gu)异常?/span>
java.lang.TypeNotPresentException
cd不存在异常。当应用试图以某个类型名U的字符串表达方式访问该cdQ但是根据给定的名称又找不到该类型是抛出该异常。该异常与ClassNotFoundException的区别在于该异常是uncheckedQ不被检查)(j)异常Q而ClassNotFoundException是checkedQ被(g)查)(j)异常?/span>
java.lang.UnsupportedOperationException
不支持的Ҏ(gu)异常。指明请求的Ҏ(gu)不被支持情况的异常?/span>
异常
javax.servlet.jsp.JspException: Cannot retrieve mapping for action /Login Q?Login是你的action名字Q?nbsp;
可能原因
action没有再struts-config.xml 中定义,或没有找到匹配的actionQ例如在JSP文g中?<html:form action="Login.do".表单提交给Login.do处理Q如果出Cq异常,h看struts-config.xml中的定义部分Q有时可能是打错?jin)字W或者是某些不符合规则,可以使用strutsconsole工具来检查?br />
-----------------------------------------------------------------------------------------------------------------
异常
org.apache.jasper.JasperException: Cannot retrieve definition for form bean null
可能原因
q个异常是因为StrutsҎ(gu)struts-config.xml中的mapping没有扑ֈaction期望的form bean。大部分的情况可能是因ؓ(f)在form-bean中设|的name属性和action中设|的name属性不匚w所致。换句话_(d)action和form都应该各自有一个name属性,q且要精匹配,包括大小写。这个错误当没有name属性和action兌时也?x)发生,如果没有在action中指定name属性,那么没有name属性和action相关联。当然当action制作某些控制Ӟ譬如Ҏ(gu)参数D转到相应的jsp面Q而不是处理表单数据,q是׃用name属性,q也是action的用方法之一?br />
-----------------------------------------------------------------------------------------------------------------
异常
No action instance for path /xxxx could be created
可能原因
特别提示Q因为有很多中情况会(x)Dq个错误的发生,所以推荐大家调高(sh)的web服务器的日志/调试U别Q这样可以从更多的信息中看到潜在的、在试图创徏actioncL发生的错误,q个actioncM已经在struts-config.xml中设|了(jin)兌Q即d?lt;action>标签Q?/span>
在struts-config.xml中通过action标签的class属性指定的actioncM能被扑ֈ有很多种原因Q例如:(x)定位~译后的.class文gp|。Failure to place compiled .class file for the action in the classpath (在web开发中Qclass的的位置在r WEB-INF/classesQ所以你的action class必须要在q个目录下。例如你的actioncM于WEB-INF/classes/action/Login.class,那么在struts-config.xml中设|a(chn)ction的属性type时就是action.Login).
拼写错误Q这个也时有发生Qƈ且不易找刎ͼ特别注意W一个字母的大小写和包的名称?
-----------------------------------------------------------------------------------------------------------------
异常
javax.servlet.jsp.JspException: No getter method for property username of bean org.apache.struts.taglib.html.BEAN
可能原因
没有位form bean中的某个变量定义getter Ҏ(gu)
q个错误主要发生在表单提交的FormBean中,用struts标记<html:text property=”username”>Ӟ在FormBean中必L一个getUsername()Ҏ(gu)。注意字?#8220;U”?br />
-----------------------------------------------------------------------------------------------------------------
异常
java.lang.NoClassDefFoundError: org/apache/struts/action/ActionForm
可能原因
q个错误主要发生在在classpath中找不到相应的Java .class文g。如果这个错误发生在web应用E序的运行时Q主要是因ؓ(f)指定的class文g不在web server的classpath中(/WEB-INF/classes ?/WEB-INF/libQ。在上面的错误中Q原因是找不到ActionFormcR?br />
-----------------------------------------------------------------------------------------------------------------
异常
javax.servlet.jsp.JspException: Exception creating bean of class org.apache.struts.action.ActionForm: {1}
可能原因
Instantiating Struts-provided ActionForm class directly instead of instantiating a class derived off ActionForm. This mightoccur implicitly if you specify that a form-bean is this Struts ActionForm class rather than specifying a child of this classfor the form-bean.
Not associating an ActionForm-descended class with an action can also lead to this error.
-----------------------------------------------------------------------------------------------------------------
异常
javax.servlet.jsp.JspException: Cannot find ActionMappings or ActionFormBeans collection
可能原因
不是标识Struts actionServlet?lt;servlet>标记是映射.do扩展名的<sevlet-mapping>标记或者两者都没有在web.xml中声明?/span>
在struts-config.xml中的打字或者拼写错误也可导致这个异常的发生。例如缺一个标记的关闭W号/>。最好用struts console工具(g)查一下?/span>
另外Qload-on-startup必须在web.xml中声明,q要么是一个空标记Q要么指定一个数|q个数值用来表servletq行的优先Q数D大优先低?/span>
q有一个和使用load-on-startup有关的是使用Struts预编译JSP文g时也可能Dq个异常?br />
-----------------------------------------------------------------------------------------------------------------
异常
java.lang.NullPointerException at org.apache.struts.util.RequestUtils.forwardURL(RequestUtils.java:1223)
可能原因
在struts-config.xml中的forward元素~少path属性。例如应该是如下形式Q?br />
<forward name="userhome" path="/user/userhome.jsp"/>
-----------------------------------------------------------------------------------------------------------------
异常
javax.servlet.jsp.JspException: Cannot find bean org.apache.struts.taglib.html.BEAN in any scope
Probable Causes
试图在Struts的form标记外用form的子元素。这常常发生在你?lt;/html:form>后面使用Struts的html标记。另外要注意可能你不l意使用的无M的标讎ͼ?lt;html:form … />Q这样web 服务器解析时当作一个无M的标讎ͼ随后使用的所?lt;html>标记都被认ؓ(f)是在q个标记之外的,如又使用?lt;html:text property=”id”>q有是在用taglib引入HTML标记库时Q你使用的prefix的g是html?br />
-----------------------------------------------------------------------------------------------------------------
异常
javax.servlet.jsp.JspException: Missing message for key xx.xx.xx
Probable Causes
q个key的值对没有在资源文件ApplicationResources.properties中定义。如果你使用eclipse时经常碰到这L(fng)情况Q当目重新~译Ӟeclipse?x)自动将classes目录下的资源文g删除?/span>
资源文gApplicationResources.properties 不在classpath中应资源文件放?WEB-INF/classes 目录下,当然要在struts-config.xml中定?
-----------------------------------------------------------------------------------------------------------------
异常
Cannot find message resources under key org.apache.struts.action.MESSAGE
可能原因
很显?dng)q个错误是发生在使用资源文gӞ而Struts没有扑ֈ资源文g?/span>
Implicitly trying to use message resources that are not available (such as using empty html:options tag instead of specifyingthe options in its body -- this assumes options are specified in ApplicationResources.properties file)
XML parser issues -- too many, too few, incorrect/incompatible versions
-----------------------------------------------------------------------------------------------------------------
异常
Strange and seemingly random characters in HTML and on screen, but not in original JSP or servlet.
可能原因
混和使用Struts的html:form标记和标准的HTML标记不正?/span>
使用的编码样式在本页中不支持?br />
-----------------------------------------------------------------------------------------------------------------
异常
"Document contained no data" in Netscape
No data rendered (completely empty) page in Microsoft Internet Explorer
可能原因
使用一个Action的派生类而没有实现perform()Ҏ(gu)或execute()Ҏ(gu)。在Struts1.0中实现的是perform()Ҏ(gu)Q在Struts1.1中实现的是execute()Ҏ(gu)Q但Struts1.1向后兼容perform()Ҏ(gu)。但你用Struts1.1创徏一个Action的派生类Qƈ且实C(jin)execute()Ҏ(gu)Q而你在Struts1.0中运行的话,׃(x)得到"Document contained nodata" error message in Netscape or a completely empty (no HTML whatsoever) page rendered in Microsoft Internet Explorer.”的错误信息?/span>
---------------------------------------------------------------------------------------------------------------------------
异常
ServletException: BeanUtils.populate
解决Ҏ(gu)
在用Struts上传文g?遇到?jin)javax.servlet.ServletException: BeanUtils.populate异常?br />
我的ActionServletq没有用到BeanUtilsq些工具cR后来仔l检查代码发现是在jsp文g里的form忘(sh)(jin)加enctype="multipart/form-data" ?jin)。所以写E序遇到错误或异常应该从多方面考虑问题存在的可能性,惛_pȝ提示信息以外的东ѝ?br />
----------------------------------------------------------------------------------------------------------------------------
1. 定义Action? 如果指定?jin)name, 那么必须要定义一个与它同名的FormBean才能q行form映射.2. 如果定义Action? 提交面时出?"No input attribute for mapping path..." 错误, 则需要在其input属性中定义转向的页?3. 如果插入新的数据时出?"Batch update row count wrong:..." 错误, 则说明XXX.hbm.xml中指定的key的类型ؓ(f)原始cd(int, long),因ؓ(f)q种cd?x)自动分配? 而这个值往往?x)让pȝ认ؓ(f)已经存在该记? 正确的方法是使用java.lang.Integer或java.lang.Long对象.4. 如果插入数据时出?"argument type mismatch" 错误, 可能是你使用?jin)Date{特D对? 因ؓ(f)struts不能自动从String型{换成Date?所? 你需要在Action中手动把String型{换成Date?5. Hibernate? Query的iterator()比list()Ҏ(gu)快很?6. 如果出现 "equal symbol expected" 错误, 说明你的strtus标签中包含另一个标{或者变? 例如:
<html:select property="test" onchange="<%=test%>"/>
或?br />
<html:hidden property="test" value="<bean:write name="t" property="p"/>"/>
q样的情?..
---------------------------------------------------------------------------------------------------------------------------
错误QException in thread "main" org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update原因与解冻I(x) 因ؓ(f)Hibernate ToolsQ或者Eclipse本n的Database ExplorerQ生?.hbn.xml工具中包含有catalog="***"Q?表示数据库名Uͼ(j)q样的属?该属性删除就可以?br />
---------------------------------------------------------------------------------------------------------------------------
错误Qorg.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations)
原因与解冻I(x)
Ҏ(gu)1 删除Set方的cascade
Ҏ(gu)2 解决兌关系后,再删?br />
Ҏ(gu)3 在many-to-one方增加cascade 但g能是none
最后一招:(x)
(g)查一下hashCode equals是否使用?jin)id作ؓ(f)唯一标示的选项?jin);我用uuid.hex时是没有问题的;但是用了(jin)nativeQ就不行?jin),怎么办?删除啊!
----------------------------------------------------------------------------------------------------------------------------
问题Q今天用Tomcat 5.5.12Q发现原来很好用的系l不能用?jin),反复试发现面中不能包?taglibQ否则会(x)出现以下提示QHTTP Status 500 -type Exception reportMessage description The server encountered an internal error () that prevented it from fulfilling this request.exceptionorg.apache.jasper.JasperException: /index.jsp(1,1) Unable to read TLD "META-INF/tlds/struts-bean.tld" from JAR file"file:*****/WEB-INF/lib/struts.jar":原因Q更C(jin)工程用的lib文g夹下的jarQ发布时也发布了(jin)servlet.jar和jsp-api.jar。解冻I(x)把jsp-api.jar删除p册个问题(sh)(jin)?----------------------------------------------------------------------------------------------------------------------------
错误Q?java.lang.NullPointerException
原因Q?发现 dao 实例?manage 实例{需要注入的东西没有被注入(俗称I指针异常)(j)解决Q这个时候,你应该查看日志文Ӟ默认是应用服务器?log 文gQ比?Tomcat 是 [Tomcat 安装目录 ]/logs Q你?x)发现提CZQ可能是Qorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sf' defined in ServletContextresource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception isorg.hibernate.HibernateException: could not configure from URL: file:src/hibernate.cfg.xmlorg.hibernate.HibernateException: could not configure from URL: file:src/hibernate.cfg.xml……………………….Caused by: java.io.FileNotFoundException: src\hibernate.cfg.xml可能是:(x)org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined inServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception isorg.hibernate.MappingException: Resource: com/mcc/coupon/model/UserRole.hbm.xml not foundorg.hibernate.MappingException: Resource: com/mcc/coupon/model/UserRole.hbm.xml not found然后你就知道原因是因为配|文件的解析Z(jin)错误Q这个通过 Web 面是看不出来的。更多的是持久化影射文g出的错误Q导致了(jin)没有被解析;当然你需要的功能无法用了(jin)?br />
----------------------------------------------------------------------------------------------------------------------------
错误QStandardWrapperValve[action]: Servlet.service() for servlet action threw exception
javax.servlet.jsp.JspException: Cannot retrieve mapping for action /settlementTypeManage
或者:(x) type Status report message Servlet action is not available description The requested resource (Servlet action is not available) is not available.
原因Q???br />
----------------------------------------------------------------------------------------------------------------------------
错误StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exceptionjava.lang.ClassNotFoundException: org.apache.struts.taglib.bean.CookieTei界面错误具体描述Q?br />
org.apache.jasper.JasperException: Failed to load or instantiate TagExtraInfo class: org.apache.struts.taglib.bean.CookieTei
原因与解冻I(x) <Ҏ(gu)一>你的“html:”开头的标签没有攑֜一?lt;html:form>?nbsp; <Ҏ(gu)?gt;重新启动你的应用服务器,自动没有这个问?br />
%p 输出优先U,即DEBUGQINFOQW(xu)ARNQERRORQFATAL
%r 输出自应用启动到输出该log信息耗费的毫U数
%c 输出所属的cȝQ通常是所在类的全?
%t 输出产生该日志事件的U程?
%n 输出一个回车换行符QW(xu)indowsq_?#8220;\r\n”QUnixq_?#8220;\n”
%d 输出日志旉点的日期或时_(d)默认格式为ISO8601Q也可以在其后指定格式,比如Q?d{yyy MMM dd HH:mm:ss,SSS}Q输出类|(x)
%l 输出日志事g的发生位|,包括cȝ名、发生的U程Q以?qing)在代码中的行数。D例:(x)Testlog4.main(TestLog4.java:10)