﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-&lt;p align="left" style="font-family:华文行楷; font-size:20px; color:#FF0000"&gt;心砚手记&lt;/p&gt;-文章分类-Java</title><link>http://www.blogjava.net/zqbchina/category/22356.html</link><description>&lt;p align="right" style="font-family:华文新魏; font-size:14px; color:#660000"&gt;技术知识是基础，技术精通是目标，体系思想是境界&lt;/p&gt;</description><language>zh-cn</language><lastBuildDate>Wed, 14 May 2014 23:14:27 GMT</lastBuildDate><pubDate>Wed, 14 May 2014 23:14:27 GMT</pubDate><ttl>60</ttl><item><title>swfUpload+cos实现大附件上传</title><link>http://www.blogjava.net/zqbchina/articles/330077.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Fri, 27 Aug 2010 08:33:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/330077.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/330077.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/330077.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/330077.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/330077.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;借鉴了stephen830的<a href="http://stephen830.javaeye.com/blog/255583">step-by-step多文件WEB批量上传(swfupload)的完美解决方案</a>，在stephen830的基础上修改了一些 js代码，文件上传部分采用的是cos实现（servlet），因为公司框架封装了request请求（这和struts的差不多），所以我的servlet需要跳过封装request请求的Filter。<br />
&nbsp;&nbsp;&nbsp;&nbsp;另外，因为文件需要从客户端经过应用服务器处理（cos）上传至文件服务器，这个在本机做测试的时候（本机做应用服务器，访问文件服务器）一直没有问题，但后来放到应用服务器上是，就一直报错 not a directory&nbsp; "<a href="file://\\xxx.xxx.xxx.xxx\floder">\\xxx.xxx.xxx.xxx\floder</a>"，这个问题困扰了好几天，后来才找到原因：tomcat在服务中启动时，以本地系统账户启动，一些权限没有（比如：应用服务器访问文件服务器的共享文件夹以及客户端访问应用服务器上的应用程序如：FlashPaper），具体tomcat登陆设置如图1：<br />
<br />
<div align="center"><img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/zqbchina/5.png" width="394" height="244" /></div>
&nbsp;&nbsp;&nbsp;&nbsp;另外，上传的页面也截个图：
<p>&nbsp;</p>
<div align="center"><img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/zqbchina/4.png" width="768" height="322" /></div>
&nbsp;&nbsp;&nbsp;&nbsp;时间原因我也不贴代码了，如果哪位老兄要看具体代码的话，可以参考stephen830的文档，他的比较详细；本想顺便把自己的代码捡主要的作为附件传上来，权当留档，结果发现不知道在哪里添加附件<img border="0" align="absMiddle" src="/CuteSoft_Client/CuteEditor/images/emsmilep.gif"  alt="" />。<img src ="http://www.blogjava.net/zqbchina/aggbug/330077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2010-08-27 16:33 <a href="http://www.blogjava.net/zqbchina/articles/330077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于jQuery的显示数据加载中......</title><link>http://www.blogjava.net/zqbchina/articles/328613.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Thu, 12 Aug 2010 02:16:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/328613.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/328613.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/328613.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/328613.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/328613.html</trackback:ping><description><![CDATA[<p>项目已经快做完了，现在项目中要添加一个数据加载的显示效果(不用显示进度，只是一个动画提示之类的)，因为项目中目前已经有使用jQuery，所以考虑基于jQuery来实现，其实和jQuery关联也不大。<br />思路如下:<br /> 因为项目中大多jsp都包含了一个jsp_head.jsp，所以考虑在jsp_head.jsp中做手脚，这样可以省去很多工作量。<br /> 1、 在jsp_head.jsp中定义一个div（主要显示数据加载的动态效果，比如图片），设置style="display:none"；<br /> 2、 利用jQuery为所有的button和submit按钮添加click事件（用来显示div）:<br />    当然这里事件定义的范围可能比较广，如果不需要的话可以由选择性的定义事件，比如为按钮定义指定样式或ID，以便jQuery能够选择到它。</p>
		<p>jsp_head.jsp中代码如下：<br />  &lt;div id="dataLoad" style="display:none"&gt;&lt;!--页面载入显示--&gt;<br />   &lt;table width=100% height=100% border=0 align=center valign=middle&gt;<br />    &lt;tr height=50%&gt;&lt;td align=center&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;<br />    &lt;tr&gt;&lt;td align=center&gt;&lt;img src="&lt;%=request.getContextPath()%&gt;/XXXXX/loading-gif.gif"/&gt;&lt;/td&gt;&lt;/tr&gt;<br />    &lt;tr&gt;&lt;td align=center&gt;数据载入中，请稍后......&lt;/td&gt;&lt;/tr&gt;<br />    &lt;tr height=50%&gt;&lt;td align=center&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;<br />   &lt;/table&gt;<br />  &lt;/div&gt;<br />  &lt;script type="text/javascript"&gt;<br />   $(document).ready(function() {<br />    $("#dataLoad").hide(); //页面加载完毕后即将DIV隐藏<br />    $("#showLoadingDiv").click(function(){$("#dataLoad").show();}); //为指定按钮添加数据加载动态显示：即将DIV显示出来<br />   });<br />  &lt;/script&gt;<br />  <br />其他jsp中的代码大致如下：</p>
		<p>......<br />&lt;%@ include file="/jsp/jsp_head.jsp"%&gt;<br />......<br />&lt;input type="button" onClick="query();" id="showLoadingDiv" value="查询"&gt; <br />......</p>
		<p>这种实现对用户来说是非常真实的，没有高的技术要求，希望这种思路对你的项目有所帮助。</p><img src ="http://www.blogjava.net/zqbchina/aggbug/328613.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2010-08-12 10:16 <a href="http://www.blogjava.net/zqbchina/articles/328613.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JavaMail学习</title><link>http://www.blogjava.net/zqbchina/articles/202874.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Mon, 26 May 2008 04:24:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/202874.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/202874.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/202874.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/202874.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/202874.html</trackback:ping><description><![CDATA[<p>package com.test.mail;</p>
		<p>import java.io.BufferedReader;<br />import java.io.File;<br />import java.io.InputStreamReader;<br />import java.util.Properties;</p>
		<p>import javax.activation.DataHandler;<br />import javax.activation.DataSource;<br />import javax.activation.FileDataSource;<br />import javax.mail.Address;<br />import javax.mail.BodyPart;<br />import javax.mail.Folder;<br />import javax.mail.Message;<br />import javax.mail.Multipart;<br />import javax.mail.Session;<br />import javax.mail.Store;<br />import javax.mail.Transport;<br />import javax.mail.internet.InternetAddress;<br />import javax.mail.internet.MimeBodyPart;<br />import javax.mail.internet.MimeMessage;<br />import javax.mail.internet.MimeMultipart;</p>
		<p>public class testSendMail {<br /> public static void main(String[] arg) throws Exception{<br />  sendMailWithAttachement();<br />//  recpMail();<br /> }<br /> <br /> <br /> <br /> /**<br />  * 不需要验证的邮件发送<br />  * @throws Exception<br />  */<br /> private static void setMessage() throws Exception {<br />  Properties props = System.getProperties();<br />  props.put("mail.smtp.host","mail.infoservice.com.cn");  //设置smtp的服务器地址：该邮件服务器不需要身份验证<br />  props.put("mail.smtp.auth","false");             //设置smtp服务器要身份验证:缺省设置为false<br />  <br />  Address from = new InternetAddress("<a href="mailto:chencheng@infoservice.com.cn">chencheng@infoservice.com.cn</a>");<br />  Address to = new InternetAddress("<a href="mailto:zouqingbing@infoservice.com.cn">zouqingbing@infoservice.com.cn</a>");<br />  <br />  <br />  Session session = Session.getDefaultInstance(props,null);<br />  Message message = new MimeMessage(session);<br />  message.setFrom(from);<br />  message.addRecipient(Message.RecipientType.TO, to);<br />  message.setText("I love U!!!");<br />  message.setSubject("Test");<br />  <br />  Transport.send(message);<br />  System.out.println("邮件发送完毕!");<br /> }<br /> <br /> /**<br />  * 带授权的发送邮件<br />  * @throws Exception<br />  */<br /> private static void setMessageWithAuthentica() throws Exception{<br />  Properties props = new Properties();<br />  props.put("mail.smtp.host","smtp.126.com");  //设置smtp的服务器地址是smtp.126.com<br />  props.put("mail.smtp.auth","true");          //设置smtp服务器要身份验证。<br />  PopupAuthenticator auth = new PopupAuthenticator();<br />  Session session = Session.getInstance(props, auth);</p>
		<p>  // 发送人地址<br />  Address addressFrom = new InternetAddress("<a href="mailto:zqbchina@126.com">zqbchina@126.com</a>", "zqbchina");<br />  // 收件人地址<br />  Address addressTo = new InternetAddress("<a href="mailto:zqbchina@sina.com">zqbchina@sina.com</a>", "zqbchina");<br />  <br />  // 抄送地址<br />  // Address addressCopy = new InternetAddress("<a href="mailto:haocongping@gmail.com">haocongping@gmail.com</a>", "George Bush");<br />  Message message = new MimeMessage(session);<br />  message.setContent("This is mail content!", "text/plain");//或者使用message.setText("Hello");更详细的信息请参看后续文章.<br />  message.setSubject("测试邮件标题");<br />  message.setFrom(addressFrom);<br />  message.addRecipient(Message.RecipientType.TO,addressTo);<br />  // message.addRecipient(Message.RecipientType.CC,addressCopy);<br />  message.saveChanges();<br />  // session.setDebug(true);<br />  Transport transport = session.getTransport("smtp");  //创建连接<br />  transport.connect("smtp.126.com", "zqbchina", "你的密码");//连接服务器<br />  transport.send(message); //发送信息<br />  transport.close();   //关闭连接<br />  System.out.println("邮件发送完毕!");<br /> }<br /> <br /> /**<br />  * 带附件的邮件发送<br />  * @throws Exception<br />  */<br /> private static void sendMailWithAttachement() throws Exception{<br />  Properties props = new Properties();<br />  props.put("mail.smtp.host","smtp.126.com");  //设置smtp的服务器地址是smtp.126.com<br />  props.put("mail.smtp.auth","true");          //设置smtp服务器要身份验证。<br />  PopupAuthenticator auth = new PopupAuthenticator();<br />  Session session = Session.getInstance(props, auth);<br />  File filename = new File("c:\\cmd.txt");<br />  <br />  // 发送人地址<br />  Address from = new InternetAddress("<a href="mailto:zqbchina@126.com">zqbchina@126.com</a>", "zqbchina");<br />  Address to = new InternetAddress("<a href="mailto:zqbchina@sina.com">zqbchina@sina.com</a>", "zqbchina");<br />  <br />  //Define message<br />  Message message = new MimeMessage(session);<br />  message.setFrom(from);<br />  message.addRecipient(Message.RecipientType.TO,to);<br />  message.setSubject("Hello JavaMail Attachment");<br />  // Create the message part <br />  BodyPart messageBodyPart = new MimeBodyPart();<br />  // Fill the message<br />  messageBodyPart.setText("Pardon Ideas");<br />  Multipart multipart = new MimeMultipart();<br />  multipart.addBodyPart(messageBodyPart);<br />  // Part two is attachment<br />  messageBodyPart = new MimeBodyPart();<br />  DataSource source = new FileDataSource(filename);<br />  messageBodyPart.setDataHandler(new DataHandler(source));<br />  messageBodyPart.setFileName("cmd.txt");<br />  multipart.addBodyPart(messageBodyPart);<br />  // Put parts in message<br />  message.setContent(multipart);<br />  // Send the message<br />  Transport.send(message);<br />  <br />  <br /> }<br /> <br /> private static void recpMail() throws Exception{<br />  BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));<br />  <br />  /*Properties props = new Properties();<br />  props.put("mail.smtp.host","smtp.sina.com");<br />  props.put("mail.smtp.auth","true");<br />//  props.put("mail.pop3.socketFactory.fallback", "false");<br />  Session session = Session.getInstance(props, new PopupAuthenticator());<br />  <br />  Store store = session.getStore("pop3");<br />  store.connect();<br />  Folder folder = store.getFolder("INBOX");<br />  folder.open(Folder.READ_ONLY);<br />//  Message[] messages = folder.getMessages();<br />  System.out.println(folder.getMessageCount());<br />//  for (int i=0;i&lt;messages.length;i++)<br />  folder.close(true);<br />  store.close();*/<br />  <br />  <br />  Properties props = new Properties();<br />  props.put("mail.smtp.host","mail.infoservice.com.cn");<br />  props.put("mail.smtp.auth","false");<br />  Session session = Session.getInstance(props, new PopupAuthenticator());<br />  <br />  Store store = session.getStore("pop3");<br />  store.connect("mail.infoservice.com.cn","zouqingbing","你的密码");<br />  Folder folder = store.getFolder("INBOX");<br />  folder.open(Folder.READ_WRITE);<br />  System.out.println(folder.getPermanentFlags().getSystemFlags().length);<br />  Message[] messages = folder.getMessages();<br />  for (int i=0;i&lt;messages.length;i++){<br />   if (i==19) messages[i].reply(true);<br />   <br />   System.out.println(i+": 发件人=["+messages[i].getFrom()[0]+"],标题＝["+messages[i].getSubject()+"]");<br />//   System.out.println("需要查看邮件内容吗？[Y]---查看；[N]---暂时不看。");<br />//   String line = reader.readLine();<br />//   if ("Y".equals(line))<br />//    System.out.println(messages[i].getContent().toString().getBytes("GB2312"));<br />  }<br />  folder.close(true);<br />  store.close();<br /> }<br /> <br />}<br /><br />其中，身份验证类：<br />import javax.mail.Authenticator;<br />import javax.mail.PasswordAuthentication;</p>
		<p>public class PopupAuthenticator extends Authenticator {<br />    public PasswordAuthentication getPasswordAuthentication() {<br />        String username = "zqbchina"; //邮箱登录帐号<br />        String pwd = "密码";     //登录密码<br />        return new PasswordAuthentication(username, pwd);<br />    }<br />}<br /></p><img src ="http://www.blogjava.net/zqbchina/aggbug/202874.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2008-05-26 12:24 <a href="http://www.blogjava.net/zqbchina/articles/202874.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习杂记一</title><link>http://www.blogjava.net/zqbchina/articles/163494.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Tue, 27 Nov 2007 09:31:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/163494.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/163494.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/163494.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/163494.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/163494.html</trackback:ping><description><![CDATA[0, Spring本身的一些工作(比如,根上下文的建立)可以在ContextLoaderServlet或ContextLoaderListener中完成;<br />1, 如果需要使用Spring MVC就需要引入DispatcherServlet,否则可以不用引入这个servlet,<br />而引入其他的servlet(比如,如果webApplication需要使用struts MVC,就需要引入struts的servlet,如ActionServlet).<br />2, Spring与Struts的结合:<br />  方法一: <br />    a. 利用Spring的ContextLoaderServlet或ContextLoaderListener加载Spring所需要的Bean定义及ApplicationContext的建立等;<br />    b. 定义Struts所需要的Dispatcher类ActionServlet,其中a,b两步是独立的;<br />    c. 在Struts的action中引用Spring中的bean定义时,可以直接使用WebApplicationContextUtil<br />    <br />    如: a. web.xml的配置:<br />      &lt;context-param&gt;<br />       &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br />       &lt;param-value&gt;/WEB-INF/beanDefineA.xml&lt;/param-value&gt;<br />      &lt;/context-param&gt;<br />      <br />      &lt;servlet&gt;<br />       &lt;servlet-name&gt;ContextLoader&lt;/servlet-name&gt;<br />       &lt;servlet-class&gt;org.springframework.web.context.ContextLoaderServlet&lt;/servlet-class&gt;<br />       &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />      &lt;/servlet&gt;<br />      &lt;servlet&gt;<br />          &lt;servlet-name&gt;action&lt;/servlet-name&gt;<br />          &lt;servlet-class&gt;org.apache.struts.action.ActionServlet&lt;/servlet-class&gt;<br />          &lt;init-param&gt;<br />            &lt;param-name&gt;config&lt;/param-name&gt;<br />            &lt;param-value&gt;/WEB-INF/struts-config.xml&lt;/param-value&gt;<br />          &lt;/init-param&gt;<br />          &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br />        &lt;/servlet&gt;<br />      <br />      &lt;servlet-mapping&gt;<br />       &lt;servlet-name&gt;ContextLoader&lt;/servlet-name&gt;<br />       &lt;url-pattern&gt;/&lt;/url-pattern&gt;<br />      &lt;/servlet-mapping&gt;<br />      &lt;servlet-mapping&gt;<br />       &lt;servlet-name&gt;action&lt;/servlet-name&gt;<br />       &lt;url-pattern&gt;*.do&lt;/url-pattern&gt;<br />      &lt;/servlet-mapping&gt;<br />      <br />      b. bean定义文件内容如下:<br />       &lt;bean id="test" class="com.info.test"&gt;<br />         &lt;property name="id"&gt;<br />          &lt;value&gt;1&lt;/value&gt;<br />         &lt;/property&gt;<br />         &lt;property name="name"&gt;<br />         &lt;value&gt;zqbchina&lt;/value&gt;<br />        &lt;/property&gt;<br />         &lt;property name="age"&gt;<br />         &lt;value&gt;12&lt;/value&gt;<br />        &lt;/property&gt;<br />        &lt;/bean&gt;<br />        <br />       c. action中的引用:<br />       ...<br />       ServletContext sc = request.getSession().getServletContext();<br />      WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(sc);<br />      test t = (test)wac.getBean("test");<br />      ...<img src ="http://www.blogjava.net/zqbchina/aggbug/163494.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-11-27 17:31 <a href="http://www.blogjava.net/zqbchina/articles/163494.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库连接池技术</title><link>http://www.blogjava.net/zqbchina/articles/146223.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Tue, 18 Sep 2007 10:12:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/146223.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/146223.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/146223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/146223.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/146223.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 要下班了，先把代码贴上来，明天有时间来加说明。package com;import java.io.Serializable;public class ConnectionParam implements Serializable {    private String driver; // 数据库驱动程序    private String url; // 数据连接的URL    private...&nbsp;&nbsp;<a href='http://www.blogjava.net/zqbchina/articles/146223.html'>阅读全文</a><img src ="http://www.blogjava.net/zqbchina/aggbug/146223.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-09-18 18:12 <a href="http://www.blogjava.net/zqbchina/articles/146223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用java.lang.reflect包中的InvocationHandler、Proxy实现代理(拦截已有方法)</title><link>http://www.blogjava.net/zqbchina/articles/146218.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Tue, 18 Sep 2007 09:45:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/146218.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/146218.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/146218.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/146218.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/146218.html</trackback:ping><description><![CDATA[<p>
				<br />
				<br />本来想自己写一个日志的，发现有位老兄写的很好，我就不用费事，直接贴过来做笔记好了<img height="20" src="http://www.blogjava.net/Emoticons/QQ/14.gif" width="20" border="0" /><font color="#000000">。<br />==========================================================</font></p>
		<p class="diaryTitle">
				<font color="#000000" size="3">[转自：</font>
				<a href="http://publishblog.blogdriver.com/blog/tb.b?diaryID=842351">
						<font color="#000000" size="3">http://publishblog.blogdriver.com/blog/tb.b?diaryID=842351</font>
				</a>
				<font size="3">
						<font color="#000000"> ]</font>
						<font color="#000000">
						</font>
				</font>
		</p>
		<p class="diaryTitle">
				<font color="#000000" size="3">[Java]使用Proxy和InvocationHandler实现代理器模式</font>
		</p>
		<p>
		</p>
		<ul>
				<li>
						<strong>元对象(被代理对象):</strong>
				</li>
		</ul>
		<p>package com.zj.gof.proxy;</p>
		<p>public interface StudentInfoService {<br /> void findInfo(String studentName);<br />}<br /></p>
		<p>package com.zj.gof.proxy;</p>
		<p>public class StudentInfoServiceImpl implements StudentInfoService {<br /> public void findInfo(String name) {<br />  System.out.println("你目前输入的名字是:" + name);<br /> }<br />}</p>
		<ul>
				<li>
						<strong>代理对象:</strong>
				</li>
		</ul>
		<p>package com.zj.gof.proxy;</p>
		<p>import java.lang.reflect.InvocationHandler;<br />import java.lang.reflect.Method;<br />import java.lang.reflect.Proxy;</p>
		<p>import org.apache.log4j.Logger;</p>
		<p>public class LogHandler implements InvocationHandler {<br />  private Object proxyObj;<br />  private static Logger log=Logger.getLogger(LogHandler.class);<br />  <br />  public Object bind(Object obj){<br />   this.proxyObj=obj;<br />   return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);<br />  }<br />  <br />  public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{<br />   Object result=null;<br />   try{<br />    //请在这里插入代码，在方法前调用<br />    log.info("调用log日志方法"+method.getName());<br />    result=method.invoke(proxyObj,args); //原方法<br />    //请在这里插入代码，方法后调用<br />   }catch(Exception e){<br />    e.printStackTrace();<br />   }<br />   return result;<br />  }</p>
		<p>}</p>
		<p>
				<font color="#ff0000">注意:通过InvocationHandler接口实现的代理器只能代理接口方法.</font>
				<font color="#000000">(这点在InvocationHandler的注解中有说明)</font>
		</p>
		<ul>
				<li>
						<strong>代理工厂:</strong>
				</li>
		</ul>
		<p>package com.zj.gof.proxy;</p>
		<p>public class LogFactory {<br /> private static Object getClassInstance(String clzName) {<br />  Object obj = null;<br />  try {<br />   Class cls = Class.forName(clzName);<br />   obj = (Object) cls.newInstance();<br />  } catch (ClassNotFoundException cnfe) {<br />   System.out.println("ClassNotFoundException:" + cnfe.getMessage());<br />  } catch (Exception e) {<br />   e.printStackTrace();<br />  }<br />  return obj;<br /> }</p>
		<p> public static Object getAOPProxyedObject(String clzName) {<br />  Object proxy = null;<br />  LogHandler handler = new LogHandler();<br />  Object obj = getClassInstance(clzName);<br />  if (obj != null) {<br />   proxy = handler.bind(obj);<br />  } else {<br />   System.out.println("Can't get the proxyobj");<br />   //throw<br />  }<br />  return proxy;<br /> }</p>
		<p>}<br /></p>
		<ul>
				<li>
						<strong>客户端调用:</strong>
				</li>
		</ul>
		<p>package com.zj.gof.proxy;</p>
		<p>public class MainTest {</p>
		<p> public static void main(String[] args) {<br />  //  PropertyConfigurator.configure("d:/log4j.properties");<br />  BasicConfigurator.configure();<br />  StudentInfoService studentInfo = (StudentInfoService) LogFactory<br />    .getAOPProxyedObject("com.zj.gof.proxy.StudentInfoServiceImpl");<br />  studentInfo.findInfo("阿飞");<br /> }<br />}</p>
		<ul>
				<li>
						<strong>运行结果:</strong>
				</li>
		</ul>
		<p>
		</p>
		<p>0 [main] INFO root  - 调用log日志方法findInfo<br />你目前输入的名字是:阿飞</p><img src ="http://www.blogjava.net/zqbchina/aggbug/146218.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-09-18 17:45 <a href="http://www.blogjava.net/zqbchina/articles/146218.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet学习继续</title><link>http://www.blogjava.net/zqbchina/articles/143160.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Thu, 06 Sep 2007 06:13:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/143160.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/143160.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/143160.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/143160.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/143160.html</trackback:ping><description><![CDATA[好长时间没学习了，悲哀......<br />今天看了servlet中的一个方法感觉有点东西还是值得记下来的。<br />问题名称我就引用网上一位网友的标题了：<strong>ServletContext's getContext() method<br />一位仁兄的解释还是非常精简的，举例如下：<br /></strong>【环境】<br />webapps-&gt;app1<br />webspps-&gt;app2-&gt;jsp-&gt;app2jsp.jsp<br />【<strong>getContext() method的</strong>应用】<br />getServletContext().getContext("/app2").getRequestDispatcher("/jsp/app2jsp.jsp").forward(request,response)<br />在我自己测试了以后，做了一点总结：<br />当一个容器中有多个应用时，在其中一个应用中调用（或叫引用）另一个应用中的变量或资源时可以用上这个方法，具体的实现为调用getContext("/app2")，其中"/app2"为应用的url名。<img src ="http://www.blogjava.net/zqbchina/aggbug/143160.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-09-06 14:13 <a href="http://www.blogjava.net/zqbchina/articles/143160.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二十二楼Blog迁移 2005－12</title><link>http://www.blogjava.net/zqbchina/articles/134040.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Thu, 02 Aug 2007 09:27:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/134040.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/134040.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/134040.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/134040.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/134040.html</trackback:ping><description><![CDATA[<font size="1">数据库: 安装Oracle中的一个中文问题<br /></font>
		<p>
				<font size="1">问题：今天重装了系统，在安装oracle9.0.0.1时，点击setup.exe后出现oracle图片就没有反应了，再次点击setup.exe提示OraInstall文件夹不能写。</font>
		</p>
		<p>
				<font size="1">诊断：怀疑时安装时的中文问题，因为我的机器名是中文名，所以OraInstall所在路径是C:\Documents and Settings\邹清兵\Local Settings\Temp\OraInstall，它是根据环境变量中的Temp的值%USERPROFILE%\Local Settings\Temp得来的 。</font>
		</p>
		<p>
				<font size="1">解决：将Temp的值改成C:\Documents and Settings\Default User\temp，点击setup.exe终于可以进行oracle的安装了。安装完毕后再将Temp的值换回原来的%USERPROFILE%\Local Settings\Temp就OK了！</font>
		</p>
		<font size="1">zqbchina 发表于: 2005-12-07 11:49:28<br /><br /><hr /><br />Java: displaytag+struts的一个问题<br /></font>
		<p>
				<font size="1">解决的是一个在request范围内跳转的问题：A.do---&gt;A.jsp，在A.jsp中排序时request中的变量就取不到了（session中可以）。解决方法是设定一下requestURI的值就OK了。如：</font>
		</p>
		<p>
				<?xml:namespace prefix = display /?>
				<display:table color="#ff0000">
						<font name="requestScope.co">
								<font size="1">
										<display:table name="requestScope.co">
												<em>&lt;display:table name="requestScope.co" <em>requestURI = "/infoResource/infoResource/showAllCorporateUI.do"</em> defaultsort="1" defaultorder="descending"&gt; <br />  &lt;display:column property="personId" title="身份证号" sortable="true" headerClass="sortable" /&gt;<br />  &lt;display:column property="corporateName" title="法人姓名" sortable="true" headerClass="sortable"/&gt;<br />&lt;/display:table&gt;<br /></em>
										</display:table>
										<display:column title="法人姓名" headerclass="sortable" sortable="true" property="corporateName">
										</display:column>
										<br />
								</font>
						</font>
				</display:table>
		</p>
		<font size="1">zqbchina 发表于: 2005-12-08 16:53:48<br /><br /><hr /><br />Java: displaytag的中文问题<br /></font>
		<p>
				<font size="1">在Jboss＋struts＋displaytag中将TableProperties.properties中的分页等显示信息修改成中文，在Web页中显示为乱码（这个问题在Tomcat＋displaytag中没有出现）。参照网上的大多解决方案，修改TableProperties.java中的方法getProperties（String）：<br />    private String getProperty(String key)<br />    {<br />        return properties.getProperty(key);<br />    }</font>
		</p>
		<p>
				<font size="1">为：<br />    private String getProperty(String key) {<br />        String s = null;<br />        try {<br />            s = new String(this.properties.getProperty(key).getBytes("8859_1"), "GBK");<br />        } catch (UnsupportedEncodingException e) {<br />            e.printStackTrace();<br />        }<br />        return s;<br />    }</font>
		</p>
		<p>
				<font size="1">问题到是解决了，唉………………</font>
		</p>
		<font size="1">zqbchina 发表于: 2005-12-14 15:48:40<br /></font><img src ="http://www.blogjava.net/zqbchina/aggbug/134040.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-08-02 17:27 <a href="http://www.blogjava.net/zqbchina/articles/134040.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Portal: Liferay在Eclipse中的编译</title><link>http://www.blogjava.net/zqbchina/articles/134038.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Thu, 02 Aug 2007 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/134038.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/134038.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/134038.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/134038.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/134038.html</trackback:ping><description><![CDATA[<br />
		<p>
				<font size="1">问题表现:</font>
		</p>
		<p>
				<font size="1">     下载的Liferay在Eclipse中进行build时,首先会有Jikes编译器的错误提示(当然我以前用的是javac),将编译器改成"modern"后,又提示内存方面的错误,不能怎么改配置文件都没用.</font>
		</p>
		<p>
				<font size="1">解决方法:</font>
		</p>
		<p>
				<font size="1">     下载Jikes编译器,添加路径到path中后(确保Liferay工程中的build.properties文件中的javac.compiler=jikes),再次编译就什么问题都没有了:)</font>
		</p><img src ="http://www.blogjava.net/zqbchina/aggbug/134038.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-08-02 17:24 <a href="http://www.blogjava.net/zqbchina/articles/134038.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java: 关于Jboss部署的一个问题</title><link>http://www.blogjava.net/zqbchina/articles/134037.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Thu, 02 Aug 2007 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/134037.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/134037.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/134037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/134037.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/134037.html</trackback:ping><description><![CDATA[<br />
		<p>
				<font size="1">问题如下:</font>
		</p>
		<p>
				<font size="1">      java.lang.NoSuchMethodError: org.jboss.proxy.GenericProxyFactory.createProxy(Lja<br />va/lang/Object;Ljavax/management/ObjectName;Ljavax/management/ObjectName;Ljava/l<br />ang/String;Ljava/lang/String;Ljava/util/ArrayList;Ljava/lang/ClassLoader;[Ljava/<br />lang/Class;)Ljava/lang/Object;</font>
		</p>
		<p>
				<font size="1">解决方法:</font>
		</p>
		<p>
				<font size="1">      去掉C:\jboss\server\default\lib中的jboss-client.jar即可.该问题在有的机器上不存在,所以原因也无从考究.</font>
		</p><img src ="http://www.blogjava.net/zqbchina/aggbug/134037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-08-02 17:24 <a href="http://www.blogjava.net/zqbchina/articles/134037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Portal: JetSpeed与Liferay的比较</title><link>http://www.blogjava.net/zqbchina/articles/134034.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Thu, 02 Aug 2007 09:23:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/134034.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/134034.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/134034.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/134034.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/134034.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体">(摘自Huihoo文章)<br /><br />提供基于门户的解决方案的开源软件有：<br /><span style="mso-spacerun: yes">    </span><b>JetSpeed</b>是Apache（http:// jakarta.apache.org/jetspeed/）组织的一个开源项目，IBM的WebSphere Portal Server正是基于JetSpeed进行二次开发。<br /><br />在满足门户可定制性的需求上，引入了门户组件概念Portlet，Portlet是一个可插拔的组件，关于Portlet有各种定义，JetSpeed在提交的JSR-168 portlet API specifications对Portlet的定义如下：<br />Portlet是一个Web组件，可以被容器管理，可以产生动态内容。 Portlet可以很容易地被插入并且运行于一个Web应用中，Portlet是被设计成聚合大量内容的组合页面，举例：同样一个Portlet，根据不同的用户，可以产生不同的实例，这些实例中是根据用户设置包含不同的内容，也就是满足用户的可定制性。<br /><br />为了实现门户内容的有效管理和监控，JetSpeed的重要内容组件Slide引入了Domain和Namespace方面的概念，对所有资源进行树形结构的控制，在Slide中，Domain是一系列Namespace的聚合，它类似文件系统中的“/”根目录， domain 可以控制在其中登记的Namespace的访问权限以及执行Namespace的初始化和连接等管理工作。<br /><br />Namespace是个自我独立的有实体内容的容器，它不能包含指向或连接到其它namespace，每个应用系统可以是一个NameSpace，Namespace包含独立的数据和这些数据的安全访问机制。<br /><br />JetSpeed虽然提供了丰富的Portal技术功能，但是其可定制性比较差，其重要的内容组件Slide也比较难以让人理解，它的安全控制框架与通用的J2EE使用JAAS不相融合，所有这些都造成了在其基础上进行二次开发的难度。<br /><br /><b>Liferay</b><br />Liferay（http://www.liferay.com）代表了完整的J2EE应用，使用了Web、EJB以及JMS等技术，特别是其前台界面部分使用Struts框架技术，基于XML的portlet配置文件可以自由地动态扩展，使用了Web Services来支持一些远程信息的获取，使用Apahce Lucene实现全文检索功能。Liferay业务层使用Stateless Session EJBs,通过hibernate实现持续层,使用jaas实现安全策略.另外表示层使用struts和tiles.<br /><br />Liferay的缺点是它缺乏一个简单清晰可拓展的架构设计，portlet设计显得比较凌乱，进行二次开发有一定的难度</span>
		</p><img src ="http://www.blogjava.net/zqbchina/aggbug/134034.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-08-02 17:23 <a href="http://www.blogjava.net/zqbchina/articles/134034.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java: 编译器的选择问题</title><link>http://www.blogjava.net/zqbchina/articles/134033.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Thu, 02 Aug 2007 09:23:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/134033.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/134033.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/134033.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/134033.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/134033.html</trackback:ping><description><![CDATA[<font size="1">
				<br />
		</font>
		<p>
				<font size="1">
						<strong>[错误症状]--</strong>在Eclipse中用Ant执行build.xml文件时,出现了"Error running jikes compiler"的错误.</font>
		</p>
		<p>
				<font size="1">&lt;javac<br />   classpathref="project.classpath"<br />   compiler=<font color="#ff0000">"${javac.compiler}"</font><br />   debug="${javac.debug}"<br />/&gt;</font>
		</p>
		<p>
				<font size="1">
						<strong>[解决方法]--</strong>在build.xml中的javac部分,指定其属性compiler的值为modern.</font>
		</p>
		<p>
				<font size="1">&lt;javac<br />   classpathref="project.classpath"<br />   compiler=<font color="#ff0000">"{modern}"</font><br />   debug="${javac.debug}"<br />/&gt;</font>
		</p><img src ="http://www.blogjava.net/zqbchina/aggbug/134033.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-08-02 17:23 <a href="http://www.blogjava.net/zqbchina/articles/134033.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java: Java常见数据库连接</title><link>http://www.blogjava.net/zqbchina/articles/134032.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Thu, 02 Aug 2007 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/134032.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/134032.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/134032.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/134032.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/134032.html</trackback:ping><description><![CDATA[<font size="1">[转帖]Java常见数据库连接 </font>
		<p>
				<font size="1">1、Oracle8/8i/9i数据库（thin模式） <br />Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); <br />String url="jdbc:oracle:thin:@localhost:1521:orcl"; <br />//orcl为数据库的SID <br />String user="test"; <br />String password="test"; <br />Connection conn= DriverManager.getConnection(url,user,password); </font>
		</p>
		<p>
				<font size="1">2、DB2数据库 <br />Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); <br />String url="jdbc:db2://localhost:5000/sample"; <br />//sample为你的数据库名 <br />String user="admin"; <br />String password=""; <br />Connection conn= DriverManager.getConnection(url,user,password); </font>
		</p>
		<p>
				<font size="1">3、Sql Server7.0/2000数据库 <br />Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); <br />String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb"; <br />//mydb为数据库 <br />String user="sa"; <br />String password=""; <br />Connection conn= DriverManager.getConnection(url,user,password); </font>
		</p>
		<p>
				<font size="1">4、Sybase数据库 <br />Class.forName("com.sybase.jdbc.SybDriver").newInstance(); <br />String url =" jdbc:sybase:Tds:localhost:5007/myDB"; <br />//myDB为你的数据库名 <br />Properties sysProps = System.getProperties(); <br />SysProps.put("user","userid"); <br />SysProps.put("password","user_password"); <br />Connection conn= DriverManager.getConnection(url, SysProps); </font>
		</p>
		<p>
				<font size="1">5、Informix数据库 <br />Class.forName("com.informix.jdbc.IfxDriver").newInstance(); <br />String url = <br />"jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver; <br />user=testuser;password=testpassword"; <br />//myDB为数据库名 <br />Connection conn= DriverManager.getConnection(url); </font>
		</p>
		<p>
				<font size="1">6、MySQL数据库 <br />Class.forName("org.gjt.mm.mysql.Driver").newInstance(); <br />String url ="jdbc:mysql://localhost/myDB?user=soft&amp;password=soft1234&amp;useUnicode=true&amp;characterEncoding=8859_1" <br />//myDB为数据库名 <br />Connection conn= DriverManager.getConnection(url); </font>
		</p>
		<p>
				<font size="1">7、PostgreSQL数据库 <br />Class.forName("org.postgresql.Driver").newInstance(); <br />String url ="jdbc:postgresql://localhost/myDB" <br />//myDB为数据库名 <br />String user="myuser"; <br />String password="mypassword"; <br />Connection conn= DriverManager.getConnection(url,user,password); </font>
		</p><img src ="http://www.blogjava.net/zqbchina/aggbug/134032.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-08-02 17:22 <a href="http://www.blogjava.net/zqbchina/articles/134032.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java: 初涉StreamTokenizer类</title><link>http://www.blogjava.net/zqbchina/articles/134031.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Thu, 02 Aug 2007 09:21:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/134031.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/134031.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/134031.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/134031.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/134031.html</trackback:ping><description><![CDATA[<p>
				<font size="1">package test.c11;</font>
		</p>
		<p>
				<font size="1">import java.io.*;</font>
		</p>
		<p>
				<font size="1">public class FileStreamTokenizerTest {<br /> public static void main(String[] args) {<br />  try{<br />//   BufferedReader br = new BufferedReader(<br />//    new InputStreamReader(new FileInputStream("c:\\2.txt")));<br />//   StreamTokenizer st = new StreamTokenizer(br);<br />   StreamTokenizer st = new StreamTokenizer(<br />     new StringReader("abc.a.azqbchi;na2.bmmdchina3.1223a.0ckyychina4.dwmjchina5.ethchina6.wmjchina"));<br />   st.quoteChar('.');<br />//   st.ordinaryChars('a','c');<br />//   st.whitespaceChars('a','c');<br />//   st.wordChars('a','c');<br />//   st.resetSyntax();<br />   while(st.nextToken()!=StreamTokenizer.TT_EOF){<br />    if (st.ttype==StreamTokenizer.TT_NUMBER){<br />     System.out.println("this NUMBER value is : "+st.nval);<br />    }else if(st.ttype==StreamTokenizer.TT_WORD){<br />     System.out.println("this WORD value is : "+st.sval);<br />    }else{<br />     System.out.println("type is : "+st.ttype+" the value is :"+st.sval);<br />    }<br />   }<br />  }catch(FileNotFoundException e){<br />   e.printStackTrace();<br />  }catch(IOException e){<br />   e.printStackTrace();<br />  }<br /> }<br />}</font>
		</p>
		<p>
				<font size="1">输出如下:<br />this WORD value is : abc<br />type is : 46 the value is :a<br />this WORD value is : azqbchi<br />type is : 59 the value is :null<br />this WORD value is : na2<br />type is : 46 the value is :bmmdchina3<br />this NUMBER value is : 1223.0<br />this WORD value is : a<br />type is : 46 the value is :0ckyychina4<br />this WORD value is : dwmjchina5<br />type is : 46 the value is :ethchina6<br />this WORD value is : wmjchina</font>
		</p>
		<p>
				<font size="1">==========================<br />有一点不明白:<br />na2和ethchina6为什么一个类型是WORD(-3),一个类型是46呢?</font>
		</p><img src ="http://www.blogjava.net/zqbchina/aggbug/134031.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-08-02 17:21 <a href="http://www.blogjava.net/zqbchina/articles/134031.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat中用web.xml控制Web应用详解(转)</title><link>http://www.blogjava.net/zqbchina/articles/122373.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Wed, 06 Jun 2007 07:27:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/122373.html</guid><description><![CDATA[<p>摘自:  <a href="http://fanqiang.chinaunix.net/app/web/">http://fanqiang.chinaunix.net/app/web/</a>   &lt;&lt;Tomcat中用web.xml控制Web应用详解1,2&gt;&gt;<br /><br />1 定义头和根元素</p>
		<p>部署描述符文件就像所有XML文件一样，必须以一个XML头开始。这个头声明可以使用的XML版本并给出文件的字符编码。<br />DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本（如2.2或2.3）并指定管理此文件其余部分内容的语法的DTD(Document Type Definition，文档类型定义)。<br />所有部署描述符文件的顶层（根）元素为web-app。请注意，XML元素不像HTML，他们是大小写敏感的。因此，web-App和WEB-APP都是不合法的，web-app必须用小写。</p>
		<p>2 部署描述符文件内的元素次序</p>
		<p>XML元素不仅是大小写敏感的，而且它们还对出现在其他元素中的次序敏感。例如，XML头必须是文件中的第一项，DOCTYPE声明必须是第二项，而web-app元素必须是第三项。在web-app元素内，元素的次序也很重要。服务器不一定强制要求这种次序，但它们允许（实际上有些服务器就是这样做的）完全拒绝执行含有次序不正确的元素的Web应用。这表示使用非标准元素次序的web.xml文件是不可移植的。<br />下面的列表给出了所有可直接出现在web-app元素内的合法元素所必需的次序。例如，此列表说明servlet元素必须出现在所有servlet-mapping元素之前。请注意，所有这些元素都是可选的。因此，可以省略掉某一元素，但不能把它放于不正确的位置。<br /> icon icon元素指出IDE和GUI工具用来表示Web应用的一个和两个图像文件的位置。<br /> display-name display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名称。<br /> description description元素给出与此有关的说明性文本。<br /> context-param context-param元素声明应用范围内的初始化参数。<br /> filter 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联。<br /> filter-mapping 一旦命名了一个过滤器，就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。<br /> listener servlet API的版本2.3增加了对事件监听程序的支持，事件监听程序在建立、修改和删除会话或servlet环境时得到通知。Listener元素指出事件监听程序类。<br /> servlet 在向servlet或JSP页面制定初始化参数或定制URL时，必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。<br /> servlet-mapping 服务器一般为servlet提供一个缺省的URL：<a href="http://host/webAppPrefix/servlet/ServletName"><font color="#e6a306">http://host/webAppPrefix/servlet/ServletName</font></a>。但是，常常会更改这个URL，以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时，使用servlet-mapping元素。<br /> session-config 如果某个会话在一定时间内未被访问，服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveInterval方法明确设置单个会话对象的超时值，或者可利用session-config元素制定缺省超时值。<br /> mime-mapping 如果Web应用具有想到特殊的文件，希望能保证给他们分配特定的MIME类型，则mime-mapping元素提供这种保证。<br /> welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URL时，使用哪个文件。<br /> error-page error-page元素使得在返回特定HTTP状态代码时，或者特定类型的异常被抛出时，能够制定将要显示的页面。<br /> taglib taglib元素对标记库描述符文件（Tag Libraryu Descriptor file）指定别名。此功能使你能够更改TLD文件的位置，而不用编辑使用这些文件的JSP页面。<br /> resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象。<br /> resource-ref resource-ref元素声明一个资源工厂使用的外部资源。<br /> security-constraint security-constraint元素制定应该保护的URL。它与login-config元素联合使用<br /> login-config 用login-config元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。<br /> security-role security-role元素给出安全角色的一个列表，这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。<br /> env-entry env-entry元素声明Web应用的环境项。<br /> ejb-ref ejb-ref元素声明一个EJB的主目录的引用。<br /> ejb-local-ref ejb-local-ref元素声明一个EJB的本地主目录的应用。</p>
		<p>3 分配名称和定制的UL</p>
		<p>在web.xml中完成的一个最常见的任务是对servlet或JSP页面给出名称和定制的URL。用servlet元素分配名称，使用servlet-mapping元素将定制的URL与刚分配的名称相关联。<br />3.1 分配名称<br />为了提供初始化参数，对servlet或JSP页面定义一个定制URL或分配一个安全角色，必须首先给servlet或JSP页面一个名称。可通过servlet元素分配一个名称。最常见的格式包括servlet-name和servlet-class子元素（在web-app元素内），如下所示：<br />&lt;servlet&gt;<br />   &lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />   &lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt; </p>
		<p>这表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已经得到了注册名Test。给servlet一个名称具有两个主要的含义。首先，初始化参数、定制的URL模式以及其他定制通过此注册名而不是类名引用此servlet。其次,可在URL而不是类名中使用此名称。因此，利用刚才给出的定义，URL <a href="http://host/webAppPrefix/servlet/Test"><font color="#e6a306">http://host/webAppPrefix/servlet/Test</font></a> 可用于 <a href="http://host/webAppPrefix/servlet/moreservlets.TestServlet"><font color="#e6a306">http://host/webAppPrefix/servlet/moreservlets.TestServlet</font></a> 的场所。<br />请记住：XML元素不仅是大小写敏感的，而且定义它们的次序也很重要。例如，web-app元素内所有servlet元素必须位于所有servlet-mapping元素（下一小节介绍）之前，而且还要位于5.6节和5.11节讨论的与过滤器或文档相关的元素（如果有的话）之前。类似地，servlet的servlet-name子元素也必须出现在servlet-class之前。5.2节"部署描述符文件内的元素次序"将详细介绍这种必需的次序。<br />例如，程序清单5-1给出了一个名为TestServlet的简单servlet，它驻留在moreservlets程序包中。因为此servlet是扎根在一个名为deployDemo的目录中的Web应用的组成部分，所以TestServlet.class放在deployDemo/WEB-INF/classes/moreservlets中。程序清单5-2给出将放置在deployDemo/WEB-INF/内的web.xml文件的一部分。此web.xml文件使用servlet-name和servlet-class元素将名称Test与TestServlet.class相关联。图5-1和图5-2分别显示利用缺省URL和注册名调用TestServlet时的结果。</p>
		<p>程序清单5-1 TestServlet.java<br />package moreservlets;</p>
		<p>import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;</p>
		<p>/** Simple servlet used to illustrate servlet naming<br />* and custom URLs.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* <a href="http://www.moreservlets.com/"><font color="#e6a306">http://www.moreservlets.com/</font></a>.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p>
		<p>public class TestServlet extends HttpServlet {<br />public void doGet(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />response.setContentType("text/html");<br />PrintWriter out = response.getWriter();<br />String uri = request.getRequestURI();<br />out.println(ServletUtilities.headWithTitle("Test Servlet") +<br />"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />"&lt;H2&gt;URI: " + uri + "&lt;/H2&gt;\n" +<br />"&lt;/BODY&gt;&lt;/HTML&gt;");<br />}<br />}</p>
		<p>
				<br />程序清单5-2 web.xml（说明servlet名称的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;!-- … --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- … --&gt;<br />&lt;/web-app&gt;</p>
		<p>3.2 定义定制的URL<br />大多数服务器具有一个缺省的serlvet URL：<br /><a href="http://host/webAppPrefix/servlet/packageName.ServletName"><font color="#e6a306">http://host/webAppPrefix/servlet/packageName.ServletName</font></a>。虽然在开发中使用这个URL很方便，但是我们常常会希望另一个URL用于部署。例如，可能会需要一个出现在Web应用顶层的URL（如，<a href="http://host/webAppPrefix/Anyname"><font color="#e6a306">http://host/webAppPrefix/Anyname</font></a>），并且在此URL中没有servlet项。位于顶层的URL简化了相对URL的使用。此外，对许多开发人员来说，顶层URL看上去比更长更麻烦的缺省URL更简短。<br />事实上，有时需要使用定制的URL。比如，你可能想关闭缺省URL映射，以便更好地强制实施安全限制或防止用户意外地访问无初始化参数的servlet。如果你禁止了缺省的URL，那么你怎样访问servlet呢？这时只有使用定制的URL了。<br />为了分配一个定制的URL，可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet-name元素提供了一个任意名称，可利用此名称引用相应的servlet；url-pattern描述了相对于Web应用的根目录的URL。url-pattern元素的值必须以斜杠（/）起始。<br />下面给出一个简单的web.xml摘录，它允许使用URL <a href="http://host/webAppPrefix/UrlTest"><font color="#e6a306">http://host/webAppPrefix/UrlTest</font></a>而不是<a href="http://host/webAppPrefix/servlet/Test"><font color="#e6a306">http://host/webAppPrefix/servlet/Test</font></a>或<br /><a href="http://host/webAppPrefix/servlet/moreservlets.TestServlet"><font color="#e6a306">http://host/webAppPrefix/servlet/moreservlets.TestServlet</font></a>。请注意，仍然需要XML头、DOCTYPE声明以及web-app封闭元素。此外，可回忆一下，XML元素出现地次序不是随意的。特别是，需要把所有servlet元素放在所有servlet-mapping元素之前。<br />&lt;servlet&gt;<br />   &lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />   &lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />   &lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />   &lt;url-pattern&gt;/UrlTest&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />URL模式还可以包含通配符。例如，下面的小程序指示服务器发送所有以Web应用的URL前缀开始，以..asp结束的请求到名为BashMS的servlet。<br />&lt;servlet&gt;<br />   &lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />   &lt;servlet-class&gt;msUtils.ASPTranslator&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />   &lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />   &lt;url-pattern&gt;/*.asp&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />3.3 命名JSP页面<br />因为JSP页面要转换成sevlet，自然希望就像命名servlet一样命名JSP页面。毕竟，JSP页面可能会从初始化参数、安全设置或定制的URL中受益，正如普通的serlvet那样。虽然JSP页面的后台实际上是servlet这句话是正确的，但存在一个关键的猜疑：即，你不知道JSP页面的实际类名（因为系统自己挑选这个名字）。因此，为了命名JSP页面，可将jsp-file元素替换为servlet-calss元素，如下所示：<br />&lt;servlet&gt;<br />   &lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />   &lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />&lt;/servlet&gt;<br />命名JSP页面的原因与命名servlet的原因完全相同：即为了提供一个与定制设置（如，初始化参数和安全设置）一起使用的名称，并且，以便能更改激活JSP页面的URL（比方说，以便多个URL通过相同页面得以处理，或者从URL中去掉.jsp扩展名）。但是，在设置初始化参数时，应该注意，JSP页面是利用jspInit方法，而不是init方法读取初始化参数的。<br />例如，程序清单5-3给出一个名为TestPage.jsp的简单JSP页面，它的工作只是打印出用来激活它的URL的本地部分。TestPage.jsp放置在deployDemo应用的顶层。程序清单5-4给出了用来分配一个注册名PageName，然后将此注册名与<a href="http://host/webAppPrefix/UrlTest2/anything"><font color="#e6a306">http://host/webAppPrefix/UrlTest2/anything</font></a> 形式的URL相关联的web.xml文件（即，deployDemo/WEB-INF/web.xml）的一部分。</p>
		<p>程序清单5-3 TestPage.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;<br />&lt;TITLE&gt;<br />JSP Test Page<br />&lt;/TITLE&gt;<br />&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;URI: &lt;%= request.getRequestURI() %&gt;&lt;/H2&gt;<br />&lt;/BODY&gt;<br />&lt;/HTML&gt;</p>
		<p>
				<br />程序清单5-4 web.xml（说明JSP页命名的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />   &lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />   &lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />   &lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />   &lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p>
		<p>
				<br />4 禁止激活器servlet</p>
		<p>对servlet或JSP页面建立定制URL的一个原因是，这样做可以注册从init（servlet）或jspInit（JSP页面）方法中读取得初始化参数。但是，初始化参数只在是利用定制URL模式或注册名访问servlet或JSP页面时可以使用，用缺省URL <a href="http://host/webAppPrefix/servlet/ServletName"><font color="#e6a306">http://host/webAppPrefix/servlet/ServletName</font></a> 访问时不能使用。因此，你可能会希望关闭缺省URL，这样就不会有人意外地调用初始化servlet了。这个过程有时称为禁止激活器servlet，因为多数服务器具有一个用缺省的servlet URL注册的标准servlet，并激活缺省的URL应用的实际servlet。<br />有两种禁止此缺省URL的主要方法：<br />l 在每个Web应用中重新映射/servlet/模式。<br />l 全局关闭激活器servlet。<br />重要的是应该注意到，虽然重新映射每个Web应用中的/servlet/模式比彻底禁止激活servlet所做的工作更多，但重新映射可以用一种完全可移植的方式来完成。相反，全局禁止激活器servlet完全是针对具体机器的，事实上有的服务器（如ServletExec）没有这样的选择。下面的讨论对每个Web应用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局禁止激活器servlet的详细内容。<br />4.1 重新映射/servlet/URL模式<br />在一个特定的Web应用中禁止以<a href="http://host/webAppPrefix/servlet/"><font color="#e6a306">http://host/webAppPrefix/servlet/</font></a> 开始的URL的处理非常简单。所需做的事情就是建立一个错误消息servlet，并使用前一节讨论的url-pattern元素将所有匹配请求转向该servlet。只要简单地使用：<br />&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />作为servlet-mapping元素中的模式即可。<br />例如，程序清单5-5给出了将SorryServlet servlet（程序清单5-6）与所有以<a href="http://host/webAppPrefix/servlet/"><font color="#e6a306">http://host/webAppPrefix/servlet/</font></a> 开头的URL相关联的部署描述符文件的一部分。</p>
		<p>程序清单5-5 web.xml（说明JSP页命名的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />   &lt;servlet-name&gt;Sorry&lt;/servlet-name&gt;<br />   &lt;servlet-class&gt;moreservlets.SorryServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />   &lt;servlet-name&gt; Sorry &lt;/servlet-name&gt;<br />   &lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p>
		<p>
				<br />程序清单5-6 SorryServlet.java<br />package moreservlets;</p>
		<p>import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;</p>
		<p>/** Simple servlet used to give error messages to<br />* users who try to access default servlet URLs<br />* (i.e., <a href="http://host/webAppPrefix/servlet/ServletName"><font color="#e6a306">http://host/webAppPrefix/servlet/ServletName</font></a>)<br />* in Web applications that have disabled this<br />* behavior.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* <a href="http://www.moreservlets.com/"><font color="#e6a306">http://www.moreservlets.com/</font></a>.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p>
		<p>public class SorryServlet extends HttpServlet {<br />public void doGet(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />response.setContentType("text/html");<br />PrintWriter out = response.getWriter();<br />String title = "Invoker Servlet Disabled.";<br />out.println(ServletUtilities.headWithTitle(title) +<br />"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />"&lt;H2&gt;" + title + "&lt;/H2&gt;\n" +<br />"Sorry, access to servlets by means of\n" +<br />"URLs that begin with\n" +<br />"<a href="http://host/webAppPrefix/servlet//n"><font color="#e6a306">http://host/webAppPrefix/servlet/\n</font></a>" +<br />"has been disabled.\n" + <br />"&lt;/BODY&gt;&lt;/HTML&gt;");<br />}</p>
		<p>public void doPost(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />doGet(request, response);<br />}<br />}</p>
		<p>
				<br />4.2 全局禁止激活器：Tomcat<br />Tomcat 4中用来关闭缺省URL的方法与Tomcat 3中所用的很不相同。下面介绍这两种方法：<br />1．禁止激活器： Tomcat 4<br />Tomcat 4用与前面相同的方法关闭激活器servlet，即利用web.xml中的url-mapping元素进行关闭。不同之处在于Tomcat使用了放在install_dir/conf中的一个服务器专用的全局web.xml文件，而前面使用的是存放在每个Web应用的WEB-INF目录中的标准web.xml文件。<br />因此，为了在Tomcat 4中关闭激活器servlet，只需在install_dir/conf/web.xml中简单地注释出/servlet/* URL映射项即可，如下所示：<br />&lt;!-- <br />&lt;servlet-mapping&gt;<br />   &lt;servlet-name&gt;invoker&lt;/servlet-name&gt;<br />   &lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />--&gt;<br />再次提醒，应该注意这个项是位于存放在install_dir/conf的Tomcat专用的web.xml文件中的，此文件不是存放在每个Web应用的WEB-INF目录中的标准web.xml。<br />2．禁止激活器：Tomcat3<br />在Apache Tomcat的版本3中，通过在install_dir/conf/server.xml中注释出InvokerInterceptor项全局禁止缺省servlet URL。例如，下面是禁止使用缺省servlet URL的server.xml文件的一部分。<br />&lt;!-- <br />&lt;RequsetInterceptor <br />className="org.apache.tomcat.request.InvokerInterceptor"<br />debug="0" prefix="/servlet/" /&gt;<br />--&gt;</p>
		<p>5 初始化和预装载servlet与JSP页面</p>
		<p>这里讨论控制servlet和JSP页面的启动行为的方法。特别是，说明了怎样分配初始化参数以及怎样更改服务器生存期中装载servlet和JSP页面的时刻。<br />5.1 分配servlet初始化参数<br />利用init-param元素向servlet提供初始化参数，init-param元素具有param-name和param-value子元素。例如，在下面的例子中，如果initServlet servlet是利用它的注册名（InitTest）访问的，它将能够从其方法中调用getServletConfig().getInitParameter("param1")获得"Value 1"，调用getServletConfig().getInitParameter("param2")获得"2"。<br />&lt;servlet&gt;<br />   &lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />   &lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />&lt;init-param&gt;<br />   &lt;param-name&gt;param1&lt;/param-name&gt;<br />   &lt;param-value&gt;value1&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;init-param&gt;<br />   &lt;param-name&gt;param2&lt;/param-name&gt;<br />   &lt;param-value&gt;2&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;/servlet&gt;<br />在涉及初始化参数时，有几点需要注意：<br />l 返回值。GetInitParameter的返回值总是一个String。因此，在前一个例子中，可对param2使用Integer.parseInt获得一个int。<br />l JSP中的初始化。JSP页面使用jspInit而不是init。JSP页面还需要使用jsp-file元素代替servlet-class。<br />l 缺省URL。初始化参数只在通过它们的注册名或与它们注册名相关的定制URL模式访问Servlet时可以使用。因此，在这个例子中，param1和param2初始化参数将能够在使用URL <a href="http://host/webAppPrefix/servlet/InitTest"><font color="#e6a306">http://host/webAppPrefix/servlet/InitTest</font></a> 时可用，但在使用URL <a href="http://host/webAppPrefix/servlet/myPackage.InitServlet"><font color="#e6a306">http://host/webAppPrefix/servlet/myPackage.InitServlet</font></a> 时不能使用。<br />例如，程序清单5-7给出一个名为InitServlet的简单servlet，它使用init方法设置firstName和emailAddress字段。程序清单5-8给出分配名称InitTest给servlet的web.xml文件。<br />程序清单5-7 InitServlet.java<br />package moreservlets;</p>
		<p>import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;</p>
		<p>/** Simple servlet used to illustrate servlet<br />* initialization parameters.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* <a href="http://www.moreservlets.com/"><font color="#e6a306">http://www.moreservlets.com/</font></a>.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p>
		<p>public class InitServlet extends HttpServlet {<br />private String firstName, emailAddress;</p>
		<p>public void init() {<br />ServletConfig config = getServletConfig();<br />firstName = config.getInitParameter("firstName");<br />emailAddress = config.getInitParameter("emailAddress");<br />}</p>
		<p>public void doGet(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />response.setContentType("text/html");<br />PrintWriter out = response.getWriter();<br />String uri = request.getRequestURI();<br />out.println(ServletUtilities.headWithTitle("Init Servlet") +<br />"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />"&lt;H2&gt;Init Parameters:&lt;/H2&gt;\n" +<br />"&lt;UL&gt;\n" +<br />"&lt;LI&gt;First name: " + firstName + "\n" +<br />"&lt;LI&gt;Email address: " + emailAddress + "\n" +<br />"&lt;/UL&gt;\n" + <br />"&lt;/BODY&gt;&lt;/HTML&gt;");<br />}<br />}</p>
		<p>
				<br />程序清单5-8 web.xml（说明初始化参数的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />   &lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />   &lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />   &lt;init-param&gt;<br />      &lt;param-name&gt;firstName&lt;/param-name&gt;<br />      &lt;param-value&gt;Larry&lt;/param-value&gt;<br />   &lt;/init-param&gt;<br />   &lt;init-param&gt;<br />      &lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />      &lt;param-value&gt;Ellison@Microsoft.com&lt;/param-value&gt;<br />   &lt;/init-param&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p>
		<p>5.2 分配JSP初始化参数<br />给JSP页面提供初始化参数在三个方面不同于给servlet提供初始化参数。<br />1）使用jsp-file而不是servlet-class。因此，WEB-INF/web.xml文件的servlet元素如下所示：<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />&lt;init-param&gt;<br />   &lt;param-name&gt;...&lt;/param-name&gt;<br />   &lt;param-value&gt;...&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />...<br />&lt;/servlet&gt;<br />2)几乎总是分配一个明确的URL模式。对servlet，一般相应地使用以<a href="http://host/webAppPrefix/servlet/"><font color="#e6a306">http://host/webAppPrefix/servlet/</font></a> 开始的缺省URL。只需记住，使用注册名而不是原名称即可。这对于JSP页面在技术上也是合法的。例如，在上面给出的例子中，可用URL <a href="http://host/webAppPrefix/servlet/PageName"><font color="#e6a306">http://host/webAppPrefix/servlet/PageName</font></a> 访问RealPage.jsp的对初始化参数具有访问权的版本。但在用于JSP页面时，许多用户似乎不喜欢应用常规的servlet的URL。此外，如果JSP页面位于服务器为其提供了目录清单的目录中（如，一个既没有index.html也没有index.jsp文件的目录），则用户可能会连接到此JSP页面，单击它，从而意外地激活未初始化的页面。因此，好的办法是使用url-pattern（5.3节）将JSP页面的原URL与注册的servlet名相关联。这样，客户机可使用JSP页面的普通名称，但仍然激活定制的版本。例如，给定来自项目1的servlet定义，可使用下面的servlet-mapping定义：<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/RealPage.jsp&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />3）JSP页使用jspInit而不是init。自动从JSP页面建立的servlet或许已经使用了inti方法。因此，使用JSP声明提供一个init方法是不合法的，必须制定jspInit方法。<br />为了说明初始化JSP页面的过程，程序清单5-9给出了一个名为InitPage.jsp的JSP页面，它包含一个jspInit方法且放置于deployDemo Web应用层次结构的顶层。一般，<a href="http://host/deployDemo/InitPage.jsp"><font color="#e6a306">http://host/deployDemo/InitPage.jsp</font></a> 形式的URL将激活此页面的不具有初始化参数访问权的版本，从而将对firstName和emailAddress变量显示null。但是，web.xml文件（程序清单5-10）分配了一个注册名，然后将该注册名与URL模式/InitPage.jsp相关联。</p>
		<p>程序清单5-9 InitPage.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;&lt;TITLE&gt;JSP Init Test&lt;/TITLE&gt;&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;Init Parameters:&lt;/H2&gt;<br />&lt;UL&gt;<br />&lt;LI&gt;First name: &lt;%= firstName %&gt;<br />&lt;LI&gt;Email address: &lt;%= emailAddress %&gt;<br />&lt;/UL&gt;<br />&lt;/BODY&gt;&lt;/HTML&gt;<br />&lt;%!<br />private String firstName, emailAddress;</p>
		<p>public void jspInit() {<br />ServletConfig config = getServletConfig();<br />firstName = config.getInitParameter("firstName");<br />emailAddress = config.getInitParameter("emailAddress");<br />}<br />%&gt;</p>
		<p>
				<br />程序清单5-10 web.xml（说明JSP页面的init参数的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;InitPage&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/InitPage.jsp&lt;/jsp-file&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;firstName&lt;/param-name&gt;<br />&lt;param-value&gt;Bill&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />&lt;param-value&gt;gates@oracle.com&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt; <br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; InitPage&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/InitPage.jsp&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p>
		<p>
				<br />5.3 提供应用范围内的初始化参数<br />一般，对单个地servlet或JSP页面分配初始化参数。指定的servlet或JSP页面利用ServletConfig的getInitParameter方法读取这些参数。但是，在某些情形下，希望提供可由任意servlet或JSP页面借助ServletContext的getInitParameter方法读取的系统范围内的初始化参数。<br />可利用context-param元素声明这些系统范围内的初始化值。context-param元素应该包含param-name、param-value以及可选的description子元素，如下所示：<br />&lt;context-param&gt;<br />&lt;param-name&gt;support-email&lt;/param-name&gt;<br />&lt;param-value&gt;blackhole@mycompany.com&lt;/param-value&gt;<br />&lt;/context-param&gt;<br />可回忆一下，为了保证可移植性，web.xml内的元素必须以正确的次序声明。但这里应该注意，context-param元素必须出现任意与文档有关的元素（icon、display-name或description）之后及filter、filter-mapping、listener或servlet元素之前。<br />5.4 在服务器启动时装载servlet<br />假如servlet或JSP页面有一个要花很长时间执行的init（servlet）或jspInit（JSP）方法。例如，假如init或jspInit方法从某个数据库或ResourceBundle查找产量。这种情况下，在第一个客户机请求时装载servlet的缺省行为将对第一个客户机产生较长时间的延迟。因此，可利用servlet的load-on-startup元素规定服务器在第一次启动时装载servlet。下面是一个例子。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt; … &lt;/servlet-name&gt;<br />&lt;servlet-class&gt; … &lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />&lt;load-on-startup/&gt;<br />&lt;/servlet&gt;<br />可以为此元素体提供一个整数而不是使用一个空的load-on-startup。想法是服务器应该在装载较大数目的servlet或JSP页面之前装载较少数目的servlet或JSP页面。例如，下面的servlet项（放置在Web应用的WEB-INF目录下的web.xml文件中的web-app元素内）将指示服务器首先装载和初始化SearchServlet，然后装载和初始化由位于Web应用的result目录中的index.jsp文件产生的servlet。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Search&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;myPackage.SearchServlet&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />&lt;/servlet&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Results&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;/results/index.jsp&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br />&lt;/servlet&gt;</p>
		<p>6 声明过滤器</p>
		<p>servlet版本2.3引入了过滤器的概念。虽然所有支持servlet API版本2.3的服务器都支持过滤器，但为了使用与过滤器有关的元素，必须在web.xml中使用版本2.3的DTD。<br />过滤器可截取和修改进入一个servlet或JSP页面的请求或从一个servlet或JSP页面发出的相应。在执行一个servlet或JSP页面之前，必须执行第一个相关的过滤器的doFilter方法。在该过滤器对其FilterChain对象调用doFilter时，执行链中的下一个过滤器。如果没有其他过滤器，servlet或JSP页面被执行。过滤器具有对到来的ServletRequest对象的全部访问权，因此，它们可以查看客户机名、查找到来的cookie等。为了访问servlet或JSP页面的输出，过滤器可将响应对象包裹在一个替身对象（stand-in object）中，比方说把输出累加到一个缓冲区。在调用FilterChain对象的doFilter方法之后，过滤器可检查缓冲区，如有必要，就对它进行修改，然后传送到客户机。<br />例如，程序清单5-11帝国难以了一个简单的过滤器，只要访问相关的servlet或JSP页面，它就截取请求并在标准输出上打印一个报告（开发过程中在桌面系统上运行时，大多数服务器都可以使用这个过滤器）。</p>
		<p>程序清单5-11 ReportFilter.java<br />package moreservlets;</p>
		<p>import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;<br />import java.util.*;</p>
		<p>/** Simple filter that prints a report on the standard output <br />* whenever the associated servlet or JSP page is accessed.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* <a href="http://www.moreservlets.com/"><font color="#e6a306">http://www.moreservlets.com/</font></a>.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p>
		<p>public class ReportFilter implements Filter {<br />public void doFilter(ServletRequest request,<br />ServletResponse response,<br />FilterChain chain)<br />throws ServletException, IOException {<br />HttpServletRequest req = (HttpServletRequest)request;<br />System.out.println(req.getRemoteHost() +<br />" tried to access " +<br />req.getRequestURL() +<br />" on " + new Date() + ".");<br />chain.doFilter(request,response);<br />}</p>
		<p>public void init(FilterConfig config)<br />throws ServletException {<br />}</p>
		<p>public void destroy() {}<br />}</p>
		<p>一旦建立了一个过滤器，可以在web.xml中利用filter元素以及filter-name（任意名称）、file-class（完全限定的类名）和（可选的）init-params子元素声明它。请注意，元素在web.xml的web-app元素中出现的次序不是任意的；允许服务器（但不是必需的）强制所需的次序，并且实际中有些服务器也是这样做的。但这里要注意，所有filter元素必须出现在任意filter-mapping元素之前，filter-mapping元素又必须出现在所有servlet或servlet-mapping元素之前。<br />例如，给定上述的ReportFilter类，可在web.xml中作出下面的filter声明。它把名称Reporter与实际的类ReportFilter（位于moreservlets程序包中）相关联。<br />&lt;filter&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />&lt;/filter&gt;<br />一旦命名了一个过滤器，可利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。关于此项工作有两种选择。<br />首先，可使用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名（此servlet名必须稍后在相同的web.xml文件中使用servlet元素声明）关联。例如，下面的程序片断指示系统只要利用一个定制的URL访问名为SomeServletName的servlet或JSP页面，就运行名为Reporter的过滤器。<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;servlet-name&gt;SomeServletName&lt;/servlet-name&gt;<br />&lt;/filter-mapping&gt;<br />其次，可利用filter-name和url-pattern子元素将过滤器与一组servlet、JSP页面或静态内容相关联。例如，相面的程序片段指示系统只要访问Web应用中的任意URL，就运行名为Reporter的过滤器。<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />&lt;/filter-mapping&gt;<br />例如，程序清单5-12给出了将ReportFilter过滤器与名为PageName的servlet相关联的web.xml文件的一部分。名字PageName依次又与一个名为TestPage.jsp的JSP页面以及以模式<a href="http://host/webAppPrefix/UrlTest2/"><font color="#e6a306">http://host/webAppPrefix/UrlTest2/</font></a> 开头的URL相关联。TestPage.jsp的源代码已经JSP页面命名的谈论在前面的3节"分配名称和定制的URL"中给出。事实上，程序清单5-12中的servlet和servlet-name项从该节原封不动地拿过来的。给定这些web.xml项，可看到下面的标准输出形式的调试报告（换行是为了容易阅读）。<br />audit.irs.gov tried to access <br /><a href="http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html"><font color="#e6a306">http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html</font></a><br />on Tue Dec 25 13:12:29 EDT 2001.</p>
		<p>程序清单5-12 Web.xml（说明filter用法的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;filter&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />&lt;/filter&gt;<br />&lt;!-- ... --&gt;<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;/filter-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p>
		<p>
				<font color="#cccccc">7 指定欢迎页 </font>
		</p>
		<p>假如用户提供了一个像<a href="http://host/webAppPrefix/directoryName/"><font color="#e6a306">http://host/webAppPrefix/directoryName/</font></a> 这样的包含一个目录名但没有包含文件名的URL，会发生什么事情呢？用户能得到一个目录表？一个错误？还是标准文件的内容？如果得到标准文件内容，是index.html、index.jsp、default.html、default.htm或别的什么东西呢？<br />Welcome-file-list元素及其辅助的welcome-file元素解决了这个模糊的问题。例如，下面的web.xml项指出，如果一个URL给出一个目录名但未给出文件名，服务器应该首先试用index.jsp，然后再试用index.html。如果两者都没有找到，则结果有赖于所用的服务器（如一个目录列表）。<br />&lt;welcome-file-list&gt;<br />&lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br />&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;<br />&lt;/welcome-file-list&gt;<br />虽然许多服务器缺省遵循这种行为，但不一定必须这样。因此，明确地使用welcom-file-list保证可移植性是一种良好的习惯。</p>
		<p>8 指定处理错误的页面</p>
		<p>现在我了解到，你在开发servlet和JSP页面时从不会犯错误，而且你的所有页面是那样的清晰，一般的程序员都不会被它们的搞糊涂。但是，是人总会犯错误的，用户可能会提供不合规定的参数，使用不正确的URL或者不能提供必需的表单字段值。除此之外，其它开发人员可能不那么细心，他们应该有些工具来克服自己的不足。<br />error-page元素就是用来克服这些问题的。它有两个可能的子元素，分别是：error-code和exception-type。第一个子元素error-code指出在给定的HTTP错误代码出现时使用的URL。第二个子元素excpetion-type指出在出现某个给定的Java异常但未捕捉到时使用的URL。error-code和exception-type都利用location元素指出相应的URL。此URL必须以/开始。location所指出的位置处的页面可通过查找HttpServletRequest对象的两个专门的属性来访问关于错误的信息，这两个属性分别是：javax.servlet.error.status_code和javax.servlet.error.message。<br />可回忆一下，在web.xml内以正确的次序声明web-app的子元素很重要。这里只要记住，error-page出现在web.xml文件的末尾附近，servlet、servlet-name和welcome-file-list之后即可。</p>
		<p>8.1 error-code元素<br />为了更好地了解error-code元素的值，可考虑一下如果不正确地输入文件名，大多数站点会作出什么反映。这样做一般会出现一个<font size="+0">404</font>错误信息，它表示不能找到该文件，但几乎没提供更多有用的信息。另一方面，可以试一下在<a href="http://www.microsoft.com/"><font color="#e6a306">www.microsoft.com</font></a>、<a href="http://www.ibm.com/"><font color="#e6a306">www.ibm.com</font></a> 处或者特别是在<a href="http://www.bea.com/"><font color="#e6a306">www.bea.com</font></a> 处输出未知的文件名。这是会得出有用的消息，这些消息提供可选择的位置，以便查找感兴趣的页面。提供这样有用的错误页面对于Web应用来说是很有价值得。事实上，<a href="http://www.plinko.net/404/"><font color="#e6a306">http://www.plinko.net/404/</font></a> 就是把整个站点专门用于<font size="+0">404</font>错误页面这个内容。这个站点包含来自全世界最好、最糟和最搞笑的<font size="+0">404</font>页面。<br />程序清单5-13给出一个JSP页面，此页面可返回给提供位置程序名的客户机。程序清单5-14给出指定程序清单5-13作为返回<font size="+0">404</font>错误代码时显示的页面的web.xml。请注意，浏览器中显示的URL仍然是客户机所提供的。错误页面是一种后台实现技术。<br />最后一点，请记住IE5的缺省配置显然不符合HTTP规范，它忽略了服务器生成的错误消息，而是显示自己的标准出错信息。可转到其Tools菜单，选择Internet Options，单击Advanced，取消Show Friendly HTTP Error Message来解决此问题。</p>
		<p>程序清单5-13 NotFound.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;&lt;TITLE&gt;<font size="+0">404</font>: Not Found&lt;/TITLE&gt;&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;Error!&lt;/H2&gt;<br />I'm sorry, but I cannot find a page that matches<br />&lt;%= request.getRequestURI() %&gt; on the system. Maybe you should<br />try one of the following:<br />&lt;UL&gt;<br />&lt;LI&gt;Go to the server's &lt;A HREF="/"&gt;home page&lt;/A&gt;.<br />&lt;LI&gt;Search for relevant pages.&lt;BR&gt;<br />&lt;FORM ACTION="<a href="http://www.google.com/search"><font color="#e6a306">http://www.google.com/search</font></a>"&gt;<br />&lt;CENTER&gt;<br />Keywords: &lt;INPUT TYPE="TEXT" NAME="q"&gt;&lt;BR&gt;<br />&lt;INPUT TYPE="SUBMIT" VALUE="Search"&gt;<br />&lt;/CENTER&gt;<br />&lt;/FORM&gt;<br />&lt;LI&gt;Admire a random multiple of <font size="+0">404</font>:<br />&lt;%= <font size="+0">404</font>*((int)(1000*Math.random())) %&gt;.<br />&lt;LI&gt;Try a &lt;A HREF="<a href="http://www.plinko.net/404/rndindex.asp"><font color="#e6a306">http://www.plinko.net/404/rndindex.asp</font></a>"<br />TARGET="_blank"&gt;<br />random <font size="+0">404</font> error message&lt;/A&gt;. From the amazing and<br />amusing plinko.net &lt;A HREF="<a href="http://www.plinko.net/404/"><font color="#e6a306">http://www.plinko.net/404/</font></a>"&gt;<br /><font size="+0">404</font> archive&lt;/A&gt;.<br />&lt;/UL&gt;<br />&lt;/BODY&gt;&lt;/HTML&gt;</p>
		<p>
				<br />程序清单5-14 web.xml（指出HTTP错误代码的错误页面的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;error-page&gt;<br />&lt;error-code&gt;<font size="+0">404</font>&lt;/error-code&gt;<br />&lt;location&gt;/NotFound.jsp&lt;/location&gt;<br />&lt;/error-page&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p>
		<p>
				<br />8.2 exception-type元素<br />error-code元素处理某个请求产生一个特定的HTTP状态代码时的情况。然而，对于servlet或JSP页面返回200但产生运行时异常这种同样是常见的情况怎么办呢？这正是exception-type元素要处理的情况。只需提供两样东西即可：即提供如下的一个完全限定的异常类和一个位置：<br />&lt;error-page&gt;<br />&lt;exception-type&gt;packageName.className&lt;/exception-type&gt;<br />&lt;location&gt;/SomeURL&lt;/location&gt;<br />&lt;/error-page&gt;<br />这样，如果Web应用中的任何servlet或JSP页面产生一个特定类型的未捕捉到的异常，则使用指定的URL。此异常类型可以是一个标准类型，如javax.ServletException或java.lang.OutOfMemoryError，或者是一个专门针对你的应用的异常。<br />例如，程序清单5-15给出了一个名为DumbDeveloperException的异常类，可用它来特别标记经验较少的程序员（不是说你的开发组中一定有这种人）所犯的错误。这个类还包含一个名为dangerousComputation的静态方法，它时不时地生成这种类型的异常。程序清单5-16给出对随机整数值调用dangerousCompution的一个JSP页面。在抛出此异常时，如程序清单5-18的web.xml版本中所给出的exception-type所指出的那样，对客户机显示DDE.jsp（程序清单5-17）。图5-16和图5-17分别给出幸运和不幸的结果。</p>
		<p>程序清单5-15 DumbDeveloperException.java<br />package moreservlets;</p>
		<p>/** Exception used to flag particularly onerous<br />programmer blunders. Used to illustrate the<br />exception-type web.xml element.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* <a href="http://www.moreservlets.com/"><font color="#e6a306">http://www.moreservlets.com/</font></a>.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p>
		<p>public class DumbDeveloperException extends Exception {<br />public DumbDeveloperException() {<br />super("Duh. What was I *thinking*?");<br />}</p>
		<p>public static int dangerousComputation(int n)<br />throws DumbDeveloperException {<br />if (n &lt; 5) {<br />return(n + 10);<br />} else {<br />throw(new DumbDeveloperException());<br />}<br />}<br />}</p>
		<p>
				<br />程序清单5-16 RiskyPage.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;&lt;TITLE&gt;Risky JSP Page&lt;/TITLE&gt;&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;Risky Calculations&lt;/H2&gt;<br />&lt;%@ page import="moreservlets.*" %&gt;<br />&lt;% int n = ((int)(10 * Math.random())); %&gt;<br />&lt;UL&gt;<br />&lt;LI&gt;n: &lt;%= n %&gt;<br />&lt;LI&gt;dangerousComputation(n): <br />&lt;%= DumbDeveloperException.dangerousComputation(n) %&gt;<br />&lt;/UL&gt;<br />&lt;/BODY&gt;&lt;/HTML&gt;</p>
		<p>
				<br />程序清单5-17 DDE.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;&lt;TITLE&gt;Dumb&lt;/TITLE&gt;&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;Dumb Developer&lt;/H2&gt;<br />We're brain dead. Consider using our competitors.<br />&lt;/BODY&gt;&lt;/HTML&gt;</p>
		<p>
				<br />程序清单5-18 web.xml（为异常指定错误页面的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt; … &lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;error-page&gt;<br />&lt;exception-type&gt;<br />moreservlets.DumbDeveloperException<br />&lt;/exception-type&gt;<br />&lt;location&gt;/DDE.jsp&lt;/location&gt;<br />&lt;/error-page&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p>
		<p>9 提供安全性</p>
		<p>利用web.xml中的相关元素为服务器的内建功能提供安全性。<br />9.1 指定验证的方法<br />使用login-confgi元素规定服务器应该怎样验证试图访问受保护页面的用户。它包含三个可能的子元素，分别是：auth-method、realm-name和form-login-config。login-config元素应该出现在web.xml部署描述符文件的结尾附近，紧跟在security-constraint元素之后。<br /> auth-method<br />login-config的这个子元素列出服务器将要使用的特定验证机制。有效值为BASIC、DIGEST、FORM和CLIENT-CERT。服务器只需要支持BASIC和FORM。<br />BASIC指出应该使用标准的HTTP验证，在此验证中服务器检查Authorization头。如果缺少这个头则返回一个401状态代码和一个WWW-Authenticate头。这导致客户机弹出一个用来填写Authorization头的对话框。此机制很少或不提供对攻击者的防范，这些攻击者在Internet连接上进行窥探（如通过在客户机的子网上执行一个信息包探测装置），因为用户名和口令是用简单的可逆base64编码发送的，他们很容易得手。所有兼容的服务器都需要支持BASIC验证。<br />DIGEST指出客户机应该利用加密Digest Authentication形式传输用户名和口令。这提供了比BASIC验证更高的防范网络截取得的安全性，但这种加密比SSL（HTTPS）所用的方法更容易破解。不过，此结论有时没有意义，因为当前很少有浏览器支持Digest Authentication，所以servlet容器不需要支持它。<br />FORM指出服务器应该检查保留的会话cookie并且把不具有它的用户重定向到一个指定的登陆页。此登陆页应该包含一个收集用户名和口令的常规HTML表单。在登陆之后，利用保留会话级的cookie跟踪用户。虽然很复杂，但FORM验证防范网络窥探并不比BASIC验证更安全，如果有必要可以在顶层安排诸如SSL或网络层安全（如IPSEC或VPN）等额外的保护。所有兼容的服务器都需要支持FORM验证。<br />CLIENT-CERT规定服务器必须使用HTTPS（SSL之上的HTTP）并利用用户的公开密钥证书（Pulic Key Certificat）对用户进行验证。这提供了防范网络截取的很强的安全性，但只有兼容J2EE的服务器需要支持它。<br /> realm-name<br />此元素只在auth-method为BASIC时使用。它指出浏览器在相应对话框标题使用的、并作为Authorization头组成部分的安全域的名称。<br /> form-login-config<br />此元素只在auth-method为FORM时适用。它指定两个页面，分别是：包含收集用户名及口令的HTML表单的页面（利用form-login-page子元素），用来指示验证失败的页面（利用form-error-page子元素）。由form-login-page给出的HTML表单必须具有一个j_security_check的ACTION属性、一个名为j_username的用户名文本字段以及一个名为j_password的口令字段。<br />例如，程序清单5-19指示服务器使用基于表单的验证。Web应用的顶层目录中的一个名为login.jsp的页面将收集用户名和口令，并且失败的登陆将由相同目录中名为login-error.jsp的页面报告。</p>
		<p>程序清单5-19 web.xml（说明login-config的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;security-constraint&gt; ... &lt;/security-constraint&gt;<br />&lt;login-config&gt;<br />&lt;auth-method&gt; FORM &lt;/auth-method&gt;<br />&lt;form-login-config&gt;<br />&lt;form-login-page&gt;/login.jsp&lt;/form-login-page&gt;<br />&lt;form-error-page&gt;/login-error.jsp&lt;/form-error-page&gt;<br />&lt;/form-login-config&gt;<br />&lt;/login-config&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p>
		<p>
				<br />9.2 限制对Web资源的访问<br />现在，可以指示服务器使用何种验证方法了。"了不起，"你说道，"除非我能指定一个来收到保护的URL，否则没有多大用处。"没错。指出这些URL并说明他们应该得到何种保护正是security-constriaint元素的用途。此元素在web.xml中应该出现在login-config的紧前面。它包含是个可能的子元素，分别是：web-resource-collection、auth-constraint、user-data-constraint和display-name。下面各小节对它们进行介绍。<br /> web-resource-collection<br />此元素确定应该保护的资源。所有security-constraint元素都必须包含至少一个web-resource-collection项。此元素由一个给出任意标识名称的web-resource-name元素、一个确定应该保护的URL的url-pattern元素、一个指出此保护所适用的HTTP命令（GET、POST等，缺省为所有方法）的http-method元素和一个提供资料的可选description元素组成。例如，下面的Web-resource-collection项（在security-constratint元素内）指出Web应用的proprietary目录中所有文档应该受到保护。<br />&lt;security-constraint&gt;<br />&lt;web-resource-coolection&gt;<br />&lt;web-resource-name&gt;Proprietary&lt;/web-resource-name&gt;<br />&lt;url-pattern&gt;/propritary/*&lt;/url-pattern&gt;<br />&lt;/web-resource-coolection&gt;<br />&lt;!-- ... --&gt;<br />&lt;/security-constraint&gt;<br />重要的是应该注意到，url-pattern仅适用于直接访问这些资源的客户机。特别是，它不适合于通过MVC体系结构利用RequestDispatcher来访问的页面，或者不适合于利用类似jsp:forward的手段来访问的页面。这种不匀称如果利用得当的话很有好处。例如，servlet可利用MVC体系结构查找数据，把它放到bean中，发送请求到从bean中提取数据的JSP页面并显示它。我们希望保证决不直接访问受保护的JSP页面，而只是通过建立该页面将使用的bean的servlet来访问它。url-pattern和auth-contraint元素可通过声明不允许任何用户直接访问JSP页面来提供这种保证。但是，这种不匀称的行为可能让开发人员放松警惕，使他们偶然对应受保护的资源提供不受限制的访问。 <br /> auth-constraint<br />尽管web-resource-collention元素质出了哪些URL应该受到保护，但是auth-constraint元素却指出哪些用户应该具有受保护资源的访问权。此元素应该包含一个或多个标识具有访问权限的用户类别role-name元素，以及包含（可选）一个描述角色的description元素。例如，下面web.xml中的security-constraint元素部门规定只有指定为Administrator或Big Kahuna（或两者）的用户具有指定资源的访问权。<br />&lt;security-constraint&gt;<br />&lt;web-resource-coolection&gt; ... &lt;/web-resource-coolection&gt;<br />&lt;auth-constraint&gt;<br />&lt;role-name&gt;administrator&lt;/role-name&gt;<br />&lt;role-name&gt;kahuna&lt;/role-name&gt;<br />&lt;/auth-constraint&gt;<br />&lt;/security-constraint&gt;<br />重要的是认识到，到此为止，这个过程的可移植部分结束了。服务器怎样确定哪些用户处于任何角色以及它怎样存放用户的口令，完全有赖于具体的系统。<br />例如，Tomcat使用install_dir/conf/tomcat-users.xml将用户名与角色名和口令相关联，正如下面例子中所示，它指出用户joe（口令bigshot）和jane（口令enaj）属于administrator和kahuna角色。<br />&lt;tomcat-users&gt;<br />&lt;user name="joe" password="bigshot" roles="administrator,kahuna" /&gt;<br />&lt;user name="jane" password="enaj" roles="kahuna" /&gt;<br />&lt;/tomcat-users&gt;<br /> user-data-constraint<br />这个可选的元素指出在访问相关资源时使用任何传输层保护。它必须包含一个transport-guarantee子元素（合法值为NONE、INTEGRAL或CONFIDENTIAL），并且可选地包含一个description元素。transport-guarantee为NONE值将对所用的通讯协议不加限制。INTEGRAL值表示数据必须以一种防止截取它的人阅读它的方式传送。虽然原理上（并且在未来的HTTP版本中），在INTEGRAL和CONFIDENTIAL之间可能会有差别，但在当前实践中，他们都只是简单地要求用SSL。例如，下面指示服务器只允许对相关资源做HTTPS连接：<br />&lt;security-constraint&gt;<br />&lt;!-- ... --&gt;<br />&lt;user-data-constraint&gt;<br />&lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;<br />&lt;/user-data-constraint&gt;<br />&lt;/security-constraint&gt;<br /> display-name<br />security-constraint的这个很少使用的子元素给予可能由GUI工具使用的安全约束项一个名称。<br />9.3 分配角色名<br />迄今为止，讨论已经集中到完全由容器（服务器）处理的安全问题之上了。但servlet以及JSP页面也能够处理它们自己的安全问题。<br />例如，容器可能允许用户从bigwig或bigcheese角色访问一个显示主管人员额外紧贴的页面，但只允许bigwig用户修改此页面的参数。完成这种更细致的控制的一种常见方法是调用HttpServletRequset的isUserInRole方法，并据此修改访问。<br />Servlet的security-role-ref子元素提供出现在服务器专用口令文件中的安全角色名的一个别名。例如，假如编写了一个调用request.isUserInRole（"boss"）的servlet，但后来该servlet被用在了一个其口令文件调用角色manager而不是boss的服务器中。下面的程序段使该servlet能够使用这两个名称中的任何一个。<br />&lt;servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;security-role-ref&gt;<br />&lt;role-name&gt;boss&lt;/role-name&gt; &lt;!-- New alias --&gt;<br />&lt;role-link&gt;manager&lt;/role-link&gt; &lt;!-- Real name --&gt;<br />&lt;/security-role-ref&gt;<br />&lt;/servlet&gt;<br />也可以在web-app内利用security-role元素提供将出现在role-name元素中的所有安全角色的一个全局列表。分别地生命角色使高级IDE容易处理安全信息。</p>
		<p>10 控制会话超时</p>
		<p>如果某个会话在一定的时间内未被访问，服务器可把它扔掉以节约内存。可利用HttpSession的setMaxInactiveInterval方法直接设置个别会话对象的超时值。如果不采用这种方法，则缺省的超时值由具体的服务器决定。但可利用session-config和session-timeout元素来给出一个适用于所有服务器的明确的超时值。超时值的单位为分钟，因此，下面的例子设置缺省会话超时值为三个小时（180分钟）。<br />&lt;session-config&gt;<br />&lt;session-timeout&gt;180&lt;/session-timeout&gt;<br />&lt;/session-config&gt;</p>
		<p>11 Web应用的文档化</p>
		<p>越来越多的开发环境开始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun Studio（写此文时，已被Macromedia收购）以及IBM VisuaAge for Java等。<br />大量的web.xml元素不仅是为服务器设计的，而且还是为可视开发环境设计的。它们包括icon、display-name和discription等。<br />可回忆一下，在web.xml内以适当地次序声明web-app子元素很重要。不过，这里只要记住icon、display-name和description是web.xml的web-app元素内的前三个合法元素即可。<br />l icon<br />icon元素指出GUI工具可用来代表Web应用的一个和两个图像文件。可利用small-icon元素指定一幅16 x 16的GIF或JPEG图像，用large-icon元素指定一幅32 x 32的图像。下面举一个例子： <br />&lt;icon&gt;<br />&lt;small-icon&gt;/images/small-book.gif&lt;/small-icon&gt;<br />&lt;large-icon&gt;/images/tome.jpg&lt;/large-icon&gt;<br />&lt;/icon&gt;<br /> display-name<br />display-name元素提供GUI工具可能会用来标记此Web应用的一个名称。下面是个例子。<br />&lt;display-name&gt;Rare Books&lt;/display-name&gt;<br /> description<br />description元素提供解释性文本，如下所示：<br />&lt;description&gt;<br />This Web application represents the store developed for<br />rare-books.com, an online bookstore specializing in rare<br />and limited-edition books.<br />&lt;/description&gt;</p>
		<p>12 关联文件与MIME类型</p>
		<p>服务器一般都具有一种让Web站点管理员将文件扩展名与媒体相关联的方法。例如，将会自动给予名为mom.jpg的文件一个image/jpeg的MIME类型。但是，假如你的Web应用具有几个不寻常的文件，你希望保证它们在发送到客户机时分配为某种MIME类型。mime-mapping元素（具有extension和mime-type子元素）可提供这种保证。例如，下面的代码指示服务器将application/x-fubar的MIME类型分配给所有以.foo结尾的文件。<br />&lt;mime-mapping&gt;<br />&lt;extension&gt;foo&lt;/extension&gt;<br />&lt;mime-type&gt;application/x-fubar&lt;/mime-type&gt;<br />&lt;/mime-mapping&gt;<br />或许，你的Web应用希望重载（override）标准的映射。例如，下面的代码将告诉服务器在发送到客户机时指定.ps文件作为纯文本（text/plain）而不是作为PostScript（application/postscript）。<br />&lt;mime-mapping&gt;<br />&lt;extension&gt;ps&lt;/extension&gt;<br />&lt;mime-type&gt;application/postscript&lt;/mime-type&gt;<br />&lt;/mime-mapping&gt;</p>
		<p>
				<br />13 定位TLD</p>
		<p>JSP taglib元素具有一个必要的uri属性，它给出一个TLD（Tag Library Descriptor）文件相对于Web应用的根的位置。TLD文件的实际名称在发布新的标签库版本时可能会改变，但我们希望避免更改所有现有JSP页面。此外，可能还希望使用保持taglib元素的简练性的一个简短的uri。这就是部署描述符文件的taglib元素派用场的所在了。Taglib包含两个子元素：taglib-uri和taglib-location。taglib-uri元素应该与用于JSP taglib元素的uri属性的东西相匹配。Taglib-location元素给出TLD文件的实际位置。例如，假如你将文件chart-tags-1.3beta.tld放在WebApp/WEB-INF/tlds中。现在，假如web.xml在web-app元素内包含下列内容。<br />&lt;taglib&gt;<br />&lt;taglib-uri&gt;/charts.tld&lt;/taglib-uri&gt;<br />&lt;taglib-location&gt;<br />/WEB-INF/tlds/chart-tags-1.3beta.tld<br />&lt;/taglib-location&gt;<br />&lt;/taglib&gt;<br />给出这个说明后，JSP页面可通过下面的简化形式使用标签库。<br />&lt;%@ taglib uri="/charts.tld" prefix="somePrefix" %&gt;</p>
		<p>14 指定应用事件监听程序</p>
		<p>应用事件监听器程序是建立或修改servlet环境或会话对象时通知的类。它们是servlet规范的版本2.3中的新内容。这里只简单地说明用来向Web应用注册一个监听程序的web.xml的用法。<br />注册一个监听程序涉及在web.xml的web-app元素内放置一个listener元素。在listener元素内，listener-class元素列出监听程序的完整的限定类名，如下所示：<br />&lt;listener&gt;<br />&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />&lt;/listener&gt;<br />虽然listener元素的结构很简单，但请不要忘记，必须正确地给出web-app元素内的子元素的次序。listener元素位于所有的servlet元素之前以及所有filter-mapping元素之后。此外，因为应用生存期监听程序是serlvet规范的2.3版本中的新内容，所以必须使用web.xml DTD的2.3版本，而不是2.2版本。<br />例如，程序清单5-20给出一个名为ContextReporter的简单的监听程序，只要Web应用的Servlet-Context建立（如装载Web应用）或消除（如服务器关闭）时，它就在标准输出上显示一条消息。程序清单5-21给出此监听程序注册所需要的web.xml文件的一部分。</p>
		<p>程序清单5-20 ContextReporterjava<br />package moreservlets;</p>
		<p>import javax.servlet.*;<br />import java.util.*;</p>
		<p>/** Simple listener that prints a report on the standard output <br />* when the ServletContext is created or destroyed.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* <a href="http://www.moreservlets.com/"><font color="#e6a306">http://www.moreservlets.com/</font></a>.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p>
		<p>public class ContextReporter implements ServletContextListener {<br />public void contextInitialized(ServletContextEvent event) {<br />System.out.println("Context created on " +<br />new Date() + ".");<br />}</p>
		<p>public void contextDestroyed(ServletContextEvent event) {<br />System.out.println("Context destroyed on " +<br />new Date() + ".");<br />}<br />}</p>
		<p>
				<br />程序清单5-21 web.xml（声明一个监听程序的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#e6a306">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;</p>
		<p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;filter-mapping&gt; … &lt;/filter-mapping&gt;<br />&lt;listener&gt;<br />&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />&lt;/listener&gt;<br />&lt;servlet&gt; ... &lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p>
		<p>
				<br />15 J2EE元素</p>
		<p>本节描述用作J2EE环境组成部分的Web应用的web.xml元素。这里将提供一个简明的介绍，详细内容可以参阅<a href="http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf"><font color="#e6a306">http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf</font></a>的Java 2 Plantform Enterprise Edition版本1.3规范的第5章。<br />l distributable<br />distributable元素指出，Web应用是以这样的方式编程的：即，支持集群的服务器可安全地在多个服务器上分布Web应用。例如，一个可分布的应用必须只使用Serializable对象作为其HttpSession对象的属性，而且必须避免用实例变量（字段）来实现持续性。distributable元素直接出现在discription元素之后，并且不包含子元素或数据，它只是一个如下的标志。<br />&lt;distributable /&gt;<br /> resource-env-ref<br />resource-env-ref元素声明一个与某个资源有关的管理对象。此元素由一个可选的description元素、一个resource-env-ref-name元素（一个相对于java:comp/env环境的JNDI名）以及一个resource-env-type元素（指定资源类型的完全限定的类），如下所示：<br />&lt;resource-env-ref&gt;<br />&lt;resource-env-ref-name&gt;<br />jms/StockQueue<br />&lt;/resource-env-ref-name&gt;<br />&lt;resource-env-ref-type&gt;<br />javax.jms.Queue<br />&lt;/resource-env-ref-type&gt;<br />&lt;/resource-env-ref&gt;<br /> env-entry<br />env-entry元素声明Web应用的环境项。它由一个可选的description元素、一个env-entry-name元素（一个相对于java:comp/env环境JNDI名）、一个env-entry-value元素（项值）以及一个env-entry-type元素（java.lang程序包中一个类型的完全限定类名，java.lang.Boolean、java.lang.String等）组成。下面是一个例子：<br />&lt;env-entry&gt;<br />&lt;env-entry-name&gt;minAmout&lt;/env-entry-name&gt;<br />&lt;env-entry-value&gt;100.00&lt;/env-entry-value&gt;<br />&lt;env-entry-type&gt;minAmout&lt;/env-entry-type&gt;<br />&lt;/env-entry&gt;<br /> ejb-ref<br />ejb-ref元素声明对一个EJB的主目录的应用。它由一个可选的description元素、一个ejb-ref-name元素（相对于java:comp/env的EJB应用）、一个ejb-ref-type元素（bean的类型，Entity或Session）、一个home元素（bean的主目录接口的完全限定名）、一个remote元素（bean的远程接口的完全限定名）以及一个可选的ejb-link元素（当前bean链接的另一个bean的名称）组成。<br /> ejb-local-ref<br />ejb-local-ref元素声明一个EJB的本地主目录的引用。除了用local-home代替home外，此元素具有与ejb-ref元素相同的属性并以相同的方式使用。</p>
		<!-- 正文end --><img src ="http://www.blogjava.net/zqbchina/aggbug/122373.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-06-06 15:27 <a href="http://www.blogjava.net/zqbchina/articles/122373.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet监听器的一点认识</title><link>http://www.blogjava.net/zqbchina/articles/122313.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Wed, 06 Jun 2007 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/122313.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/122313.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/122313.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/122313.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/122313.html</trackback:ping><description><![CDATA[<p align="left">1, 如果在web.xml中同时定义了filter 和 listener(ServletContextListener)时, 容器将先执行listener,与其在web.xml中定义的顺序无关.<br />2, web容器的启动和关闭事件是ServletContextListener接口定义的.<br /><br /><span lang="EN-US" style="FONT-SIZE: 7.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">3. Servlet Context</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">事件监听器</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">:<br /></span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">   </span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">对于应用程序而言在</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">JVM</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">层别管理资源或保存状态</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><br />   <span style="mso-tab-count: 1">     </span></span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">a. ServletContextListener(</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">以下是该监听器的方法</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">) <br />        b. ServletContextAttributeListener(</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">以下是该监听器的方法</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">) <br />        </span></span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><br />4. HTTP Session</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">事件监听器</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><br /></span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">   </span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"></span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">管理从同一个客户端或用户向一个</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Web</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">应用程序发出的一系列请求相关的状态或资源</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">;<br />   <span style="mso-tab-count: 1">     </span></span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">a. HttpSessionListener(</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">以下是该监听器的方法</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">)<br />        b. HttpSessionAttributeListener(</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">以下是该监听器的方法</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">)<br />        <br />5. Servlet Requst</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">事件监听器</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><br /></span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">   </span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"></span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">管理整个</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">request</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">生命周期的状态</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><br />   <span style="mso-tab-count: 1">     </span></span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">a. ServletRequestListener(</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">以下是该监听器的方法</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">)<br />        b. ServletRequestAttributeListener(</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">以下是该监听器的方法</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">)<br style="mso-special-character: line-break" /></span></span></span></p><img src ="http://www.blogjava.net/zqbchina/aggbug/122313.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-06-06 10:53 <a href="http://www.blogjava.net/zqbchina/articles/122313.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>过滤器的一点认识</title><link>http://www.blogjava.net/zqbchina/articles/122198.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Tue, 05 Jun 2007 09:52:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/122198.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/122198.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/122198.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/122198.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/122198.html</trackback:ping><description><![CDATA[<p>参考文章 :  <a href="http://blog.csdn.net/gunandrose/archive/2003/08/20/19841.aspx">http://blog.csdn.net/gunandrose/archive/2003/08/20/19841.aspx</a><br /><br />1, 过虑器在web.xml中的注册:<br />    .......<br />   &lt;filter&gt;<br />        &lt;filter-name&gt;mySecondFilter&lt;/filter-name&gt;<br />        &lt;filter-class&gt;Filter.mySecondFilter&lt;/filter-class&gt;<br /> &lt;/filter&gt;<br /> &lt;filter&gt;<br />        &lt;filter-name&gt;myFirstFilter&lt;/filter-name&gt;<br />        &lt;filter-class&gt;Filter.myFirstFilter&lt;/filter-class&gt;<br />        &lt;init-param&gt;<br />                  &lt;param-name&gt;grant&lt;/param-name&gt;<br />                  &lt;param-value&gt;zqb&lt;/param-value&gt;<br />        &lt;/init-param&gt;<br />        &lt;init-param&gt;<br />                  &lt;param-name&gt;encoding&lt;/param-name&gt;<br />                  &lt;param-value&gt;gbk&lt;/param-value&gt;<br />        &lt;/init-param&gt;<br /> &lt;/filter&gt;</p>
		<p> &lt;filter-mapping&gt;<br />        &lt;filter-name&gt;myFirstFilter&lt;/filter-name&gt;<br />        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br /> &lt;/filter-mapping&gt;<br /> &lt;filter-mapping&gt;<br />        &lt;filter-name&gt;mySecondFilter&lt;/filter-name&gt;<br />        &lt;url-pattern&gt;/moudleA/*&lt;/url-pattern&gt;<br /> &lt;/filter-mapping&gt;<br />   ......<br />2,过滤器类的制作:<br />   这个很简单,主要是实现Filter的接口就行了. 需要注意的是,在做完你想要做的事情后, 记得 chain.doFilter(arg0,arg1) , 将过滤器向下一个过滤器传递(像接力赛一样) ,当然如果有必要也可以不传递给下一个,比如. 登陆用户角色不符合时.<br />3,过滤器的执行顺序:<br />   如果有多个过滤器,它们的执行顺序应该是按照web.xml中&lt;filter-mapping&gt;的定义顺序来的; 当然,前提是&lt;url-pattern&gt;都匹配的时候.<br />4,接口Filter中的三个主要方法的执行时机:<br />   init() : <font face="宋体">这是一个容器所调用的初始化方法。它保证了在第一次doFilter()</font><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调用前<strong>由容器调用</strong>。您能获取在</span><span lang="EN-US"> web.xml </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件中指定的初始化参数。<br /> doFilter(): 这是一个完成过滤行为的方法。这同样是上游过滤器调用的方法。引入的 <code><span lang="EN-US" style="FONT-FAMILY: 黑体; mso-ansi-font-size: 10.5pt">FilterChain</span></code><span lang="EN-US"></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象提供了后续过滤器所要调用的信息。<br /> destory(): 容器在破坏过滤器实例前，<code><span lang="EN-US" style="FONT-FAMILY: 黑体; mso-ansi-font-size: 10.5pt"><font face="宋体">doFilter():</font></span></code><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的所有活动都被该实例终止后，调用该方法。</span></span></span></p><img src ="http://www.blogjava.net/zqbchina/aggbug/122198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-06-05 17:52 <a href="http://www.blogjava.net/zqbchina/articles/122198.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>线程学习---对synchronized的测试</title><link>http://www.blogjava.net/zqbchina/articles/119043.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Tue, 22 May 2007 01:34:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/119043.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/119043.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/119043.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/119043.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/119043.html</trackback:ping><description><![CDATA[<p>public class myThread extends Thread {<br /> public void run() {<br />  <strong><font color="#0000ff">synchronized(System.out)</font></strong>{ <br />   for (int i = 0; i &lt; 10; i++) {<br />    try{<br />    <font color="#0000ff"> sleep(100);<br /></font>    }catch(InterruptedException e){e.printStackTrace();}<br />    <br />    System.out.println(getName() + ": i=" + i);<br />    if (i==9) System.out.println("=========");<br />   }<br />  }<br /> }</p>
		<p> public static void main(String[] a) {<br />  myThread thread1 = new myThread();<br />  myThread thread2 = new myThread();<br />  thread1.setName("A");thread1.start();<br />  thread2.setName("B");thread2.start();<br /> }<br />}<br /><br />在这个测试中,由于执行所需时间片太短,如果不在其中加一句sleep(100)的话,线程A 和线程B的交叉就体现不出来,就更不用说验证synchronized的作用了; 另,注意synchronized所同步的对象是System.out, 而不是this.</p><img src ="http://www.blogjava.net/zqbchina/aggbug/119043.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-05-22 09:34 <a href="http://www.blogjava.net/zqbchina/articles/119043.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习net包---利用socket进行文件传送</title><link>http://www.blogjava.net/zqbchina/articles/117852.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Wed, 16 May 2007 07:33:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/117852.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/117852.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/117852.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/117852.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/117852.html</trackback:ping><description><![CDATA[<p>和昨天的类似,只是今天学习了文件的传递,主要是加深对socket的理解以及对IO操作中DataInputStream和DataOutputStream类的使用,主要程序代码如下:<br /></p>
		<li>
				<font color="#3366ff">
						<strong>服务器端:</strong>
				</font>
		</li>
		<br />package test.net;
<p></p><p>import java.io.DataInputStream;<br />import java.io.DataOutputStream;<br />import java.io.File;<br />import java.io.FileInputStream;<br />import java.io.IOException;<br />import java.net.ServerSocket;<br />import java.net.Socket;</p><p>/**<br /> * 本例为通过socket编程实现从服务器端发送文件到客户端<br /> * @author zouqingbing<br /> */<br />public class fileServer {</p><p> public static void main(String[] a) {<br />  fileServer fileServer = new fileServer();<br />  fileServer.sendFile();<br /> }</p><p> public void sendFile() {<br />  byte[] buffer = new byte[1024];// 定义一byte类型的缓冲区。<br />  try {<br />   ServerSocket ssocket = new ServerSocket(2000);<br />   System.out.println("服务器启动！");<br />   Socket socket = ssocket.accept();<br />   int length = 0;</p><p>   File f = new File("d:\\aaa.txt");<br />   FileInputStream fis = new FileInputStream(f);<br />   DataInputStream dataIn = new DataInputStream(fis);<br />   DataOutputStream dataOut = new DataOutputStream(socket<br />     .getOutputStream());</p><p>   while ((length = dataIn.read(buffer)) != -1) {<br />    dataOut.write(buffer, 0, length);<br />   }<br />   dataOut.flush();<br />   dataOut.close();<br />   fis.close();<br />   System.out.println("文件传送完毕!!!");<br />   socket.close();<br />  } catch (IOException ex) {<br />   ex.printStackTrace();<br />  }<br /> }<br />}<br /><br /></p><li><strong><font color="#0066ff">客户端:</font></strong></li><br />package test.net;
<p></p><p>import java.io.DataInputStream;<br />import java.io.File;<br />import java.io.FileOutputStream;<br />import java.io.IOException;<br />import java.net.Socket;</p><p>/**<br /> * 本例使用socket编程实现从服务器端接收程序到客户端<br /> * @author zouqingbing<br /> */<br />public class fileClient {<br /> public static void main(String[] args) {<br />  fileClient fileClient = new fileClient();<br />  fileClient.receiveFile();<br /> }</p><p> public void receiveFile() {<br />  byte[] buffer = new byte[1024];<br />  int length = 0;<br />  try {<br />   Socket socket = new Socket("10.40.2.7", 2000);<br />   DataInputStream dataIn = new DataInputStream(socket<br />     .getInputStream());</p><p>   File f = new File("d:\\fff.txt");<br />   if (!f.exists())<br />    f.createNewFile();<br />   FileOutputStream fos = new FileOutputStream(f);</p><p>   while ((length = dataIn.read(buffer)) != -1) {<br />    fos.write(buffer, 0, length);<br />   }</p><p>   fos.close();<br />   System.out.println("客户端文件接收完毕！！！");<br />   socket.close();<br />  } catch (IOException e) {<br />   e.printStackTrace();<br />  }<br /> }<br />}<br /><br />另,要注意的是在socket通讯完毕后要关闭文件和socket连接,这里我起初没有关闭,结果抛出异常,关闭后就ok了.</p><img src ="http://www.blogjava.net/zqbchina/aggbug/117852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-05-16 15:33 <a href="http://www.blogjava.net/zqbchina/articles/117852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习net包---简单的socket通讯</title><link>http://www.blogjava.net/zqbchina/articles/117653.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Tue, 15 May 2007 09:05:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/117653.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/117653.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/117653.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/117653.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/117653.html</trackback:ping><description><![CDATA[
		<p>本篇文章主要学习net包中socket类及serversocket的使用,亦即通常所说的socket编程(网络编程的方法很多,socket只是其中一种).初步学习,记下来,不对的地方请指教.程序代码如下:<br /></p>
		<li>
				<font color="#cc0000">
						<strong>服务器端代码:</strong>
				</font>
				<br />package test.net; 
<p></p><p>import java.io.BufferedReader;<br />import java.io.IOException;<br />import java.io.InputStreamReader;<br />import java.io.PrintWriter;<br />import java.net.ServerSocket;<br />import java.net.Socket;</p><p>public class socketServer {<br /> public static void main(String args[]){<br />  try{<br />   ServerSocket server = new ServerSocket(2000);<br />   Socket client = server.accept(); //服务器侦听端口并接受到此套接字的连接<br />   BufferedReader in = new BufferedReader(new InputStreamReader(<em><font color="#0066cc">client.getInputStream()</font></em>)); //接收客户端传递的数据流<br />   PrintWriter out=new PrintWriter(<em><font color="#0033cc">client.getOutputStream()</font></em>);  //服务器的返回值<br />   while(true){<br />    String str = in.readLine();<br />    System.out.println("Client: "+str);<br />    <br />    out.println("... received!");<br />    out.flush();<br />    if (str.equals("end")){<br />     break;<br />    }<br />   }<br />   client.close();<br />  }catch(IOException e){<br />   e.printStackTrace();<br />  }<br />  <br /> }<br />}<br /><br /></p></li>
		<li>
				<font color="#cc0000">
						<strong>客户端程序代码:</strong>
				</font>
				<br />package com; 
<p></p><p>import java.io.BufferedReader;<br />import java.io.IOException;<br />import java.io.InputStreamReader;<br />import java.io.PrintWriter;<br />import java.net.Socket;<br />import java.net.UnknownHostException;</p><p>public class clientSocket {<br /> public static void main(String[] args){<br />  try{<br />   Socket server = new Socket("10.40.2.7",2000);<br />   BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));  //接收服务器信息<br />   PrintWriter out = new PrintWriter(server.getOutputStream()); //向服务器发送信息<br />   <br />   BufferedReader wt = new BufferedReader(new InputStreamReader(System.in)); //接收键盘输入信息<br />   while(true){<br />    String outStr = wt.readLine();<br />    out.println(outStr);<br />    out.flush();<br />    <br />    if (outStr.equals("end")){<br />     break;<br />    }<br />    System.out.println(in.readLine());<br />   }<br />   <br />   server.close();<br />  }catch(UnknownHostException e){<br />   <br />  }catch(IOException e){<br />   <br />  }<br /> }<br />}<br />~~end.<br />其中服务器和客户端数据是通过socket对象进行传递的,socket.getInputStream()得到客户端(相对而言:程序本机就是服务器,别人就是客户机)传递过来的数据输入流;server.getOutputStream()是即将返回的数据输出流.  另,程序的测试需要同时启动客户端和服务器端程序.如果在一台机器上同样可以做这样的测试,在eclipse的console中display selected console的选项可以在服务器端程序控制台和客户端程序控制台间进行切换.</p></li>
<img src ="http://www.blogjava.net/zqbchina/aggbug/117653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-05-15 17:05 <a href="http://www.blogjava.net/zqbchina/articles/117653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在JBoss中利用JNDI配置数据源连接数据库</title><link>http://www.blogjava.net/zqbchina/articles/116762.html</link><dc:creator>心砚</dc:creator><author>心砚</author><pubDate>Fri, 11 May 2007 07:57:00 GMT</pubDate><guid>http://www.blogjava.net/zqbchina/articles/116762.html</guid><wfw:comment>http://www.blogjava.net/zqbchina/comments/116762.html</wfw:comment><comments>http://www.blogjava.net/zqbchina/articles/116762.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqbchina/comments/commentRss/116762.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqbchina/services/trackbacks/116762.html</trackback:ping><description><![CDATA[
		<p>这个测试的这个例子中不含EJB内容,只是一个非常简单的数据库连接,因为其中一个细节纠缠了一整天所以记下来权做教训:).<br />试验的最终目的是这样:<br />  ......<br />    Context ctx = new InitialContext();   //具体jndi环境设置在jndi.properties中指定<br />    DataSource ds = (DataSource)ctx.lookup("Zqb Oracle Test"); //其中Zqb Oracle Test是我在oracle-ds.xml中指定的JNDI名<br />    <br />    Connection conn = ds.getConnection();<br />    PreparedStatement ps = conn.prepareStatement("select count(1) from css_emp_info");<br />    ResultSet rs = ps.executeQuery();<br /> ......<br /><br />步骤如下:<br />   1,jndi.properties(使用jboss缺省的内容,不做修改):<br />          java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory<br />          java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces<br />   2,将jboss-4.0.1sp1\docs\examples\jca下的oracle-ds.xml拷贝到jboss-4.0.1sp1\server\default\deploy下,并做相应修改,主要内容如下:<br />&lt;datasources&gt;<br />  &lt;local-tx-datasource&gt;<br />    &lt;jndi-name&gt;Zqb Oracle Test&lt;/jndi-name&gt;<br />    <strong><font color="#ff3300">&lt;use-java-context&gt;false&lt;/use-java-context&gt;</font><br /></strong>    &lt;connection-url&gt;jdbc:oracle:thin:@10.25.10.175:1521:pacesdev&lt;/connection-url&gt;<br />    &lt;driver-class&gt;oracle.jdbc.driver.OracleDriver&lt;/driver-class&gt;<br />    &lt;user-name&gt;cesbase&lt;/user-name&gt;<br />    &lt;password&gt;voiture6&lt;/password&gt;<br />    &lt;exception-sorter-class-name&gt;org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter&lt;/exception-sorter-class-name&gt;<br />      &lt;metadata&gt;<br />         &lt;type-mapping&gt;Oracle9i&lt;/type-mapping&gt;<br />      &lt;/metadata&gt;<br />  &lt;/local-tx-datasource&gt;<br />&lt;/datasources&gt;<br />   3,OK,部署war,搞定!其中红色标注的是后面加上的,有了这句在jndi前可以不用加前缀;否则,需要加前缀java(即:lookup("Zqb Oracle Test") 和 lookup("java:Zqb Oracle Test")的区别)<font color="#000000">.<br /><br />补充: 发现在jboss官方网站有关于<strong><font color="#ff3300">use-java-context</font></strong>这个属性的说明 <a href="http://wiki.jboss.org/wiki/Wiki.jsp?page=ConfigDataSources">http://wiki.jboss.org/wiki/Wiki.jsp?page=ConfigDataSources</a> ,仔细看看!</font></p>
<img src ="http://www.blogjava.net/zqbchina/aggbug/116762.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqbchina/" target="_blank">心砚</a> 2007-05-11 15:57 <a href="http://www.blogjava.net/zqbchina/articles/116762.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>