??xml version="1.0" encoding="utf-8" standalone="yes"?>久久精品国产亚洲av瑜伽,亚洲国语精品自产拍在线观看 ,亚洲AV日韩综合一区http://m.tkk7.com/freiberg/用键盘改变生z?/description>zh-cnMon, 12 May 2025 16:28:01 GMTMon, 12 May 2025 16:28:01 GMT60<html:cancel>标签报org.apache.struts.action.InvalidCancelException错误问题http://m.tkk7.com/freiberg/archive/2007/10/20/154384.htmlEndlessEndlessFri, 19 Oct 2007 17:20:00 GMThttp://m.tkk7.com/freiberg/archive/2007/10/20/154384.htmlhttp://m.tkk7.com/freiberg/comments/154384.htmlhttp://m.tkk7.com/freiberg/archive/2007/10/20/154384.html#Feedback5http://m.tkk7.com/freiberg/comments/commentRss/154384.htmlhttp://m.tkk7.com/freiberg/services/trackbacks/154384.html 下面看看解决Ҏ(gu)吧:(x)

Any existing applications that use the Cancel processing will need to modify their struts-config.xml to set the cancellable property for actions which require it.

In Struts 1.2.9 the <set-property> is used to set the cancellable property for an action....

    <action path="/fooAction"
input="/foo.jsp"
validate="true">
<set-property property="cancellable" value="true"/>
<forward name="success" path="/bar.jsp"/>
</action>

From Struts 1.3.x a new cancellable attribute can be used....

    <action path="/fooAction"
input="/foo.jsp"
validate="true"
cancellable="true">
<forward name="success" path="/bar.jsp"/>
</action>

In both Struts 1.2.9 and Struts 1.3.x an exception handler can be configured to handle the InvalidCancelException

    <action path="/fooAction"
input="/foo.jsp"
validate="true"
cancellable="true">
<forward name="success" path="/bar.jsp"/>
<exception key="errors.cancel"
type="org.apache.struts.action.InvalidCancelException"
path="/foo.jsp"/>
</action>


