﻿<?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-agun 阿甘 ---分享,共同进步-随笔分类-java web</title><link>http://www.blogjava.net/agun/category/30011.html</link><description>激情成就梦想，努力创造未来</description><language>zh-cn</language><lastBuildDate>Sat, 03 Nov 2012 20:44:16 GMT</lastBuildDate><pubDate>Sat, 03 Nov 2012 20:44:16 GMT</pubDate><ttl>60</ttl><item><title>java web 导出excel </title><link>http://www.blogjava.net/agun/archive/2012/11/03/390722.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Sat, 03 Nov 2012 04:45:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2012/11/03/390722.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/390722.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2012/11/03/390722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/390722.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/390722.html</trackback:ping><description><![CDATA[<p>看到这个标题，会很疑问，java导出excel 有很多文章呀，都知道怎么用呀，呵呵，我也是这么认为，我们常用的就是jxl 或者poi ，现在jxl 代码不在更新不支持2007，一般都采用poi 进行excel的操作，今天在看系统（架构struts+ spring+ hibernate），需要做一个excel导出，一个简单的方法，这个方法只适用于excel简单的导出，直接通过输出的页面，然后设置页面为输出流的文件格式，这样当action转向到jsp页面的时候，直接就是将页面输出。</p>
<p>&nbsp;</p>
<p>jsp页面的代码：</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://agun.iteye.com/admin/blogs/1714955#"><img alt="复制代码" src="http://agun.iteye.com/images/icon_copy.gif" /></a></div></div>
<ol class="dp-j"><li><span>&lt;%@&nbsp;page&nbsp;language=</span><span class="string">"java"</span><span>&nbsp;pageEncoding=</span><span class="string">"UTF8"</span><span>%&gt; &nbsp;&nbsp;</span></li><li><span>&lt;html:html&nbsp;locale=</span><span class="string">"true"</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;head&gt;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;title&gt;LogExport&lt;/title&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;meta&nbsp;http-equiv=</span><span class="string">"pragma"</span><span>&nbsp;content=</span><span class="string">"no-cache"</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;meta&nbsp;http-equiv=</span><span class="string">"cache-control"</span><span>&nbsp;content=</span><span class="string">"no-cache"</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;meta&nbsp;http-equiv=</span><span class="string">"expires"</span><span>&nbsp;content=</span><span class="string">"0"</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;meta&nbsp;http-equiv=</span><span class="string">"Content-Type"</span><span>&nbsp;content=</span><span class="string">"text/html;&nbsp;charset=UTF-8"</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;% &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setCharacterEncoding(</span><span class="string">"UTF-8"</span><span>); &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType(</span><span class="string">"application/vnd.ms-excel;"</span><span>);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setHeader(</span><span class="string">"Content-Disposition"</span><span>,&nbsp;</span><span class="string">"attachment;filename=\""</span><span>+</span><span class="keyword">new</span><span>&nbsp;String(</span><span class="string">"Log.xls"</span><span>.getBytes(),</span><span class="string">"ISO-8859-1"</span><span>)+</span><span class="string">"\""</span><span>); &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&gt;&nbsp;&nbsp; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/head&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;body&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;form&nbsp;action=</span><span class="string">"/Action_export.do"</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;table&nbsp;width=</span><span class="string">"100%"</span><span>&nbsp;border=</span><span class="string">"1"</span><span>&nbsp;cellspacing=</span><span class="string">"0"</span><span>&nbsp;cellpadding=</span><span class="string">"0"</span><span>&nbsp;id=</span><span class="string">"datagrid"</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;thead&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&nbsp;</span><span class="keyword">class</span><span>=</span><span class="string">"HeaderStyle"</span><span>&nbsp;style=</span><span class="string">"font-weight:&nbsp;normal;"</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;用户&lt;/th&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;姓名&lt;/th&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;日期&lt;/th&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;登录IP&lt;/th&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;主机名&lt;/th&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&nbsp;colspan=</span><span class="string">"3"</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;table&nbsp;width=</span><span class="string">'100%'</span><span>&nbsp;&nbsp;border=</span><span class="string">"1"</span><span>&nbsp;cellspacing=</span><span class="string">"3"</span><span>&nbsp;cellpadding=</span><span class="string">"0"</span><span>&nbsp;frame=</span><span class="string">'void'</span><span>&nbsp;&gt;&nbsp; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;&lt;td&nbsp;colspan=</span><span class="string">"3"</span><span>&nbsp;style=</span><span class="string">'background:transparent;'</span><span>&nbsp;align=</span><span class="string">"center"</span><span>&gt;操作信息&lt;/td&gt;&lt;/tr&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&nbsp;style=</span><span class="string">'background:transparent;'</span><span>&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;width=</span><span class="string">"40px"</span><span>&nbsp;align=</span><span class="string">"center"</span><span>&gt;操作&lt;/td&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;width=</span><span class="string">"100px"</span><span>&nbsp;align=</span><span class="string">"center"</span><span>&gt;标题&lt;/td&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;align=</span><span class="string">"center"</span><span>&gt;扩展信息&lt;/td&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/table&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/thead&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;jsp:include&nbsp;page=</span><span class="string">"common.jsp"</span><span>&nbsp;flush=</span><span class="string">"true"</span><span>&nbsp;/&gt; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/table&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/form&gt; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/body&gt; &nbsp;&nbsp;</span></li><li><span>&lt;/html:html&gt;&nbsp;&nbsp;</span></li></ol></div><img src ="http://www.blogjava.net/agun/aggbug/390722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2012-11-03 12:45 <a href="http://www.blogjava.net/agun/archive/2012/11/03/390722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>list合并单元格</title><link>http://www.blogjava.net/agun/archive/2011/10/17/361437.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Mon, 17 Oct 2011 06:44:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2011/10/17/361437.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/361437.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2011/10/17/361437.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/361437.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/361437.html</trackback:ping><description><![CDATA[<div class="blog_content">
<p>1，在今天整理代码的时候，发现原来的一段代码，前台合并单元格。</p>
<p>&nbsp;</p>
<p>需要在后端，原来的列表基础上，再增加一层。</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://agun.iteye.com/admin/blogs/1198422#"><img alt="复制代码" src="http://agun.iteye.com/images/icon_copy.gif" /></a></div></div>
<ol class="dp-j"><li><span>List&lt;CASEListVO&gt;&nbsp;list2&nbsp;=&nbsp;</span><span class="keyword"><font color="#7f0055">super</font></span><span>.doFind(hql.toString(),&nbsp;params.toArray(),&nbsp;currPage,&nbsp;pageSize); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;ArrayList&lt;List&lt;CASEListVO&gt;&gt;&nbsp;linkedList&nbsp;=&nbsp;</span><span class="keyword"><font color="#7f0055">new</font></span><span>&nbsp;ArrayList&lt;List&lt;CASEListVO&gt;&gt;(); &nbsp;&nbsp;</span></span></li><li><span>List&lt;String&gt;&nbsp;keyList&nbsp;=&nbsp;</span><span class="keyword"><font color="#7f0055">new</font></span><span>&nbsp;ArrayList&lt;String&gt;(); &nbsp;&nbsp;</span></span></li><li><span></span><span class="keyword"><font color="#7f0055">for</font></span><span>&nbsp;(CASEListVO&nbsp;vo&nbsp;:&nbsp;list2) &nbsp;&nbsp;</span></span></li><li><span>{ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;String&nbsp;key&nbsp;=&nbsp;vo.getItemCode(); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;List&lt;CASEListVO&gt;&nbsp;tempList&nbsp;=&nbsp;</span><span class="keyword"><font color="#7f0055">new</font></span><span>&nbsp;ArrayList&lt;CASEListVO&gt;(); &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword"><font color="#7f0055">if</font></span><span>&nbsp;(keyList.indexOf(key)&nbsp;==&nbsp;-</span><span class="number"><font color="#c00000">1</font></span><span>) &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyList.add(key); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword"><font color="#7f0055">else</font></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><font color="#7f0055">continue</font></span><span>; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword"><font color="#7f0055">for</font></span><span>&nbsp;(CASEListVO&nbsp;vo1&nbsp;:&nbsp;list2) &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><font color="#7f0055">if</font></span><span>&nbsp;(vo1.getItemCode().endsWith(key)) &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempList.add(vo1); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;linkedList.add(tempList); &nbsp;&nbsp;</span></li><li><span>} &nbsp;&nbsp;</span></li><li><span>page.setList(linkedList);</span><span class="comment">//返回的列表</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none" class="java" name="code">            List&lt;CASEListVO&gt; list2 = super.doFind(hql.toString(), params.toArray(), currPage, pageSize);
               ArrayList&lt;List&lt;CASEListVO&gt;&gt; linkedList = new ArrayList&lt;List&lt;CASEListVO&gt;&gt;();
            List&lt;String&gt; keyList = new ArrayList&lt;String&gt;();
            for (CASEListVO vo : list2)
            {
               String key = vo.getItemCode();
               List&lt;CASEListVO&gt; tempList = new ArrayList&lt;CASEListVO&gt;();
               if (keyList.indexOf(key) == -1)
               {
                  keyList.add(key);
               }
               else
               {
                  continue;
               }
               for (CASEListVO vo1 : list2)
               {
                  if (vo1.getItemCode().endsWith(key))
                  {
                     tempList.add(vo1);
                  }
               }
               linkedList.add(tempList);
            }
            page.setList(linkedList);//返回的列表</pre>
<p>&nbsp;页面上操作，struts2 </p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Html代码 <a title="复制代码" href="http://agun.iteye.com/admin/blogs/1198422#"><img alt="复制代码" src="http://agun.iteye.com/images/icon_copy.gif" /></a></div></div>
<ol class="dp-xml"><li><span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">s:iterator</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">value</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"page"</font></span><span>&nbsp;</span><span class="attribute"><font color="#ff0000">id</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"list"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">c:forEach</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">var</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"recordList"</font></span><span>&nbsp;</span><span class="attribute"><font color="#ff0000">items</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"${list}"</font></span><span>&nbsp;</span><span class="attribute"><font color="#ff0000">varStatus</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"varStatus"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">c:forEach</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">var</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"record"</font></span><span>&nbsp;</span><span class="attribute"><font color="#ff0000">items</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"${recordList}"</font></span><span>&nbsp;</span><span class="attribute"><font color="#ff0000">varStatus</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"status"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">tr</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">td</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">input</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">name</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"selectIds"</font></span><span>&nbsp;</span><span class="attribute"><font color="#ff0000">type</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"checkbox"</font></span><span>&nbsp;</span><span class="attribute"><font color="#ff0000">value</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"${record.ltVo.listTmpId}"</font></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute"><font color="#ff0000">oldValue</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"${record.estTmpId&nbsp;}"</font></span><span>&nbsp;</span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">td</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${status.index&nbsp;}-- &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><strong><font color="#006699">&lt;</font></strong></span><span>%=((List)&nbsp;pageContext.getAttribute("recordList")).size()%</span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">c:if</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">test</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"${status.index&nbsp;eq&nbsp;0}"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">td</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">rowspan</font></span><span>="</span><span class="tag"><strong><font color="#006699">&lt;</font></strong></span><span>%=((List)&nbsp;pageContext.getAttribute("recordList</span><span class="attribute-value"><font color="#0000ff">")).size()%&gt;"</font></span><span>&nbsp;</span><span class="attribute"><font color="#ff0000">style</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"width:&nbsp;240px;text-align:&nbsp;center;"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${record.listName} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">td</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">c:if</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">td</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">style</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"text-align:&nbsp;center;width:200px;"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${record.itemCode} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">td</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">td</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">style</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"text-align:&nbsp;center;width:&nbsp;200px;"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${record.projectName} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">td</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">td</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">style</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"text-align:&nbsp;right;width:&nbsp;200px"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">fmt:formatNumber</span></font></strong><span>&nbsp;</span><span class="attribute"><font color="#ff0000">value</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"${record.rate}"</font></span><span>&nbsp;</span><span class="attribute"><font color="#ff0000">pattern</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">"##0.00"</font></span><span>&nbsp;</span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">td</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">tr</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">c:forEach</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">c:forEach</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">s:iterator</span><span class="tag">&gt;</span></font></strong><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none" class="html" name="code">	&lt;s:iterator value="page" id="list"&gt;
					&lt;c:forEach var="recordList" items="${list}" varStatus="varStatus"&gt;
						&lt;c:forEach var="record" items="${recordList}" varStatus="status"&gt;
							&lt;tr&gt;
								&lt;td&gt;
									&lt;input name="selectIds" type="checkbox" value="${record.ltVo.listTmpId}"
										oldValue="${record.estTmpId }" /&gt;
								&lt;/td&gt;
								${status.index }--
								&lt;%=((List) pageContext.getAttribute("recordList")).size()%&gt;
								&lt;c:if test="${status.index eq 0}"&gt;
									&lt;td rowspan="&lt;%=((List) pageContext.getAttribute("recordList")).size()%&gt;" style="width: 240px;text-align: center;"&gt;
										${record.listName}
									&lt;/td&gt;
								&lt;/c:if&gt;
								&lt;td style="text-align: center;width:200px;"&gt;
									${record.itemCode}
								&lt;/td&gt;
								&lt;td style="text-align: center;width: 200px;"&gt;
									${record.projectName}
								&lt;/td&gt;
								&lt;td style="text-align: right;width: 200px"&gt;
									&lt;fmt:formatNumber value="${record.rate}" pattern="##0.00" /&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/c:forEach&gt;
					&lt;/c:forEach&gt;
				&lt;/s:iterator&gt;</pre>
<p>&nbsp;</p>
<p>这样根据code在页面上就会显示分组合并单元格的效果。</p></div><img src ="http://www.blogjava.net/agun/aggbug/361437.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2011-10-17 14:44 <a href="http://www.blogjava.net/agun/archive/2011/10/17/361437.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate lazy</title><link>http://www.blogjava.net/agun/archive/2011/08/12/356365.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Fri, 12 Aug 2011 05:17:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2011/08/12/356365.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/356365.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2011/08/12/356365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/356365.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/356365.html</trackback:ping><description><![CDATA[<p>今天项目组有要使用的hibernate lazy的，我一直对这种lazy的方式是不赞成使用的，所以我的项目组内是明确不能使lazy，包括true和false当然hibernate 默认的模式是true ，但是在程序中我们是可以控制，当然如果不做配置话，也无法在前端使用，其实在项目中，用到lazy的时候并不是特别多（个人观点），大部分的数据都是明确的要在后台查询出来的。用lazy也并不复杂，在web.xml中配置</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码 <a title="复制代码" href="#"><img alt="复制代码" src="http://www.blogjava.net/images/icon_copy.gif" /></a></div></div>
<ol class="dp-xml"><li><span class="tag">&lt;</span><span class="tag-name">filter</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>hibernateFilter</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">filter-class</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.springframework.orm.hibernate3.support.OpenSessionInViewFilter &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">filter-class</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>singleSession</span><span class="tag">&lt;/</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>false</span><span class="tag">&lt;/</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span></span><span class="tag">&lt;/</span><span class="tag-name">filter</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span></span><span class="tag">&lt;</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>hibernateFilter</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>*.do</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span></span><span class="tag">&lt;/</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none" class="xml" name="code">	&lt;filter&gt;
		&lt;filter-name&gt;hibernateFilter&lt;/filter-name&gt;
		&lt;filter-class&gt;
			org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
		&lt;/filter-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;singleSession&lt;/param-name&gt;
			&lt;param-value&gt;false&lt;/param-value&gt;
		&lt;/init-param&gt;
	&lt;/filter&gt;

	&lt;filter-mapping&gt;
		&lt;filter-name&gt;hibernateFilter&lt;/filter-name&gt;
		&lt;url-pattern&gt;*.do&lt;/url-pattern&gt;
	&lt;/filter-mapping&gt;</pre>
<p>&nbsp;</p>
<p>就可以使用延迟加载了，spring通过filter的方式对绑定hibernate session 到request的线程中。</p>
<p>that binds a Hibernate Session to the thread for the entire processing of the request</p>
<p>&nbsp;</p>
<p>刚开始我是把上面这段配置随便放到web.xml中，一致不成功总报session 关闭，不起作用，最后查了一下，我把这个filter放到了struts的filter之上，就可以了。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>说明FlushMode有五种属性<br /><br />1 <code><span style="font-family: NSimsun">NEVEL&nbsp;&nbsp; <br /></span></code></p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #000000">已经废弃了，被MANUAL取代了</span></div>
<p><br /><span style="font-family: NSimsun"><code>2 MANUAL </code><br /></span></p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #000000">spring3.x中的opensessioninviewfilter已经将默认的FlushMode设置为MANUAL了；<br />如果FlushMode是MANUAL或NEVEL,在操作过程中hibernate会将事务设置为readonly，所以在</span><span style="color: #000000">增加、删除或修改</span><span style="color: #000000">操作过程中会出现如下错误<br />org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read</span><span style="color: #000000">-</span><span style="color: #000000">only mode (FlushMode.NEVER) </span><span style="color: #000000">-</span><span style="color: #000000"> turn your Session into FlushMode.AUTO or remove </span><span style="color: #000000">'</span><span style="color: #000000">readOnly</span><span style="color: #000000">'</span><span style="color: #000000"> marker from transaction definition；<br />解决办法网上有很多；<br /></span><span style="color: #000000">1</span><span style="color: #000000"> 配置事务，spring会读取事务中的各种配置来覆盖hibernate的session中的FlushMode；<br /></span><span style="color: #000000">2</span><span style="color: #000000"> 先编程式修改FlushMode，比如session.setFlushMode(FlushMode.AUTO); 这样hibernate就会自动去除readonly限制；<br /></span><span style="color: #000000">3</span><span style="color: #000000"> 直接修改opensessioninviewfilter过滤器的配置，配置过滤器的时候配置<br /></span><span style="color: #000000">&lt;</span><span style="color: #000000">filter</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">filter</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000">openSession</span><span style="color: #000000">&lt;/</span><span style="color: #000000">filter</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">filter</span><span style="color: #000000">-</span><span style="color: #0000ff">class</span><span style="color: #000000">&gt;</span><span style="color: #000000">org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</span><span style="color: #000000">&lt;/</span><span style="color: #000000">filter</span><span style="color: #000000">-</span><span style="color: #0000ff">class</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">init</span><span style="color: #000000">-</span><span style="color: #000000">param</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">param</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000">flushMode</span><span style="color: #000000">&lt;/</span><span style="color: #000000">param</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">param</span><span style="color: #000000">-</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000">AUTO</span><span style="color: #000000">&lt;/</span><span style="color: #000000">param</span><span style="color: #000000">-</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">init</span><span style="color: #000000">-</span><span style="color: #000000">param</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">filter</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span></div>
<p><code><span style="font-family: NSimsun">3 AUTO<br /></span></code></p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #000000">设置成auto之后，当程序进行查询、提交事务或者调用session.flush()的时候，都会使缓存和数据库进行同步，也就是刷新数据库</span></div>
<p><code><span style="font-family: NSimsun">4 COMMIT<br /></span></code></p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #000000">提交事务或者session.flush()时，刷新数据库；查询不刷新</span></div>
<p><br /><code><span style="font-family: NSimsun">5 ALWAYS<br /></span></code></p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #000000">每次进行查询、提交事务、session.flush()的时候都会刷数据库<br /><strong>这里需要说一下和AUTO的区别，当hibernate缓存中的对象被改动之后，会被标记为脏数据（即与数据库不同步了）。当session设置为FlushMode.AUTO时，hibernate在进行查询的时候会判断缓存中的数据是否为脏数据，是则刷数据库，不是则不刷，而always是直接刷新，不进行任何判断。很显然auto比always要高效得多。</strong><br /></span></div>
<p>&nbsp;</p><img src ="http://www.blogjava.net/agun/aggbug/356365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2011-08-12 13:17 <a href="http://www.blogjava.net/agun/archive/2011/08/12/356365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts2 泛型 Hibernate</title><link>http://www.blogjava.net/agun/archive/2011/05/08/349767.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Sun, 08 May 2011 01:20:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2011/05/08/349767.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/349767.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2011/05/08/349767.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/349767.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/349767.html</trackback:ping><description><![CDATA[<p>今天在整理代码的时候，我的Action 和 DAO基类都是使用的泛型：如Action&lt;T&gt; DAO&lt;T&gt;。</p>
<p>&nbsp;</p>
<p>我用的是Struts2基类代码，如下</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://agun.iteye.com/blog/1036013#"><img alt="复制代码" src="http://agun.iteye.com/images/icon_copy.gif" /></a>&nbsp;<a title="收藏这段代码" onclick="code_favorites_do_favorite(this);return false;" href="javascript:void()"><img class="star" alt="收藏代码" src="http://agun.iteye.com/images/icon_star.png" /><img class="spinner" style="display: none" src="http://agun.iteye.com/images/spinner.gif"  alt="" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;BaseStrutsAction&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;</span><span class="keyword">implements</span><span>&nbsp;ModelDriven&lt;BaseStrutsForm&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;Logger&nbsp;log&nbsp;=&nbsp;Logger.getLogger(BaseStrutsAction.</span><span class="keyword">class</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" title="struts2 泛型 Hibernate" style="display: none" name="code" pre_index="0" source_url="http://agun.iteye.com/blog/1036013" codeable_type="Post" codeable_id="2090345">public abstract class BaseStrutsAction extends ActionSupport implements ModelDriven&lt;BaseStrutsForm&gt;
{
public static final Logger log = Logger.getLogger(BaseStrutsAction.class);
}</pre>
<p>&nbsp;先说一下：</p>
<p><span style="color: #ff0000"><span style="font-size: small">一，struts2的ModelDriven</span> （下面来源网络）</span></p>
<p>&nbsp;</p>
<p style="text-indent: 2em">可以根据Action属性的不同将它分为两类：Field-Driven（属性驱动） Action和Model-Driven（模型驱动） Action。 <br />
一、Field-Driven（属性驱动）Action，Action拥有自己的属性，这些属性一般是Java的基本类型。表单字段直接和Action的属性 对应。</p>
<p style="text-indent: 2em">二、实现了modelDriven接口可以在action中直接获得例如User对象，它会将Object getModel()取得的User放到ValueStack中。可以理解为将这个User的属性追加到Action中。它主要是作用是实现类似 Struts的FormBean功能。</p>
<p style="text-indent: 2em">在struts2中，提供了一种直接使用领域对象的方式，就是让action实现com.opensymphony.xwork2.ModelDriven接口，ModelDriven让你可以直接操作应用程序中的领域对象，允许你在web层和业务层使用相同的对象。</p>
<p style="text-indent: 2em">ModelDriven接口只有一个方法</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object getModel() {<br />
return null;<br />
}</p>
<p style="text-indent: 2em">该方法返回一个用于接收用户输入数据的对象模型，在这个模型对象中的属性可以直接通过(属性名)userName来访问，而不需要使用（对象名.属 性名）user.userName这种格式来访问了，在action也不需要对对象提供getter和setter方法了，但是必须要在action中进 行new操作</p>
<p style="text-indent: 2em">如下</p>
<p style="text-indent: 2em">//&nbsp;ModelDriven要使用泛型哦</p>
<p style="text-indent: 2em">public class LoginAction extends ActionSupport<span style="color: #ff0000"> implements ModelDriven&lt;User&gt;</span>{</p>
<p style="text-indent: 2em">private static final long serialVersionUID = -6434128483294080524L;</p>
<p style="text-indent: 2em">//这里必须要new<br />
private User user=new User();<br />
public String login() throws Exception {<br />
// TODO Auto-generated method stub&nbsp;&nbsp;<br />
return SUCCESS;<br />
}</p>
<p style="text-indent: 2em">//这里是实现接口方法</p>
<p style="text-indent: 2em">@Override<br />
public User getModel() {<br />
// TODO Auto-generated method stub</p>
<p style="text-indent: 2em">//别忘记了，要把返回值写上哦<br />
return user;<br />
}<br />
}</p>
<p style="text-indent: 2em">这样一个ModelDriven就实现完毕了</p>
<p style="text-indent: 2em">和属性驱动的Action有很大的区别，下面一一列举：</p>
<p style="text-indent: 2em">（1）模型驱动的Action必须实现ModelDriven接口，而且要提供相应的泛型，这里当然就是具体使用的Java Bean了。</p>
<p style="text-indent: 2em">（2）实现ModelDriven的getModel方法，其实就是简单的返回泛型的一个对象。</p>
<p style="text-indent: 2em">（3）在Action提供一个泛型的私有对象，这里就是定义一个User的user对象，并提供相应的getter与setter。</p>
<p style="text-indent: 2em">好了，上面的三件事做完之后，Action就会去自动调用User的setter将表单中的name属性的值赋给User中的属性。而Action的后续处理的Jsp页面后者是Servlet就可以使用user对象了。</p>
<p style="text-indent: 2em">到底是用属性驱动和是模型驱动呢？ </p>
<p style="text-indent: 2em">这个问题困扰了很多Struts2的初学者，我这里提供一些建议：</p>
<p style="text-indent: 2em">（1）请你统一整个系统中的Action使用的驱动模型，即要么都是用属性驱动，要么都是用模型驱动。</p>
<p style="text-indent: 2em">（2）如果你的DB中的持久层的对象与表单中的属性都是一一对应的话，那么就使用模型驱动吧，毕竟看起来代码要整洁得多。</p>
<p style="text-indent: 2em">（3）如果表单的属性不是一一对应的话，那么就应该使用属性驱动，否则，你的系统就必须提供两个Bean，一个对应表单提交的数据，另一个用与持久层。</p>
<p style="text-indent: 2em"><span style="font-size: small; color: #ff0000">二，持久层基类 HibernateDao</span></p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em"><span style="font-size: x-small">代码如：</span></p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://agun.iteye.com/blog/1036013#"><img alt="复制代码" src="http://agun.iteye.com/images/icon_copy.gif" /></a>&nbsp;<a title="收藏这段代码" onclick="code_favorites_do_favorite(this);return false;" href="javascript:void()"><img class="star" alt="收藏代码" src="http://agun.iteye.com/images/icon_star.png" /><img class="spinner" style="display: none" src="http://agun.iteye.com/images/spinner.gif"  alt="" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HibernateDao&lt;T,&nbsp;PK&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Serializable&gt;&nbsp;&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;用于Dao层子类的构造函数. </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;通过子类的泛型定义取得对象类型Class. </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;eg. </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;public&nbsp;class&nbsp;UserDao&nbsp;extends&nbsp;HibernateDao&lt;User,&nbsp;Long&gt;{ </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;} </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;HibernateDao()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">super</span><span>(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" title="struts2 泛型 Hibernate" style="display: none" name="code" pre_index="1" source_url="http://agun.iteye.com/blog/1036013" codeable_type="Post" codeable_id="2090345">public class HibernateDao&lt;T, PK extends Serializable&gt;  {
/**
* 用于Dao层子类的构造函数.
* 通过子类的泛型定义取得对象类型Class.
* eg.
* public class UserDao extends HibernateDao&lt;User, Long&gt;{
* }
*/
public HibernateDao() {
super();
}
</pre>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em"><span style="color: #ff0000">上面的代码，基类没有使用HibernateDaoSupport，我们需要自己引入SessionFactory。</span></p>
<p style="text-indent: 2em">持久层基类，一般Spring的Hibernate ORM <a href="http://agun.iteye.com/view/66971.htm" target="_blank">框架</a>带来了方便的HibernateDaoSupport类,你的<a href="http://agun.iteye.com/view/160596.htm" target="_blank">DAO</a>类可以继承它: </p>
<p style="text-indent: 2em">　　public class DaoHibernate extends HibernateDaoSupport { </p>
<p style="text-indent: 2em">　　................. </p>
<p style="text-indent: 2em">　　} </p>
<p style="text-indent: 2em">　　<span style="color: #ff0000">如果你选择这种设计,就需要动态注入SessionFactory而HibernateDaoSupport包含这个属性</span>.这个类提供了一个方便的方法getHibernateTemplate(); 就能得到HibernateTemplate的一个实例.它也有getSession()和releaseSession,以便于你应为某些原因而不使用HibernateTempate的情况下执行Hibernate操作。 </p>
<p style="text-indent: 2em">　　HibernateDaoSupport提供了基于AOP事务的自动处理，程序员完全可以不用理会事务的开始与提交。在JDBC中一个Connection对象使用一个事务，那么在Hibernate中一个事务肯定要关联一个SessionFactory了，然而这个SessionFactory却没有在DAO中体现。其实主要的原因是HibernateDaoSupport类已经默默地做了封装的工作，它用一个setSessionFactory方法将SessionFactory进行注入，所以继承自HibernateDaoSupport类的DAO都会具有SessionFactory的属性，从而可以通过SessionFactory创建Session实例操作数据库。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">如果使用像 public class HibernateDao&lt;T, PK extends Serializable&gt;&nbsp; 这样的泛型基类就会有问题，可以拿个T代表任意类型，Java的泛型拿不到T.class，就无法得到类对象，&nbsp;如下面的clazz，</p>
<p style="text-indent: 2em">public T get(final PK id) {<br />
&nbsp;&nbsp;Assert.notNull(id, "id不能为空");<br />
&nbsp;&nbsp;return (T) getSession().load(<span style="color: #ff0000">clazz</span>, id);<br />
&nbsp;}</p>
<p style="text-indent: 2em">最后在网上找到了解决方案，可以使用泛型public class HibernateDao&lt;T, PK extends Serializable&gt;基类了。</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://agun.iteye.com/blog/1036013#"><img alt="复制代码" src="http://agun.iteye.com/images/icon_copy.gif" /></a>&nbsp;<a title="收藏这段代码" onclick="code_favorites_do_favorite(this);return false;" href="javascript:void()"><img class="star" alt="收藏代码" src="http://agun.iteye.com/images/icon_star.png" /><img class="spinner" style="display: none" src="http://agun.iteye.com/images/spinner.gif"  alt="" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;BaseHibernateEntityDao&lt;T&gt;&nbsp;</span><span class="keyword">extends</span><span>&nbsp;HibernateDaoSupport&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;</span><span class="keyword">private</span><span>&nbsp;Class&lt;T&gt;&nbsp;entityClass; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;BaseHibernateEntityDao()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;SPAN&nbsp;style=</span><span class="string">"COLOR:&nbsp;#000000"</span><span>&gt;entityClass&nbsp;=(Class&lt;T&gt;)&nbsp;((ParameterizedType)&nbsp;getClass() &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getGenericSuperclass()).getActualTypeArguments()[</span><span class="number">0</span><span>];&lt;/SPAN&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;T&nbsp;get(Serializable&nbsp;id)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;o&nbsp;=&nbsp;(T)&nbsp;getHibernateTemplate().get(entityClass,&nbsp;id); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" title="struts2 泛型 Hibernate" style="display: none" name="code" pre_index="2" source_url="http://agun.iteye.com/blog/1036013" codeable_type="Post" codeable_id="2090345">abstract public class BaseHibernateEntityDao&lt;T&gt; extends HibernateDaoSupport {
private Class&lt;T&gt; entityClass;
public BaseHibernateEntityDao() {
<span style="color: #000000">entityClass =(Class&lt;T&gt;) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];</span>
}
public T get(Serializable id) {
T o = (T) getHibernateTemplate().get(entityClass, id);
}
}</pre>
<p style="text-indent: 2em"><span style="color: #ff0000">重点这句：&nbsp;entityClass =(Class&lt;T&gt;) ((ParameterizedType) getClass()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .getGenericSuperclass()).getActualTypeArguments()[0];<br />
</span></p>
<img src ="http://www.blogjava.net/agun/aggbug/349767.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2011-05-08 09:20 <a href="http://www.blogjava.net/agun/archive/2011/05/08/349767.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Cookie 和 Session</title><link>http://www.blogjava.net/agun/archive/2010/12/04/339792.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Sat, 04 Dec 2010 04:14:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2010/12/04/339792.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/339792.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2010/12/04/339792.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/339792.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/339792.html</trackback:ping><description><![CDATA[<p><span class="wenzhang_con" id="articlecontent" style="width: 740px">一、cookie机制和session机制的区别<br />
*************************************************************************************<br />
具体来说cookie机制采用的是在客户端保持状态的方案，而session机制采用的是在服务器端保持状态的方案。<br />
同时我们也看到，由于才服务器端保持状态的方案在客户端也需要保存一个标识，所以session<br />
机制可能需要借助于cookie机制来达到保存标识的目的，但实际上还有其他选择<br />
*************************************************************************************<br />
<br />
二、会话cookie和持久cookie的区别<br />
*************************************************************************************<br />
如果不设置过期时间，则表示这个cookie生命周期为浏览器会话期间，只要关闭浏览器窗口，cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。<br />
　　如果设置了过期时间，浏览器就会把cookie保存到硬盘上，关闭后再次打开浏览器，这些cookie依然有效直到超过设定的过期时间。<br />
　　存储在硬盘上的cookie可以在不同的浏览器进程间共享，比如两个IE窗口。而对于保存在内存的cookie，不同的浏览器有不同的处理方式。<br />
*************************************************************************************<br />
<br />
三、如何利用实现自动登录<br />
*************************************************************************************<br />
　　当用户在某个网站注册后，就会收到一个惟一用户ID的cookie。客户后来重新连接时，这个<br />
用户ID会自动返回，服务器对它进行检查，确定它是否为注册用户且选择了自动登录，从而使用户务需给出明确的用户名和密码，就可以访问服务器上的资源。<br />
*************************************************************************************<br />
<br />
四、如何根据用户的爱好定制站点<br />
*************************************************************************************<br />
　　网站可以使用cookie记录用户的意愿。对于简单的设置，网站可以直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制，网站只需仅将一个惟一的标识符发送给用户，由服务器端的数据库存储每个标识符对应的页面设置。<br />
*************************************************************************************<br />
<br />
五、cookie的发送<br />
*************************************************************************************<br />
1.创建Cookie对象<br />
2.设置最大时效<br />
3.将Cookie放入到HTTP响应报头<br />
如果你创建了一个cookie，并将他发送到浏览器，默认情况下它是一个会话级别的cookie:存储在浏览器的内存中，用户退出浏览器之后被删除。如果你希望浏览器将该cookie存储在磁盘上，则<br />
需要使用maxAge，并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。<br />
发送cookie需要使用HttpServletResponse的addCookie方法，将cookie插入到一个Set-Cookie　HTTP请求报头中。由于这个方法并不修改任何之前指定的Set-Cookie报头，而是创建新的报头，因此我们将这个方法称为是addCookie，而非setCookie。同样要记住响应报头必须在任何文档内容发送到客户端之前设置。<br />
<br />
六、cookie的读取<br />
*************************************************************************************<br />
1.调用request.getCookie<br />
要获取有浏览器发送来的cookie，需要调用HttpServletRequest的getCookies方法，这个调用返回Cookie对象的数组，对应由HTTP请求中Cookie报头输入的值。<br />
2.对数组进行循环，调用每个cookie的getName方法，直到找到感兴趣的cookie为止<br />
　cookie与你的主机(域)相关，而非你的servlet或JSP页面。因而，尽管你的servlet可能只发送了单个cookie，你也可能会得到许多不相关的cookie。<br />
例如：<br />
　　String&nbsp;cookieName&nbsp;=&nbsp;&#8220;userID&#8221;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Cookie&nbsp;cookies[]&nbsp;=&nbsp;request.getCookies();<br />
&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cookies!=null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=0;i&lt;cookies.length;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;Cookie&nbsp;cookie&nbsp;=&nbsp;cookies[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cookieName.equals(cookie.getName())){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doSomethingWith(cookie.getValue());<br />
}<br />
}<br />
}<br />
*************************************************************************************<br />
<br />
七、如何使用cookie检测初访者<br />
*************************************************************************************<br />
A.调用HttpServletRequest.getCookies()获取Cookie数组<br />
B.在循环中检索指定名字的cookie是否存在以及对应的值是否正确<br />
C.如果是则退出循环并设置区别标识<br />
D.根据区别标识判断用户是否为初访者从而进行不同的操作<br />
*************************************************************************************<br />
<br />
八、使用cookie检测初访者的常见错误<br />
*************************************************************************************<br />
不能仅仅因为cookie数组中不存在在特定的数据项就认为用户是个初访者。如果cookie数组为null，客户可能是一个初访者，也可能是由于用户将cookie删除或禁用造成的结果。<br />
但是，如果数组非null,也不过是显示客户曾经到过你的网站或域，并不能说明他们曾经访问过你的servlet。其它servlet、JSP页面以及非Java&nbsp;Web应用都可以设置cookie，依据路径的设置，其中的任何cookie都有可能返回给用户的浏览器。<br />
正确的做法是判断cookie数组是否为空且是否存在指定的Cookie对象且值正确。<br />
*************************************************************************************<br />
<br />
九、使用cookie属性的注意问题<br />
*************************************************************************************<br />
　　属性是从服务器发送到浏览器的报头的一部分；但它们不属于由浏览器返回给服务器的报头。　<br />
　　因此除了名称和值之外，cookie属性只适用于从服务器输出到客户端的cookie；服务器端来自于浏览器的cookie并没有设置这些属性。　<br />
　　因而不要期望通过request.getCookies得到的cookie中可以使用这个属性。这意味着，你不能仅仅通过设置cookie的最大时效，发出它，在随后的输入数组中查找适当的cookie,读取它的值，修改它并将它存回Cookie，从而实现不断改变的cookie值。<br />
*************************************************************************************<br />
<br />
十、如何使用cookie记录各个用户的访问计数<br />
*************************************************************************************<br />
1.获取cookie数组中专门用于统计用户访问次数的cookie的值<br />
2.将值转换成int型<br />
3.将值加1并用原来的名称重新创建一个Cookie对象<br />
4.重新设置最大时效<br />
5.将新的cookie输出<br />
*************************************************************************************<br />
<br />
十一、session在不同环境下的不同含义<br />
*************************************************************************************<br />
session，中文经常翻译为会话，其本来的含义是指有始有终的一系列动作/消息，比如打电话是从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。<br />
然而当session一词与网络协议相关联时，它又往往隐含了&#8220;面向连接&#8221;和/或&#8220;保持状态&#8221;这样两个含义。<br />
　　session在Web开发环境下的语义又有了新的扩展，它的含义是指一类用来在客户端与服务器端之间保持状态的解决方案。有时候Session也用来指这种解决方案的存储结构。<br />
*************************************************************************************<br />
<br />
十二、session的机制<br />
*************************************************************************************<br />
　　session机制是一种服务器端的机制，服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。<br />
但程序需要为某个客户端的请求创建一个session的时候，服务器首先检查这个客户端的请求里是否包含了一个session标识－称为session&nbsp;id,如果已经包含一个session&nbsp;id则说明以前已经为此客户创建过session，服务器就按照session&nbsp;id把这个session检索出来使用(如果检索不到，可能会新建一个，这种情况可能出现在服务端已经删除了该用户对应的session对象，但用户人为地在请求的URL后面附加上一个JSESSION的参数)。<br />
如果客户请求不包含session&nbsp;id，则为此客户创建一个session并且生成一个与此session相关联的session&nbsp;id，这个session&nbsp;id将在本次响应中返回给客户端保存。<br />
*************************************************************************************<br />
<br />
十三、保存session&nbsp;id的几种方式<br />
*************************************************************************************<br />
A．保存session&nbsp;id的方式可以采用cookie，这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。<br />
B．由于cookie可以被人为的禁止，必须有其它的机制以便在cookie被禁止时仍然能够把session&nbsp;id传递回服务器，经常采用的一种技术叫做URL重写，就是把session&nbsp;id附加在URL路径的后面，附加的方式也有两种，一种是作为URL路径的附加信息，另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态，就必须在每个客户端可能请求的路径后面都包含这个session&nbsp;id。<br />
C．另一种技术叫做表单隐藏字段。就是服务器会自动修改表单，添加一个隐藏字段，以便在表单提交时能够把session&nbsp;id传递回服务器。<br />
*************************************************************************************<br />
<br />
十四、session什么时候被创建<br />
*************************************************************************************<br />
一个常见的错误是以为session在有客户端访问时就被创建，然而事实是直到某server端程序(如Servlet)调用HttpServletRequest.getSession(true)这样的语句时才会被创建。<br />
*************************************************************************************<br />
<br />
十五、session何时被删除<br />
*************************************************************************************<br />
session在下列情况下被删除：<br />
A．程序调用HttpSession.invalidate()<br />
B．距离上一次收到客户端发送的session&nbsp;id时间间隔超过了session的最大有效时间<br />
C．服务器进程被停止<br />
<br />
再次注意关闭浏览器只会使存储在客户端浏览器内存中的session&nbsp;cookie失效，不会使服务器端的session对象失效。<br />
*************************************************************************************<br />
<br />
十六、URL重写有什么缺点<br />
*************************************************************************************<br />
　　　对所有的URL使用URL重写，包括超链接，form的action，和重定向的URL。每个引用你的站点的URL，以及那些返回给用户的URL(即使通过间接手段，比如服务器重定向中的Location字段)都要添加额外的信息。<br />
　　　这意味着在你的站点上不能有任何静态的HTML页面(至少静态页面中不能有任何链接到站点动态页面的链接)。因此，每个页面都必须使用servlet或JSP动态生成。即使所有的页面都动态生成，如果用户离开了会话并通过书签或链接再次回来，会话的信息都会丢失，因为存储下来的链接含有错误的标识信息－该URL后面的SESSION&nbsp;ID已经过期了。　　<br />
*************************************************************************************<br />
<br />
十七、使用隐藏的表单域有什么缺点<br />
*************************************************************************************<br />
&nbsp;&nbsp;&nbsp;&nbsp;仅当每个页面都是有表单提交而动态生成时，才能使用这种方法。单击常规的&lt;A&nbsp;HREF..&gt;超文本链接并不产生表单提交，因此隐藏的表单域不能支持通常的会话跟踪，只能用于一系列特定的操作中，比如在线商店的结账过程<br />
*************************************************************************************<br />
<br />
十八、会话跟踪的基本步骤<br />
*************************************************************************************<br />
1．访问与当前请求相关的会话对象<br />
2．查找与会话相关的信息<br />
3．存储会话信息<br />
4．废弃会话数据<br />
*************************************************************************************<br />
<br />
十九、getSession()/getSession(true)、getSession(false)的区别<br />
*************************************************************************************<br />
getSession()/getSession(true)：当session存在时返回该session，否则新建一个session并返回该对象<br />
getSession(false)：当session存在时返回该session，否则不会新建session，返回null<br />
*************************************************************************************<br />
<br />
二十、如何将信息于会话关联起来<br />
*************************************************************************************<br />
　　setAttribute会替换任何之前设定的值；如果想要在不提供任何代替的情况下移除某个值，则应使用removeAttribute。这个方法会触发所有实现了HttpSessionBindingListener接口的值的valueUnbound<br />
方法。<br />
*************************************************************************************<br />
<br />
二十一、会话属性的类型有什么限制吗<br />
*************************************************************************************<br />
通常会话属性的类型只要是Object就可以了。除了null或基本类型，如int,double,boolean。<br />
如果要使用基本类型的值作为属性，必须将其转换为相应的封装类对象<br />
*************************************************************************************<br />
<br />
二十二、如何废弃会话数据<br />
*************************************************************************************<br />
A．只移除自己编写的servlet创建的数据：<br />
&nbsp;&nbsp;&nbsp;调用removeAttribute(&#8220;key&#8221;)将指定键关联的值废弃<br />
B．删除整个会话(在当前Web应用中)：<br />
&nbsp;&nbsp;&nbsp;调用invalidate，将整个会话废弃掉。这样做会丢失该用户的所有会话数据，而非仅仅由我们<br />
servlet或JSP页面创建的会话数据<br />
C．将用户从系统中注销并删除所有属于他(或她)的会话<br />
&nbsp;&nbsp;&nbsp;调用logOut，将客户从Web服务器中注销，同时废弃所有与该用户相关联的会话(每个Web应用至多一个)。这个操作有可能影响到服务器上多个不同的Web应用<br />
*************************************************************************************<br />
<br />
二十三、使用isNew来判断用户是否为新旧用户的错误做法<br />
*************************************************************************************<br />
public&nbsp;boolean&nbsp;isNew()方法如果会话尚未和客户程序(浏览器)发生任何联系，则这个方法返回true，这一般是因为会话是新建的，不是由输入的客户请求所引起的。<br />
但如果isNew返回false，只不过是说明他之前曾经访问该Web应用，并不代表他们曾访问过我们的servlet或JSP页面。<br />
因为session是与用户相关的，在用户之前访问的每一个页面都有可能创建了会话。因此isNew为false只能说用户之前访问过该Web应用，session可以是当前页面创建，也可能是由用户之前访问过的页面创建的。<br />
正确的做法是判断某个session中是否存在某个特定的key且其value是否正确<br />
*************************************************************************************<br />
<br />
二十四、Cookie的过期和Session的超时有什么区别<br />
*************************************************************************************<br />
会话的超时由服务器来维护，它不同于Cookie的失效日期。首先，会话一般基于驻留内存的cookie<br />
不是持续性的cookie，因而也就没有截至日期。即使截取到JSESSIONID&nbsp;cookie，并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会截然不同。<br />
*************************************************************************************<br />
<br />
二十五、session&nbsp;cookie和session对象的生命周期是一样的吗<br />
*************************************************************************************<br />
当用户关闭了浏览器虽然session&nbsp;cookie已经消失，但session对象仍然保存在服务器端<br />
*************************************************************************************<br />
<br />
二十六、是否只要关闭浏览器，session就消失了<br />
*************************************************************************************<br />
程序一般都是在用户做log&nbsp;off的时候发个指令去删除session，然而浏览器从来不会主动在关闭之前通知服务器它将要被关闭，因此服务器根本不会有机会知道浏览器已经关闭。服务器会一直保留这个会话对象直到它处于非活动状态超过设定的间隔为止。<br />
之所以会有这种错误的认识，是因为大部分session机制都使用会话cookie来保存session&nbsp;id，而关闭浏览器后这个session&nbsp;id就消失了，再次连接到服务器时也就无法找到原来的session。<br />
如果服务器设置的cookie被保存到硬盘上，或者使用某种手段改写浏览器发出的HTTP请求报头，把原来的session&nbsp;id发送到服务器，则再次打开浏览器仍然能够找到原来的session。<br />
恰恰是由于关闭浏览器不会导致session被删除，迫使服务器为session设置了一个失效时间，当距离客户上一次使用session的时间超过了这个失效时间时，服务器就可以认为客户端已经停止了活动，才会把session删除以节省存储空间。<br />
　　由此我们可以得出如下结论：<br />
　　关闭浏览器，只会是浏览器端内存里的session&nbsp;cookie消失，但不会使保存在服务器端的session对象消失，同样也不会使已经保存到硬盘上的持久化cookie消失。<br />
*************************************************************************************<br />
<br />
<br />
二十七、打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session<br />
*************************************************************************************<br />
通常session&nbsp;cookie是不能跨窗口使用的，当你新开了一个浏览器窗口进入相同页面时，系统会赋予你一个新的session&nbsp;id，这样我们信息共享的目的就达不到了。<br />
此时我们可以先把session&nbsp;id保存在persistent&nbsp;cookie中(通过设置session的最大有效时间)，然后在新窗口中读出来，就可以得到上一个窗口的session&nbsp;id了，这样通过session&nbsp;cookie和persistent&nbsp;cookie的结合我们就可以实现了跨窗口的会话跟踪。<br />
*************************************************************************************<br />
<br />
二十八、如何使用会话显示每个客户的访问次数<br />
*************************************************************************************<br />
由于客户的访问次数是一个整型的变量，但session的属性类型中不能使用int，double，boolean等基本类型的变量，所以我们要用到这些基本类型的封装类型对象作为session对象中属性的值<br />
　　但像Integer是一种不可修改(Immutable)的数据结构：构建后就不能更改。这意味着每个请求都必须创建新的Integer对象，之后使用setAttribute来代替之前存在的老的属性的值。例如：<br />
HttpSession&nbsp;session&nbsp;=&nbsp;request.getSession();<br />
SomeImmutalbeClass&nbsp;value&nbsp;=&nbsp;(SomeImmutableClass)session.getAttribute(&#8220;SomeIdentifier&#8221;);<br />
if&nbsp;(value=&nbsp;=null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;new&nbsp;SomeImmutableClass(&#8230;);　//&nbsp;新创建一个不可更改对象<br />
}else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;new&nbsp;SomeImmutableClass(calculatedFrom(value));&nbsp;//&nbsp;对value重新计算后创建新的对象<br />
}<br />
session.setAttribute(&#8220;someIdentifier&#8221;,value);&nbsp;//&nbsp;使用新创建的对象覆盖原来的老的对象<br />
*************************************************************************************<br />
<br />
二十九、如何使用会话累计用户的数据<br />
*************************************************************************************<br />
使用可变的数据结构，比如数组、List、Map或含有可写字段的应用程序专有的数据结构。通过这种方式，除非首次分配对象，否则不需要调用setAttribute。例如<br />
<br />
HttpSession&nbsp;session&nbsp;=&nbsp;request.getSession();<br />
SomeMutableClass&nbsp;value&nbsp;=&nbsp;(SomeMutableClass)session.getAttribute(&#8220;someIdentifier&#8221;);<br />
if(value&nbsp;=&nbsp;=&nbsp;null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;new&nbsp;SomeMutableClass(&#8230;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;session.setAttribute(&#8220;someIdentifier&#8221;,value);<br />
}else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;value.updateInternalAttribute(&#8230;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果已经存在该对象则更新其属性而不需重新设置属性<br />
}<br />
*************************************************************************************<br />
<br />
三十、不可更改对象和可更改对象在会话数据更新时的不同处理<br />
*************************************************************************************<br />
不可更改对象因为一旦创建之后就不能更改，所以每次要修改会话中属性的值的时候，都需要<br />
调用setAttribute(&#8220;someIdentifier&#8221;,newValue)来代替原有的属性的值，否则属性的值不会被更新<br />
可更改对象因为其自身一般提供了修改自身属性的方法，所以每次要修改会话中属性的值的时<br />
候，只要调用该可更改对象的相关修改自身属性的方法就可以了。这意味着我们就不需要调<br />
用setAttribute方法了<br />
*************************************************************************************<br />
</span></p>
<img src ="http://www.blogjava.net/agun/aggbug/339792.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2010-12-04 12:14 <a href="http://www.blogjava.net/agun/archive/2010/12/04/339792.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring 常识2</title><link>http://www.blogjava.net/agun/archive/2010/12/04/339788.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Sat, 04 Dec 2010 03:52:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2010/12/04/339788.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/339788.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2010/12/04/339788.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/339788.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/339788.html</trackback:ping><description><![CDATA[<p><span style="color: #ff0000">1， Spring bean 定义</span></p>
<p>spring bean 定义可能包含大量的配置信息，包括容器相关的信息（比如初始化方法，静态工厂方法</p>
<p>等）、构造函数参数、属性等。如果两个bean之间的配置信息大同小异，可采用bean的继承来减少重</p>
<p>复配置工作。子bean定义可以从父bean定义继承部分配置。它也可覆盖一些配置，或者添加一些配置</p>
<p>。使用继承配置可以节省很多输入工作，实际上就是一种模板形式。</p>
<p><span style="color: #ff0000">spring中事务配置中就有这样例子，为了使用事务只要父配置了事务代理就可以了，所有需要事务的</span></p>
<p><span style="color: #ff0000">bean只要继承父就可以了。说到这个就在多说几句，父bean通常不需要实例化的，而仅仅作为子bean</span></p>
<p><span style="color: #ff0000">定的的模板使用；而ApplicationContext默认预初始化所有的singleton bean。为了阻止父bean被预</span></p>
<p><span style="color: #ff0000">初始化，可以使用abstract属性设置父bean为抽象bean。容器会忽略所有的抽象bean定义，预初始化</span></p>
<p><span style="color: #ff0000">时不初始化抽象bean</span>。</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000">2， spring 事务管理</span></p>
<p>传统的J2EE开发者对事务管理可能采用两种策略</p>
<p><span style="color: #ff0000">（1），全局事务</span>：全局事务通常由应用服务器管理，使用JTA。全局事务可跨越多个事务性的资源，保证</p>
<p>在多个事务性资源间跨越时资源一致性。<br />
<span style="color: #ff0000">（2），局部事务</span>：局部事务和特定资源相关，如，一个和JDBC链接关联的事务。该事务尽能保证对该</p>
<p>JDBC连接数据库的一致性，对局部事务，应用服务器不需要参与事务管理，不能保证跨越多个资源的</p>
<p>事务正确性。</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000">3，编程式事务</span></p>
<p>Spring 提供两种编程式的事务管理</p>
<p>&nbsp;</p>
<p>（1）使用TransactionTemplate事务管理</p>
<p>（2）直接使用一个PlatformTransactionManager实现类管理事务。</p>
<p>&nbsp;</p>
<p>两种编程式的事务都不需要与特定的事务API耦合，第一种更符合Spring模板式的编程模型，因此通常推荐采用第一种方式，第二种非常类似于JTA的UserTransaction的API编程，区别是减少了异常处理。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000">4，声明式事务</span></p>
<p>Spring的声明式事务是通过面向切面（AOP）实现。</p>
<p>（1）使用声明式事务管理</p>
<p>通常，通过TransactionPoxyFactoryBean为目标Bean生成Spring事务代理。当bean实例的方法需要事务管理时，采用TransactionPoxyFactoryBean来自目标bean生成事务代理。<span style="color: #ff0000">每个TransactionPoxyFactoryBean为一个具体的目标bean生成代理对象，代理对象的方法改写了目标bean的方法，就是在目标bean的方法执行之前加入开始事务，在目标bean方法结束之后提交事务，遇到指定异常回滚事务</span>。</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 定义事务代理bean模板</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://agun.javaeye.com/blog/789046#"><img alt="复制代码" src="http://agun.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-xml">
    <li><span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"txProxyTemplate"</span><span>&nbsp;</span><span class="attribute">abstract</span><span>=</span><span class="attribute-value">"true"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">class</span><span>="</span><span class="tag">&lt;</span><span class="tag-name">SPAN</span><span>&nbsp;style="</span><span class="attribute-value">COLOR</span><span>:&nbsp;#ff0000"</span><span class="tag">&gt;</span><span>org.springframework.transaction.interceptor.TransactionProxyFactoryBean</span><span class="tag">&lt;/</span><span class="tag-name">SPAN</span><span class="tag">&gt;</span><span>"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"transactionManager"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">ref</span><span>&nbsp;</span><span class="attribute">bean</span><span>=</span><span class="attribute-value">"transactionManager"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"transactionAttributes"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">props</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"trans_*"</span><span class="tag">&gt;</span><span>PROPAGATION_REQUIRED</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"query*"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROPAGATION_REQUIRED,readOnly,-Exception &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"find*"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROPAGATION_REQUIRED,readOnly,-Exception &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"load*"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROPAGATION_REQUIRED,readOnly,-Exception &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"*"</span><span class="tag">&gt;</span><span>PROPAGATION_REQUIRED,-Exception</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">props</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none" name="code">	&lt;bean id="txProxyTemplate" abstract="true"
class="<span style="color: #ff0000">org.springframework.transaction.interceptor.TransactionProxyFactoryBean</span>"&gt;
&lt;property name="transactionManager"&gt;
&lt;ref bean="transactionManager" /&gt;
&lt;/property&gt;
&lt;property name="transactionAttributes"&gt;
&lt;props&gt;
&lt;prop key="trans_*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="query*"&gt;
PROPAGATION_REQUIRED,readOnly,-Exception
&lt;/prop&gt;
&lt;prop key="find*"&gt;
PROPAGATION_REQUIRED,readOnly,-Exception
&lt;/prop&gt;
&lt;prop key="load*"&gt;
PROPAGATION_REQUIRED,readOnly,-Exception
&lt;/prop&gt;
&lt;prop key="*"&gt;PROPAGATION_REQUIRED,-Exception&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
&lt;/bean&gt;</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>（2）根据BeanName自动创建事务代理</p>
<p>如果同一个应用中有很多目标bean需要生成事务代理，当然可以为每个目标bean额外配置一个TransactionPoxyFactoryBean bean.这样做的缺点是，配置文件相当臃肿而且难以维护，此时可以考虑使用自动事务代理。自动事务代理的思路是，当ApplicationContext初始化完成后，由上下文中的某个bean<span style="color: #ff0000">"后处理"</span>每个目标bean，为这些目标bean生成事务代理。</p>
<p>能为目标bean执行<span style="color: #ff0000">"后处理"</span>的bean必须实现<span style="color: #ff0000">BeanFactoryPostProcessor</span>接口，ApplicationContext完成初始化后，会自动初始化所有实现BeanFactoryPostProcessor接口的bean，并且让它<span style="color: #ff0000">&#8220;后处理&#8221;</span>其他bean.Spring提供BeanFactoryPostProcessor的实现类<span style="color: #ff0000">BeanNameAutoPoxyCreator</span>，<span style="color: #ff0000">BeanNameAutoPoxyCreator</span>可以用来处理ApplicationContext中其他bean，方法是通过名称来识别，并且把他们用事务代理包装起来。<span style="color: #ff0000">BeanNameAutoPoxyCreator</span>生成的事务代理，和使用TransactionPoxyFactoryBean生成的事务代理基本一致。</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 定义事务拦截bean</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://agun.javaeye.com/blog/789046#"><img alt="复制代码" src="http://agun.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-xml">
    <li><span><span>&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"transactionInterceptor"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="attribute">class</span><span>="</span><span class="tag">&lt;</span><span class="tag-name">SPAN</span><span>&nbsp;style="</span><span class="attribute-value">COLOR</span><span>:&nbsp;#ff0000"</span><span class="tag">&gt;</span><span>org.springframework.transaction.interceptor.TransactionInterceptor</span><span class="tag">&lt;/</span><span class="tag-name">SPAN</span><span class="tag">&gt;</span><span>"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"transactionManager"</span><span>&nbsp;</span><span class="attribute">ref</span><span>=</span><span class="attribute-value">"TransactionManager"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"transactionAttributes"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">props</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"create*"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROPAGATION_REQUIRED,-Exception &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"delete*"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROPAGATION_REQUIRED,-Exception &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"update*"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROPAGATION_REQUIRED,-Exception &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"get*"</span><span class="tag">&gt;</span><span>PROPAGATION_REQUIRED</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">props</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none" name="code">&nbsp;&lt;bean id="transactionInterceptor"
&nbsp;&nbsp;class="<span style="color: #ff0000">org.springframework.transaction.interceptor.TransactionInterceptor</span>"&gt;
&nbsp;&nbsp;&lt;property name="transactionManager" ref="TransactionManager" /&gt;
&nbsp;&nbsp;
&nbsp;&nbsp;&lt;property name="transactionAttributes"&gt;
&nbsp;&nbsp;&nbsp;&lt;props&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="create*"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROPAGATION_REQUIRED,-Exception
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/prop&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="delete*"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROPAGATION_REQUIRED,-Exception
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/prop&gt;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="update*"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROPAGATION_REQUIRED,-Exception
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/prop&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="get*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&nbsp;&nbsp;&nbsp;&lt;/props&gt;
&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&lt;/bean&gt;</pre>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://agun.javaeye.com/blog/789046#"><img alt="复制代码" src="http://agun.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-xml">
    <li><span><span>&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="attribute">class</span><span>="</span><span class="tag">&lt;</span><span class="tag-name">SPAN</span><span>&nbsp;style="</span><span class="attribute-value">COLOR</span><span>:&nbsp;#ff0000"</span><span class="tag">&gt;</span><span>org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator</span><span class="tag">&lt;/</span><span class="tag-name">SPAN</span><span class="tag">&gt;</span><span>"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"beanNames"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>*Service</span><span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"interceptorNames"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>transactionInterceptor</span><span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none" name="code">&nbsp;&lt;bean
&nbsp;&nbsp;class="<span style="color: #ff0000">org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator</span>"&gt;
&nbsp;&nbsp;&lt;property name="beanNames"&gt;
&nbsp;&nbsp;&nbsp;&lt;value&gt;*Service&lt;/value&gt;
&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&lt;property name="interceptorNames"&gt;
&nbsp;&nbsp;&nbsp;&lt;list&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;transactionInterceptor&lt;/value&gt;
&nbsp;&nbsp;&nbsp;&lt;/list&gt;
&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&lt;/bean&gt;&nbsp;</pre>
<p>&nbsp;</p>
<p>次配置关键在两个bean </p>
<p>TransactionInterceptor</p>
<p>BeanNameAutoProxyCreator</p>
<p>&nbsp;</p>
<p>（3）基于注释式事务代理配置</p>
<img src ="http://www.blogjava.net/agun/aggbug/339788.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2010-12-04 11:52 <a href="http://www.blogjava.net/agun/archive/2010/12/04/339788.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring 常识1</title><link>http://www.blogjava.net/agun/archive/2010/12/04/339787.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Sat, 04 Dec 2010 03:50:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2010/12/04/339787.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/339787.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2010/12/04/339787.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/339787.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/339787.html</trackback:ping><description><![CDATA[<span style="color: #ff0000">1,实例化bean</span><br />
就Spring IoC容器而言，bean定义基本上描述了创建一个或多个实际bean对象的内容。当需要的时候，容器会从bean定义列表中取得一个指定的bean定义，并根据bean定义里面的配置元数据使用反射机制来创建一个实际的对象。因此这一节将讲解如何告知Spring IoC容器我们将要实例化的对象的类型以及如何实例化对象。
<p>当采用XML描述配置元数据时，将通过&lt;bean/&gt;元素的class属性来指定实例化对象的类型。class 属性 (对应BeanDefinition实例的Class属性)通常是必须的(不过也有两种例外的情形，&#8220;使用实例工厂方法实例化&#8221;和&#8220;bean定义的继承&#8221;)。class属性主要有两种用途：在大多数情况下，容器将直接通过反射调用指定类的构造器来创建bean(这有点等类似于在Java代码中使用new操作符)；在极少数情况下，容器将调用类的静态工厂方法来创建bean实例，class属性将用来指定实际具有静态工厂方法的类(至于调用静态工厂方法创建的对象类型是当前class还是其他的class则无关紧要)。</p>
<p><span style="color: #ff0000">2, 延迟初始化bean</span><br />
ApplicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化。提前实例化意味着作为初始化过程的一部分，ApplicationContext实例会创建并配置所有的singleton bean。通常情况下这是件好事，因为这样在配置中的任何错误就会即刻被发现（否则的话可能要花几个小时甚至几天）。</p>
<p>有时候这种默认处理可能并不是你想要的。如果你不想让一个singleton bean在ApplicationContext实现在初始化时被提前实例化，那么可以将bean设置为延迟实例化。一个延迟初始化bean将告诉IoC 容器是在启动时还是在第一次被用到时实例化。</p>
<p>在XML配置文件中，延迟初始化将通过&lt;bean/&gt;元素中的lazy-init属性来进行控制。例如：</p>
<p>&lt;bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;!-- various properties here... --&gt;<br />
&lt;/bean&gt;<br />
&nbsp; &lt;bean name="not.lazy" class="com.foo.AnotherBean"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;!-- various properties here... --&gt;<br />
&lt;/bean&gt;<br />
当ApplicationContext实现加载上述配置时，设置为lazy的bean将不会在ApplicationContext启动时提前被实例化，而not.lazy却会被提前实例化。</p>
<p>需要说明的是，如果一个bean被设置为延迟初始化，而另一个非延迟初始化的singleton bean依赖于它，那么当ApplicationContext提前实例化singleton bean时，它必须也确保所有上述singleton 依赖bean也被预先初始化，当然也包括设置为延迟实例化的bean。因此，如果Ioc容器在启动的时候创建了那些设置为延迟实例化的bean的实例，你也不要觉得奇怪，因为那些延迟初始化的bean可能在配置的某个地方被注入到了一个非延迟初始化singleton bean里面。</p>
<p>在容器层次中通过在&lt;beans/&gt;元素上使用'default-lazy-init'属性来控制延迟初始化也是可能的。如下面的配置：<br />
&lt;beans default-lazy-init="true"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;!-- no beans will be eagerly pre-instantiated... --&gt;<br />
&lt;/beans&gt;</p>
<p><br />
<span style="color: #ff0000">3,自动装配（autowire）协作者</span><br />
Spring IoC容器可以自动装配（autowire）相互协作bean之间的关联关系。因此，如果可能的话，可以自动让Spring通过检查BeanFactory中的内容，来替我们指定bean的协作者（其他被依赖的bean）。由于autowire可以针对单个bean进行设置，因此可以让有些bean使用autowire，有些bean不采用。autowire的方便之处在减少或者消除属性或构造器参数的设置，这样可以给我们的配置文件减减肥！[2] 在xml配置文件中，autowire一共有五种类型，可以在&lt;bean/&gt;元素中使用autowire属性指定:</p>
<p>Table 3.2. Autowiring modes</p>
<p>模式 说明 </p>
<p>&nbsp;&nbsp;&nbsp; no 不使用自动装配。必须通过ref元素指定依赖，这是默认设置。由于显式指定协作者可以使配置更灵活、更清晰，因此对于较大的部署配置，推荐采用该设置。而且在某种程度上，它也是系统架构的一种文档形式。<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; byName 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean，并将其与属性自动装配。例如，在bean定义中将autowire设置为by name，而该bean包含master属性（同时提供setMaster(..)方法），Spring就会查找名为master的bean定义，并用它来装配给master属性。<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; byType 如果容器中存在一个与指定属性类型相同的bean，那么将与该属性自动装配。如果存在多个该类型的bean，那么将会抛出异常，并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean，则什么事都不发生，属性也不会被设置。如果你不希望这样，那么可以通过设置dependency-check="objects"让Spring抛出异常。<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; constructor 与byType的方式类似，不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean，那么将会抛出异常。<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; autodetect 通过bean类的自省机制（introspection）来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器，那么将使用byType方式。<br />
&nbsp;</p>
<p>如果直接使用property和constructor-arg注入依赖的话，那么将总是覆盖自动装配。而且目前也不支持简单类型的自动装配，这里所说的简单类型包括基本类型、String、Class以及简单类型的数组（这一点已经被设计，将考虑作为一个功能提供）。自动装配还可以与依赖检查结合使用，这样依赖检查将在自动装配完成之后被执行。</p>
<p>理解自动装配的优缺点是很重要的。其中优点包括：</p>
<p>自动装配能显著减少配置的数量。不过，采用bean模板（见这里）也可以达到同样的目的。</p>
<p>自动装配可以使配置与java代码同步更新。例如，如果你需要给一个java类增加一个依赖，那么该依赖将被自动实现而不需要修改配置。因此强烈推荐在开发过程中采用自动装配，而在系统趋于稳定的时候改为显式装配的方式。</p>
<p>自动装配的一些缺点：</p>
<p>尽管自动装配比显式装配更神奇，但是，正如上面所提到的，Spring会尽量避免在装配不明确的时候进行猜测，因为装配不明确可能出现难以预料的结果，而且Spring所管理的对象之间的关联关系也不再能清晰的进行文档化。</p>
<p>对于那些根据Spring配置文件生成文档的工具来说，自动装配将会使这些工具没法生成依赖信息。</p>
<p>如果采用by type方式自动装配，那么容器中类型与自动装配bean的属性或者构造函数参数类型一致的bean只能有一个，如果配置可能存在多个这样的bean，那么就要考虑采用显式装配了。</p>
<p>尽管使用autowire没有对错之分，但是能在一个项目中保持一定程度的一致性是最好的做法。例如，通常情况下如果没有使用自动装配，那么仅自动装配一个或两个bean定义可能会引起开发者的混淆。</p>
<img src ="http://www.blogjava.net/agun/aggbug/339787.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2010-12-04 11:50 <a href="http://www.blogjava.net/agun/archive/2010/12/04/339787.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ehcache分布式缓存</title><link>http://www.blogjava.net/agun/archive/2010/12/04/339786.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Sat, 04 Dec 2010 03:49:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2010/12/04/339786.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/339786.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2010/12/04/339786.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/339786.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/339786.html</trackback:ping><description><![CDATA[<p>Ehcache分布式缓存也是我一直比较较关注的，以前用过oscache的分布式缓存。在网上看到了相关文章记录下来。</p>
<p>&nbsp;</p>
<p>Ehcache支持的分布式缓存支持有三种RMI，JGroups，JMS</p>
<p>&nbsp;</p>
<p>这里介绍下MRI和JGrpups两种方式，Ehcache使用版本为1.5.0，关于ehcache的其他信息请参考http://ehcache.sourceforge.net/EhcacheUserGuide.html，关于jgroups的信息请参考<a href="http://www.jgroups.org/manual/html_single/index.html">http://www.jgroups.org/manual/html_single/index.html</a>。</p>
<p>&nbsp;</p>
<p>原始文章 <a href="http://www.javaeye.com/topic/335623">http://www.javaeye.com/topic/335623</a></p>
<img src ="http://www.blogjava.net/agun/aggbug/339786.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2010-12-04 11:49 <a href="http://www.blogjava.net/agun/archive/2010/12/04/339786.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ehcache缓存配置</title><link>http://www.blogjava.net/agun/archive/2010/12/04/339785.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Sat, 04 Dec 2010 03:46:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2010/12/04/339785.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/339785.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2010/12/04/339785.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/339785.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/339785.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 近期项目用到Ehcache，以前项目主要用到Oscache,并且缓存也是针对orm来处理，只要配置就好，不需要自定义缓存，不需管理缓存。下面描述一下，Spring+Ehcache来处理缓存。1，首先引入jar包就不说了环境也不说了，要引入ehcache.xml文件(ehcache配置文件)。Xml代码     &lt;ehcache&nbsp;xmlns:xsi="ht...&nbsp;&nbsp;<a href='http://www.blogjava.net/agun/archive/2010/12/04/339785.html'>阅读全文</a><img src ="http://www.blogjava.net/agun/aggbug/339785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2010-12-04 11:46 <a href="http://www.blogjava.net/agun/archive/2010/12/04/339785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web Services</title><link>http://www.blogjava.net/agun/archive/2010/12/04/339784.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Sat, 04 Dec 2010 03:45:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2010/12/04/339784.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/339784.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2010/12/04/339784.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/339784.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/339784.html</trackback:ping><description><![CDATA[<p>web 服务是通过标准的web协议可以访问的一个应用程序组件。</p>
<p>它是一种可以接收从internet 或者internet 上的其他系统传递过来的请求的轻量级独立的通信技术。这种技术允许网络上的所有系统进行交互。</p>
<p>&nbsp;</p>
<p>j2ee平台是围绕web服务来构架的，其中的技术和web服务相关的有<span style="color: #ff0000">JAX-RCP 、Web Service、SAAJ 、JAXR 、EJB 、JAC</span> 等，其中Web Services for J2EE 是WEB服务总框架，JAX-RCP是J2EE的WEB服务的核心技术，SAAJ为处理带附件的SOAP消息提供了JAVA编程API.</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000">在J2EE平台中，要开发WEB服务可以使用两种技术，一种基于XML远程调用的技术-JAX-RCP，另外一个基于XML的消息发送技术-JAXM</span>.</p>
<p>&nbsp;</p>
<p>这里主要针对JAX-RCP 详细说一下。</p>
<p>&nbsp;</p>
<p>JAX-RCP( JAVA API FOR XMLBASED RCP) 是一种远程方法调用（或者说远程过程调用），那么它和其他远程方法调用（RPC,COM,CORBA RMI）有什么区别呢</p>
<p>&nbsp;</p>
<p>综合比较长远的远程方法调用技术，他们有以下共性。</p>
<p>&nbsp;</p>
<p>1，在客户端和服务端有通用的编程接口。</p>
<p>&nbsp;</p>
<p>2，在客户端STUB,在服务端有SKELETON.</p>
<p>&nbsp;</p>
<p>3，客户端和服务端有专门的协议进行数据传输。</p>
<p>&nbsp;</p>
<p>对于通用接口的描述，比如CORBA 有IDL OF CORBA ，JAVA RMI 有JAVA RMI INTERFACE IN RMI ，对于基于XML的RPC 来说，IDL 就是WSDL。那么对于XML-RPC来说，这个结构中&#8220;传输协议&#8221;当然是SAOP，SOAP消息是将以传输文本为基础的协议（HTTP,SMTP FTP）作为载体来使用的。也就是说，SOAP消息的传输建立在HTTP SMTP FTP之上。</p>
<p>&nbsp;</p>
<p>&nbsp;JAX-RCP的客户端调用方法:</p>
<p>&nbsp;</p>
<p>1，基于STUB</p>
<p>2，动态代理</p>
<p>3，动态调用</p>
<img src ="http://www.blogjava.net/agun/aggbug/339784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2010-12-04 11:45 <a href="http://www.blogjava.net/agun/archive/2010/12/04/339784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate查询（1）</title><link>http://www.blogjava.net/agun/archive/2010/02/24/313818.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Wed, 24 Feb 2010 08:56:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2010/02/24/313818.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/313818.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2010/02/24/313818.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/313818.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/313818.html</trackback:ping><description><![CDATA[<p>相信越来越多的web开发者，在持久层都采用了hibernate。hibernate 可以大大提高开发效率，同时对应项目的移植也有好处，但是同样也存在问题，大家在使用hibernate的时候很少去关心效率问题，但是这个就是一个打的问题，好多项目不成功就是项目中没有对hibernate熟悉的人，大家就是会简单的使用，所以再有些细节上的东西我们开发人员没有注意。</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp; 就拿hibernate来说吧，他支持hql查询，在我们组装sql语句时，需要注意几个问题：<br />
<font class="" style="font-family: " color="#ff0000">&nbsp;&nbsp; 1、要查询当然离不开数据库，我们建表时，默认的主键都是索引，这里要注意的就是关于建立单个索引和复合索引了。</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 具体的索引的hibernate中也是适用，我发现好多人用hibernate就很少提到索引这个概念了（用ibatis自己写sql就会关注索引字段，这个还是可以的额）</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 索引的引用规则都是适用的：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 介绍下：单个索引就是出现索引字段作为条件就应用 ；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 复合索引(假设是2个字段的复合索引)，出现复合索引的第一个字段作为条件就应用；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 出现复合索引的2个字段作为条件，这应用，如果没有出现复合索引的第一个字段则不应用；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由此我们需要为我们的数据库建立索引，记住复合索引是有顺序的 。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 影响我们建立索引的条件还有就是业务(这个很重要) ，举个例子：如果有2个查询条件(性别、所在部门)，倘若我们要建立符合索引，<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么我们应该将"所在部门"字段放在前面，"性别"放在后面，主要是因为，如果某个地方的查询条件只有"所在部门"，也可以起作用。另外要注意，如果查询索引字段参与函数计算和like等，那么索引也不起作用。<br />
<font class="" style="font-family: " color="#ff0000">&nbsp; 2、 在我们写查询代码时，尽量对应各个表的已经存在索引写查询条件<br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [第一个查询条件尽量是单个索引，或者是复合索引的第一个字段]&nbsp; 。<br />
&nbsp; <font class="" style="font-family: " color="#ff0000">3、还有就是大家再拼装查询语句时，传入的查询条件值尽量不要直接写在查询语句中，而是要以参数的方式提供即</font><font class="" style="font-family: " color="#ff0000">使用</font><font class="" style="font-family: " color="#0000ff">绑定参数</font>，<br />
&nbsp;&nbsp;&nbsp;&nbsp; 这样，系统多次调用统一个查询时(比如：select * from&nbsp;TestVO where code = ?&nbsp;&nbsp; [不要写为&nbsp; select * from TestVO where code = 'aaaa']) ，<br />
&nbsp;&nbsp;&nbsp;&nbsp; 条件值都是以参数的方式提供的，这样，多次查询虽然参数值不一样，但查询语句相同，数据库只有第一次才对查询语句进行编译，<br />
&nbsp;&nbsp;&nbsp;&nbsp; 以后则不在编译，所以性能会有提升。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 用参数的方式还有一个好处是：如果你不是使用<br />
&nbsp;&nbsp;&nbsp;&nbsp; Criteria criteria = openSession().createCriteria(**PO.class);<br />
&nbsp;&nbsp;&nbsp;&nbsp; criteria.add(Restrictions.like( "name",convertDBString(name) ));<br />
&nbsp;&nbsp;&nbsp;&nbsp; 的方式，而是使用hibernate的hql的话，那么如果参数值为中文会有问题，用参数可以解决这个问题。</p>
<p><font class="" style="font-family: " color="#ff0000">注：&nbsp;使用绑定参数的优势： <br />
</font>　　我们为什么要使用绑定命名参数？任何一个事物的存在都是有其价</p>
<p>值的，具体到绑定参数对于HQL查询来说，主要有以下两个主要优势： <br />
　　①、 可以利用数据库实施性能优化，因为对Hibernate来说在底层</p>
<p>使用的是PrepareStatement来完成查询，因此对于语法相同参数不同的</p>
<p>SQL语句，可以充分利用预编译SQL语句缓存，从而提升查询效率。 <br />
　　②、 可以防止SQL Injection安全漏洞的产生： <br />
</p>
<img src ="http://www.blogjava.net/agun/aggbug/313818.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2010-02-24 16:56 <a href="http://www.blogjava.net/agun/archive/2010/02/24/313818.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>servlet线程安全问题分析(网上整理)</title><link>http://www.blogjava.net/agun/archive/2009/03/02/257297.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Mon, 02 Mar 2009 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2009/03/02/257297.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/257297.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2009/03/02/257297.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/257297.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/257297.html</trackback:ping><description><![CDATA[这两天在整理些基础的资料，在网上看到了这篇文章<br />
<br />
Servlet/JSP技术和ASP、PHP等相比，由于其多线程运行而具有很高的执行效率。由于Servlet/JSP默认是以多线程模式执行的，所以，在编写代码时需要非常细致地考虑多线程的安全性问题。然而，很多人编写Servlet/JSP程序时并没有注意到多线程安全性的问题，这往往造成编写的程序在少量用户访问时没有任何问题，而在并发用户上升到一定值时，就会经常出现一些莫明其妙的问题。<br />
<br />
　　<strong>Servlet的多线程机制</strong><br />
　 <br />
　　Servlet体系结构是建立在Java多线程机制之上的，它的生命周期是由Web容器负责的。当客户端第一次请求某个Servlet时，Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时，一般不会再实例化该Servlet类，也就是有多个线程在使用这个实例。Servlet容器会自动使用线程池等技术来支持系统的运行，如图1所示。<br />
<br />
<table width="90%" align="center" border="0">
    <tbody>
        <tr>
            <td>
            <div align="center"><img hspace="3" src="http://www.j2medev.com/Article/UploadFiles/200601/20060112210435741.jpg" align="center" vspace="1" border="1"  alt="" /><br />
            图1 Servlet线程池</div>
            </td>
        </tr>
    </tbody>
</table>
<br />
　　这样，当两个或多个线程同时访问同一个Servlet时，可能会发生多个线程同时访问同一资源的情况，数据可能会变得不一致。所以在用Servlet构建的Web应用时如果不注意线程安全的问题，会使所写的Servlet程序有难以发现的错误。<br />
<br />
　　<strong>Servlet的线程安全问题<br />
</strong><br />
　　Servlet的线程安全问题主要是由于实例变量使用不当而引起的，这里以一个现实的例子来说明。<br />
<br />
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td>Import javax.servlet. *; <br />
            Import javax.servlet.http. *; <br />
            Import java.<a href="http://www.yesky.com/key/938/160938.html" target="_blank"><u><font color="#0000ff">io</font></u></a>. *; <br />
            Public class Concurrent Test extends HttpServlet {PrintWriter output; <br />
            Public void service (HttpServletRequest request,<br />
            HttpServletResponse response) throws ServletException, IOException {String username;<br />
            Response.setContentType ("text/html; charset=gb2312");<br />
            Username = request.getParameter ("username"); <br />
            Output = response.getWriter (); <br />
            Try {Thread. sleep (5000); //为了突出并发问题，在这设置一个延时<br />
            } Catch (Interrupted Exception e){}<br />
            output.println("用户名:"+Username+"&lt;BR&gt;"); <br />
            }<br />
            }</td>
        </tr>
    </tbody>
</table>
<br />
　　该Servlet中定义了一个实例变量output，在service方法将其赋值为用户的输出。当一个用户访问该Servlet时，程序会正常的运行，但当多个用户并发访问时，就可能会出现其它用户的信息显示在另外一些用户的浏览器上的问题。这是一个严重的问题。为了突出并发问题，便于测试、观察，我们在回显用户信息时执行了一个延时的操作。假设已在web.xml配置文件中注册了该Servlet，现有两个用户a和b同时访问该Servlet（可以启动两个IE浏览器，或者在两台机器上同时访问）,即同时在浏览器中输入：<br />
<br />
　　a： <a href="http://localhost/" target="_blank"><font color="#111100">http://localhost:</font></a> 8080/servlet/ConcurrentTest? Username=a<br />
<br />
　　b： <a href="http://localhost/" target="_blank"><font color="#111100">http://localhost:</font></a> 8080/servlet/ConcurrentTest? Username=b<br />
<br />
　　如果用户b比用户a回车的时间稍慢一点，将得到如图2所示的输出：<br />
<br />
<table width="90%" align="center" border="0">
    <tbody>
        <tr>
            <td>
            <div align="center"><img hspace="3" src="http://www.j2medev.com/Article/UploadFiles/200601/20060112210436460.jpg" align="center" vspace="1" border="1"  alt="" /><br />
            图2 a用户和b用户的浏览器输出</div>
            </td>
        </tr>
    </tbody>
</table>
<br />
　　从图2中可以看到，Web服务器启动了两个线程分别处理来自用户a和用户b的请求，但是在用户a的浏览器上却得到一个空白的屏幕，用户a的信息显示在用户b的浏览器上。该Servlet存在线程不安全问题。下面我们就从分析该实例的内存模型入手,观察不同时刻实例变量output的值来分析使该Servlet线程不安全的原因。<br />
<br />
　　Java的内存模型JMM（Java <a href="http://www.yesky.com/key/1549/161549.html" target="_blank"><u><font color="#0000ff">Memory</font></u></a> <a href="http://www.yesky.com/key/2432/162432.html" target="_blank"><u><font color="#0000ff">Model</font></u></a>）JMM主要是为了规定了线程和内存之间的一些关系。根据JMM的设计，系统存在一个主内存(Main Memory)，Java中所有实例变量都储存在主存中，对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory)，工作内存由缓存和堆栈两部分组成，缓存中保存的是主存中变量的拷贝，缓存可能并不总和主存同步，也就是缓存中变量的修改可能没有立刻写到主存中；堆栈中保存的是线程的局部变量，线程之间无法相互直接访问堆栈中的变量。根据JMM，我们可以将论文中所讨论的Servlet实例的内存模型抽象为图3所示的模型。<br />
<br />
<table width="90%" align="center" border="0">
    <tbody>
        <tr>
            <td>
            <div align="center"><img hspace="3" src="http://www.j2medev.com/Article/UploadFiles/200601/20060112210436810.jpg" align="center" vspace="1" border="1"  alt="" /><br />
            图3 Servlet实例的JMM模型</div>
            </td>
        </tr>
    </tbody>
</table>
<br />
　　下面根据图3所示的内存模型，来分析当用户a和b的线程（简称为a线程、b线程）并发执行时，Servlet实例中所涉及变量的变化情况及线程的执行情况，如图4所示。<br />
<br />
<table cellspacing="0" cellpadding="2" width="85%" align="center" border="1">
    <tbody>
        <tr>
            <td width="14%">调度时刻</td>
            <td width="38%">a线程</td>
            <td width="48%">b线程</td>
        </tr>
        <tr>
            <td width="14%"><a href="http://www.yesky.com/key/1893/161893.html" target="_blank"><u><font color="#0000ff">T1</font></u></a></td>
            <td width="38%">访问Servlet页面</td>
            <td width="48%"></td>
        </tr>
        <tr>
            <td width="14%">T2</td>
            <td width="38%"></td>
            <td width="48%">访问Servlet页面</td>
        </tr>
        <tr>
            <td width="14%">T3</td>
            <td width="38%">output=a的输出username=a休眠5000毫秒，让出CPU</td>
            <td width="48%"></td>
        </tr>
        <tr>
            <td width="14%">T4</td>
            <td width="38%"></td>
            <td width="48%">output=b的输出（写回主存）username=b休眠5000毫秒，让出CPU</td>
        </tr>
        <tr>
            <td width="14%">T5</td>
            <td width="38%">在用户b的浏览器上输出a线程的username的值,a线程终止。</td>
            <td width="48%"></td>
        </tr>
        <tr>
            <td width="14%">T6</td>
            <td width="38%"></td>
            <td width="48%">在用户b的浏览器上输出b线程的username的值,b线程终止。</td>
        </tr>
    </tbody>
</table>
　　　　　　　　　　　　　　　　　　图4 Servlet实例的线程调度情况<br />
<br />
　　从图4中可以清楚的看到，由于b线程对实例变量output的修改覆盖了a线程对实例变量output的修改，从而导致了用户a的信息显示在了用户b的浏览器上。如果在a线程执行输出语句时，b线程对output的修改还没有刷新到主存，那么将不会出现图2所示的输出结果，因此这只是一种偶然现象，但这更增加了程序潜在的危险性。 <br />
<strong>设计线程安全的Servlet<br />
<br />
</strong>　　通过上面的分析，我们知道了实例变量不正确的使用是造成Servlet线程不安全的主要原因。下面针对该问题给出了三种解决方案并对方案的选取给出了一些参考性的建议。<br />
<br />
　　<span style="color: red">1、实现 SingleThreadModel 接口</span><br />
<br />
　　该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行，当然也就不存在线程安全的问题。这种方法只要将前面的Concurrent Test类的类头定义更改为：<br />
<br />
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td>Public class Concurrent Test extends HttpServlet implements SingleThreadModel {<br />
            &#8230;&#8230;&#8230;&#8230;<br />
            }</td>
        </tr>
    </tbody>
</table>
<br />
　　<span style="color: red">2、同步对共享数据的操作</span><br />
<br />
　　使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段，在本论文中的Servlet可以通过同步块操作来保证线程的安全。同步后的代码如下： <br />
<br />
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td>&#8230;&#8230;&#8230;&#8230;<br />
            Public class Concurrent Test extends HttpServlet { &#8230;&#8230;&#8230;&#8230;<br />
            Username = request.getParameter ("username"); <br />
            Synchronized (this){<br />
            Output = response.getWriter (); <br />
            Try {<br />
            Thread. Sleep (5000);<br />
            } Catch (Interrupted Exception e){}<br />
            output.println("用户名:"+Username+"&lt;BR&gt;"); <br />
            } <br />
            }<br />
            }</td>
        </tr>
    </tbody>
</table>
<br />
　　<span style="color: red">3、避免使用实例变量</span><br />
<br />
　　本实例中的线程安全问题是由实例变量造成的，只要在Servlet里面的任何方法里面都不使用实例变量，那么该Servlet就是线程安全的。<br />
<br />
　　修正上面的Servlet代码，将实例变量改为局部变量实现同样的功能，代码如下：<br />
<br />
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td>&#8230;&#8230; <br />
            Public class Concurrent Test extends HttpServlet {public void service (HttpServletRequest request, HttpServletResponse <br />
            Response) throws ServletException, IOException {<br />
            Print Writer output; <br />
            String username;<br />
            Response.setContentType ("text/html; charset=gb2312");<br />
            &#8230;&#8230; <br />
            } <br />
            }</td>
        </tr>
    </tbody>
</table>
<br />
　　对上面的三种方法进行测试，可以表明用它们都能设计出线程安全的Servlet程序。但是，如果一个Servlet实现了SingleThreadModel接口，Servlet引擎将为每个新的请求创建一个单独的Servlet实例，这将引起大量的系统开销。SingleThreadModel在Servlet2.4中已不再提倡使用；同样如果在程序中使用同步来保护要使用的共享的数据，也会使系统的性能大大下降。这是因为被同步的代码块在同一时刻只能有一个线程执行它，使得其同时处理客户请求的吞吐量降低，而且很多客户处于阻塞状态。另外为保证主存内容和线程的工作内存中的数据的一致性，要频繁地刷新缓存,这也会大大地影响系统的性能。所以在实际的开发中也应避免或最小化 Servlet 中的同步代码；在Serlet中避免使用实例变量是保证Servlet线程安全的最佳选择。从Java 内存模型也可以知道，方法中的临时变量是在栈上分配空间，而且每个线程都有自己私有的栈空间，所以它们不会影响线程的安全。<br />
<br />
　　<strong>小结</strong><br />
<br />
　　Servlet的线程安全问题只有在大量的并发访问时才会显现出来，并且很难发现，因此在编写Servlet程序时要特别注意。线程安全问题主要是由实例变量造成的,因此在Servlet中应避免使用实例变量。如果应用程序设计无法避免使用实例变量，那么使用同步来保护要使用的实例变量，但为保证系统的最佳性能，应该同步可用性最小的代码路径。<br />
同时因为struts也是通过servlet来实现的，因为Struts的Action被设计为线程不安全的，所以也涉及到这个问题，所以也使用同样的方法来解决！
<img src ="http://www.blogjava.net/agun/aggbug/257297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2009-03-02 10:53 <a href="http://www.blogjava.net/agun/archive/2009/03/02/257297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有关web效率</title><link>http://www.blogjava.net/agun/archive/2008/03/18/186927.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Tue, 18 Mar 2008 02:10:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2008/03/18/186927.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/186927.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2008/03/18/186927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/186927.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/186927.html</trackback:ping><description><![CDATA[<p style="background: white; margin: 7.5pt 0cm; text-align: left" align="left"><span style="font-size: 10pt; font-family: Verdana">1)web</span><span style="font-size: 10pt; font-family: 宋体">开发的特点是是：没有太复杂的技术难点，一切在于迅速的把握需求，其实这正式敏捷开发的要旨所在，一切都可以非常快速的建立，非常快速的重构，我们的开发工具，底层库和框架，包括搜索引擎和</span><span style="font-size: 10pt; font-family: Verdana">web</span><span style="font-size: 10pt; font-family: 宋体">文档提供的帮助，都提我们供给了敏捷的能力。</span></p>
<p style="background: white; margin: 7.5pt 0cm; text-align: left" align="left"><span style="font-size: 10pt; font-family: Verdana">2)</span><span style="font-size: 10pt; font-family: 宋体">此外，相应的，最有效率的交流方式必须留给</span><span style="font-size: 10pt; font-family: Verdana">web</span><span style="font-size: 10pt; font-family: 宋体">开发，那就是</span><span style="font-size: 10pt; font-family: Verdana">face2face</span><span style="font-size: 10pt; font-family: 宋体">（面对面），不要太担心你的设计不能被完备的文档所保留下来，他们会以交流，代码和小卡片的方式保存下来</span></p>
<p style="background: white; margin: 7.5pt 0cm; text-align: left" align="left"><span style="font-size: 10pt; font-family: Verdana">3)</span><span style="font-size: 10pt; font-family: 宋体">人的因素会更加重要，无论是对用户的需求，还是开发人员的素质。</span></p>
<p style="background: white; margin: 7.5pt 0cm; text-align: left" align="left"><span style="font-size: 10pt; font-family: 宋体">另：有关</span><span style="font-size: 10pt; font-family: Verdana">web</span><span style="font-size: 10pt; font-family: 宋体">效率，有著名的</span><span style="font-size: 10pt; font-family: Verdana">14</span><span style="font-size: 10pt; font-family: 宋体">条规则，由</span><span style="font-size: 10pt; font-family: Verdana">yahoo</span><span style="font-size: 10pt; font-family: 宋体">性能效率小组所总结，并广为流传。业已出现相关插件（</span><span style="font-size: 10pt; font-family: Verdana"><a href="http://download.csdn.net/source/299494">YSlow</a></span><span style="font-size: 10pt; font-family: 宋体">），</span><span style="font-size: 10pt; font-family: Verdana">14 rules</span><span style="font-size: 10pt; font-family: 宋体">列在下面：</span></p>
<p style="background: white; text-align: left" align="left"><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">１．</span></strong><span style="font-size: 10pt; font-family: Verdana"> <a href="http://developer.yahoo.com/performance/rules.html#num_http">Make Fewer HTTP Requests</a> </span></p>
<p style="background: white; text-align: left" align="left"><span style="font-size: 10pt; font-family: 宋体">减少</span><span style="font-size: 10pt; font-family: Verdana">http</span><span style="font-size: 10pt; font-family: 宋体">请求次数</span></p>
<p style="background: white; text-align: left" align="left"><a href="http://www.w3.org/TR/html401/struct/objects.html#h-13.6"><em><u><span style="color: blue">Image maps</u></em></a> </span><span style="font-family: 宋体">　图像中增加ｕｒｌ可以将多个图片合为一个，减少</span>http<span style="font-family: 宋体">请求。</span></p>
<p style="background: white; text-align: left" align="left"><a href="http://alistapart.com/articles/sprites"><em><u><span style="color: blue">CSS Sprites</u></em></a> </span><span style="font-family: 宋体">　通过</span>css <span style="font-family: 宋体">将图片引入到页面中减少页面请求</span>http <span style="font-family: 宋体">。</span></p>
<p style="background: white; text-align: left" align="left"><em>Combined files</em><span style="font-family: 宋体">合并文件不如合并多个请求的</span>javascript<span style="font-family: 宋体">为一个。减少</span>http<span style="font-family: 宋体">请求。</span></p>
<p style="background: white; text-align: left" align="left"><span style="font-size: 10pt; font-family: Verdana">http://developer.yahoo.net/blog/archives/2007/04/rule_1_make_few.html</span></p>
<p style="background: white; text-align: left" align="left"><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">２．</span></strong><span style="font-size: 10pt; font-family: Verdana"> <a href="http://developer.yahoo.com/performance/rules.html#cdn">Use a Content Delivery Network</a> </span></p>
<p style="background: white; text-align: left" align="left"><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">３．</span></strong><span style="font-size: 10pt; font-family: Verdana"> <a href="http://developer.yahoo.com/performance/rules.html#expires">Add an Expires Header</a> </span></p>
<p style="background: white; text-align: left" align="left"><span style="font-size: 9.5pt; color: black; font-family: 宋体">在下载的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">css</span><span style="font-size: 9.5pt; color: black; font-family: 宋体">、</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">js</span><span style="font-size: 9.5pt; color: black; font-family: 宋体">、</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">image</span><span style="font-size: 9.5pt; color: black; font-family: 宋体">组件里增加过期时间</span></p>
<p style="background: white; text-align: left" align="left"><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">４．</span></strong><span style="font-size: 10pt; font-family: Verdana"> <a href="http://developer.yahoo.com/performance/rules.html#gzip">Gzip Components</a> </span></p>
<p><span style="font-size: 9.5pt; color: black">（对下载的组件进行压缩）</span></p>
<p><span style="font-size: 9.5pt; color: black">毫无疑问，对站点内容进行压缩是一个比较常用的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> Web </span><span style="font-size: 9.5pt; color: black">优化手段．但是并不一定都能达到理想的效果．原因在于</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> <a href="http://sourceforge.net/projects/mod-gzip/">mod-gzip</a> </span><span style="font-size: 9.5pt; color: black">模块不但消耗服务器端</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> <acronym><span style="font-family: Verdana">CPU</span></acronym></span><span style="font-size: 9.5pt; color: black">资源，也消耗客户端</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> <acronym><span style="font-family: Verdana">CPU</span></acronym></span><span style="font-size: 9.5pt; color: black">资源</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. </span><span style="font-size: 9.5pt; color: black">而且</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">, mod_gzip </span><span style="font-size: 9.5pt; color: black">压缩文件后创建的临时文件是放到磁盘上的，这也会给磁盘</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> <acronym><span style="font-family: Verdana">IO</span></acronym></span><span style="font-size: 9.5pt; color: black">带来严重的问题</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. </span></p>
<p><span style="font-size: 9.5pt; color: black; font-family: Verdana">Flickr </span><span style="font-size: 9.5pt; color: black">采用的是</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> Httpd 2.x </span><span style="font-size: 9.5pt; color: black">以后支持的　</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"><a href="http://httpd.apache.org/docs/2.0/mod/mod_deflate.html">mod_deflate</a> </span><span style="font-size: 9.5pt; color: black">模块．压缩操作都在内存中进行．</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">mod_deflate </span><span style="font-size: 9.5pt; color: black">在</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> Httpd 1.x </span><span style="font-size: 9.5pt; color: black">是不可用的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">, </span><span style="font-size: 9.5pt; color: black">不过可以通过创建</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> <acronym><span style="font-family: Verdana">RAM</span></acronym></span><span style="font-size: 9.5pt; color: black">盘的方式来间接提高性能．</span></p>
<p><span style="font-size: 9.5pt; color: black">当然</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">, mod_gzip </span><span style="font-size: 9.5pt; color: black">到也不是一无是处</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">, </span><span style="font-size: 9.5pt; color: black">对于预压缩的文件</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">, </span><span style="font-size: 9.5pt; color: black">还是有好处的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. </span><span style="font-size: 9.5pt; color: black">而且</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">, </span><span style="font-size: 9.5pt; color: black">采用压缩的时候</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">,</span><span style="font-size: 9.5pt; color: black">也要注意策略</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. </span><span style="font-size: 9.5pt; color: black">图片文件压缩就没什么必要了</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">(Flickr </span><span style="font-size: 9.5pt; color: black">上图像多</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">, </span><span style="font-size: 9.5pt; color: black">而且压缩得不到什么好处</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">). Flickr </span><span style="font-size: 9.5pt; color: black">只对</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">JavaScript </span><span style="font-size: 9.5pt; color: black">和</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> <acronym><span style="font-family: Verdana">CSS</span></acronym></span><span style="font-size: 9.5pt; color: black">进行压缩</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. mod_gzip </span><span style="font-size: 9.5pt; color: black">新一点的版本能够自动通过配置</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> mod_gzip_update_static </span><span style="font-size: 9.5pt; color: black">选项自动处理</span><span style="font-size: 9.5pt; color: black">预压缩的文件</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. Cal </span><span style="font-size: 9.5pt; color: black">也指出这个特性在一些旧版本的浏览器上会出问题</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. </span></p>
<p><span style="font-size: 9.5pt; color: black">压缩的另一个主要手段是内容的压缩</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. </span><span style="font-size: 9.5pt; color: black">针对</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> JavaScript </span><span style="font-size: 9.5pt; color: black">可以进行通过减少注释、合并空格、使用紧凑的语法等小技巧</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">(Google </span><span style="font-size: 9.5pt; color: black">的所有脚本都非常难读，而且非常紧凑，思想类似</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">).</span><span style="font-size: 9.5pt; color: black">当然，经过这样处理的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> JavaScript </span><span style="font-size: 9.5pt; color: black">可能带了很多括号不容易解析，</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"><a href="http://www.flickr.com/">Flickr</a> </span><span style="font-size: 9.5pt; color: black">使用了</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> <a href="http://dojotoolkit.org/docs/compressor_system.html">Dojo Compressor</a> </span><span style="font-size: 9.5pt; color: black">来构建解析树。</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">Dojo Compressor </span><span style="font-size: 9.5pt; color: black">开销很低，而且对于最终用户是透明的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. JavaScript </span><span style="font-size: 9.5pt; color: black">的处理方法介绍过，</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">CSS </span><span style="font-size: 9.5pt; color: black">处理则相对简单</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">.</span><span style="font-size: 9.5pt; color: black">通过简单的正则表达式替换</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">(</span><span style="font-size: 9.5pt; color: black">比如把多个空格替换为一个空格符</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">), </span><span style="font-size: 9.5pt; color: black">最高可以获得</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> 50% </span><span style="font-size: 9.5pt; color: black">的压缩比。</span></p>
<p style="background: white; text-align: left" align="left"><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">５．</span></strong><span style="font-size: 10pt; font-family: Verdana"> <a href="http://developer.yahoo.com/performance/rules.html#css_top">Put CSS at the Top</a> </span></p>
<p style="background: white; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: Verdana"><span style="color: black">css</span></span><span style="font-size: 9.5pt; color: black; font-family: 宋体">文件尽可能放在页面的最上面</span></p>
<p style="background: white; text-align: left" align="left"><span style="font-size: 10pt; font-family: Symbol">&#183;</span><span style="font-size: 10pt; font-family: Verdana">&nbsp;<a href="http://developer.yahoo.com/performance/rules.html#js_bottom">Move Scripts to the Bottom</a> </span></p>
<p style="background: white; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: Verdana"><span style="color: black">js</span></span><span style="font-size: 9.5pt; color: black; font-family: 宋体">文件尽可能放在页面的最下面</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">6</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Put JS components as close to the bottom of the page as possible.</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">js</span><span style="font-size: 9.5pt; color: black">文件尽可能放在页面的最下面）</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">7</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Avoid CSS Expressions</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（在</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">css</span><span style="font-size: 9.5pt; color: black">文件中慎用表达式）</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">8</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Make JavaScript and CSS External</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（在外部包含</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">js</span><span style="font-size: 9.5pt; color: black">和</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">css</span><span style="font-size: 9.5pt; color: black">文件）</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">9</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Reduce DNS Lookups</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（减少请求中域名的解析次数）</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">10</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Minify JavaScript</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">js</span><span style="font-size: 9.5pt; color: black">代码压缩）</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">11</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Avoid doing redirects.</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（避免重定向）</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">12</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Remove Duplicates Scripts</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（避免请求重复的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">js</span><span style="font-size: 9.5pt; color: black">文件）</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">13</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Configure ETags</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（配置好</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">ETag</span><span style="font-size: 9.5pt; color: black">）</span></p>
<p><span style="font-size: 9.5pt; color: black; font-family: Verdana"><a href="http://www.flickr.com/">Flickr</a> </span><span style="font-size: 9.5pt; color: black">的开发者充分利用了</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> Http 1.1 </span><span style="font-size: 9.5pt; color: black">规范定义的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> <a href="http://www.dbanotes.net/web/http_11_etag_lastmodified.html">Etag <span style="font-family: 宋体">与 Last-Modified <span style="font-family: 宋体">机制</span></a> </span></span><span style="font-size: 9.5pt; color: black">来提高</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> Caching </span><span style="font-size: 9.5pt; color: black">的效率</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. </span><span style="font-size: 9.5pt; color: black">值得注意的是，</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">Cal </span><span style="font-size: 9.5pt; color: black">介绍了一个在负载均衡条件下的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> e-Tag </span><span style="font-size: 9.5pt; color: black">小技巧</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">. </span><span style="font-size: 9.5pt; color: black">即可以设定</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> Apache </span><span style="font-size: 9.5pt; color: black">通过文件调整时间与文件大小获得</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> E-Tag ,</span><span style="font-size: 9.5pt; color: black">而默认情况下</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">, Apache </span><span style="font-size: 9.5pt; color: black">是通过文件节点获取</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> e-Tag </span><span style="font-size: 9.5pt; color: black">的。当然，这也不是很完美，因为会影响</span><span style="font-size: 9.5pt; color: black; font-family: Verdana"> if-modified-since </span><span style="font-size: 9.5pt; color: black">。</span></p>
<p><span style="font-size: 9.5pt; color: black">但是有的网站的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">e-Tag</span><span style="font-size: 9.5pt; color: black">，如</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">yahoo</span><span style="font-size: 9.5pt; color: black">，其产生规则是基于节点的。相同的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">css</span><span style="font-size: 9.5pt; color: black">或</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">js</span><span style="font-size: 9.5pt; color: black">脚本在不同节点服务器上的</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">e-Tag</span><span style="font-size: 9.5pt; color: black">不同，所以如果有</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">n</span><span style="font-size: 9.5pt; color: black">个服务器，那么浏览器获得</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">304</span><span style="font-size: 9.5pt; color: black">应答消息的概率是</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">1/n</span><span style="font-size: 9.5pt; color: black">。</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">14</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Make Ajax Cacheable</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（缓存</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">Ajax</span><span style="font-size: 9.5pt; color: black">请求）</span></p>
<p><span style="font-size: 9.5pt; color: black">以下几点是新增的准则，还没有正式公布，所以大家要注意，</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">15</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Flush the Header</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（先发送</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">Header</span><span style="font-size: 9.5pt; color: black">里的信息）</span></p>
<p><span style="font-size: 9.5pt; color: black; font-family: Verdana">We improved the page load times by flushing the apache output buffer after the document HEAD was generated.This had two benefits. </span></p>
<p><span style="font-size: 9.5pt; color: black; font-family: Verdana">First, the HEAD contains SCRIPT and LINK tags for scripts and stylesheets. By flushing the HEAD, those tags are received and parsed by the browser sooner, and in turn the browser starts downloading those components earlier. </span></p>
<p><span style="font-size: 9.5pt; color: black; font-family: Verdana">Second, the HEAD is flushed before actually generating the search results. This is a win for any property doing a significant backend computation or especially making one or more backend web service calls. </span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">16</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Split</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana"> Static Content Across Multiple Hostnames</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（把较大的静态文件分割成不同域的请求）</span></p>
<p><span style="font-size: 9.5pt; color: black; font-family: Verdana">If you have many (10 or more) components downloaded from a single hostname, it might be better to split those across two hostnames. </span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">17</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Reduce the Size of Cookies</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（不要让</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">Cookie</span><span style="font-size: 9.5pt; color: black">内容过大）</span></p>
<p><span style="font-size: 9.5pt; color: black; font-family: Verdana">Reduce the amount of data in the cookie by storing state information on the backend, and abbreviating names and values stored in the cookie. Set expiration dates on your cookies, and make them as short as possible. </span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">18</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Host Static Content on a Different Top-Level Domain</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（把静态文件放在不同的顶级域名下）</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">19</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Minify CSS</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">Css</span><span style="font-size: 9.5pt; color: black">代码压缩）</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">20</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Use GET for XHR</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（有</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">XHR</span><span style="font-size: 9.5pt; color: black">时使用</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">GET</span><span style="font-size: 9.5pt; color: black">请求）</span></p>
<p><span style="font-size: 9.5pt; color: black; font-family: Verdana">Iain Lamb did a deep study of how using POST for XMLHttpRequests is inefficient, especially in IE. His recommendation: &#8220;If the amount of data you have to send to the server is small (less than 2k), I suggest you design your webservice / client application to use GET rather than POST</span><span style="font-size: 9.5pt; color: black">。</span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">21</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Avoid IFrames</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（尽量避免使用</span><span style="font-size: 9.5pt; color: black; font-family: Verdana">IFrame</span><span style="font-size: 9.5pt; color: black">）</span></p>
<p><span style="font-size: 9.5pt; color: black; font-family: Verdana">Don&#8217;t use SRC (set it via JS instead). Each IFrame takes 20-50ms, even if it contains nothing </span></p>
<p><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">22</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: 宋体">。</span></strong><strong><span style="font-size: 9.5pt; color: black; font-family: Verdana">Optimize images</span></strong></p>
<p><span style="font-size: 9.5pt; color: black">（优化图片）</span></p>
 <img src ="http://www.blogjava.net/agun/aggbug/186927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2008-03-18 10:10 <a href="http://www.blogjava.net/agun/archive/2008/03/18/186927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>quartz在spring中的使用</title><link>http://www.blogjava.net/agun/archive/2008/03/17/186689.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Mon, 17 Mar 2008 01:29:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2008/03/17/186689.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/186689.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2008/03/17/186689.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/186689.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/186689.html</trackback:ping><description><![CDATA[<p>(1)在spring 中的配置bean<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">(1)在spring&nbsp;中的配置bean<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="methodInvokingJobDetail"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;class</span><span style="color: #0000ff">="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="targetObject"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ref&nbsp;</span><span style="color: #ff0000">bean</span><span style="color: #0000ff">="quartzTest"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000">--指定请求的bean的对象<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="targetMethod"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">quartzTimer</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">--指定对象中的方法<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="cronTrigger"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;class</span><span style="color: #0000ff">="org.springframework.scheduling.quartz.CronTriggerBean"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="jobDetail"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ref&nbsp;</span><span style="color: #ff0000">bean</span><span style="color: #0000ff">="methodInvokingJobDetail"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="cronExpression"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">0&nbsp;25&nbsp;17,12,20&nbsp;*&nbsp;*&nbsp;?</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">--定时控制操作<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">class</span><span style="color: #0000ff">="org.springframework.scheduling.quartz.SchedulerFactoryBean"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="triggers"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">list</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ref&nbsp;</span><span style="color: #ff0000">local</span><span style="color: #0000ff">="cronTrigger"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">list</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span></div>
<p>&nbsp;</p>
<p>(2)定时控制--定时的格式（网上总结）<br />
</p>
<p>一个Cron-表达式是一个由六至七个字段组成由空格分隔的字符串，其中6个字段是必须的而一个是可选的，如下： <br />
<table cellspacing="8">
    <tbody>
        <tr>
            <th align="left">字段名 </th>
            <th align="left">&nbsp; </th>
            <th align="left">允许的值 </th>
            <th align="left">&nbsp; </th>
            <th align="left">允许的特殊字符 </th>
        </tr>
        <tr>
            <td align="left"><code>秒</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>0-59</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code> </td>
        </tr>
        <tr>
            <td align="left"><code>分</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>0-59</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code> </td>
        </tr>
        <tr>
            <td align="left"><code>小时</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>0-23</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code> </td>
        </tr>
        <tr>
            <td align="left"><code>日</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>1-31</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * ? / L W C</code> </td>
        </tr>
        <tr>
            <td align="left"><code>月</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>1-12 or JAN-DEC</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code> </td>
        </tr>
        <tr>
            <td align="left"><code>周几</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>1-7 or SUN-SAT</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * ? / L C #</code> </td>
        </tr>
        <tr>
            <td align="left"><code>年&nbsp;(可选字段)</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>empty, 1970-2099</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>, - * /</code></td>
        </tr>
    </tbody>
</table>
</p>
<p>&nbsp;'*' 字符可以用于所有字段，在&#8220;分&#8221;字段中设为"*"表示"每一分钟"的含义。 </p>
<p>'?' 字符可以用在&#8220;日&#8221;和&#8220;周几&#8221;字段.&nbsp;它用来指定 '不明确的值'. 这在你需要指定这两个字段中的某一个值而不是另外一个的时候会被用到。在后面的例子中可以看到其含义。 </p>
<p>'-' 字符被用来指定一个值的范围，比如在&#8220;小时&#8221;字段中设为"10-12"表示"10点到12点". </p>
<p>&nbsp;','&nbsp;字符指定数个值。比如在&#8220;周几&#8221;字段中设为"MON,WED,FRI"表示"the days Monday, Wednesday, and Friday". </p>
<p>'/'&nbsp;字符用来指定一个值的的增加幅度. 比如在&#8220;秒&#8221;字段中设置为"0/15"表示"第0, 15, 30,&nbsp;和 45秒"。而 "5/15"则表示"第5, 20, 35,&nbsp;和 50". 在'/'前加"*"字符相当于指定从0秒开始. 每个字段都有一系列可以开始或结束的数值。对于&#8220;秒&#8221;和&#8220;分&#8221;字段来说，其数值范围为0到59，对于&#8220;小时&#8221;字段来说其为0到23, 对于&#8220;日&#8221;字段来说为0到31, 而对于&#8220;月&#8221;字段来说为1到12。"/"字段仅仅只是帮助你在允许的数值范围内从开始"第n"的值。&nbsp;因此 对于&#8220;月&#8221;字段来说"7/6"只是表示7月被开启而不是&#8220;每六个月&#8221;, 请注意其中微妙的差别。 </p>
<p>'L'字符可用在&#8220;日&#8221;和&#8220;周几&#8221;这两个字段。它是"last"的缩写, 但是在这两个字段中有不同的含义。例如,&#8220;日&#8221;字段中的"L"表示"一个月中的最后一天" —— 对于一月就是31号对于二月来说就是28号（非闰年）。而在&#8220;周几&#8221;字段中, 它简单的表示"7" or "SAT"，但是如果在&#8220;周几&#8221;字段中使用时跟在某个数字之后, 它表示"该月最后一个星期&#215;" —— 比如"6L"表示"该月最后一个周五"。当使用'L'选项时,指定确定的列表或者范围非常重要，否则你会被结果搞糊涂的。 </p>
<p>'W' 可用于&#8220;日&#8221;字段。用来指定历给定日期最近的工作日(周一到周五)&nbsp;。比如你将&#8220;日&#8221;字段设为"15W"，意为: "离该月15号最近的工作日"。因此如果15号为周六，触发器会在14号即周五调用。如果15号为周日, 触发器会在16号也就是周一触发。如果15号为周二,那么当天就会触发。然而如果你将&#8220;日&#8221;字段设为"1W", 而一号又是周六, 触发器会于下周一也就是当月的3号触发,因为它不会越过当月的值的范围边界。'W'字符只能用于&#8220;日&#8221;字段的值为单独的一天而不是一系列值的时候。 </p>
<p>'L'和'W'可以组合用于&#8220;日&#8221;字段表示为'LW'，意为"该月最后一个工作日"。 </p>
<p>'#' 字符可用于&#8220;周几&#8221;字段。该字符表示&#8220;该月第几个周&#215;&#8221;，比如"6#3"表示该月第三个周五( 6表示周五而"#3"该月第三个)。再比如: "2#1" =&nbsp;表示该月第一个周一而 "4#5" = 该月第五个周三。注意如果你指定"#5"该月没有第五个&#8220;周&#215;&#8221;，该月是不会触发的。 </p>
<p>'C' 字符可用于&#8220;日&#8221;和&#8220;周几&#8221;字段，它是"calendar"的缩写。 它表示为基于相关的日历所计算出的值（如果有的话）。如果没有关联的日历, 那它等同于包含全部日历。&#8220;日&#8221;字段值为"5C"表示"日历中的第一天或者5号以后"，&#8220;周几&#8221;字段值为"1C"则表示"日历中的第一天或者周日以后"。 </p>
<p>对于&#8220;月份&#8221;字段和&#8220;周几&#8221;字段来说合法的字符都不是大小写敏感的。 </p>
<p>下面是一些完整的例子: <br />
<table cellspacing="8">
    <tbody>
        <tr>
            <th align="left">表达式 </th>
            <th align="left">&nbsp; </th>
            <th align="left">含义 </th>
        </tr>
        <tr>
            <td align="left"><code>"0 0 12 * * ?"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>每天中午十二点触发</code> </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 ? * *"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>每天早上10：15触发</code> </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 * * ?"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>每天早上10：15触发</code> </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 * * ? *"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>每天早上10：15触发</code> </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 * * ? 2005"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left"><code>2005年的每天早上10：15触发</code> </td>
        </tr>
        <tr>
            <td align="left"><code>"0 * 14 * * ?"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每天从下午2点开始到2点59分每分钟一次触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 0/5 14 * * ?"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每天从下午2点开始到2：55分结束每5分钟一次触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 0/5 14,18 * * ?"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每天的下午2点至2：55和6点至6点55分两个时间段内每5分钟一次触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 0-5 14 * * ?"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每天14:00至14:05每分钟一次触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 10,44 14 ? 3 WED"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">三月的每周三的14：10和14：44触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 ? * MON-FRI"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每个周一、周二、周三、周四、周五的10：15触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 15 * ?"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每月15号的10：15触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 L * ?"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每月的最后一天的10：15触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 ? * 6L"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每月最后一个周五的10：15触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 ? * 6L"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每月最后一个周五的10：15触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 ? * 6L 2002-2005"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">2002年至2005年的每月最后一个周五的10：15触发 </td>
        </tr>
        <tr>
            <td align="left"><code>"0 15 10 ? * 6#3"</code> </td>
            <td align="left">&nbsp; </td>
            <td align="left">每月的第三个周五的10：15触发</td>
        </tr>
    </tbody>
</table>
</p>
 <img src ="http://www.blogjava.net/agun/aggbug/186689.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2008-03-17 09:29 <a href="http://www.blogjava.net/agun/archive/2008/03/17/186689.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring ApplicationContext简单研究</title><link>http://www.blogjava.net/agun/archive/2008/03/11/185269.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Tue, 11 Mar 2008 01:57:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2008/03/11/185269.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/185269.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2008/03/11/185269.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/185269.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/185269.html</trackback:ping><description><![CDATA[<p>spring 研究装载配置文件</p>
<p>1，研究spring webApplicationContext初始化。spring 如何初始化。 <br />
spring 有两种方法，一个是ContextLoaderListener这个Listerner，另一个是ContextLoaderServlet这个Servlet，这两个方法都是在web应用启动的时候来初始化WebApplicationContext，ContextLoader是一个工具类，用来初始化WebApplicationContext，其主要方法就是initWebApplicationContext，ContextLoader是把WebApplicationContext（XmlWebApplicationContext是默认实现类）放在了ServletContext中，ServletContext也是一个&#8220;容器&#8221;，也是一个类似Map的结构，而WebApplicationContext在ServletContext中的KEY就是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE，我们如果要使用WebApplicationContext则需要从ServletContext取出，Spring提供了一WebApplicationContextUtils类，可以方便的取出WebApplicationContext，只要把ServletContext传入就可以了。 </p>
<p>2，研究通过使用ApplicationContext对spring 进行初始化。 </p>
<p>初始化流程，在初始化的时候，新增一个加载servlet ，这个serlvet负责初始化。AppContextLoader 提供了初始化applicationContext的方法, <br />
通过定义ClassPathXmlApplicationContext　来加载spring 配置文件。装载配置文件。 <br />
并把装载的ApplicationContext文件放在servletContext中作为全局变量来使用。在使用ClassPathXmlApplicationContext 则需要从ServletContext取出.<br />
</p>
 <img src ="http://www.blogjava.net/agun/aggbug/185269.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2008-03-11 09:57 <a href="http://www.blogjava.net/agun/archive/2008/03/11/185269.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>httpclient (2)</title><link>http://www.blogjava.net/agun/archive/2008/01/29/178365.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Tue, 29 Jan 2008 06:55:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2008/01/29/178365.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/178365.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2008/01/29/178365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/178365.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/178365.html</trackback:ping><description><![CDATA[<p>根据以上步骤，我们来编写用GET方法来取得某网页内容的代码。</p>
<ul>
    <li>大部分情况下 HttpClient 默认的构造函数已经足够使用。
    <table cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td class="code-outline">
                <pre class="displaycode">HttpClient httpClient = new HttpClient();
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br />
    <li>创建GET方法的实例。在GET方法的构造函数中传入待连接的地址即可。用GetMethod将会自动处理转发过程，如果想要把自动处理转发过程去掉的话，可以调用方法setFollowRedirects(false)。
    <table cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td class="code-outline">
                <pre class="displaycode">GetMethod getMethod = new GetMethod("http://www.ibm.com/");
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br />
    <li>调用实例httpClient的executeMethod方法来执行getMethod。由于是执行在网络上的程序，在运行executeMethod方法的时候，需要处理两个异常，分别是HttpException和IOException。引起第一种异常的原因主要可能是在构造getMethod的时候传入的协议不对，比如不小心将"http"写成"htp"，或者服务器端返回的内容不正常等，并且该异常发生是不可恢复的；第二种异常一般是由于网络原因引起的异常，对于这种异常 （IOException），HttpClient会根据你指定的恢复策略自动试着重新执行executeMethod方法。HttpClient的恢复策略可以自定义（通过实现接口HttpMethodRetryHandler来实现）。通过httpClient的方法setParameter设置你实现的恢复策略，本文中使用的是系统提供的默认恢复策略，该策略在碰到第二类异常的时候将自动重试3次。executeMethod返回值是一个整数，表示了执行该方法后服务器返回的状态码，该状态码能表示出该方法执行是否成功、需要认证或者页面发生了跳转（默认状态下GetMethod的实例是自动处理跳转的）等。
    <table cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td class="code-outline">
                <pre class="displaycode">//设置成了默认的恢复策略，在发生异常时候将自动重试3次，在这里你也可以设置成自定义的恢复策略
                getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                new DefaultHttpMethodRetryHandler());
                //执行getMethod
                int statusCode = client.executeMethod(getMethod);
                if (statusCode != HttpStatus.SC_OK) {
                System.err.println("Method failed: " + getMethod.getStatusLine());
                }
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br />
    <li>在返回的状态码正确后，即可取得内容。取得目标地址的内容有三种方法：第一种，getResponseBody，该方法返回的是目标的二进制的byte流；第二种，getResponseBodyAsString，这个方法返回的是String类型，值得注意的是该方法返回的String的编码是根据系统默认的编码方式，所以返回的String值可能编码类型有误，在本文的"字符编码"部分中将对此做详细介绍；第三种，getResponseBodyAsStream，这个方法对于目标地址中有大量数据需要传输是最佳的。在这里我们使用了最简单的getResponseBody方法。
    <table cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td class="code-outline">
                <pre class="displaycode">byte[] responseBody = method.getResponseBody();
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br />
    <li>释放连接。无论执行方法是否成功，都必须释放连接。
    <table cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td class="code-outline">
                <pre class="displaycode">method.releaseConnection();
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br />
    <li>处理内容。在这一步中根据你的需要处理内容，在例子中只是简单的将内容打印到控制台。
    <table cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td class="code-outline">
                <pre class="displaycode">System.out.println(new String(responseBody));
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br />
    </li>
</ul>
<p>下面是程序的完整代码，这些代码也可在附件中的test.GetSample中找到。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">package test;
            import java.io.IOException;
            import org.apache.commons.httpclient.*;
            import org.apache.commons.httpclient.methods.GetMethod;
            import org.apache.commons.httpclient.params.HttpMethodParams;
            public class GetSample{
            public static void main(String[] args) {
            //构造HttpClient的实例
            HttpClient httpClient = new HttpClient();
            //创建GET方法的实例
            GetMethod getMethod = new GetMethod("http://www.ibm.com");
            //使用系统提供的默认的恢复策略
            getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
            new DefaultHttpMethodRetryHandler());
            try {
            //执行getMethod
            int statusCode = httpClient.executeMethod(getMethod);
            if (statusCode != HttpStatus.SC_OK) {
            System.err.println("Method failed: "
            + getMethod.getStatusLine());
            }
            //读取内容
            byte[] responseBody = getMethod.getResponseBody();
            //处理内容
            System.out.println(new String(responseBody));
            } catch (HttpException e) {
            //发生致命的异常，可能是协议不对或者返回的内容有问题
            System.out.println("Please check your provided http address!");
            e.printStackTrace();
            } catch (IOException e) {
            //发生网络异常
            e.printStackTrace();
            } finally {
            //释放连接
            getMethod.releaseConnection();
            }
            }
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="N100F0"><span class="smalltitle">POST方法</span></a></p>
<p>根据RFC2616，对POST的解释如下：POST方法用来向目的服务器发出请求，要求它接受被附在请求后的实体，并把它当作请求队列（Request-Line）中请求URI所指定资源的附加新子项。POST被设计成用统一的方法实现下列功能：</p>
<ul>
    <li>对现有资源的注释（Annotation of existing resources）
    <li>向电子公告栏、新闻组，邮件列表或类似讨论组发送消息
    <li>提交数据块，如将表单的结果提交给数据处理过程
    <li>通过附加操作来扩展数据库 </li>
</ul>
<p>调用HttpClient中的PostMethod与GetMethod类似，除了设置PostMethod的实例与GetMethod有些不同之外，剩下的步骤都差不多。在下面的例子中，省去了与GetMethod相同的步骤，只说明与上面不同的地方，并以登录清华大学BBS为例子进行说明。</p>
<ul>
    <li>构造PostMethod之前的步骤都相同，与GetMethod一样，构造PostMethod也需要一个URI参数，在本例中，登录的地址是http://www.newsmth.net/bbslogin2.php。在创建了PostMethod的实例之后，需要给method实例填充表单的值，在BBS的登录表单中需要有两个域，第一个是用户名（域名叫id），第二个是密码（域名叫passwd）。表单中的域用类NameValuePair来表示，该类的构造函数第一个参数是域名，第二参数是该域的值；将表单所有的值设置到PostMethod中用方法setRequestBody。另外由于BBS登录成功后会转向另外一个页面，但是HttpClient对于要求接受后继服务的请求，比如POST和PUT，不支持自动转发，因此需要自己对页面转向做处理。具体的页面转向处理请参见下面的"自动转向"部分。代码如下：
    <table cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td class="code-outline">
                <pre class="displaycode">String url = "http://www.newsmth.net/bbslogin2.php";
                PostMethod postMethod = new PostMethod(url);
                // 填入各个表单域的值
                NameValuePair[] data = { new NameValuePair("id", "youUserName"),
                new NameValuePair("passwd", "yourPwd") };
                // 将表单的值放入postMethod中
                postMethod.setRequestBody(data);
                // 执行postMethod
                int statusCode = httpClient.executeMethod(postMethod);
                // HttpClient对于要求接受后继服务的请求，象POST和PUT等不能自动处理转发
                // 301或者302
                if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||
                statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
                // 从头中取出转向的地址
                Header locationHeader = postMethod.getResponseHeader("location");
                String location = null;
                if (locationHeader != null) {
                location = locationHeader.getValue();
                System.out.println("The page was redirected to:" + location);
                } else {
                System.err.println("Location field value is null.");
                }
                return;
                }
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br />
    </li>