Endless 2007-10-20 01:20 发表评论
]]>
log4j入门与应?/title><link>http://m.tkk7.com/freiberg/archive/2007/10/18/153765.html</link><dc:creator>Endless</dc:creator><author>Endless</author><pubDate>Thu, 18 Oct 2007 01:39:00 GMT</pubDate><guid>http://m.tkk7.com/freiberg/archive/2007/10/18/153765.html</guid><wfw:comment>http://m.tkk7.com/freiberg/comments/153765.html</wfw:comment><comments>http://m.tkk7.com/freiberg/archive/2007/10/18/153765.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/freiberg/comments/commentRss/153765.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/freiberg/services/trackbacks/153765.html</trackback:ping><description><![CDATA[<p><font color="#333333">W一部分Q快速入?br /> <br /> 首先Q需要去下蝲LOG4Jq个软gq解压羃出其中的log4j.jar.在你的应用程序的classpath中包含该JAR文gQ你也可以简单地这个文件拷贝到JDK?java_home%\lib\ext目录下?br /> 在作完以上工作后Q你可以下面的代码保存到名为TestLogging.java中:(x)<br /> ##############################<br /> import org.apache.log4j.*;<br /> <br /> // How to use log4j<br /> public class TestLogging {<br /> <br /> // Initialize a logging category. Here, we get THE ROOT CATEGORY<br /> //static Category cat = Category.getRoot();<br /> // Or, get a custom category<br /> static Category cat = Category.getInstance(TestLogging.class.getName());<br /> <br /> // From here on, log away! Methods are: cat.debug(your_message_string),<br /> // cat.info(...), cat.warn(...), cat.error(...), cat.fatal(...)<br /> <br /> public static void main(String args[]) {<br /> // Try a few logging methods<br /> cat.debug("Start of main()");<br /> cat.info("Just testing a log message with priority set to INFO");<br /> cat.warn("Just testing a log message with priority set to WARN");<br /> cat.error("Just testing a log message with priority set to ERROR");<br /> cat.fatal("Just testing a log message with priority set to FATAL");<br /> <br /> // Alternate but INCONVENIENT form<br /> cat.log(Priority.DEBUG, "Calling init()");<br /> <br /> new TestLogging().init();<br /> }<br /> <br /> public void init() {<br /> java.util.Properties prop = System.getProperties();<br /> java.util.Enumeration enum = prop.propertyNames();<br /> <br /> cat.info("***System Environment As Seen By Java***");<br /> cat.debug("***Format: PROPERTY = VALUE***");<br /> <br /> while (enum.hasMoreElements()) {<br /> String key = (String) enum.nextElement();<br /> cat.info(key + " = " + System.getProperty(key));<br /> }<br /> }<br /> <br /> }<br /> <br /> ############################################################<br /> Log4J 默认情况下可以记录五个层ơ(׃到高Q的日志消息?br /> 1) debug<br /> 2)info<br /> 3)warn<br /> 4)error<br /> 5)fatal<br /> <br /> 在TestLoggin.class的目录中保存下列行在一个名字ؓ(f)log4j.properties 文g?默认情况下,当你在代码中使用getRoot()或getInstance("category_name")ӞLog4j?x)在应用E序?classpath中查找该文gQ?br /> ############################################<br /> log4j.rootCategory=DEBUG, dest1<br /> log4j.appender.dest1=org.apache.log4j.ConsoleAppender<br /> log4j.appender.dest1.layout=org.apache.log4j.PatternLayout<br /> ############################################<br /> ConsoleAppender指定的是控制台附加器Q即日志消息?x)输出到控制CQ而PatternLayout则指定了消息输出的格式,默认情况下格式ؓ(f)%m%n,%m指定的是消息内容Q?n指定的是操作pȝq_上的换行W?q里更类gC语言中的输出控制语句?br /> 现在Q你可以~译q且q行TestLogging.java了,你可以获得以下输出结果:(x)<br /> <br /> Start of main()<br /> Just testing a log message with priority set to INFO<br /> Just testing a log message with priority set to WARN<br /> Just testing a log message with priority set to ERROR<br /> Just testing a log message with priority set to FATAL<br /> Calling init()<br /> ***System Environment As Seen By Java***<br /> ***Format: PROPERTY = VALUE***<br /> java.runtime.name = Java(TM) 2 Runtime Environment, Standard Edition<br /> sun.boot.library.path = c:\jdk1.3\jre\bin<br /> java.vm.version = 1.3.0_02<br /> java.vm.vendor = Sun Microsystems Inc.<br /> ... and so on<br /> <br /> 如果x印消息的层次如debug,info,error{,那可以在log4j.properties 文g的最后一行上增加如下一行:(x)<br /> log4j.appender.dest1.layout.ConversionPattern=%-5p: %m%n<br /> q一行覆盖了默认的消息输出格?m%n,%p指定的是打印消息的层ơ(info,debug...,其中-5指定的是五个字符的宽度,-指定的是左对?,%m指定的是消息的内容,%n指定的则是操作系l^C的换行符.<br /> 当作完这些工作后Q无重新编译TestLogging.javaQ再ơ运用TestLoggQ会(x)得到以下不出的输出结果:(x)<br /> DEBUG: Start of main()<br /> INFO : Just testing a log message with priority set to INFO<br /> WARN : Just testing a log message with priority set to WARN<br /> ERROR: Just testing a log message with priority set to ERROR<br /> FATAL: Just testing a log message with priority set to FATAL<br /> DEBUG: Calling init()<br /> INFO : ***System Environment As Seen By Java***<br /> DEBUG: ***Format: PROPERTY = VALUE***<br /> INFO : java.runtime.name = Java(TM) 2 Runtime Environment, Standard Edition<br /> INFO : sun.boot.library.path = c:\jdk1.3\jre\bin<br /> INFO : java.vm.version = 1.3.0_02<br /> INFO : java.vm.vendor = Sun Microsystems Inc.<br /> ... and so on<br /> <br /> 如果不想输出日志的DEBUG与INFO消息Q那么可以修?log4j.rotCategory=DEBUG,dest1"为:(x)<br /> log4j.rootCategory=WARN,dest1<br /> 该行文g告诉Log4j跌层次低于WARN的消息输出,也就是说如DEBUG,INFO层次的消息将不会(x)产生输出Q再ơ运行TestLogging.classQ得C下结果:(x)<br /> ####################<br /> WARN : Just testing a log message with priority set to WARN<br /> ERROR: Just testing a log message with priority set to ERROR<br /> FATAL: Just testing a log message with priority set to FATAL<br /> ####################<br /> <br /> W二部分 Log4j 详解<br /> Log4j有三个主要的lgQcategory ,附g器和布局?br /> 在程序中Q你可以初始化一个category q且调用它的各种日志Ҏ(gu)来将消息字符串记录到日志中?br /> 一个category可以被配|用来输出到多个目标Q这些日志目标在Log4j框架中被UCؓ(f)附g?q些附g器可以包括控制台、文本文件、HTML文g?XML文g甚至是Windowsq的事g日志pȝQ甚臛_以被作ؓ(f)邮g被发送。而这些所有的目标都是通过log4j.properties文g来进行配|,对于使用Log4j框架的程序来讲只是简单地调用cM于info()、debug(){的Ҏ(gu)?br /> 附g器类可以是ConsoleAppender, FileAppender, SMTPAppender, SocketAppender, NTEventLogAppender, SyslogAppender, JMSAppender, AsyncAppender ?NullAppender{?附g器类可以使用布局QlayoutQ来在发送消息到目标之前q行格式化。例如HTMLLayout会(x)把消息格式化为HTML 格式?br /> 除了可以记录消息字符串到日志文g之外Q同时还可以记录日期、时间、消息层ơ、类名、源代码的行数、方法名U、线E名UC?qing)其它信息,而具体的输出需要由附g器的布局理器来配置?br /> category的名字是大小写区分以"."分隔的一个字W串。一般情况下我们通常使用your_class_name.class.getName()来获得一个JAVAcd来作为category的名字,例如testproj.util.test?br /> Each word in the category name is said to be an ancestor of the subsequent words and a parent of the immediately following word. This is important because Log4j has this concept of inheriting priorities and appenders from ancestors until overridden in a particular category.<br /> 有一个没有名U的category叫root,它就像xml的document元素Q是所有category的祖先?br /> 可以使用以下代码来初始一个根category或指定的category?br /> ################<br /> Category cat = Category.getRoot();<br /> Category cat2 = Category.getInstance("your.category.name");<br /> ###################<br /> 代表层次的常量由高到ơ是FATAL、ERROR、WARN、INFO和DEBUGQ可以在log4j.properties中指定category所属的层次Q例如指定log4j.rootCategory=WARN,simple则意呌用rootq个category的程序只?x)记录WARN?WARN以上的消息。如果没有ؓ(f)一个category指定默认的categoryQ那么category会(x)从其父category来ѝ?br /> 常见的Categorycȝ日志Ҏ(gu)有:(x)<br /> public void log(Priority p, Object message);<br /> <br /> // Convenient shortcuts to the generic logging method<br /> public void debug(Object message);<br /> public void info(Object message);<br /> public void warn(Object message);<br /> public void error(Object message);<br /> public void fatal(Object message);<br /> <br /> log4j 只记录层ơ与预设层次相等或更高别的消息Q如以下代码Q?br /> Category cat = Category.getRoot();<br /> cat.setPriority(Priority.ERROR);//讄预设层次为ERRORU?br /> // Later...<br /> //cat.info("Started processing..."); //q条消息不?x)输出,ERROR<br /> cat.error("User input is erroneous!"); //消息输出Q层ơ相{?br /> cat.fatal("Cannot process user input. Program terminated!"); //消息输出Q层ơ高于预讑ֱ?br /> <br /> W三部分 Log4j 配置<br /> 所有的配置工作应该在log4j.properties文g中完成,而该文g一般须攑֜应用E序的相同的目录中?br /> 在日志系l用之前,我们必须首先配置log4j.配置log4j意味着增加附g器到Categoryq且为每一个Category讄一个Layout?br /> category之间是有l承关系Q但他们增加到l(f)og4j.properties文g中的序是不固定的?br /> CZ一:<br /> #############################################################<br /> # 讄log4j的根category所使用的预讑ֱơ是DEBUG,而只使用A1q个附g?<br /> log4j.rootCategory=DEBUG, A1<br /> #附g器A1被设|ؓ(f)控制台附件器?br /> log4j.appender.A1=org.apache.log4j.ConsoleAppender<br /> #附g器用的布局是PatternLayout,x式布局<br /> log4j.appender.A1.layout=org.apache.log4j.PatternLayout<br /> #附g器A1的模式是%-4r [%t] %-5p %c %x - %m%n,其中%m代表消息字符Ԍ%n代表换行W?其它?开头的字符代表的含义如下文?br /> log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n<br /> ################################################################# <br /> CZ二:(x)<br /> #########################################################<br /> #### Use two appenders, one to log to console, another to log to a file<br /> log4j.rootCategory=debug, stdout, R<br /> # Print only messages of priority WARN or higher for your category<br /> log4j.category.your.category.name=WARN<br /> # Specifically inherit the priority level<br /> #log4j.category.your.category.name=INHERITED<br /> #### First appender writes to console<br /> log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br /> <br /> log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br /> # Pattern to output the caller's file name and line number.<br /> log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n<br /> #### Second appender writes to a file<br /> log4j.appender.R=org.apache.log4j.RollingFileAppender<br /> log4j.appender.R.File=example.log<br /> # Control the maximum log file size<br /> log4j.appender.R.MaxFileSize=100KB<br /> # Archive log files (one backup file here)<br /> log4j.appender.R.MaxBackupIndex=1<br /> log4j.appender.R.layout=org.apache.log4j.PatternLayout<br /> log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n<br /> ########################################################</font></p> W四部分 Log4j中有用的Layout<br /> 一些有用的layout有TTCCLayout, HTMLLayout, PatternLayout, SimpleLayout ?XMLLayout.<br /> 其中SimpleLayout和PatternLayout忽略JAVA throwable 接口z出来的errors和Exceptions.HTMLLayout和XMLLayout处理q些异常?br /> SimpleLayout的输Z包含日志消息的层ơ,紧跟着“-”后面的日志消息字W串。例如:(x)<br /> DEBUG - Hello World Message<br /> Patternlayout 可以Ҏ(gu)输出的模式字W串来决定消息的输出Q模式字W串cM于C语言中的模式字符丌Ӏ例如PatternLayout中如果用模式字W串“%r [%t] %-5p %c -%m%n”?x)输Z下消息:(x)<br /> 176 [main] INFO org.foo.Bar -Located nearest gas station<br /> 以下对各域作一下解释:(x)<br /> 1Q?r输出E序开始执行之后的微秒?br /> 2Q?t输出当前U程的名U?br /> 3Q?-5p输出消息的层ơ?br /> 4Q?c 输出category的名U?br /> 5)-%m?qing)s是日志消息本w?%n是换行符?br /> 当前在模式字W串中你可以嵌入M惌输出的字W?br /> 模式字符串中的模式如下:(x)<br /> %m:消息本n<br /> %p:消息的层?br /> %r:从程序开始执行到当前日志产生时的旉间隔Q微U)(j)<br /> %c:输出当前日志动作所在的category名称。例如:(x)如果category名称?a.b.c","%c{2}"会(x)输出"b.c". {2}意谓着输出“以点分隔开的category名称的后两个lg”,如果 {n}没有Q将?x)输出整个category名称.<br /> %t:输出当前U程的名U?br /> %x:输出和当前线E相兌的NDC(具体解释见下?,其用到像java servletsq样的多客户多线E的应用中?br /> %n:输出q_相关的换行符?br /> %%:输出一?%"字符<br /> %d:输出日志产生时候的日期Q当然可以对日期的格式进行定制。例如:(x)%d{HH:mm:ss,SSSS}或者是%d{dd MMM yyyy HH:mm:ss,SSSS},如果没有指定后面的格式,会(x)输出ISO8601的格式?br /> %l:输出位置信息Q相当于%C.%M(%F:%L)的组合?br /> %C:输出日志消息产生时所在的cdQ如果类名是“test.page.Class1”%C{1}表示输出cd"Class1",%C{2}输出"page.Class1",?C则输?test.page.Class1"?br /> %M:输出日志消息产生时的Ҏ(gu)名称<br /> %F:输出日志消息产生时所在的文g名称<br /> %L:输出代码中的行号<br /> 可以?与模式字W之间加上修饰符来控制其最宽度、最大宽度、和文本的对齐方式。如Q?br /> 1)%20cQ指定输出category的名Uͼ最的宽度?0Q如果category的名U小?0的话Q默认的情况下右寚w?br /> 2) %-20c:指定输出category的名Uͼ最的宽度?0Q如果category的名U小?0的话Q?-"h定左寚w?br /> 3) %.30c:指定输出category的名Uͼ最大的宽度?0Q如果category的名U大?0的话Q就?x)将左边多出的字W截掉,但小?0的话也不?x)有I格?br /> 4)%20.30c:如果category的名U小?0pI格Qƈ且右寚wQ如果其名称长于30字符Q就从左边交q销出的字符截掉?br /> 4)%20.30c:<br /> <br /> <br /> <br /> W五部分 Log4j中附件器?qing)相关的键值参?br /> 1.ConsoleAppender选项<br /> Threshold=WARN:指定日志消息的输出最低层ơ?br /> ImmediateFlush=true:默认值是true,意谓着所有的消息都会(x)被立卌出?br /> Target=System.errQ默认情况下是:(x)System.out,指定输出控制?br /> 2.FileAppender 选项<br /> Threshold=WARN:指定日志消息的输出最低层ơ?br /> ImmediateFlush=true:默认值是true,意谓着所有的消息都会(x)被立卌出?br /> File=mylog.txt:指定消息输出到mylog.txt文g?br /> Append=false:默认值是true,卛_消息增加到指定文件中Qfalse指将消息覆盖指定的文件内宏V?br /> 3.RollingFileAppender 选项<br /> Threshold=WARN:指定日志消息的输出最低层ơ?br /> ImmediateFlush=true:默认值是true,意谓着所有的消息都会(x)被立卌出?br /> File=mylog.txt:指定消息输出到mylog.txt文g?br /> Append=false:默认值是true,卛_消息增加到指定文件中Qfalse指将消息覆盖指定的文件内宏V?br /> MaxFileSize=100KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小Ӟ会(x)自动滚动Q即原来的内容Udmylog.log.1文g?br /> MaxBackupIndex=2:指定可以产生的滚动文件的最大数?br /> 4.DailyRollingFileAppender 选项<br /> Threshold=WARN:指定日志消息的输出最低层ơ?br /> ImmediateFlush=true:默认值是true,意谓着所有的消息都会(x)被立卌出?br /> File=mylog.txt:指定消息输出到mylog.txt文g?br /> Append=false:默认值是true,卛_消息增加到指定文件中Qfalse指将消息覆盖指定的文件内宏V?br /> DatePattern='.'yyyy-ww:每周滚动一ơ文Ӟx周生一个新的文件。当然也可以指定按月、周、天、时和分。即对应的格式如下:(x)<br /> 1)'.'yyyy-MM: 每月<br /> 2)'.'yyyy-ww: 每周<br /> 3)'.'yyyy-MM-dd: 每天<br /> 4)'.'yyyy-MM-dd-a: 每天两次<br /> 5)'.'yyyy-MM-dd-HH: 每小?br /> 6)'.'yyyy-MM-dd-HH-mm: 每分?br /> 5.PatternLayout 选项<br /> ConversionPattern=%m%n :指定怎样格式化指定的消息?br /> 6.HTMLLayout 选项<br /> LocationInfo=true:默认值是false,输出java文g名称和行?br /> Title=my app file: 默认值是 Log4J Log Messages.<br /> 7.XMLLayout 选项<br /> LocationInfo=true:默认值是false,输出java文g和行?br /> <br /> W六部分 Log4j配置案例解析<br /> #log4j.debug=true<br /> #log4j.disable=fatal<br /> #log4j.additivity.TestLogging=false<br /> <br /> log4j.rootCategory=, dest1<br /> log4j.category.TestLogging=DEBUG, dest1<br /> log4j.appender.dest1=org.apache.log4j.ConsoleAppender<br /> #log4j.appender.dest1.layout=org.apache.log4j.SimpleLayout<br /> log4j.appender.dest1.layout=org.apache.log4j.PatternLayout<br /> #log4j.appender.dest1.layout.ConversionPattern=%-5p %l %x: %m%n<br /> <br /> <br /> !----------------------####### END OF PROPERTIES #######----------------------!<br /> <br /> <br /> ##############################################################<br /> # Below I document in more detail how to write a log4j configuration file. #<br /> # SELECTIVELY copy lines beginning with #, paste and uncomment them above. #<br /> ##############################################################<br /> <br /> !-----------------------------------------------------------------------------!<br /> ! PLACE THIS FILE ANYWHERE IN CLASSPATH !<br /> ! Appenders are additive by default. !<br /> ! Priorities are inherited until overridden in a category. !<br /> ! In ${property_key}, the value of the key can be defined as a system !<br /> ! property or in this file itself. System properties are searched first and !<br /> ! then this file. !<br /> !-----------------------------------------------------------------------------!<br /> <br /> <br /> <br /> !-----------------------------------------------------------------------------!<br /> ! Configure log4j's operation at the meta level !<br /> !-----------------------------------------------------------------------------!<br /> ! Observe log4j parsing this file<br /> #log4j.debug=true<br /> ! Set this to false for log4j to actually obey the log4j.disable property(next)<br /> #log4j.disableOverride=false<br /> ! Disable all logging in all categories for messages with priority equal to<br /> ! or lower than the one given here<br /> #log4j.disable=INFO<br /> <br /> <br /> <br /> !-----------------------------------------------------------------------------!<br /> ! Configure categories (loggers) !<br /> !-----------------------------------------------------------------------------!<br /> <br /> ! ROOT CATEGORY (Usually sufficient to set this one only)<br /> ! Here, logs messages with priority DEBUG (default) or higher<br /> #log4j.rootCategory=, dest1<br /> ! Or,<br /> #log4j.rootCategory=debug, dest1, dest2<br /> <br /> ! YOUR CATEGORIES (to customize logging per class/pkg/project/etc)<br /> ! Here, overrides ancestor's priority and makes it WARN or higher for this cat.<br /> #log4j.category.TestLogging=WARN, dest3<br /> ! Or,<br /> #log4j.category.TestLogging=DEBUG, dest3<br /> <br /> !--------DON'T DO THIS!!! APPENDERS ARE ADDITIVE BY DEFAULT!!!----!<br /> ! It will write the same log message TWICE to dest1. Once for root, then for !<br /> ! this category. !<br /> !#log4j.category.TestLogging=DEBUG, dest1, dest3 !<br /> ! If you DO NOT want additivity for this category, say so !<br /> !#log4j.additivity.TestLogging=false !<br /> !-----------------------------------------------------------------------------!<br /> <br /> <br /> <br /> !-----------------------------------------------------------------------------!<br /> ! Configure appenders (log destinations/targets) and their options !<br /> !-----------------------------------------------------------------------------!<br /> <br /> ! WRITE TO CONSOLE (stdout or stderr)<br /> #log4j.appender.dest1=org.apache.log4j.ConsoleAppender<br /> #log4j.appender.dest1.ImmediateFlush=true<br /> <br /> ! WRITE LOG TO A FILE, ROLL THE FILE AFTER SOME SIZE<br /> #log4j.appender.dest2=org.apache.log4j.RollingFileAppender<br /> ! This appender will only log messages with priority equal to or higher than<br /> ! the one specified here<br /> #log4j.appender.dest2.Threshold=ERROR<br /> ! Specify the file name (${property_key} gets substituted with its value)<br /> #log4j.appender.dest2.File=${java.home}/log4j.log<br /> ! Don't append, overwrite<br /> #log4j.appender.dest2.Append=false<br /> ! Control the maximum log file size<br /> #log4j.appender.dest2.MaxFileSize=100KB<br /> ! Keep backup file(s) (backups will be in filename.1, .2 etc.)<br /> #log4j.appender.dest2.MaxBackupIndex=2<br /> <br /> ! WRITE LOG TO A FILE, ROLL THE FILE EVERY WEEK<br /> #log4j.appender.dest3=org.apache.log4j.DailyRollingFileAppender<br /> ! Specify the file name<br /> #log4j.appender.dest3.File=log4TestLogging2.html<br /> ! Control the maximum log file size<br /> #log4j.appender.dest3.MaxFileSize=300KB<br /> ! Rollover log file at the start of each week<br /> #log4j.appender.dest3.DatePattern='.'yyyy-ww<br /> <br /> <br /> <br /> !-----------------------------------------------------------------------------!<br /> ! Configure appender layouts (log formats) and their options !<br /> !-----------------------------------------------------------------------------!<br /> <br /> ! USE SIMPLE LOG FORMAT (e.g. INFO - your log message)<br /> #log4j.appender.dest1.layout=org.apache.log4j.SimpleLayout<br /> <br /> ! USE A C PRINTF STYLE PATTERN TO FORMAT LOG MESSAGE<br /> #log4j.appender.dest1.layout=org.apache.log4j.PatternLayout<br /> ! For a pattern layout, specify the pattern (Default is %m%n which is fastest)<br /> #log4j.appender.dest1.layout.ConversionPattern=%-5p: %m%n<br /> ! Or,<br /> #log4j.appender.dest1.layout.ConversionPattern=%-5p %6.10r[%t]%x(%F:%L) - %m%n<br /> <br /> #log4j.appender.dest2.layout=org.apache.log4j.PatternLayout<br /> #log4j.appender.dest2.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x(%F:%L) - %m%n<br /> ! Or, (the pattern below will slow down your app)<br /> #log4j.appender.dest2.layout.ConversionPattern=[%d{yyyy-mm-dd hh:mm},%6.6r]%-5p[%t]%x(%F:%L) - %m%n<br /> <br /> <br /> ! FORMAT LOG MESSAGES IN THE FORM OF AN HTML TABLE<br /> #log4j.appender.dest3.layout=org.apache.log4j.HTMLLayout<br /> ! Include Java file name and line number (Default is false)<br /> #log4j.appender.dest3.layout.LocationInfo=true<br /> ! Set <br /> <img src ="http://m.tkk7.com/freiberg/aggbug/153765.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/freiberg/" target="_blank">Endless</a> 2007-10-18 09:39 <a href="http://m.tkk7.com/freiberg/archive/2007/10/18/153765.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>要介l一下学?fn)web开发的q程和几本书http://m.tkk7.com/freiberg/archive/2007/09/19/146545.htmlEndlessEndlessWed, 19 Sep 2007 09:23:00 GMThttp://m.tkk7.com/freiberg/archive/2007/09/19/146545.htmlhttp://m.tkk7.com/freiberg/comments/146545.htmlhttp://m.tkk7.com/freiberg/archive/2007/09/19/146545.html#Feedback0http://m.tkk7.com/freiberg/comments/commentRss/146545.htmlhttp://m.tkk7.com/freiberg/services/trackbacks/146545.html 1.首先要先学习(fn)javaQ这是用jsp的基Q我当时是结合c++d?fn)的javaQ对比着学的。推荐大家看一下《Think in java?不过最好是E微入门后看。然后编一下java的程序,熟?zhn)java语言?br /> 2.学习(fn)servlet和jspQ这两者不要分开学,因ؓ(f)两者是相同的东西,只不q用到的地方不同Q然后摸清javabeanQ这样就可以做一些小目?了解mvc机制。推荐看《servlet/jsp核心~程》?br /> 3.然后要对协议有了解,《tcp/ip详解》一Q二Q三PL(fng)圣经的书?br /> 4.学习(fn)一些现在主的框架Qstruts我看的是《精通struts》,spring是《spring in action》由于我也在学习(fn)的过E中Q所以不好提什么徏议,然后我觉得就该看一下持久层框架Q现在比较流行的是hibernate吧,我看的是《深入浅出hibernate?br /> 5.最后应该是ejb了,q没有学Q只是有个概c(din)?br /> 在学的过E中Q我认ؓ(f)主要是要培养自己面向对象的概念,和对pȝ架构的了解,q样在可以对目q行把握?br /> q有要学?fn)的是xmlQsql{等q都是基我就不多说了?br />

Endless 2007-09-19 17:23 发表评论
]]>
java用于_计算的类http://m.tkk7.com/freiberg/archive/2007/09/17/145815.htmlEndlessEndlessMon, 17 Sep 2007 05:01:00 GMThttp://m.tkk7.com/freiberg/archive/2007/09/17/145815.htmlhttp://m.tkk7.com/freiberg/comments/145815.htmlhttp://m.tkk7.com/freiberg/archive/2007/09/17/145815.html#Feedback0http://m.tkk7.com/freiberg/comments/commentRss/145815.htmlhttp://m.tkk7.com/freiberg/services/trackbacks/145815.html  * 创徏日期 2004-10-14
 *
 * 如果需要精计?非要用String来够造BigDecimal不可
 */
package com.lims.actions.testqc.comm;

/**
 * @author Jstar
 *
 *
 * H口 > 首选项 > Java > 代码生成 > 代码和注?br />  */

import java.math.BigDecimal;

/**
* ׃Java的简单类型不能够_的对点数进行运,q个工具cL供精
* 的点数运,包括加减乘除和四舍五入?br /> */

public class Arith {

 //默认除法q算_ֺ

 private static final int DEF_DIV_SCALE = 10;

 //q个cM能实例化

 private Arith() {

 }

 /**
 
  * 提供_的加法运?br />  
  * @param v1 被加?br />  
  * @param v2 加数
 
  * @return 两个参数的和
 
  */

 public static double add(double v1, double v2) {

  bigdecimal b1 = new BigDecimal(Double.toString(v1));

  bigdecimal b2 = new BigDecimal(Double.toString(v2));

  return b1.add(b2).doubleValue();

 }

 /**
  * 提供_的减法运?br />   * @param v1 被减?br />   * @param v2 减数
  * @return 两个参数的差
  */

 public static double sub(double v1, double v2) {

  bigdecimal b1 = new BigDecimal(Double.toString(v1));

  bigdecimal b2 = new BigDecimal(Double.toString(v2));

  return b1.subtract(b2).doubleValue();

 }

 /**
 
  * 提供_的乘法运?br />  
  * @param v1 被乘?br />  
  * @param v2 乘数
 
  * @return 两个参数的积
 
  */

 public static double mul(double v1, double v2) {

  bigdecimal b1 = new BigDecimal(Double.toString(v1));

  bigdecimal b2 = new BigDecimal(Double.toString(v2));

  return b1.multiply(b2).doubleValue();

 }

 /**
 
  * 提供Q相对)(j)_的除法运,当发生除不尽的情冉|Q精到
 
  * 数点以?0位,以后的数字四舍五入?br />  
  * @param v1 被除?br />  
  * @param v2 除数
 
  * @return 两个参数的商
 
  */

 public static double div(double v1, double v2) {

  return div(v1, v2, DEF_DIV_SCALE);

 }

 /**
 
  * 提供Q相对)(j)_的除法运。当发生除不的情况Ӟ由scale参数?br />  
  * 定精度,以后的数字四舍五入?br />  
  * @param v1 被除?br />  
  * @param v2 除数
 
  * @param scale 表示表示需要精到数点以后几位?br />  
  * @return 两个参数的商
 
  */

 public static double div(double v1, double v2, int scale) {

  if (scale < 0) {

   throw new IllegalArgumentException("The scale must be a positive integer or zero");

  }

  bigdecimal b1 = new BigDecimal(Double.toString(v1));

  bigdecimal b2 = new BigDecimal(Double.toString(v2));

  return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

 }

 /**
 
  * 提供_的小C四舍五入处理?br />  
  * @param v 需要四舍五入的数字
 
  * @param scale 数点后保留几位
 
  * @return 四舍五入后的l果
 
  */

 public static double round(double v, int scale) {

  if (scale < 0) {

   throw new IllegalArgumentException("The scale must be a positive integer or zero");

  }

  bigdecimal b = new BigDecimal(Double.toString(v));

  bigdecimal one = new BigDecimal("1");

  return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

 }

};