</ul>
 <img src ="http://www.blogjava.net/agun/aggbug/178365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2008-01-29 14:55 <a href="http://www.blogjava.net/agun/archive/2008/01/29/178365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>httpclient (1) </title><link>http://www.blogjava.net/agun/archive/2008/01/29/178362.html</link><dc:creator>agun</dc:creator><author>agun</author><pubDate>Tue, 29 Jan 2008 06:50:00 GMT</pubDate><guid>http://www.blogjava.net/agun/archive/2008/01/29/178362.html</guid><wfw:comment>http://www.blogjava.net/agun/comments/178362.html</wfw:comment><comments>http://www.blogjava.net/agun/archive/2008/01/29/178362.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/agun/comments/commentRss/178362.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/agun/services/trackbacks/178362.html</trackback:ping><description><![CDATA[<blockquote>
<p>最近用到了HttpClient ，搜集的资料：</p>
<p>HttpClient 是 Apache Jakarta Common 下的子项目，可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包，并且它支持 HTTP 协议最新的版本和建议。本文首先介绍 HTTPClient，然后根据作者实际工作经验给出了一些常见问题的解决方法。</p>
</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
<p><a name="N10053"><span class="atitle">HttpClient简介</span></a></p>
<p>HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了，越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能，但是对于大部分应用程序来说，JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目，用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包，并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中，比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient，更多使用 HttpClient 的应用可以参见<a href="http://wiki.apache.org/jakarta-httpclient/HttpClientPowered">http://wiki.apache.org/jakarta-httpclient/HttpClientPowered</a>。HttpClient 项目非常活跃，使用的人还是非常多的。目前 HttpClient 版本是在 2005.10.11 发布的 3.0 RC4 。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="N10060"><span class="atitle">HttpClient 功能介绍</span></a></p>
<p>以下列出的是 HttpClient 提供的主要的功能，要知道更多详细的功能可以参见 HttpClient 的主页。</p>
<ul>
    <li>实现了所有 HTTP 的方法（GET,POST,PUT,HEAD 等）
    <li>支持自动转向
    <li>支持 HTTPS 协议
    <li>支持代理服务器等 </li>
</ul>
<p>下面将逐一介绍怎样使用这些功能。首先，我们必须安装好 HttpClient。</p>
<ul>
    <li>HttpClient 可以在<a href="http://jakarta.apache.org/commons/httpclient/downloads.html">http://jakarta.apache.org/commons/httpclient/downloads.html</a>下载
    <li>HttpClient 用到了 Apache Jakarta common 下的子项目 logging，你可以从这个地址<a href="http://jakarta.apache.org/site/downloads/downloads_commons-logging.cgi">http://jakarta.apache.org/site/downloads/downloads_commons-logging.cgi</a>下载到 common logging，从下载后的压缩包中取出 commons-logging.jar 加到 CLASSPATH 中
    <li>HttpClient 用到了 Apache Jakarta common 下的子项目 codec，你可以从这个地址<a href="http://jakarta.apache.org/site/downloads/downloads_commons-codec">http://jakarta.apache.org/site/downloads/downloads_commons-codec</a>.cgi 下载到最新的 common codec，从下载后的压缩包中取出 commons-codec-1.x.jar 加到 CLASSPATH 中 </li>
</ul>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="N10093"><span class="atitle">HttpClient 基本功能的使用</span></a></p>
<p><a name="N10099"><span class="smalltitle">GET 方法</span></a></p>
<p>使用 HttpClient 需要以下 6 个步骤：</p>
<p>1. 创建 HttpClient 的实例</p>
<p>2. 创建某种连接方法的实例，在这里是 GetMethod。在 GetMethod 的构造函数中传入待连接的地址</p>
<p>3. 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例</p>
<p>4. 读 response</p>
<p>5. 释放连接。无论执行方法是否成功，都必须释放连接</p>
<p>6. 对得到后的内容进行处理</p>
 <img src ="http://www.blogjava.net/agun/aggbug/178362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/agun/" target="_blank">agun</a> 2008-01-29 14:50 <a href="http://www.blogjava.net/agun/archive/2008/01/29/178362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>