Endless 2007-09-17 13:01 发表评论
]]>
【{】一关于web.xml配置的详l说?http://m.tkk7.com/freiberg/archive/2007/09/17/145814.htmlEndlessEndlessMon, 17 Sep 2007 05:01:00 GMThttp://m.tkk7.com/freiberg/archive/2007/09/17/145814.htmlhttp://m.tkk7.com/freiberg/comments/145814.htmlhttp://m.tkk7.com/freiberg/archive/2007/09/17/145814.html#Feedback0http://m.tkk7.com/freiberg/comments/commentRss/145814.htmlhttp://m.tkk7.com/freiberg/services/trackbacks/145814.html
部v描述W文件就像所有XML文g一P必须以一个XML头开始。这个头声明可以使用的XML版本q给出文件的字符~码?br /> DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本(?.2?.3Qƈ指定理此文件其余部分内容的语法的DTD(Document Type DefinitionQ文档类型定??br /> 所有部|描q符文g的顶层(根)(j)元素为web-app。请注意QXML元素不像HTMLQ他们是大小写敏感的。因此,web-App和W(xu)EB-APP都是不合法的Qweb-app必须用小写?br />
2 部v描述W文件内的元素次?br />
XML 元素不仅是大写敏感的,而且它们q对出现在其他元素中的次序敏感。例如,XML头必L文g中的W一,DOCTYPE声明必须是第二项Q而web- app元素必须是第三项。在web-app元素内,元素的次序也很重要。服务器不一定强制要求这U次序,但它们允许(实际上有些服务器是q样做的Q完全拒l执行含有次序不正确的元素的Web应用。这表示使用非标准元素次序的web.xml文g是不可移植的?br /> 下面的列表给Z所有可直接出现在web-app元素内的合法元素所必需的次序。例如,此列表说明servlet元素必须出现在所有servlet-mapping元素之前。请注意Q所有这些元素都是可选的。因此,可以省略掉某一元素Q但不能把它放于不正的位置?br /> l icon icon元素指出IDE和GUI工具用来表示Web应用的一个和两个囑փ文g的位|?br /> l display-name display-name元素提供GUI工具可能?x)用来标记这个特定的Web应用的一个名U?br /> l description description元素l出与此有关的说明性文本?br /> l context-param context-param元素声明应用范围内的初始化参数?br /> l filter qo(h)器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联?br /> l filter-mapping 一旦命名了一个过滤器Q就要利用filter-mapping元素把它与一个或多个servlet或JSP面相关联?br /> l listener servlet API的版?.3增加了对事g监听E序的支持,事g监听E序在徏立、修改和删除?x)话或servlet环境时得到通知。Listener元素指出事g监听E序cR?br /> l servlet 在向servlet或JSP面制定初始化参数或定制URLӞ必须首先命名servlet或JSP面。Servlet元素是用来完成此项d的?br /> l servlet-mapping 服务器一般ؓ(f)servlet提供一个缺省的URLQ?a href="http://host/webAppPrefix/servlet/ServletName" target="_blank">http://host/webAppPrefix/servlet/ServletName。但是,常常?x)更改这个URLQ以便servlet可以讉K初始化参数或更容易地处理相对URL。在更改~省URLӞ使用servlet-mapping元素?br /> l session-config 如果某个?x)话在一定时间内未被讉KQ服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveIntervalҎ(gu)明确讄单个?x)话对象的超时|或者可利用session-config元素制定~省时倹{?br /> l mime-mapping 如果Web应用h惛_Ҏ(gu)的文Ӟ希望能保证给他们分配特定的MIMEcdQ则mime-mapping元素提供q种保证?br /> l welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URLӞ使用哪个文g?br /> l error-page error-page元素使得在返回特定HTTP状态代码时Q或者特定类型的异常被抛出时Q能够制定将要显C的面?br /> l taglib taglib元素Ҏ(gu)记库描述W文ӞTag Libraryu Descriptor fileQ指定别名。此功能使你能够更改TLD文g的位|,而不用编辑用这些文件的JSP面?br /> l resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象?br /> l resource-ref resource-ref元素声明一个资源工厂用的外部资源?br /> l security-constraint security-constraint元素制定应该保护的URL。它与login-config元素联合使用
l login-config 用login-config元素来指定服务器应该怎样l试图访问受保护面的用h权。它与sercurity-constraint元素联合使用?br /> l security-role security-role元素l出安全角色的一个列表,q些角色出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可高IDE处理安全信息更ؓ(f)Ҏ(gu)?br /> l env-entry env-entry元素声明Web应用的环境项?br /> l ejb-ref ejb-ref元素声明一个EJB的主目录的引用?br /> l ejb-local-ref ejb-local-ref元素声明一个EJB的本C目录的应用?br />
3 分配名称和定制的UL

在web.xml中完成的一个最常见的Q务是对servlet或JSP面l出名称和定制的URL。用servlet元素分配名称Q用servlet-mapping元素定制的URL与刚分配的名U相兌?br /> 3.1 分配名称
Z提供初始化参敎ͼ对servlet或JSP面定义一个定制URL或分配一个安全角Ԍ必须首先lservlet或JSP面一个名U。可通过 servlet元素分配一个名U。最常见的格式包括servlet-name和servlet-class子元素(在web-app元素内)(j)Q如下所C:(x)
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>moreservlets.TestServlet</servlet-class>
</servlet>
q表CZ于WEB-INF/classes/moreservlets/TestServlet的servlet已经得到了注册名Test。给 servlet一个名U具有两个主要的含义。首先,初始化参数、定制的URL模式以及(qing)其他定制通过此注册名而不是类名引用此servlet。其?可在 URL而不是类名中使用此名U。因此,利用刚才l出的定义,URL
http://host/webAppPrefix/servlet/Test 可用?http://host/webAppPrefix/servlet/moreservlets.TestServlet 的场所?br /> 误住:(x)XML元素不仅是大写敏感的,而且定义它们的次序也很重要。例如,web-app元素内所有servlet元素必须位于所有servlet- mapping元素Q下一节介绍Q之前,而且q要位于5.6节和5.11节讨论的与过滤器或文档相关的元素Q如果有的话Q之前。类似地Qservlet 的servlet-name子元素也必须出现在servlet-class之前?.2?部v描述W文件内的元素次?详l介l这U必需的次序?br /> 例如Q程序清?-1l出了一个名为TestServlet的简单servletQ它ȝ在moreservletsE序包中。因为此servlet是扎根在一个名为deployDemo的目录中的Web应用的组成部分,所以TestServlet.class攑֜deployDemo/WEB- INF/classes/moreservlets中。程序清?-2l出放|在deployDemo/WEB-INF/内的web.xml文g的一部分。此web.xml文g使用servlet-name和servlet-class元素名UTest与TestServlet.class相关联。图 5-1和图5-2分别昄利用~省URL和注册名调用TestServlet时的l果?br />
E序清单5-1 TestServlet.java
package moreservlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/** Simple servlet used to illustrate servlet naming
* and custom URLs.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
*
http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/

public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String uri = request.getRequestURI();
out.println(ServletUtilities.headWithTitle("Test Servlet") +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H2>URI: " + uri + "</H2>\n" +
"</BODY></HTML>");
}
}


E序清单5-2 web.xmlQ说明servlet名称的摘录)(j)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"
http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<!-- … -->
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>moreservlets.TestServlet</servlet-class>
</servlet>
<!-- … -->
</web-app>

3.2 定义定制的URL
大多数服务器h一个缺省的serlvet URLQ?br />
http://host/webAppPrefix/servlet/packageName.ServletName。虽然在开发中使用q个URL很方便,但是我们常常?x)希望另一个URL用于部v。例如,可能?x)需要一个出现在Web应用层的URLQ如Qhttp: //host/webAppPrefix/AnynameQ,q且在此URL中没有servletV位于顶层的URL化了相对URL的用。此外,对许多开发h员来_(d)层URL看上L更长更麻?ch)的~省URL更简短?br /> 事实上,有时需要用定制的URL。比如,你可能想关闭~省URL映射Q以便更好地强制实施安全限制或防止用h外地讉K无初始化参数的servlet。如果你止了缺省的URLQ那么你怎样讉Kservlet呢?q时只有使用定制的URL了?br /> Z分配一个定制的URLQ可使用servlet-mapping元素?qing)其servlet-name和url-pattern子元素。Servlet- name元素提供了一个Q意名Uͼ可利用此名称引用相应的servletQurl-pattern描述了相对于Web应用的根目录的URL。url- pattern元素的值必M斜杠Q?Qv始?br /> 下面l出一个简单的web.xml摘录Q它允许使用URL http://host/webAppPrefix/UrlTest而不?/font>http://host/webAppPrefix/servlet/Test?br /> http: //host/webAppPrefix/servlet/moreservlets.TestServlet。请注意Q仍焉要XML头?DOCTYPE声明以及(qing)web-app闭元素。此外,可回忆一下,XML元素出现地次序不是随意的。特别是Q需要把所有servlet元素攑֜所?servlet-mapping元素之前?br /> <servlet>
<servlet-name>Test</servlet-name>
<servlet-class>moreservlets.TestServlet</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/UrlTest</url-pattern>
</servlet-mapping>
URL模式q可以包含通配W。例如,下面的小E序指示服务器发送所有以Web应用的URL前缀开始,?.aspl束的请求到名ؓ(f)BashMS的servlet?br /> <servlet>
<servlet-name>BashMS</servlet-name>
<servlet-class>msUtils.ASPTranslator</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name>BashMS</servlet-name>
<url-pattern>/*.asp</url-pattern>
</servlet-mapping>
3.3 命名JSP面
因ؓ(f)JSP面要{换成sevletQ自然希望就像命名servlet一样命名JSP面。毕竟,JSP面可能?x)从初始化参数、安全设|或定制的URL中受益,正如普通的serlvet那样。虽然JSP面的后台实际上是servletq句话是正确的,但存在一个关键的猜疑Q即Q你不知道JSP面的实际类名(因ؓ(f)pȝ自己挑选这个名字)(j)。因此,Z命名JSP面Q可jsp-file元素替换为servlet-calss元素Q如下所C:(x)
<servlet>
<servlet-name>Test</servlet-name>
<jsp-file>/TestPage.jsp</jsp-file>
</servlet>
命名JSP面的原因与命名servlet的原因完全相同:(x)即ؓ(f)了提供一个与定制讄Q如Q初始化参数和安全设|)(j)一起用的名称Qƈ且,以便能更Ҏ(gu)z?JSP面的URLQ比方说Q以便多个URL通过相同面得以处理Q或者从URL中去?jsp扩展名)(j)。但是,在设|初始化参数Ӟ应该注意QJSP面是利用jspInitҎ(gu)Q而不是initҎ(gu)d初始化参数的?br /> 例如Q程序清?-3l出一个名为TestPage.jsp的简单JSP面Q它的工作只是打印出用来Ȁzd的URL的本地部分。TestPage.jsp攄在deployDemo应用的顶层。程序清?-4l出了用来分配一个注册名PageNameQ然后将此注册名?/font>http://host/webAppPrefix/UrlTest2/anything 形式的URL相关联的web.xml文gQ即QdeployDemo/WEB-INF/web.xmlQ的一部分?br />
E序清单5-3 TestPage.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>
JSP Test Page
</TITLE>
</HEAD>
<BODY BGCOLOR="#FDF5E6">
<H2>URI: <%= request.getRequestURI() %></H2>
</BODY>
</HTML>


E序清单5-4 web.xmlQ说明JSP命名的摘录Q?br /> <?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"
http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<!-- ... -->
<servlet>
<servlet-name>PageName</servlet-name>
<jsp-file>/TestPage.jsp</jsp-file>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name> PageName </servlet-name>
<url-pattern>/UrlTest2/*</url-pattern>
</servlet-mapping>
<!-- ... -->
</web-app>


4 止Ȁzdservlet

对servlet或JSP面建立定制URL的一个原因是Q这样做可以注册?initQservletQ或jspInitQJSP面Q方法中d得初始化参数。但是,初始化参数只在是利用定制URL模式或注册名讉K servlet或JSP面时可以用,用缺省URL
http://host/webAppPrefix/servlet/ServletName 讉K时不能用。因此,你可能会(x)希望关闭~省URLQ这样就不会(x)有h意外地调用初始化servlet了。这个过E有时称为禁止激zdservletQ因为多数服务器h一个用~省的servlet URL注册的标准servletQƈȀzȝ省的URL应用的实际servlet?br /> 有两U禁止此~省URL的主要方法:(x)
l 在每个Web应用中重新映?servlet/模式?br /> l 全局关闭Ȁzdservlet?br /> 重要的是应该注意刎ͼ虽然重新映射每个Web应用中的/servlet/模式比彻底禁止激zservlet所做的工作更多Q但重新映射可以用一U完全可UL的方式来完成。相反,全局止Ȁzdservlet完全是针对具体机器的Q事实上有的服务器(如ServletExecQ没有这L(fng)选择。下面的讨论Ҏ(gu)个Web应用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局止Ȁzdservlet的详l内宏V?br /> 4.1 重新映射/servlet/URL模式
在一个特定的Web应用中禁止以
http://host/webAppPrefix/servlet/ 开始的URL的处理非常简单。所需做的事情是建立一个错误消息servletQƈ使用前一节讨论的url-pattern元素所有匹配请求{向该 servlet。只要简单地使用Q?br /> <url-pattern>/servlet/*</url-pattern>
作ؓ(f)servlet-mapping元素中的模式卛_?br /> 例如Q程序清?-5l出了将SorryServlet servletQ程序清?-6Q与所有以
http://host/webAppPrefix/servlet/ 开头的URL相关联的部v描述W文件的一部分?br />
E序清单5-5 web.xmlQ说明JSP命名的摘录Q?br /> <?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"
http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<!-- ... -->
<servlet>
<servlet-name>Sorry</servlet-name>
<servlet-class>moreservlets.SorryServlet</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name> Sorry </servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
<!-- ... -->
</web-app>


E序清单5-6 SorryServlet.java
package moreservlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/** Simple servlet used to give error messages to
* users who try to access default servlet URLs
* (i.e.,
http://host/webAppPrefix/servlet/ServletName)
* in Web applications that have disabled this
* behavior.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
*
http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/

public class SorryServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "Invoker Servlet Disabled.";
out.println(ServletUtilities.headWithTitle(title) +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H2>" + title + "</H2>\n" +
"Sorry, access to servlets by means of\n" +
"URLs that begin with\n" +
"
http://host/webAppPrefix/servlet/\n" +
"has been disabled.\n" +
"</BODY></HTML>");
}

public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}


4.2 全局止ȀzdQTomcat
Tomcat 4中用来关闭缺省URL的方法与Tomcat 3中所用的很不相同。下面介l这两种Ҏ(gu)Q?br /> 1Q禁止激zdQ?Tomcat 4
Tomcat 4用与前面相同的方法关闭激zdservletQ即利用web.xml中的url-mapping元素q行关闭。不同之处在于Tomcat使用了放?install_dir/conf中的一个服务器专用的全局web.xml文gQ而前面用的是存攑֜每个Web应用的WEB-INF目录中的标准 web.xml文g?br /> 因此Qؓ(f)了在Tomcat 4中关闭激zdservletQ只需在install_dir/conf/web.xml中简单地注释?servlet/* URL映射即可,如下所C:(x)
<!--
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
-->
再次提醒Q应该注意这个项是位于存攑֜install_dir/conf的Tomcat专用的web.xml文g中的Q此文g不是存放在每个Web应用的WEB-INF目录中的标准web.xml?br /> 2Q禁止激zdQTomcat3
在Apache Tomcat的版?中,通过在install_dir/conf/server.xml中注释出InvokerInterceptor全局止~省 servlet URL。例如,下面是禁止用缺省servlet URL的server.xml文g的一部分?br /> <!--
<RequsetInterceptor
className="org.apache.tomcat.request.InvokerInterceptor"
debug="0" prefix="/servlet/" />
-->

5 初始化和预装载servlet与JSP面

q里讨论控制servlet和JSP面的启动行为的Ҏ(gu)。特别是Q说明了怎样分配初始化参C?qing)怎样更改服务器生存期中装载servlet和JSP面的时刅R?br /> 5.1 分配servlet初始化参?br /> 利用init-param元素向servlet提供初始化参敎ͼinit-param元素hparam-name和param-value子元素。例如,在下面的例子中,如果initServlet servlet是利用它的注册名QInitTestQ访问的Q它?yu)能够从其方法中调用getServletConfig(). getInitParameter("param1")获得"Value 1"Q调用getServletConfig().getInitParameter("param2")获得"2"?br /> <servlet>
<servlet-name>InitTest</servlet-name>
<servlet-class>moreservlets.InitServlet</servlet-class>
<init-param>
<param-name>param1</param-name>
<param-value>value1</param-value>
</init-param>
<init-param>
<param-name>param2</param-name>
<param-value>2</param-value>
</init-param>
</servlet>
在涉?qing)初始化参数Ӟ有几炚w要注意:(x)
l q回倹{GetInitParameter的返回值L一个String。因此,在前一个例子中Q可对param2使用Integer.parseInt获得一个int?br /> l JSP中的初始化。JSP面使用jspInit而不是init。JSP面q需要用jsp-file元素代替servlet-class?br /> l ~省URL。初始化参数只在通过它们的注册名或与它们注册名相关的定制URL模式讉KServlet时可以用。因此,在这个例子中Qparam1?param2初始化参数将能够在用URL
http://host/webAppPrefix/servlet/InitTest 时可用,但在使用URL http://host/webAppPrefix/servlet/myPackage.InitServlet 时不能用?br /> 例如Q程序清?-7l出一个名为InitServlet的简单servletQ它使用initҎ(gu)讄firstName和emailAddress字段。程序清?-8l出分配名称InitTestlservlet的web.xml文g?br /> E序清单5-7 InitServlet.java
package moreservlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/** Simple servlet used to illustrate servlet
* initialization parameters.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
*
http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/

public class InitServlet extends HttpServlet {
private String firstName, emailAddress;

public void init() {
ServletConfig config = getServletConfig();
firstName = config.getInitParameter("firstName");
emailAddress = config.getInitParameter("emailAddress");
}

public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String uri = request.getRequestURI();
out.println(ServletUtilities.headWithTitle("Init Servlet") +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H2>Init Parameters:</H2>\n" +
"<UL>\n" +
"<LI>First name: " + firstName + "\n" +
"<LI>Email address: " + emailAddress + "\n" +
"</UL>\n" +
"</BODY></HTML>");
}
}


E序清单5-8 web.xmlQ说明初始化参数的摘录)(j)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"
http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<!-- ... -->
<servlet>
<servlet-name>InitTest</servlet-name>
<servlet-class>moreservlets.InitServlet</servlet-class>
<init-param>
<param-name>firstName</param-name>
<param-value>Larry</param-value>
</init-param>
<init-param>
<param-name>emailAddress</param-name>
<param-value>
Ellison@Microsoft.com</param-value>
</init-param>
</servlet>
<!-- ... -->
</web-app>

5.2 分配JSP初始化参?br /> lJSP面提供初始化参数在三个斚w不同于给servlet提供初始化参数?br /> 1Q用jsp-file而不是servlet-class。因此,W(xu)EB-INF/web.xml文g的servlet元素如下所C:(x)
<servlet>
<servlet-name>PageName</servlet-name>
<jsp-file>/RealPage.jsp</jsp-file>
<init-param>
<param-name>...</param-name>
<param-value>...</param-value>
</init-param>
...
</servlet>
2) 几乎L分配一个明的URL模式。对servletQ一般相应地使用?/font>http://host/webAppPrefix/servlet/ 开始的~省URL。只需CQ用注册名而不是原名称卛_。这对于JSP面在技术上也是合法的。例如,在上面给出的例子中,可用URL http://host/webAppPrefix/servlet/PageName 讉KRealPage.jsp的对初始化参数具有访问权的版本。但在用于JSP面Ӟ许多用户g不喜Ƣ应用常规的servlet的URL。此外,如果 JSP面位于服务器ؓ(f)其提供了目录清单的目录中Q如Q一个既没有index.html也没有index.jsp文g的目录)(j)Q则用户可能?x)连接到?JSP面Q单dQ从而意外地ȀzL初始化的面。因此,好的办法是用url-patternQ?.3节)(j)JSP面的原URL与注册的 servlet名相兌。这P客户机可使用JSP面的普通名Uͼ但仍然激zd制的版本。例如,l定来自目1的servlet定义Q可使用下面?servlet-mapping定义Q?br /> <servlet-mapping>
<servlet-name>PageName</servlet-name>
<url-pattern>/RealPage.jsp</url-pattern>
</servlet-mapping>
3QJSP用jspInit而不是init。自动从JSP面建立的servlet或许已经使用了intiҎ(gu)。因此,使用JSP声明提供一个initҎ(gu)是不合法的,必须制定jspInitҎ(gu)?br /> Z说明初始化JSP面的过E,E序清单5-9l出了一个名为InitPage.jsp的JSP面Q它包含一个jspInitҎ(gu)且放|于 deployDemo Web应用层次l构的顶层。一般,
http://host/deployDemo/InitPage.jsp 形式的URL激zL面的不h初始化参数访问权的版本,从而将对firstName和emailAddress变量昄null。但是, web.xml文gQ程序清?-10Q分配了一个注册名Q然后将该注册名与URL模式/InitPage.jsp相关联?br />
E序清单5-9 InitPage.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD><TITLE>JSP Init Test</TITLE></HEAD>
<BODY BGCOLOR="#FDF5E6">
<H2>Init Parameters:</H2>
<UL>
<LI>First name: <%= firstName %>
<LI>Email address: <%= emailAddress %>
</UL>
</BODY></HTML>
<%!
private String firstName, emailAddress;

public void jspInit() {
ServletConfig config = getServletConfig();
firstName = config.getInitParameter("firstName");
emailAddress = config.getInitParameter("emailAddress");
}
%>


E序清单5-10 web.xmlQ说明JSP面的init参数的摘录)(j)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"
http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<!-- ... -->
<servlet>
<servlet-name>InitPage</servlet-name>
<jsp-file>/InitPage.jsp</jsp-file>
<init-param>
<param-name>firstName</param-name>
<param-value>Bill</param-value>
</init-param>
<init-param>
<param-name>emailAddress</param-name>
<param-value>
gates@oracle.com</param-value>
</init-param>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name> InitPage</servlet-name>
<url-pattern>/InitPage.jsp</url-pattern>
</servlet-mapping>
<!-- ... -->
</web-app>


5.3 提供应用范围内的初始化参?br /> 一般,对单个地servlet或JSP面分配初始化参数。指定的servlet或JSP面利用ServletConfig的getInitParameterҎ(gu)dq些参数。但是,在某些情形下Q希望提供可׃Q意servlet或JSP面借助ServletContext的getInitParameterҎ(gu)d的系l范围内的初始化参数?br /> 可利用context-param元素声明q些pȝ范围内的初始化倹{context-param元素应该包含param-name、param-value以及(qing)可选的description子元素,如下所C:(x)
<context-param>
<param-name>support-email</param-name>
<param-value>
blackhole@mycompany.com</param-value>
</context-param>
可回忆一下,Z保证可移植性,web.xml内的元素必须以正的ơ序声明。但q里应该注意Qcontext-param元素必须出现L与文档有关的元素Qicon、display-name或descriptionQ之后及(qing)filter、filter-mapping、listener?servlet元素之前?br /> 5.4 在服务器启动时装载servlet
假如servlet或JSP面有一个要花很长时间执行的init QservletQ或jspInitQJSPQ方法。例如,假如init或jspInitҎ(gu)从某个数据库或ResourceBundle查找产量。这U情况下Q在W一个客hh时装载servlet的缺省行为将对第一个客h产生较长旉的gq。因此,可利用servlet的load-on- startup元素规定服务器在W一ơ启动时装蝲servlet。下面是一个例子?br /> <servlet>
<servlet-name> … </servlet-name>
<servlet-class> … </servlet-class> <!-- Or jsp-file -->
<load-on-startup/>
</servlet>
可以为此元素体提供一个整数而不是用一个空的load-on-startup。想法是服务器应该在装蝲较大数目的servlet或JSP面之前装蝲较少数目的servlet或JSP面。例如,下面的servlet(攄在Web应用的WEB-INF目录下的web.xml文g中的web-app元素内)(j)指C服务器首先装蝲和初始化SearchServletQ然后装载和初始化由位于Web应用的result目录中的index.jsp文g产生?servlet?br /> <servlet>
<servlet-name>Search</servlet-name>
<servlet-class>myPackage.SearchServlet</servlet-class> <!-- Or jsp-file -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Results</servlet-name>
<servlet-class>/results/index.jsp</servlet-class> <!-- Or jsp-file -->
<load-on-startup>2</load-on-startup>
</servlet>

6 声明qo(h)?br />
servlet版本2.3引入了过滤器的概c(din)虽然所有支持servlet API版本2.3的服务器都支持过滤器Q但Z使用与过滤器有关的元素,必须在web.xml中用版?.3的DTD?br /> qo(h)器可截取和修改进入一个servlet或JSP面的请求或从一个servlet或JSP面发出的相应。在执行一个servlet或JSP面之前Q必L行第一个相关的qo(h)器的doFilterҎ(gu)。在该过滤器对其FilterChain对象调用doFilterӞ执行链中的下一个过滤器。如果没有其他过滤器Qservlet或JSP面被执行。过滤器h对到来的ServletRequest对象的全部访问权Q因此,它们可以查看客户机名、查扑ֈ来的cookie{。ؓ(f)了访问servlet或JSP面的输出,qo(h)器可响应对象包裹在一个替w对象(stand-in objectQ中Q比方说把输出篏加到一个缓冲区。在调用FilterChain对象的doFilterҎ(gu)之后Q过滤器可检查缓冲区Q如有必要,对它进行修改,然后传送到客户机?br /> 例如Q程序清?-11帝国难以了一个简单的qo(h)器,只要讉K相关的servlet或JSP面Q它?yu)截取请求ƈ在标准输Z打印一个报告(开发过E中在桌面系l上q行Ӟ大多数服务器都可以用这个过滤器Q?br />
E序清单5-11 ReportFilter.java
package moreservlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

/** Simple filter that prints a report on the standard output
* whenever the associated servlet or JSP page is accessed.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
*
http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/

public class ReportFilter implements Filter {
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest)request;
System.out.println(req.getRemoteHost() +
" tried to access " +
req.getRequestURL() +
" on " + new Date() + ".");
chain.doFilter(request,response);
}

public void init(FilterConfig config)
throws ServletException {
}

public void destroy() {}
}

一旦徏立了一个过滤器Q可以在web.xml中利用filter元素以及(qing)filter-nameQQ意名Uͼ(j)、file-classQ完全限定的cdQ和Q可选的Qinit-params子元素声明它。请注意Q元素在web.xml的web-app元素中出现的ơ序不是L的;允许服务器(但不是必需的)(j)强制所需的次序,q且实际中有些服务器也是q样做的。但q里要注意,所有filter元素必须出现在Q意filter-mapping元素之前Q?filter-mapping元素又必d现在所有servlet或servlet-mapping元素之前?br /> 例如Q给定上q的ReportFilterc,可在web.xml中作Z面的filter声明。它把名UReporter与实际的cReportFilterQ位于moreservletsE序包中Q相兌?br /> <filter>
<filter-name>Reporter</filter-name>
<filter-class>moresevlets.ReportFilter</filter-class>
</filter>
一旦命名了一个过滤器Q可利用filter-mapping元素把它与一个或多个servlet或JSP面相关联。关于此工作有两种选择?br /> 首先Q可使用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名(此servlet名必ȝ后在相同?web.xml文g中用servlet元素声明Q关联。例如,下面的程序片断指C系l只要利用一个定制的URL讉K名ؓ(f)SomeServletName 的servlet或JSP面Q就q行名ؓ(f)Reporter的过滤器?br /> <filter-mapping>
<filter-name>Reporter</filter-name>
<servlet-name>SomeServletName</servlet-name>
</filter-mapping>
其次Q可利用filter-name和url-pattern子元素将qo(h)器与一lservlet、JSP面或静态内容相兌。例如,盔R的程序片D|C系l只要访问Web应用中的LURLQ就q行名ؓ(f)Reporter的过滤器?br /> <filter-mapping>
<filter-name>Reporter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
例如Q程序清?-12l出了将ReportFilterqo(h)器与名ؓ(f)PageName的servlet相关联的web.xml文g的一部分。名?PageName依次又与一个名为TestPage.jsp的JSP面以及(qing)以模式http: //host/webAppPrefix/UrlTest2/ 开头的URL相关联。TestPage.jsp的源代码已经JSP面命名的谈论在前面??分配名称和定制的URL"中给出。事实上Q程序清?- 12中的servlet和servlet-name从该节原封不动地拿q来的。给定这些web.xml,可看C面的标准输出形式的调试报告(换行是ؓ(f)了容易阅读)(j)?br /> audit.irs.gov tried to access
http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html
on Tue Dec 25 13:12:29 EDT 2001.

E序清单5-12 Web.xmlQ说明filter用法的摘录)(j)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"
http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<filter>
<filter-name>Reporter</filter-name>
<filter-class>moresevlets.ReportFilter</filter-class>
</filter>
<!-- ... -->
<filter-mapping>
<filter-name>Reporter</filter-name>
<servlet-name>PageName</servlet-name>
</filter-mapping>
<!-- ... -->
<servlet>
<servlet-name>PageName</servlet-name>
<jsp-file>/RealPage.jsp</jsp-file>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name> PageName </servlet-name>
<url-pattern>/UrlTest2/*</url-pattern>
</servlet-mapping>
<!-- ... -->
</web-app>


7 指定Ƣ迎?br />
假如用户提供了一个像http: //host/webAppPrefix/directoryName/ q样的包含一个目录名但没有包含文件名的URLQ会(x)发生什么事情呢Q用戯得到一个目录表Q一个错误?q是标准文g的内容?如果得到标准文g内容Q是 index.html、index.jsp、default.html、default.htm或别的什么东西呢Q?br /> Welcome-file-list 元素?qing)其辅助的welcome-file元素解决了这个模p的问题。例如,下面的web.xmlҎ(gu)出,如果一个URLl出一个目录名但未l出文g名,服务器应该首先试用index.jspQ然后再试用index.html。如果两者都没有扑ֈQ则l果有赖于所用的服务器(如一个目录列表)(j)?br /> <welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
虽然许多服务器缺省遵循这U行为,但不一定必这栗因此,明确C用welcom-file-list保证可移植性是一U良好的?fn)惯?br />
8 指定处理错误的页?br />
现在我了解到Q你在开发servlet和JSP面时从不会(x)犯错误,而且你的所有页面是那样的清晎ͼ一般的E序员都不会(x)被它们的搞糊涂。但是,是hM(x)犯错误的Q用户可能会(x)提供不合规定的参敎ͼ使用不正的URL或者不能提供必需的表单字D倹{除此之外,其它开发h员可能不那么l心Q他们应该有些工h克服自己的不?br /> error-page元素是用来克服q些问题的。它有两个可能的子元素,分别是:(x)error-code和exception- type。第一个子元素error-code指出在给定的HTTP错误代码出现时用的URL。第二个子元素excpetion-type指出在出现某个给定的Java异常但未捕捉到时使用的URL。error-code和exception-type都利用location元素指出相应的URL。此 URL必须?开始。location所指出的位|处的页面可通过查找HttpServletRequest对象的两个专门的属性来讉K关于错误的信息,q两个属性分别是Qjavax.servlet.error.status_code和javax.servlet.error.message?br /> 可回忆一下,在web.xml内以正确的次序声明web-app的子元素很重要。这里只要记住,error-page出现在web.xml文g的末Nq,servlet、servlet-name和welcome-file-list之后卛_?br />
8.1 error-code元素
Z更好C解error-code元素的|可考虑一下如果不正确地输入文件名Q大多数站点?x)作Z么反映。这样做一般会(x)出现一?04错误信息Q它表示不能扑ֈ该文Ӟ但几乎没提供更多有用的信息。另一斚wQ可以试一下在
www.microsoft.com?/font>www.ibm.com 处或者特别是?/font>www.bea.com 处输出未知的文g名。这是会(x)得出有用的消息,q些消息提供可选择的位|,以便查找感兴的面。提供这h用的错误面对于Web应用来说是很有h(hun)值得。事实上rm-error-page子元素)(j)。由form-login-pagel出的HTML表单必须h一个j_security_check?ACTION属性、一个名为j_username的用户名文本字段以及(qing)一个名为j_password的口令字Dc(din)?br /> 例如Q程序清?-19指示服务器用基于表单的验证。Web应用的顶层目录中的一个名为login.jsp的页面将攉用户名和口o(h)Qƈ且失败的登陆由相同目录中名为login-error.jsp的页面报告?br />
E序清单5-19 web.xmlQ说明login-config的摘录)(j)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"
http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<!-- ... -->
<security-constraint> ... </security-constraint>
<login-config>
<auth-method> FORM </auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login-error.jsp</form-error-page>
</form-login-config>
</login-config>
<!-- ... -->
</web-app>


9.2 限制对Web资源的访?br /> 现在Q可以指C服务器使用何种验证Ҏ(gu)了?了不P"你说道,"除非我能指定一个来收到保护?URLQ否则没有多大用处?没错。指些URLq说明他们应该得CU保护正是security-constriaint元素的用途。此元素?web.xml中应该出现在login-config的紧前面。它包含是个可能的子元素Q分别是Qweb-resource-collection?auth-constraint、user-data-constraint和display-name。下面各节对它们进行介l?br /> l web-resource-collection
此元素确定应该保护的资源。所有security-constraint元素都必d含至一个web-resource-collectionV此元素׃个给ZQ意标识名U的web-resource-name元素、一个确定应该保护的URL的url-pattern元素、一个指出此保护所适用?HTTP命o(h)QGET、POST{,~省为所有方法)(j)的http-method元素和一个提供资料的可选description元素l成。例如,下面?Web-resource-collection(在security-constratint元素内)(j)指出Web应用的proprietary目录中所有文档应该受C护?br /> <security-constraint>
<web-resource-coolection>
<web-resource-name>Proprietary</web-resource-name>
<url-pattern>/propritary/*</url-pattern>
</web-resource-coolection>
<!-- ... -->
</security-constraint>
重要的是应该注意刎ͼurl-pattern仅适用于直接访问这些资源的客户机。特别是Q它不适合于通过MVC体系l构利用 RequestDispatcher来访问的面Q或者不适合于利用类似jsp:forward的手D|讉K的页面。这U不匀U如果利用得当的话很有好处。例如,servlet可利用MVC体系l构查找数据Q把它放到bean中,发送请求到从bean中提取数据的JSP面q显C它。我们希望保证决不直接访问受保护的JSP面Q而只是通过建立该页面将使用的bean的servlet来访问它。url-pattern和auth-contraint元素可通过声明不允怓Q何用L(fng)接访问JSP面来提供这U保证。但是,q种不匀U的行ؓ(f)可能让开发h员放松警惕,使他们偶然对应受保护的资源提供不受限制的讉K?
l auth-constraint
管web-resource-collention元素质出了哪些URL应该受到保护Q但是auth-constraint元素却指出哪些用户应该具有受保护资源的访问权。此元素应该包含一个或多个标识h讉K权限的用L(fng)别role- name元素Q以?qing)包含(可选)(j)一个描q角色的description元素。例如,下面web.xml中的security-constraint元素部门规定只有指定为Administrator或Big KahunaQ或两者)(j)的用户具有指定资源的讉K权?br /> <security-constraint>
<web-resource-coolection> ... </web-resource-coolection>
<auth-constraint>
<role-name>administrator</role-name>
<role-name>kahuna</role-name>
</auth-constraint>
</security-constraint>
重要的是认识刎ͼ到此为止Q这个过E的可移植部分结束了。服务器怎样定哪些用户处于M角色以及(qing)它怎样存放用户的口令,完全有赖于具体的pȝ?br /> 例如QTomcat使用install_dir/conf/tomcat-users.xml用户名与角色名和口令相兌Q正如下面例子中所C,它指出用户joeQ口令bigshotQ和janeQ口令enajQ属于administrator和kahuna角色?br /> <tomcat-users>
<user name="joe" password="bigshot" roles="administrator,kahuna" />
<user name="jane" password="enaj" roles="kahuna" />
</tomcat-users>
l user-data-constraint
q个可选的元素指出在访问相兌源时使用M传输层保护。它必须包含一个transport-guarantee子元素(合法gؓ(f)NONE?INTEGRAL或CONFIDENTIALQ,q且可选地包含一个description元素。transport-guarantee为NONE值将Ҏ(gu)用的通讯协议不加限制。INTEGRALDC数据必M一U防止截取它的h阅读它的方式传送。虽然原理上Qƈ且在未来的HTTP版本中)(j)Q在 INTEGRAL和CONFIDENTIAL之间可能?x)有差别Q但在当前实践中Q他们都只是单地要求用SSL。例如,下面指示服务器只允许对相兌源做 HTTPSq接Q?br /> <security-constraint>
<!-- ... -->
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
l display-name
security-constraint的这个很用的子元素给予可能由GUI工具使用的安全约束项一个名U?br /> 9.3 分配角色?br /> q今为止Q讨论已l集中到完全由容器(服务器)(j)处理的安全问题之上了。但servlet以及(qing)JSP面也能够处理它们自q安全问题?br /> 例如Q容器可能允许用户从bigwig或bigcheese角色讉K一个显CZh员额外紧贴的面Q但只允许bigwig用户修改此页面的参数。完成这U更l致的控制的一U常见方法是调用HttpServletRequset的isUserInRoleҎ(gu)Qƈ据此修改讉K?br /> Servlet?security-role-ref子元素提供出现在服务器专用口令文件中的安全角色名的一个别名。例如,假如~写了一个调?request.isUserInRoleQ?boss"Q的servletQ但后来该servlet被用在了一个其口o(h)文g调用角色manager而不是boss的服务器中。下面的E序D该servlet能够使用q两个名UC的Q何一个?br /> <servlet>
<!-- ... -->
<security-role-ref>
<role-name>boss</role-name> <!-- New alias -->
<role-link>manager</role-link> <!-- Real name -->
</security-role-ref>
</servlet>
也可以在web-app内利用security-role元素提供出现在role-name元素中的所有安全角色的一个全局列表。分别地生命角色佉KUIDEҎ(gu)处理安全信息?br />
10 控制?x)话?br />
如果某个?x)话在一定的旉内未被访问,服务器可把它扔掉以节U内存。可利用HttpSession的setMaxInactiveIntervalҎ(gu)直接讄个别?x)话对象的超时倹{如果不采用q种Ҏ(gu)Q则~省的超时值由具体的服务器军_。但可利用session-config和session- timeout元素来给Z个适用于所有服务器的明的时倹{超时值的单位为分钟,因此Q下面的例子讄~省?x)话时gؓ(f)三个时Q?80分钟Q?br /> <session-config>
<session-timeout>180</session-timeout>
</session-config>

11 Web应用的文档化

来多的开发环境开始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun StudioQ写此文Ӟ已被Macromedia收购Q以?qing)IBM VisuaAge for Java{?br /> 大量的web.xml元素不仅是ؓ(f)服务器设计的Q而且q是为可视开发环境设计的。它们包括icon、display-name和discription{?br /> 可回忆一下,在web.xml内以适当地次序声明web-app子元素很重要。不q,q里只要Cicon、display-name和description是web.xml的web-app元素内的前三个合法元素即可?br /> l icon
icon元素指出GUI工具可用来代表Web应用的一个和两个囑փ文g。可利用small-icon元素指定一q?6 x 16的GIF或JPEG囑փQ用large-icon元素指定一q?2 x 32的图像。下面D一个例子:(x)
<icon>
<small-icon>/images/small-book.gif</small-icon>
<large-icon>/images/tome.jpg</large-icon>
</icon>
l display-name
display-name元素提供GUI工具可能?x)用来标记此Web应用的一个名U。下面是个例子?br /> <display-name>Rare Books</display-name>
l description
description元素提供解释性文本,如下所C:(x)
<description>
This Web application represents the store developed for
rare-books.com, an online bookstore specializing in rare
and limited-edition books.
</description>

12 兌文g与MIMEcd

服务器一般都h一U让Web站点理员将文g扩展名与媒体相关联的Ҏ(gu)。例如,会(x)自动l予名ؓ(f)mom.jpg的文件一个image/jpeg的MIME cd。但是,假如你的Web应用h几个不寻常的文gQ你希望保证它们在发送到客户机时分配为某UMIMEcd。mime-mapping元素Q具?extension和mime-type子元素)(j)可提供这U保证。例如,下面的代码指C服务器application/x-fubar的MIMEcd分配l所有以.fool尾的文件?br /> <mime-mapping>
<extension>foo</extension>
<mime-type>application/x-fubar</mime-type>
</mime-mapping>
或许Q你的Web应用希望重蝲QoverrideQ标准的映射。例如,下面的代码将告诉服务器在发送到客户机时指定.ps文g作ؓ(f)U文本(text/plainQ而不是作为PostScriptQapplication/postscriptQ?br /> <mime-mapping>
<extension>ps</extension>
<mime-type>application/postscript</mime-type>
</mime-mapping>


13 定位TLD

JSP taglib元素h一个必要的uri属性,它给Z个TLDQTag Library DescriptorQ文件相对于Web应用的根的位|。TLD文g的实际名U在发布新的标签库版本时可能?x)改变,但我们希望避免更?gu)有现有JSP面。此外,可能q希望用保持taglib元素的简l性的一个简短的uri。这是部v描述W文件的taglib元素z场的所在了。Taglib包含两个子元素:(x)taglib-uri和taglib-location。taglib-uri元素应该与用于JSP taglib元素的uri属性的东西相匹配。Taglib-location元素l出TLD文g的实际位|。例如,假如你将文gchart-tags- 1.3beta.tld攑֜WebApp/WEB-INF/tlds中。现在,假如web.xml在web-app元素内包含下列内宏V?br /> <taglib>
<taglib-uri>/charts.tld</taglib-uri>
<taglib-location>
/WEB-INF/tlds/chart-tags-1.3beta.tld
</taglib-location>
</taglib>
l出q个说明后,JSP面可通过下面的简化Ş式用标{ֺ?br /> <%@ taglib uri="/charts.tld" prefix="somePrefix" %>

14 指定应用事g监听E序

应用事g监听器程序是建立或修改servlet环境或会(x)话对象时通知的类。它们是servlet规范的版?.3中的新内宏V这里只单地说明用来向Web应用注册一个监听程序的web.xml的用法?br /> 注册一个监听程序涉?qing)在web.xml的web-app元素内放|一个listener元素。在listener元素内,listener-class元素列出监听E序的完整的限定cdQ如下所C:(x)
<listener>
<listener-class>package.ListenerClass</listener-class>
</listener>
虽然listener元素的结构很单,但请不要忘记Q必L地l出web-app元素内的子元素的ơ序。listener元素位于所有的servlet 元素之前以及(qing)所有filter-mapping元素之后。此外,因ؓ(f)应用生存期监听程序是serlvet规范?.3版本中的新内容,所以必M?web.xml DTD?.3版本Q而不?.2版本?br /> 例如Q程序清?-20l出一个名为ContextReporter的简单的监听E序Q只要Web应用的Servlet-Context建立Q如装蝲Web应用Q或消除Q如服务器关闭)(j)Ӟ它就在标准输Z昄一条消息。程序清?-21l出此监听程序注册所需要的web.xml文g的一部分?br />
E序清单5-20 ContextReporterjava
package moreservlets;

import javax.servlet.*;
import java.util.*;

/** Simple listener that prints a report on the standard output
* when the ServletContext is created or destroyed.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
*
http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/

public class ContextReporter implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
System.out.println("Context created on " +
new Date() + ".");
}

public void contextDestroyed(ServletContextEvent event) {
System.out.println("Context destroyed on " +
new Date() + ".");
}
}


E序清单5-21 web.xmlQ声明一个监听程序的摘录Q?br /> <?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"
http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<!-- ... -->
<filter-mapping> … </filter-mapping>
<listener>
<listener-class>package.ListenerClass</listener-class>
</listener>
<servlet> ... </servlet>
<!-- ... -->
</web-app>


15 J2EE元素

本节描述用作J2EE环境l成部分的Web应用的web.xml元素。这里将提供一个简明的介绍Q详l内容可以参?/font>http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf的Java 2 Plantform Enterprise Edition版本1.3规范的第5章?br /> l distributable
distributable 元素指出QW(xu)eb应用是以q样的方式编E的Q即Q支持集的服务器可安全地在多个服务器上分布Web应用。例如,一个可分布的应用必d使用 Serializable对象作ؓ(f)其HttpSession对象的属性,而且必须避免用实例变量(字段Q来实现持箋性。distributable元素直接出现在discription元素之后Qƈ且不包含子元素或数据Q它只是一个如下的标志?br /> <distributable />
l resource-env-ref
resource -env-ref元素声明一个与某个资源有关的管理对象。此元素׃个可选的description元素、一个resource-env-ref- name元素Q一个相对于java:comp/env环境的JNDI名)(j)以及(qing)一个resource-env-type元素Q指定资源类型的完全限定的类Q,如下所C:(x)
<resource-env-ref>
<resource-env-ref-name>
jms/StockQueue
</resource-env-ref-name>
<resource-env-ref-type>
javax.jms.Queue
</resource-env-ref-type>
</resource-env-ref>
l env-entry
env -entry元素声明Web应用的环境项。它׃个可选的description元素、一个env-entry-name元素Q一个相对于java: comp/env环境JNDI名)(j)、一个env-entry-value元素Q项|(j)以及(qing)一个env-entry-type元素Qjava.langE序包中一个类型的完全限定cdQjava.lang.Boolean、java.lang.String{)(j)l成。下面是一个例子:(x)
<env-entry>
<env-entry-name>minAmout</env-entry-name>
<env-entry-value>100.00</env-entry-value>
<env-entry-type>minAmout</env-entry-type>
</env-entry>
l ejb-ref
ejb -ref元素声明对一个EJB的主目录的应用。它׃个可选的description元素、一个ejb-ref-name元素Q相对于java: comp/env的EJB应用Q、一个ejb-ref-type元素Qbean的类型,Entity或SessionQ、一个home元素Qbean的主目录接口的完全限定名Q、一个remote元素Qbean的远E接口的完全限定名)(j)以及(qing)一个可选的ejb-link元素Q当前bean链接的另一?bean的名Uͼ(j)l成?br /> l ejb-local-ref
ejb-local-ref元素声明一个EJB的本C目录的引用。除了用local-home代替home外,此元素具有与ejb-ref元素相同的属性ƈ以相同的方式使用?/font>

Endless 2007-09-17 13:01 发表评论
]]>
【{】JSP三种面跌{方式 http://m.tkk7.com/freiberg/archive/2007/09/17/145812.htmlEndlessEndlessMon, 17 Sep 2007 04:54:00 GMThttp://m.tkk7.com/freiberg/archive/2007/09/17/145812.htmlhttp://m.tkk7.com/freiberg/comments/145812.htmlhttp://m.tkk7.com/freiberg/archive/2007/09/17/145812.html#Feedback1http://m.tkk7.com/freiberg/comments/commentRss/145812.htmlhttp://m.tkk7.com/freiberg/services/trackbacks/145812.html使用JSP大约有下列三U蟩转方式:(x)
1. response.sendRedirect();
2. response.setHeader("Location","");
3. <jsp:forward page="" />

l过试验得到下面的一些规则:(x)

一. response.sendRedirect()

  1. 此语句前不允许有out.flush()Q如果有Q会(x)有异常:(x)
    java.lang.IllegalStateException: Can't sendRedirect() after data has committed to the client.
     at com.caucho.server.connection.AbstractHttpResponse.sendRedirect(AbstractHttpResponse.java:558)
    ...
  2. 跌{后浏览器地址栏变?
  3. 如果要蟩C同主ZQ蟩转后Q此语句后面的语句会(x)l箋执行Q如同新开了线E,但是对response的操作已l无意义了;
  4. 如果要蟩到相同主ZQ此语句后面的语句执行完成后才会(x)跌{Q?

? response.setHeader("Location","")

  1. 此语句前不允许有out.flush()Q如果有Q页面不?x)蟩转?
  2. 跌{后浏览器地址栏变?
  3. 此语句后面的语句执行完成后才?x)蟩?

? <jsp:forward page="" />

  1. 此语句前不允许有out.flush()Q如果有Q会(x)有异常:(x)
    java.lang.IllegalStateException: forward() not allowed after buffer has committed.
     at com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:134)
     at com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:101)
     at com.caucho.jsp.PageContextImpl.forward(PageContextImpl.java:836)
     ...
  2. 跌{后浏览器地址栏不变,但是只能跛_当前L?
  3. 此语句后面的语句执行完成后才?x)蟩?nbsp;
  4. 跌{后得路径变ؓ(f)当前路径Q图片不是绝对\径将无法昄

JSP跌{面详解
在JSP中用jsp forward Action来实现页面的跌{功能?/h4>
   语法Q?/div>
<jsp:forward page="{relativeURL|<%= expression %>}"/> ?br /> <jsp:forward page="{relativeURL|<%= expression %>}">
<jsp:param name="parameterName"
value="{parameterValue|<%= expression %>}"/>+</jsp:forward>
  q个action使?zhn)可以request向前到另外一个页面。它只有一个属性,page。Page应有一个相对的URLl成。这可以是一个静态的值或者是能够在被h的时候计得到的|如下面两个例子一般:(x)
<jsp:forward page="/utils/errorReporter.jsp"/>
<jsp:forward page="<%= someJavaExpression %>"/>
!supportEmptyParas]>
  现在以一个具体例子来说明Q在test1.jsp中用forward使其跌{到test2.jsp面中?/div>
Test1.jsp
<HTML>
<HEAD>
<TITLE>forward test</TITLE>
!supportEmptyParas]>
</HEAD>
!supportEmptyParas]>
<BODY BGCOLOR="#FFFFFF">
<!--跌{到test2.jsp--!>
<jsp:forward page="/test2.jsp"/>
</BODY>
</HTML>
!supportEmptyParas]>
test2.jsp
<HTML>
<HEAD>
<TITLE> forward test </TITLE>
!supportEmptyParas]>
</HEAD>
!supportEmptyParas]>
<BODY BGCOLOR="#FFFFFF">
<%out.println("q是jsp2.jsp面产生出的输出");%>
</BODY>
</HTML>
!supportEmptyParas]>
  q行test1.jspQ可在浏览器中看见:(x)"q是jsp2.jsp面产生出的输出"的输Z息。但是如果你在test1.jsp和test2.jspq两个页面中有参C递怎么办呢Q用get方式吧,不但ȝ长度有限Ӟ使用现在十分不方便,而且有时候还不安全。其实我们完全可以用jsp1.1中给forward里提供的para属性就可以解决。现以test3.jsp和test4.jsp来说明?/div>
!supportEmptyParas]>
Test1.jsp
<HTML>
<HEAD>
<TITLE> forward test </TITLE>
!supportEmptyParas]>
</HEAD>
!supportEmptyParas]>
<BODY BGCOLOR="#FFFFFF">
<jsp:forward page="/test4.jsp">
<jsp:param name="name" value="powerman"/>
<jsp:param name="address" value=" 北京西大?88?/>
</jsp:forward>
</BODY>
</HTML>
!supportEmptyParas]>
test2.jsp
<HTML>
<HEAD>
<TITLE>forward test</TITLE>
!supportEmptyParas]>
</HEAD>
!supportEmptyParas]>
<BODY BGCOLOR="#FFFFFF">
<%
out.println("q是jsp4.jsp面产生出的输出"+"<br>");
out.println("姓名Q?+request.getParameter("name")+"<br>");
out.println("地址Q?+request.getParameter("address")+"<br>");
!supportEmptyParas]>
%>
</BODY>
</HTML>
   q行test3.jspQ可在浏览器中看见:(x)
   "q是jsp4.jsp面产生出的输出
   姓名Qpowerman
   地址Q北京西大街188?
的输Z?br />


Endless 2007-09-17 12:54 发表评论
]]>【{】java中文件操作大?/title><link>http://m.tkk7.com/freiberg/archive/2007/09/17/145811.html</link><dc:creator>Endless</dc:creator><author>Endless</author><pubDate>Mon, 17 Sep 2007 04:53:00 GMT</pubDate><guid>http://m.tkk7.com/freiberg/archive/2007/09/17/145811.html</guid><wfw:comment>http://m.tkk7.com/freiberg/comments/145811.html</wfw:comment><comments>http://m.tkk7.com/freiberg/archive/2007/09/17/145811.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/freiberg/comments/commentRss/145811.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/freiberg/services/trackbacks/145811.html</trackback:ping><description><![CDATA[     摘要: 一.获得控制台用戯入的信息 /** *//**获得控制台用戯入的信息      * @return      * @throws IOException      */   ...  <a href='http://m.tkk7.com/freiberg/archive/2007/09/17/145811.html'>阅读全文</a><img src ="http://m.tkk7.com/freiberg/aggbug/145811.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/freiberg/" target="_blank">Endless</a> 2007-09-17 12:53 <a href="http://m.tkk7.com/freiberg/archive/2007/09/17/145811.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不用imagemagicQ生成高质量~略囄法http://m.tkk7.com/freiberg/archive/2007/09/17/145810.htmlEndlessEndlessMon, 17 Sep 2007 04:53:00 GMThttp://m.tkk7.com/freiberg/archive/2007/09/17/145810.htmlhttp://m.tkk7.com/freiberg/comments/145810.htmlhttp://m.tkk7.com/freiberg/archive/2007/09/17/145810.html#Feedback0http://m.tkk7.com/freiberg/comments/commentRss/145810.htmlhttp://m.tkk7.com/freiberg/services/trackbacks/145810.html    
  import   java.awt.image.BufferedImage;  
   
  public   class   ImageScale   {  
  private   int   width;  
  private   int   height;  
  private   int   scaleWidth;  
  double   support   =   (double)   3.0;  
  double   PI   =   (double)   3.14159265358978;  
  double[]   contrib;  
  double[]   normContrib;  
  double[]   tmpContrib;  
  int   startContrib,   stopContrib;  
  int   nDots;  
  int   nHalfDots;  
   
  /**  
    *   Start:  
    *   Use   Lanczos   filter   to   replace   the   original   algorithm   for   image   scaling.   Lanczos   improves   quality   of   the   scaled   image  
    *   modify   by   :blade  
    *   */  
  public   BufferedImage   imageZoomOut(BufferedImage   srcBufferImage,int   w,   int   h)   {  
  width   =   srcBufferImage.getWidth();  
  height   =   srcBufferImage.getHeight();  
  scaleWidth   =   w;  
   
  if   (DetermineResultSize(w,   h)   ==   1)   {  
  return   srcBufferImage;  
  }  
  CalContrib();  
  BufferedImage   pbOut   =   HorizontalFiltering(srcBufferImage,   w);  
  BufferedImage   pbFinalOut   =   VerticalFiltering(pbOut,   h);  
  return   pbFinalOut;  
  }  
   
  /**  
    *   军_囑փ寸  
    *   */  
  private   int   DetermineResultSize(int   w,   int   h)   {  
  double   scaleH,   scaleV;  
  scaleH   =   (double)   w   /   (double)   width;  
  scaleV   =   (double)   h   /   (double)   height;  
  //需要判断一下scaleHQscaleVQ不做放大操? 
  if   (scaleH   >=   1.0   &&   scaleV   >=   1.0)   {  
  return   1;  
  }  
  return   0;  
   
  }   //   end   of   DetermineResultSize()  
   
  private   double   Lanczos(int   i,   int   inWidth,   int   outWidth,   double   Support)   {  
  double   x;  
   
  x   =   (double)   i   *   (double)   outWidth   /   (double)   inWidth;  
   
  return   Math.sin(x   *   PI)   /   (x   *   PI)   *   Math.sin(x   *   PI   /   Support)  
  /   (x   *   PI   /   Support);  
   
  }   //   end   of   Lanczos()  
   
  //  
  //       Assumption:   same   horizontal   and   vertical   scaling   factor  
  //  
  private   void   CalContrib()   {  
  nHalfDots   =   (int)   ((double)   width   *   support   /   (double)   scaleWidth);  
  nDots   =   nHalfDots   *   2   +   1;  
  try   {  
  contrib   =   new   double[nDots];  
  normContrib   =   new   double[nDots];  
  tmpContrib   =   new   double[nDots];  
  }   catch   (Exception   e)   {  
  System.out.println("init   contrib,normContrib,tmpContrib"   +   e);  
  }  
   
  int   center   =   nHalfDots;  
  contrib[center]   =   1.0;  
   
  double   weight   =   0.0;  
  int   i   =   0;  
  for   (i   =   1;   i   <=   center;   i++)   {  
  contrib[center   +   i]   =   Lanczos(i,   width,   scaleWidth,   support);  
  weight   +=   contrib[center   +   i];  
  }  
   
  for   (i   =   center   -   1;   i   >=   0;   i--)   {  
  contrib[i]   =   contrib[center   *   2   -   i];  
  }  
   
  weight   =   weight   *   2   +   1.0;  
   
  for   (i   =   0;   i   <=   center;   i++)   {  
  normContrib[i]   =   contrib[i]   /   weight;  
  }  
   
  for   (i   =   center   +   1;   i   <   nDots;   i++)   {  
  normContrib[i]   =   normContrib[center   *   2   -   i];  
  }  
  }   //   end   of   CalContrib()  
   
  //处理边缘  
  private   void   CalTempContrib(int   start,   int   stop)   {  
  double   weight   =   0;  
   
  int   i   =   0;  
  for   (i   =   start;   i   <=   stop;   i++)   {  
  weight   +=   contrib[i];  
  }  
   
  for   (i   =   start;   i   <=   stop;   i++)   {  
  tmpContrib[i]   =   contrib[i]   /   weight;  
  }  
   
  }   //   end   of   CalTempContrib()  
   
  private   int   GetRedValue(int   rgbValue)   {  
  int   temp   =   rgbValue   &   0x00ff0000;  
  return   temp   >>   16;  
  }  
   
  private   int   GetGreenValue(int   rgbValue)   {  
  int   temp   =   rgbValue   &   0x0000ff00;  
  return   temp   >>   8;  
  }  
   
  private   int   GetBlueValue(int   rgbValue)   {  
  return   rgbValue   &   0x000000ff;  
  }  
   
  private   int   ComRGB(int   redValue,   int   greenValue,   int   blueValue)   {  
   
  return   (redValue   <<   16)   +   (greenValue   <<   8)   +   blueValue;  
  }  
   
  //行水qxo(h)? 
  private   int   HorizontalFilter(BufferedImage   bufImg,   int   startX,   int   stopX,  
  int   start,   int   stop,   int   y,   double[]   pContrib)   {  
  double   valueRed   =   0.0;  
  double   valueGreen   =   0.0;  
  double   valueBlue   =   0.0;  
  int   valueRGB   =   0;  
  int   i,   j;  
   
  for   (i   =   startX,   j   =   start;   i   <=   stopX;   i++,   j++)   {  
  valueRGB   =   bufImg.getRGB(i,   y);  
   
  valueRed   +=   GetRedValue(valueRGB)   *   pContrib[j];  
  valueGreen   +=   GetGreenValue(valueRGB)   *   pContrib[j];  
  valueBlue   +=   GetBlueValue(valueRGB)   *   pContrib[j];  
  }  
   
  valueRGB   =   ComRGB(Clip((int)   valueRed),   Clip((int)   valueGreen),  
  Clip((int)   valueBlue));  
  return   valueRGB;  
   
  }   //   end   of   HorizontalFilter()  
   
  //囄水^滤L  
  private   BufferedImage   HorizontalFiltering(BufferedImage   bufImage,   int   iOutW)   {  
  int   dwInW   =   bufImage.getWidth();  
  int   dwInH   =   bufImage.getHeight();  
  int   value   =   0;  
  BufferedImage   pbOut   =   new   BufferedImage(iOutW,   dwInH,  
  BufferedImage.TYPE_INT_RGB);  
   
  for   (int   x   =   0;   x   <   iOutW;   x++)   {  
   
  int   startX;  
  int   start;  
  int   X   =   (int)   (((double)   x)   *   ((double)   dwInW)   /   ((double)   iOutW)   +   0.5);  
  int   y   =   0;  
   
  startX   =   X   -   nHalfDots;  
  if   (startX   <   0)   {  
  startX   =   0;  
  start   =   nHalfDots   -   X;  
  }   else   {  
  start   =   0;  
  }  
   
  int   stop;  
  int   stopX   =   X   +   nHalfDots;  
  if   (stopX   >   (dwInW   -   1))   {  
  stopX   =   dwInW   -   1;  
  stop   =   nHalfDots   +   (dwInW   -   1   -   X);  
  }   else   {  
  stop   =   nHalfDots   *   2;  
  }  
   
  if   (start   >   0   ||   stop   <   nDots   -   1)   {  
  CalTempContrib(start,   stop);  
  for   (y   =   0;   y   <   dwInH;   y++)   {  
  value   =   HorizontalFilter(bufImage,   startX,   stopX,   start,  
  stop,   y,   tmpContrib);  
  pbOut.setRGB(x,   y,   value);  
  }  
  }   else   {  
  for   (y   =   0;   y   <   dwInH;   y++)   {  
  value   =   HorizontalFilter(bufImage,   startX,   stopX,   start,  
  stop,   y,   normContrib);  
  pbOut.setRGB(x,   y,   value);  
  }  
  }  
  }  
   
  return   pbOut;  
   
  }   //   end   of   HorizontalFiltering()  
   
  private   int   VerticalFilter(BufferedImage   pbInImage,   int   startY,   int   stopY,  
  int   start,   int   stop,   int   x,   double[]   pContrib)   {  
  double   valueRed   =   0.0;  
  double   valueGreen   =   0.0;  
  double   valueBlue   =   0.0;  
  int   valueRGB   =   0;  
  int   i,   j;  
   
  for   (i   =   startY,   j   =   start;   i   <=   stopY;   i++,   j++)   {  
  valueRGB   =   pbInImage.getRGB(x,   i);  
   
  valueRed   +=   GetRedValue(valueRGB)   *   pContrib[j];  
  valueGreen   +=   GetGreenValue(valueRGB)   *   pContrib[j];  
  valueBlue   +=   GetBlueValue(valueRGB)   *   pContrib[j];  
  //     System.out.println(valueRed+"->"+Clip((int)valueRed)+"<-");  
  //  
  //     System.out.println(valueGreen+"->"+Clip((int)valueGreen)+"<-");  
  //     System.out.println(valueBlue+"->"+Clip((int)valueBlue)+"<-"+"-->");  
  }  
   
  valueRGB   =   ComRGB(Clip((int)   valueRed),   Clip((int)   valueGreen),  
  Clip((int)   valueBlue));  
  //       System.out.println(valueRGB);  
  return   valueRGB;  
   
  }   //   end   of   VerticalFilter()  
   
  private   BufferedImage   VerticalFiltering(BufferedImage   pbImage,   int   iOutH)   {  
  int   iW   =   pbImage.getWidth();  
  int   iH   =   pbImage.getHeight();  
  int   value   =   0;  
  BufferedImage   pbOut   =   new   BufferedImage(iW,   iOutH,  
  BufferedImage.TYPE_INT_RGB);  
   
  for   (int   y   =   0;   y   <   iOutH;   y++)   {  
   
  int   startY;  
  int   start;  
  int   Y   =   (int)   (((double)   y)   *   ((double)   iH)   /   ((double)   iOutH)   +   0.5);  
   
  startY   =   Y   -   nHalfDots;  
  if   (startY   <   0)   {  
  startY   =   0;  
  start   =   nHalfDots   -   Y;  
  }   else   {  
  start   =   0;  
  }  
   
  int   stop;  
  int   stopY   =   Y   +   nHalfDots;  
  if   (stopY   >   (int)   (iH   -   1))   {  
  stopY   =   iH   -   1;  
  stop   =   nHalfDots   +   (iH   -   1   -   Y);  
  }   else   {  
  stop   =   nHalfDots   *   2;  
  }  
   
  if   (start   >   0   ||   stop   <   nDots   -   1)   {  
  CalTempContrib(start,   stop);  
  for   (int   x   =   0;   x   <   iW;   x++)   {  
  value   =   VerticalFilter(pbImage,   startY,   stopY,   start,   stop,  
  x,   tmpContrib);  
  pbOut.setRGB(x,   y,   value);  
  }  
  }   else   {  
  for   (int   x   =   0;   x   <   iW;   x++)   {  
  value   =   VerticalFilter(pbImage,   startY,   stopY,   start,   stop,  
  x,   normContrib);  
  pbOut.setRGB(x,   y,   value);  
  }  
  }  
   
  }  
   
  return   pbOut;  
   
  }   //   end   of   VerticalFiltering()  
   
  int   Clip(int   x)   {  
  if   (x   <   0)  
  return   0;  
  if   (x   >   255)  
  return   255;  
  return   x;  
  }  
   
  /**  
    *   End:  
    *   Use   Lanczos   filter   to   replace   the   original   algorithm   for   image   scaling.   Lanczos   improves   quality   of   the   scaled   image  
    *   modify   by   :blade  
    *   */  
   
   
  }  


Endless 2007-09-17 12:53 发表评论
]]>
用Url Rewrite Filter 重写urlQ不依赖与WEB服务器组?http://m.tkk7.com/freiberg/archive/2007/09/17/145809.htmlEndlessEndlessMon, 17 Sep 2007 04:52:00 GMThttp://m.tkk7.com/freiberg/archive/2007/09/17/145809.htmlhttp://m.tkk7.com/freiberg/comments/145809.htmlhttp://m.tkk7.com/freiberg/archive/2007/09/17/145809.html#Feedback0http://m.tkk7.com/freiberg/comments/commentRss/145809.htmlhttp://m.tkk7.com/freiberg/services/trackbacks/145809.html  <filter>
  <filter-name>UrlRewriteFilter</filter-name>
   <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
            <init-param>
                <param-name>logLevel</param-name>
                <param-value>WARN</param-value>
            </init-param>
 </filter>
    <filter-mapping>
  <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

然后在WEB-INF目录下新建urlrewrite.xml
在其中进行重写规则的定义Q它使用正则表达式来q行规则的定?/p>

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 2.6//EN"
        "

<!--

    Configuration file for UrlRewriteFilter
   
http://tuckey.org/urlrewrite/

-->
<urlrewrite>

        <rule>
            <from>/test.html</from>
            <to type="redirect">%{context-path}/page.html</to>
        </rule>

        <rule>
            <from>/param/(.*)</from>
            <to>/param.jsp?param=$1</to>
        </rule>

</urlrewrite>

上面是我的一个简单的试
        <rule>
            <from>/test.html</from>
            <to type="redirect">%{context-path}/page.html</to>
        </rule>
是将test.html的访问请求{发给page.html

        <rule>
            <from>/param/(.*)</from>
            <to>/param.jsp?param=$1</to>
        </rule>
param.jsp?param=111q种h重写?param/111

里面有详l的例子Q大家可以自q?

Endless 2007-09-17 12:52 发表评论
]]>
【{】ImageMagick, JMagick安装、配|及(qing)使用http://m.tkk7.com/freiberg/archive/2007/09/17/145808.htmlEndlessEndlessMon, 17 Sep 2007 04:51:00 GMThttp://m.tkk7.com/freiberg/archive/2007/09/17/145808.htmlhttp://m.tkk7.com/freiberg/comments/145808.htmlhttp://m.tkk7.com/freiberg/archive/2007/09/17/145808.html#Feedback2http://m.tkk7.com/freiberg/comments/commentRss/145808.htmlhttp://m.tkk7.com/freiberg/services/trackbacks/145808.html
ImageMagick, JMagick安装、配|及(qing)使用Q?br /> q_QwinXP
1. 安装ImageMagickQImageMagick website:http://www.imagemagick.org/script/index.phpQ?br />     下蝲q安装ImageMagick。file name: ImageMagick-6.2.6-8-Q16-windows-dll.exe
     download address: http://prdownloads.sourceforge.net/imagemagick/ImageMagick-6.2.6-8-Q16-windows-dll.exe?download
    安装成功后,把install path加入pȝpathQ以便能调用dll.如C:\Program Files\ImageMagick-6.2.6-Q16
2. 安装JMagickQJMagick website: http://www.yeo.id.au/jmagick/Q?br />     下蝲JMatick。file name: jmagick-6.2.6-win.zip
    download address: http://www.yeo.id.au/jmagick/quickload/win-6.2.6/jmagick-6.2.6-win.zip
    解压后把jmagick-6.2.6-win\jar\jmagick.jar copy到项目的WEB-INF\lib目录下,把jmagick-6.2.6-win\q16\jmagick.dll copy 到c:\windows\system32目录下?/span>
3. E序参考:(x)
   JMagickScale.java 实现囄~略?
------------------------------------------------------------------
package images;
import magick.ImageInfo;
import magick.MagickException;
import magick.MagickImage;
public class JMagickScale {
 /**
  * Description:
  * @param args
  * @throws MagickException
  */
 public static void main(String[] args) throws MagickException {
  System.setProperty("jmagick.systemclassloader","no");
 
  //reading image
  ImageInfo info = new ImageInfo("c:/image4.bmp");
  MagickImage image = new MagickImage(info);
 
  //resize image
  MagickImage scaleImg = image.scaleImage(95, 80);
 
  //write image to file
  scaleImg.setFileName("c:/MyFile4.bmp");
  scaleImg.writeImage(info);
 }
}
 JMagickTest.java 实现囄的各U操作示?如旋?加边框,讄背景Q提升质量,加盖文字说明{等...
-----------------------------------------------------------------------------------------------------------------------------
package images;
import java.awt.Dimension;
import java.awt.Rectangle;
import magick.ImageInfo;
import magick.MagickImage;
import magick.MagickException;
import magick.QuantizeInfo;
import magick.ColorspaceType;
import magick.MagickApiException;
import magick.PixelPacket;
import magick.DrawInfo;
import magick.ResolutionType;
import magick.ProfileInfo;
import magick.MontageInfo;
import magick.Magick;
import magick.MagickInfo;
import java.io.IOException;
import java.io.FileOutputStream;
/**
 * For testing JMagick functions.
 *
 * @author Eric Yeo
 */
public class JMagickTest {
    /**
     * Display the information about the profile supplied.
     *
     * @param profile
     *            the profile for which to display
     */
    private static void displayProfile(ProfileInfo profile) {
        if (profile.getName() == null) {
            System.out.println("Profile name is null");
        }
        else {
            System.out.println("Profile name is " + profile.getName());
        }
        if (profile.getInfo() == null) {
            System.out.println("No profile info");
        }
        else {
            System.out.println("Profile length is " + profile.getInfo().length);
        }
    }
    public static void main(String[] args) {
        try {
            Rectangle rect = new Rectangle(0, 0, 80, 40);
            int flags = Magick.parseImageGeometry("60x50", rect);
            System.out.println("Scaled to " + rect.width + "x" + rect.height);
            // Copy an image.
            ImageInfo info = new ImageInfo("pics.jpg");
            info.setPage("50x50+0+0");
            info.setUnits(ResolutionType.PixelsPerInchResolution);
            info.setColorspace(ColorspaceType.RGBColorspace);
            info.setBorderColor(PixelPacket.queryColorDatabase("red"));
            info.setDepth(8);
            System.out.println("Depth "+info.getDepth());
            info.setDepth(0);
            MagickImage image = new MagickImage(info);
            image.setImageAttribute("Comment", "Processed by JMagick");
            System.out.println("Quality is "+image.getQuality());
            System.out.println("Colorspace is " + image.getColorspace());
            System.out.println("Resolution units is " + image.getUnits());
            System.out.println("X resolution is " + image.getXResolution());
            System.out.println("Y resolution is " + image.getYResolution());
            System.out.println("Size blob is " + image.sizeBlob());
            System.out.println("Colors " + image.getColors());
            System.out.println("Total colors " + image.getTotalColors());
            System.out.println("Depth is "+image.getDepth());
            image.signatureImage();
            image.setFileName("copy.jpg");
            image.writeImage(info);
            // Background Color
            System.out.println("Old colour " + image.getBackgroundColor());
            image.setBackgroundColor(PixelPacket.queryColorDatabase("red"));
            System.out.println("New colour " + image.getBackgroundColor());
            // Border image
            image.setBorderColor(PixelPacket.queryColorDatabase("green"));
            MagickImage borderedImage = image.borderImage(new Rectangle(0, 0,
                    10, 20));
            borderedImage.setFileName("border.jpg");
            borderedImage.writeImage(info);
            // Raise image
            MagickImage raisedImage = new MagickImage(new ImageInfo("pics.jpg"));
            raisedImage.raiseImage(new Rectangle(0, 0, 10, 20), true);
            raisedImage.setFileName("raised.jpg");
            raisedImage.writeImage(info);
            // Profile test
            System.out.println("Number of generic profiles "
                    + image.getGenericProfileCount());
            displayProfile(image.getColorProfile());
            image.setColorProfile(new ProfileInfo());
            displayProfile(image.getColorProfile());
            image.setColorProfile(new ProfileInfo("Test", new byte[20]));
            displayProfile(image.getColorProfile());
            // Montage test
            MagickImage images[] = new MagickImage[2];
            images[0] = image;
            images[1] = image;
            MagickImage seqImage = new MagickImage(images);
            MontageInfo montageInfo = new MontageInfo(new ImageInfo());
            montageInfo.setFileName("montage.jpg");
            montageInfo.setTitle("Melbourne");
            montageInfo.setBorderWidth(5);
            MagickImage montage = seqImage.montageImages(montageInfo);
            montage.writeImage(new ImageInfo());
           
            // Converting the montage into a blob
            montage.setMagick("JPG");
            byte[] mblob = montage.imageToBlob(new ImageInfo());
            System.out.println("Length "+mblob.length);
            // Test average
            MagickImage average = seqImage.averageImages();
            average.setFileName("average.jpg");
            average.writeImage(new ImageInfo());
            // Image to blob
            info = new ImageInfo();
            byte[] blob = image.imageToBlob(info);
            // Blob to image
            info = new ImageInfo();
            MagickImage blobImage = new MagickImage(info, blob);
            Dimension imageDim = blobImage.getDimension();
            System.out.println("Blob width is " + imageDim.width);
            System.out.println("Blob heght is " + imageDim.height);
            System.out.println(imageDim);
            blobImage.setFileName("blob.jpg");
            blobImage.writeImage(info);
            // JPEG Image to GIF blob
            image.setMagick("GIF");
            blob = image.imageToBlob(info);
            try {
                FileOutputStream out = new FileOutputStream("blob.gif");
                out.write(blob);
                out.close();
            }
            catch (IOException ex) {
                System.out.println("Unable to write blob to file: " + ex);
            }
            // Rotation and shear
            image = new MagickImage(new ImageInfo("pics.jpg"));
            MagickImage rotated = image.rotateImage(45.0);
            rotated.setFileName("rotated.jpg");
            rotated.writeImage(info);
            MagickImage sheared = image.shearImage(50.0, 10.0);
            sheared.setFileName("sheared.jpg");
            sheared.writeImage(info);
            MagickImage scaled = image.scaleImage(100, 80);
            scaled.setFileName("scaled.jpg");
            scaled.writeImage(info);
            // Cloning
            imageDim = image.getDimension();
            System.out.println("Width is " + imageDim.width);
            System.out.println("Height is " + imageDim.height);
            System.out.println("Depth is " + image.getDepth());
            System.out.println("Storage class is " + image.getStorageClass());
            System.out.println("Comment is \""
                    + image.getImageAttribute("Comment") + "\"");
            MagickImage clonedImage = image.cloneImage(0, 0, false);
            clonedImage.setFileName("clone.jpg");
            clonedImage.writeImage(info);
            // Quantization
            MagickImage quantizedImage = new MagickImage(new ImageInfo(
                    "pics.jpg"));
            QuantizeInfo quantizeInfo = new QuantizeInfo();
            quantizeInfo.setColorspace(ColorspaceType.GRAYColorspace);
            quantizeInfo.setNumberColors(256);
            quantizeInfo.setTreeDepth(4);
            System.out.println("QuantizeImage "
                    + quantizedImage.quantizeImage(quantizeInfo));
            System.out.println("Colors " + quantizedImage.getColors());
            System.out.println("Total colors "
                    + quantizedImage.getTotalColors());
            quantizedImage.setFileName("quantized.png");
            quantizedImage.writeImage(info);
//            for (int i = 0; i < quantizedImage.getColors(); i++) {
//                PixelPacket pp = quantizedImage.getColormap(i);
//                System.out.println("Colormap[" + i + "] = (" + pp.getRed()
//                        + ", " + pp.getGreen() + ", " + pp.getBlue() + ")");
//            }
//            PixelPacket[] ppArray = quantizedImage.getColormap();
//            for (int i = 0; i < quantizedImage.getColors(); i++) {
//                System.out.println("Colormap2[" + i + "] = ("
//                        + ppArray[i].getRed() + ", " + ppArray[i].getGreen()
//                        + ", " + ppArray[i].getBlue() + ")");
//            }
            // Create an image from scratch
            MagickImage blankImage = new MagickImage();
            byte[] pixels = new byte[200 * 100 * 4];
            for (int i = 0; i < 200 * 100; i++) {
                pixels[4 * i] = (byte) 255;
                pixels[4 * i + 1] = (byte) 255;
                pixels[4 * i + 2] = (byte) 255;
                pixels[4 * i + 3] = (byte) 0;
            }
            blankImage.constituteImage(200, 100, "RGBA", pixels);
            // Put a red rectangle around the border
            DrawInfo drawInfo = new DrawInfo(new ImageInfo());
            drawInfo.setPrimitive("Rectangle 10 10 190 90");
            drawInfo.setStroke(PixelPacket.queryColorDatabase("red"));
            drawInfo.setFill(PixelPacket.queryColorDatabase("white"));
            blankImage.drawImage(drawInfo);
            // Annotate the image with a green Hello
            ImageInfo blankImageInfo = new ImageInfo();
            DrawInfo annotateInfo = new DrawInfo(blankImageInfo);
            annotateInfo.setOpacity(0);
            annotateInfo.setFont("fixed");
            annotateInfo.setFill(PixelPacket.queryColorDatabase("green"));
            annotateInfo.setText("Hello");
            annotateInfo.setGeometry("+30+30");
            blankImage.annotateImage(annotateInfo);
            blankImage.setFileName("blank.jpg");
            blankImage.writeImage(info);
            // Make the white page of the image transparent
            blankImage.transparentImage(
                    PixelPacket.queryColorDatabase("white"), 65535);
            blankImage.setFileName("transparent.png");
            blankImage.writeImage(info);
            // Crop image
            rect = new Rectangle(20, 20, 150, 120);
            MagickImage cropped = image.cropImage(rect);
            cropped.setFileName("cropped.jpg");
            cropped.writeImage(info);
            // Chop image
            rect = new Rectangle(0, 0, 150, 120);
            MagickImage chopped = image.chopImage(rect);
            chopped.setFileName("chopped.jpg");
            chopped.writeImage(info);
            // Sharpen image
            MagickImage sharpened = image.sharpenImage(1.0, 5.0);
            sharpened.setFileName("sharpened.jpg");
            sharpened.writeImage(info);
            // Despeckle image
            MagickImage despeckled = image.despeckleImage();
            despeckled.setFileName("despeckled.jpg");
            despeckled.writeImage(info);
            // Convolve image
            double[] kernel = new double[9];
            for (int i = 0; i < 9; i++) {
                kernel[i] = 1.0;
            }
            kernel[4] = 2.0;
            MagickImage convolvedImage = image.convolveImage(3, kernel);
            convolvedImage.setFileName("convolved.jpg");
            convolvedImage.writeImage(info);
            // Finally display the image.
            MagickWindow window = new MagickWindow(image);
            window.setVisible(true);
            // MagickInfo test
            MagickInfo minfo = new MagickInfo("JPEG");
            System.out.println("JPG description: " + minfo.getDescription());
        }
        catch (MagickApiException ex) {
            System.err.println("MagickException: " + ex + ": " + ex.getReason()
                    + ", " + ex.getDescription());
        }
        catch (MagickException ex) {
            System.err.println("MagickException: " + ex);
        }
    }
}
 
MagickWindow.java  在java.awtlg中显C?br /> -----------------------------------------------------------------------------------------------------------------------
package images;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import magick.MagickImage;
import magick.util.MagickViewer;
/**
 * This class implements a window that displays a MagickImage.
 *
 * @author Eric Yeo
 */
public class MagickWindow extends Frame {
    /**
     * A listener that exits the application when we receive
     * the window closing event.
     */
    private final class MyListener extends WindowAdapter {
 /**
  * This method is called when the window closes.
  */
 public void windowClosing(WindowEvent event)
 {
     System.exit(0);
 }
    }
    /**
     * We want the window size to be this big.
     */
    public Dimension getPreferredSize() {
 return new Dimension(250, 200);
    }
    /**
     * We want the window size to be at this minimum.
     */
    public Dimension getMinimumSize() {
 return new Dimension(300, 200);
    }
 
    /**
     * Constructor.
     */
    public MagickWindow(MagickImage image)
    {
 setResizable(true);
 addWindowListener(new MyListener());
 MagickViewer imageViewer = new MagickViewer();
 add(imageViewer, "Center");
 
 setTitle("Magick Window");
 pack();
 imageViewer.setImage(image);
    }
}

 


Endless 2007-09-17 12:51 发表评论
]]> վ֩ģ壺 ҹƬ߹ۿ| avƷҹɫҹ | ¸Ļ | һëƬ߲Ƶ| һ| ޾ƷŮþþ| ˾Ʒձרһ| һëƬƵվ| վѹۿ| ޳a߿| ޸߹ۿ| ɫҳѹۿ| ձվƵwww| ҹ޸˾| ŷ͵ۺ| һ˿wwwѸ| Ůˬ̼ƵѲ | Ʒۺ| 鶹Ƶѹۿ| ƷƵ| ששר2023| ŷƵվ| һ߹ۿ | һƵ| Ƶ69½| ղһ| ˮwww| ձڵƵӰ| 񼶵Ӱ| ߹ۿƬڲ| vƬѲ| xxxxxx| ޾þһ| AVһ | ɫͼѧ| ٸ͵˾ƷƵ | Ʒһ| պƷרվ| ɫٸ߳18p| òƵ| avһ|