﻿<?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-waysun一路阳光-随笔分类-Struts</title><link>http://www.blogjava.net/1504/category/32240.html</link><description>不轻易服输,不轻言放弃.--心是梦的舞台，心有多大，舞台有多大。踏踏实实做事，认认真真做人。</description><language>zh-cn</language><lastBuildDate>Mon, 22 Mar 2010 20:51:44 GMT</lastBuildDate><pubDate>Mon, 22 Mar 2010 20:51:44 GMT</pubDate><ttl>60</ttl><item><title>使用Struts的Token机制解决表单的重复提交【收藏】</title><link>http://www.blogjava.net/1504/archive/2009/04/13/265329.html</link><dc:creator>weesun一米阳光</dc:creator><author>weesun一米阳光</author><pubDate>Mon, 13 Apr 2009 09:13:00 GMT</pubDate><guid>http://www.blogjava.net/1504/archive/2009/04/13/265329.html</guid><wfw:comment>http://www.blogjava.net/1504/comments/265329.html</wfw:comment><comments>http://www.blogjava.net/1504/archive/2009/04/13/265329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/1504/comments/commentRss/265329.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/1504/services/trackbacks/265329.html</trackback:ping><description><![CDATA[来源：<a href="http://www.blogjava.net/pdw2009/archive/2006/04/09/40094.html">http://www.blogjava.net/pdw2009/archive/2006/04/09/40094.html</a>
<div><span style="color: #4b4b4b; font-family: Verdana; font-size: 13px; line-height: 19px; ">
<p>首先必须要通过一个Action再转向那个添加记录的页面,转向函数如下.<br />
<br />
&#160;public ActionForward tokenTest(<br />
&#160;&#160;&#160;ActionMapping mapping,<br />
&#160;&#160;&#160;ActionForm form,<br />
&#160;&#160;&#160;HttpServletRequest request,<br />
&#160;&#160;&#160;HttpServletResponse response) throws Exception {<br />
&#160;&#160;saveToken(request);//把一个token ID保存到Session,并在且要转到的页面<br />
&#160;&#160;&#160;&#160;&#160;&#160; //的&lt;html:form>中添加一个&lt;input type="hideen">的标答.<br />
&#160;&#160;return mapping.findForward("add");<br />
&#160;}<br />
<br />
<br />
一个输出入页面如容如下:<br />
<br />
&lt;%@ page language="java" pageEncoding="UTF-8"%></p>
<p>&lt;%@ taglib uri="<a href="http://struts.apache.org/tags-bean" style="color: #1a8bc8; text-decoration: none; ">http://struts.apache.org/tags-bean</a>" prefix="bean" %><br />
&lt;%@ taglib uri="<a href="http://struts.apache.org/tags-html" style="color: #1a8bc8; text-decoration: none; ">http://struts.apache.org/tags-html</a>" prefix="html" %><br />
&lt;%@ taglib uri="<a href="http://struts.apache.org/tags-logic" style="color: #1a8bc8; text-decoration: none; ">http://struts.apache.org/tags-logic</a>" prefix="logic" %><br />
&lt;%@ taglib uri="<a href="http://struts.apache.org/tags-tiles" style="color: #1a8bc8; text-decoration: none; ">http://struts.apache.org/tags-tiles</a>" prefix="tiles" %></p>
<p><br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><br />
&lt;html:html lang="true"><br />
&#160; &lt;head><br />
&#160;&#160;&#160; &lt;html:base /><br />
&#160;&#160;&#160;&#160;<br />
&#160;&#160;&#160; &lt;title>tokentest.jsp&lt;/title><br />
&#160;&#160;&#160;&#160;<br />
&#160;&#160;&#160; &lt;meta http-equiv="pragma" content="no-cache"><br />
&#160;&#160;&#160; &lt;meta http-equiv="cache-control" content="no-cache"><br />
&#160;&#160;&#160; &lt;meta http-equiv="expires" content="0">&#160;&#160;&#160;&#160;<br />
&#160;&#160;&#160; &lt;meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><br />
&#160;&#160;&#160; &lt;meta http-equiv="description" content="This is my page"><br />
&#160; &lt;/head><br />
&#160;&#160;<br />
&#160; &lt;body><br />
&#160;&#160;&#160;&#160;&#160; &lt;br><br />
&#160;&#160;&#160;&#160;&#160; &lt;logic:present name="error"><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;pre style="color:#ff2255">&lt;bean:write name="error"/>&lt;/pre><br />
&#160;&#160;&#160;&#160;&#160; &lt;/logic:present><br />
&#160;&#160;&#160;&#160;&#160; &lt;center><br />
&#160;&#160;&#160;&#160;&#160; &lt;html:form action="/insert.do" method="post"><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;table border="0" cellspacing="0" ><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;tr><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;td width="30%">用户名&lt;/td><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;td width="70%">&lt;html:text property="username"/>&lt;/td><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/tr><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;tr><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;td>地址:&lt;/td><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;td>&lt;html:text property="address"/>&lt;/td><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/tr><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;tr><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;td colspan="2">&lt;html:submit value="提交"/>&lt;/td><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/tr><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/table><br />
&#160;&#160;&#160;&#160;&#160;&#160; &lt;/html:form><br />
&#160;&#160;&#160;&#160;&#160; &lt;/center><br />
&#160; &lt;/body><br />
&lt;/html:html><br />
页面的处理Action内容如下:<br />
&#160; &#160;public ActionForward execute(<br />
&#160;&#160;ActionMapping mapping,<br />
&#160;&#160;ActionForm form,<br />
&#160;&#160;HttpServletRequest request,<br />
&#160;&#160;HttpServletResponse response) {<br />
&#160;&#160;TokenTestForm tokenTestForm = (TokenTestForm) form;<br />
&#160;&#160;if(!isTokenValid(request)){ //重复提交<br />
&#160;&#160;&#160;request.setAttribute("error","不能得复提交!!!");<br />
&#160;&#160;&#160;//saveToken(request); 重新生成tokenid,<br />
&#160;&#160;&#160;return mapping.findForward("return");<br />
&#160;&#160;}else{<br />
&#160;&#160;&#160;resetToken(request);<br />
&#160;&#160;}<br />
&#160;&#160;//执行相关操作<br />
&#160;&#160;System.out.println(tokenTestForm.getUsername()+"--"+tokenTestForm.getAddress());<br />
&#160;&#160;return mapping.findForward("ok");<br />
&#160;}<br />
<br />
至此已完成,至于原理,就自己去查一些资料就完全明白了....<br />
</p>
<p><br />
</p>
<p>2.来源<a href="http://www2.cnblogs.com/snoopy/articles/54699.html">http://www2.cnblogs.com/snoopy/articles/54699.html</a></p>
<p>
</p>
<h2><a id="AjaxHolder_ctl01_TitleUrl" href="http://www.cnblogs.com/snoopy/articles/54699.html">使用Struts的Token机制解决表单的重复提交</a>
</h2>
<div class="postbody">
<h3 class="title">前几天被这个问题困扰了，在Google中搜&#8220;表单重复提交&#8221;，也搜到不少资料，但有的讲的不是很清楚，所以走了些弯路，现在写下来，不能算原创吧。</h3>
<br />
<p>Struts的Token（令牌）机制能够很好的解决表单重复提交的问题，基本原理是：服务器端在处理到达的请求之前，会将<em>请求中包含的令牌值</em>与保存在当前用户会话中的令牌值进行比较，看是否匹配。在处理完该请求后，且在答复发送给客户端之前，将会产生一个新的令牌，该令牌除传给客户端以外，也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话，客户端传过来的令牌就和服务器端的令牌不一致，从而有效地防止了重复提交的发生。</p>
<br />
<p>这时其实也就是两点，第一：你需要在请求中有这个令牌值，请求中的令牌值如何保存，其实就和我们平时在页面中保存一些信息是一样的，通过隐藏字段来保存，保存的形式如：
〈input type="hidden" name="org.apache.struts.taglib.html.TOKEN"
value="6aa35341f25184fd996c4c918255c3ae"〉，这个value是TokenProcessor类中的generateToken()获得的，是根据当前用户的session
id和当前时间的long值来计算的。第二：在客户端提交后，我们要根据判断在请求中包含的值是否和服务器的令牌一致，因为服务器每次提交都会生成新的Token，所以，如果是重复提交，客户端的Token值和服务器端的Token值就会不一致。下面就以在数据库中插入一条数据来说明如何防止重复提交。</p>
<br />
<p>在Action中的add方法中，我们需要将Token值明确的要求保存在页面中，只需增加一条语句：saveToken(request);，如下所示：
<br />
<font color="red">public ActionForward add(ActionMapping mapping, ActionForm
form, <br />
HttpServletRequest request, HttpServletResponse
response)<br />
//前面的处理省略<br />
saveToken(request);<br />
return
mapping.findForward("add");<br />
}</font>在Action的insert方法中，我们根据表单中的Token值与服务器端的Token值比较，如下所示：<br />
<font color="red">public ActionForward insert(ActionMapping mapping, ActionForm form,
<br />
HttpServletRequest request, HttpServletResponse response)<br />
if
(isTokenValid(request, true)) {<br />
// 表单不是重复提交<br />
//这里是保存数据的代码<br />
} else
{<br />
//表单重复提交<br />
saveToken(request);<br />
//其它的处理代码<br />
}<br />
}</font></p>
</div>
<p>&#160;说明：在前一个转向提交信息的页面需要<span  style="color: #ff0000; ">saveToken(request);</span></p>
<p><font  color="#FF0000">在保存页面使用</font></p>
<p><font  color="#FF0000">
<p>&#160;&#160; &#160; &#160; &#160;<span class="Apple-tab-span" style="white-space:pre">	</span>if(!isTokenValid(request))</p>
<p>&#160;&#160; &#160; &#160; &#160;<span class="Apple-tab-span" style="white-space:pre">	</span>{ //重复提交</p>
<p>&#160;&#160; &#160; &#160; &#160;<span class="Apple-tab-span" style="white-space:pre">	</span> &#160; &#160;System.out.println("重复提交");</p>
<p><br />
</p>
<p>&#160;&#160; &#160; &#160; &#160;<span class="Apple-tab-span" style="white-space:pre">		</span> &#160; System.out.println("能得复提交!!!");</p>
<p>&#160;&#160; &#160; &#160; &#160;<span class="Apple-tab-span" style="white-space:pre">	</span>}</p>
<p>&#160;&#160; &#160; &#160; &#160;<span class="Apple-tab-span" style="white-space:pre">	</span>else</p>
<p>&#160;&#160; &#160; &#160; &#160;<span class="Apple-tab-span" style="white-space:pre">	</span>{</p>
<p>&#160;&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;request.setAttribute("saveInfo", info);</p>
<p>&#160;&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;logger.debug("save successful");</p>
<p>&#160;&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;resetToken(request); //删除session中的令牌&#160;</p>
<p>&#160;&#160; &#160; &#160; &#160;<span class="Apple-tab-span" style="white-space:pre">	</span>ward=mapping.findForward("notice")；</p>
<p>&#160;&#160; &#160; &#160; &#160;<span class="Apple-tab-span" style="white-space:pre">	</span>}</p>
</font></p>
</span></div>
<img src ="http://www.blogjava.net/1504/aggbug/265329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/1504/" target="_blank">weesun一米阳光</a> 2009-04-13 17:13 <a href="http://www.blogjava.net/1504/archive/2009/04/13/265329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Struts中Action传参数 [总结]</title><link>http://www.blogjava.net/1504/archive/2009/02/22/256101.html</link><dc:creator>weesun一米阳光</dc:creator><author>weesun一米阳光</author><pubDate>Sun, 22 Feb 2009 11:47:00 GMT</pubDate><guid>http://www.blogjava.net/1504/archive/2009/02/22/256101.html</guid><wfw:comment>http://www.blogjava.net/1504/comments/256101.html</wfw:comment><comments>http://www.blogjava.net/1504/archive/2009/02/22/256101.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/1504/comments/commentRss/256101.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/1504/services/trackbacks/256101.html</trackback:ping><description><![CDATA[<font color="#0000a0">
<p><span style="font-size: 8pt;"><span style="font-size: 10pt;">public ActionForward userSave(ActionMapping mapping, ActionForm form,<br />
&#160;&#160;&#160;HttpServletRequest request, HttpServletResponse response) {<br />
&#160;&#160;UserForm userForm = (UserForm) form;</span></span><font color="#0000a0" size="3"><br />
<span style="font-size: 8pt;"><span style="font-size: 10pt;">&#160;&#160;return mapping.findForward("userSave");<br />
&#160;}</span></span></font></p>
<span style="font-size: 8pt;"><span style="font-size: 10pt;">//传参数<br />
</span></span><span style="font-size: 8pt;"><span style="font-size: 10pt;">&#160;public ActionForward userSave(ActionMapping mapping, ActionForm form,<br />
&#160;&#160;&#160;HttpServletRequest request, HttpServletResponse response) {<br />
&#160;&#160;UserForm userForm = (UserForm) form;<br />
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<br />
</span></span><font color="#0000a0" size="3">
<p><span style="font-size: 8pt;"><span style="font-size: 10pt;">&#160;String path = mapping.findForward("delete").getPath();</span></span></p>
<p><span style="font-size: 8pt;"><span style="font-size: 10pt;">&#160;&#160;//TODO: 读取本Action所有的请求参数，将path重新构造，加上请求参数</span></span></p>
<p><span style="font-size: 8pt;"><span style="font-size: 10pt;">&#160;&#160;ActionForward forward= new ActionForward(path+"&amp;pageId=1");<br />
&#160;&#160;forward.setRedirect(true);<br />
//传参数后返回<br />
&#160;&#160;return forward;</span></span></p>
<p><span style="font-size: 10pt;">&#160;</span></p>
<span style="font-size: 10pt;">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
&#160;//&#160;return mapping.findForward("userSave");<br />
&#160;}</span></font><br />
</font>
<br />
<img src ="http://www.blogjava.net/1504/aggbug/256101.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/1504/" target="_blank">weesun一米阳光</a> 2009-02-22 19:47 <a href="http://www.blogjava.net/1504/archive/2009/02/22/256101.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>bean:define id的使用[总结]</title><link>http://www.blogjava.net/1504/archive/2009/02/22/256099.html</link><dc:creator>weesun一米阳光</dc:creator><author>weesun一米阳光</author><pubDate>Sun, 22 Feb 2009 11:40:00 GMT</pubDate><guid>http://www.blogjava.net/1504/archive/2009/02/22/256099.html</guid><wfw:comment>http://www.blogjava.net/1504/comments/256099.html</wfw:comment><comments>http://www.blogjava.net/1504/archive/2009/02/22/256099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/1504/comments/commentRss/256099.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/1504/services/trackbacks/256099.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt;">&lt;bean:define &#160; id="pagename" &#160; name="requestName"/> &#160; <br />
&#160; &#160; <br />
<clk>&#160; id:指的是这个bean的唯一名字(可以自由定义或者说可以自定义但是必须唯一)，在这里定义的id="pagename" ,在要调用的网页里面可以随便的使用和访问/ &#160; </clk><br />
&#160; name:指的是从上一个页面或者action里面传过来的变量，可以是任何类型。(例如再上一网页定义<font size="3">request.setAttribute("requestName", requestName);</font>) &#160; <br />
&#160; 例如： &#160; <br />
&#160; &#160; &#160; 我有一个Bean对象User对象，这个里面保存了admin管理员的个人信息，姓名(name)，性别(sex)、年龄(age)那么怎么用呢。 &#160; <br />
&#160; 在action里面你可以把User对象传过来 &#160; <br />
&#160; request.setAttribute("user",User); &#160; <br />
&#160; 在页面 &#160; <br />
&#160; &lt;bean:define &#160; id="admin" &#160; name="user"./> &#160; <br />
&#160; 然后就可以和bean:write搭配使用 &#160; <br />
&#160; &lt;bean:write &#160; name="admin" &#160; property="name"/> &#160; <br />
&#160; &lt;bean:write &#160; name="admin" &#160; property="sex"/> &#160; <br />
&#160; &lt;bean:write &#160; name="admin" &#160; property="age"/> </span>
<img src ="http://www.blogjava.net/1504/aggbug/256099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/1504/" target="_blank">weesun一米阳光</a> 2009-02-22 19:40 <a href="http://www.blogjava.net/1504/archive/2009/02/22/256099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AJAX和Struts的action交互使用[原创总结]</title><link>http://www.blogjava.net/1504/archive/2009/02/22/256094.html</link><dc:creator>weesun一米阳光</dc:creator><author>weesun一米阳光</author><pubDate>Sun, 22 Feb 2009 11:34:00 GMT</pubDate><guid>http://www.blogjava.net/1504/archive/2009/02/22/256094.html</guid><wfw:comment>http://www.blogjava.net/1504/comments/256094.html</wfw:comment><comments>http://www.blogjava.net/1504/archive/2009/02/22/256094.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/1504/comments/commentRss/256094.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/1504/services/trackbacks/256094.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt;">1.请求页面的JS,客户端实现<br />
&lt;script type="text/javascript"><br />
&#160;var flagvalue=0;<br />
&#160;var rest="";<br />
&#160;var resta="";<br />
&#160;//实现AJAX验证<br />
&#160;var http_request = false;<br />
&#160;var infoForm_flag=false;<br />
&#160;var lotId="";<br />
function Save()<br />
{<br />
&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160; var infoForm=document.projectSetForm;<br />
&#160;&#160;&#160;&#160;&#160; infoForm_flag=infoForm;<br />
&#160;&#160;&#160;&#160;&#160; lotId=infoForm.lotId.value;<br />
&#160;&#160;&#160;&#160;&#160; //表名称<br />
&#160;&#160;&#160;&#160;&#160; var dc = infoForm.tablename.value;<br />
&#160;&#160;&#160;&#160;&#160; if(dc==""||dc==null){<br />
&#160;&#160;&#160;&#160;&#160;&#160; alert("表名称不能为空!");<br />
&#160;&#160;&#160;&#160;&#160;&#160; infoForm.tablename.focus(); <br />
&#160;&#160;&#160;&#160;&#160;&#160; infoForm.tablename.select();<br />
&#160;&#160;&#160;&#160;&#160;&#160; return false;<br />
&#160;}<br />
function send_request(url)<br />
&#160; {//初始化、指定处理函数、发送请求的函数<br />
&#160;&#160;&#160; http_request = false;<br />
&#160;&#160;&#160; //开始初始化XMLHttpRequest对象<br />
&#160;&#160;&#160; if(window.XMLHttpRequest) <br />
&#160;&#160;&#160; { //Mozilla 浏览器<br />
&#160;&#160;&#160;&#160;&#160; http_request = new XMLHttpRequest();<br />
&#160;&#160;&#160;&#160;&#160; if (http_request.overrideMimeType) <br />
&#160;&#160;&#160;&#160;&#160; {//设置MiME类别<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; http_request.overrideMimeType('text/xml');<br />
&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160; }<br />
&#160;&#160;&#160; else if (window.ActiveXObject) <br />
&#160;&#160;&#160; { // IE浏览器<br />
&#160;&#160;&#160;&#160;&#160; try <br />
&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; http_request = new ActiveXObject("Msxml2.XMLHTTP");<br />
&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160; catch (e) <br />
&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; try <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; http_request = new ActiveXObject("Microsoft.XMLHTTP");<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (e) <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160; }<br />
&#160;&#160;&#160; if (!http_request) { // 异常，创建对象实例失败<br />
&#160;&#160;&#160;&#160; window.alert("不能创建XMLHttpRequest对象实例.");<br />
&#160;&#160;&#160;&#160; return false;<br />
&#160;&#160;&#160; }<br />
&#160;&#160;&#160; http_request.onreadystatechange = processRequest;<br />
&#160;&#160;&#160; // 确定发送请求的方式和URL以及是否同步执行下段代码<br />
&#160;&#160;&#160; http_request.open("GET", url, true);<br />
&#160;&#160;&#160; http_request.send(null);<br />
&#160; }<br />
&#160;&#160;&#160;&#160; //处理返回信息的函数<br />
&#160;&#160;&#160;&#160; function processRequest() <br />
&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (http_request.readyState == 4) <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //判断对象状态<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (http_request.status == 200) <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //信息已经成功返回，开始处理信息<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var str=http_request.responseText;//获得从服务器返回的文本信息<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(str=="no")<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; alert("您选择了模型分属不同的模板,请选择同一模板对应是模型!");<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //return false;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; infoForm_flag.action="projectSet.do?do=add&amp;lotId="+lotId;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; infoForm_flag.submit();<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; infoForm_flag.action="projectSet.do?do=creattable&amp;save=-1";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; infoForm_flag.submit();<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //页面不正常<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; alert("您所请求的页面有异常。");<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160; }<br />
&#160; function userCheck() <br />
&#160; {<br />
&#160;&#160;&#160; send_request('projectSet.do?do=check&amp;rest='+rest); <br />
&#160; }<br />
&lt;/script><br />
2.ProjectSetAction.java</span>
<p><span style="font-size: 10pt;">package com.gpdi.softevaluate.action;</span></p>
<p><span style="font-size: 10pt;">import java.io.PrintWriter;<br />
import java.text.SimpleDateFormat;<br />
import java.util.ArrayList;<br />
import java.util.Calendar;<br />
import java.util.HashSet;<br />
import java.util.Map;<br />
import java.util.Set;</span></p>
<p><span style="font-size: 10pt;">import java.util.Iterator;<br />
import java.util.List;</span></p>
<p><span style="font-size: 10pt;">import javax.servlet.http.HttpServletRequest;<br />
import javax.servlet.http.HttpServletResponse;</span></p>
<p><span style="font-size: 10pt;">public class ProjectSetAction extends DispatchAction <br />
{<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span></p>
<p><span style="font-size: 10pt;">/**<br />
&#160; * &lt;p>模板验证&lt;/p><br />
&#160; * @param mapping<br />
&#160; * @param form<br />
&#160; * @param request<br />
&#160; * @param response<br />
&#160; * @return<br />
&#160; * @throws Exception<br />
&#160; */<br />
&#160;public ActionForward check(ActionMapping mapping, ActionForm
form,HttpServletRequest request, HttpServletResponse response)throws
Exception<br />
&#160;{<br />
&#160;&#160; String rest="";<br />
&#160;&#160; String lotId="";<br />
&#160;&#160; String retn="";<br />
&#160;&#160; String flag="";<br />
&#160;&#160; CommDaoFactory mgObj = new CommDaoFactory();<br />
&#160;&#160; try<br />
&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160; rest=request.getParameter("rest");<br />
&#160;&#160;&#160;&#160;&#160;&#160; lotId=request.getParameter("lotId");<br />
&#160;&#160; }<br />
&#160;&#160; catch(Exception e)<br />
&#160;&#160; {<br />
&#160;&#160;&#160; <br />
&#160;&#160; }<br />
if(!rest.equals("0")||!rest.equals("")||rest!=null)<br />
&#160;{<br />
&#160;&#160;&#160;&#160; flag="no";<br />
}<br />
else<br />
{<br />
&#160;&#160;&#160;&#160;&#160; flag="ok";</span></p>
<p><span style="font-size: 10pt;">}<br />
&#160;&#160;&#160;&#160;&#160;&#160; PrintWriter out=response.getWriter();<br />
//服务器返回信息<br />
&#160;&#160;&#160;&#160;&#160;&#160; out.write(flag);<br />
&#160;&#160;&#160;&#160;&#160;&#160; out.close();<br />
&#160;&#160;&#160;&#160; //读取本Action所有的请求参数，将path重新构造，加上请求参数</span></p>
<p><span style="font-size: 10pt;">&#160;&#160;&#160;&#160; //ActionForward forward= new ActionForward("project/projectSet.do?do=add&amp;lotId=6");<br />
&#160;&#160;&#160;&#160; //forward.setRedirect(true);<br />
&#160;&#160;&#160;&#160;&#160; //传参数后返回<br />
&#160;&#160;&#160;&#160; //return forward;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160; return mapping.findForward(null);<br />
&#160;<br />
&#160;}<br />
</span><font size="3"><font style="font-size: 10pt;" size="3">public
ActionForward creattable(ActionMapping mapping, ActionForm
form,HttpServletRequest request, HttpServletResponse response)throws
Exception<br />
{<br />
&#160;&#160;&#160;&#160; //实现功能代码<br />
return mapping.findForward("create");<br />
}</font><br />
<span style="font-size: 10pt;">}<br />
3.struts.config.xml<br />
<font style="font-size: 10pt;" size="3">&#160;&lt;action attribute="projectSetForm" name="projectSetForm"<br />
&#160;&#160;&#160;&#160;parameter="do" path="/project/projectSet" scope="request"<br />
&#160;&#160;&#160;&#160;&#160;&#160; type="com.gpdi.softevaluate.action.ProjectSetAction" validate="false"><br />
&#160;&#160;&#160;&lt;forward name="list" path="/project/viewProject.jsp" /><br />
&#160;&#160;&#160;&lt;forward name="add" path="/project/addProject.jsp" /><br />
&#160;&#160;&#160;&lt;forward name="create" path="/project/createTable.jsp" /><br />
&#160;&#160;&lt;/action></font></span></font></p>
<img src ="http://www.blogjava.net/1504/aggbug/256094.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/1504/" target="_blank">weesun一米阳光</a> 2009-02-22 19:34 <a href="http://www.blogjava.net/1504/archive/2009/02/22/256094.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DWR与Struts整合2007-08-07 【收藏】</title><link>http://www.blogjava.net/1504/archive/2008/08/03/219703.html</link><dc:creator>weesun一米阳光</dc:creator><author>weesun一米阳光</author><pubDate>Sun, 03 Aug 2008 07:34:00 GMT</pubDate><guid>http://www.blogjava.net/1504/archive/2008/08/03/219703.html</guid><wfw:comment>http://www.blogjava.net/1504/comments/219703.html</wfw:comment><comments>http://www.blogjava.net/1504/archive/2008/08/03/219703.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/1504/comments/commentRss/219703.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/1504/services/trackbacks/219703.html</trackback:ping><description><![CDATA[<div class="postText">1.下載DWR Version 2 <br />
<a class="ilink" href="https://dwr.dev.java.net/files/documents/2427/47504/dwr.jar" target="_blank">https://dwr.dev.java.net/files/documents/2427/47504/dwr.jar</a> <br />
<br />
2.安裝DWR,把dwr.jar放到WEB-INF/lib下 <br />
<br />
web.xml中加入DWRServlet &amp; ActionServlet <br />
其中&lt;load-on-startup&gt;的部分要特別注意,ActionServlet要先初始化,所以數字要比較小. <br />
<pre>  &lt;servlet&gt;    </pre>
<pre>&lt;servlet-name&gt;action&lt;/servlet-name&gt;    </pre>
<pre>&lt;servlet-class&gt;org.apache.struts.action.ActionServlet</pre>
<pre>&lt;/servlet-class&gt;    </pre>
<pre>&lt;init-param&gt;      </pre>
<pre>&lt;param-name&gt;config&lt;/param-name&gt;      </pre>
<pre>&lt;param-value&gt;/WEB-INF/struts-config.xml&lt;/param-value&gt;    </pre>
<pre>&lt;/init-param&gt;    </pre>
<pre>&lt;init-param&gt;      </pre>
<pre>&lt;param-name&gt;debug&lt;/param-name&gt;      </pre>
<pre>&lt;param-value&gt;2&lt;/param-value&gt;    </pre>
<pre>&lt;/init-param&gt;    </pre>
<pre>&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;  </pre>
<pre>&lt;/servlet&gt;  </pre>
<pre>&lt;servlet-mapping&gt;    </pre>
<pre>&lt;servlet-name&gt;action&lt;/servlet-name&gt;    </pre>
<pre>&lt;url-pattern&gt;*.do&lt;/url-pattern&gt;  </pre>
<pre>&lt;/servlet-mapping&gt;  </pre>
<pre>&lt;servlet&gt;    </pre>
<pre>&lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;    </pre>
<pre>&lt;servlet-class&gt;uk.ltd.getahead.dwr.DWRServlet&lt;/servlet-class&gt;    </pre>
<pre>&lt;init-param&gt;      </pre>
<pre>&lt;param-name&gt;debug&lt;/param-name&gt;      </pre>
<pre>&lt;param-value&gt;true&lt;/param-value&gt;    </pre>
<pre>&lt;/init-param&gt;    </pre>
<pre>&lt;load-on-startup&gt;10&lt;/load-on-startup&gt;  </pre>
<pre>&lt;/servlet&gt;  </pre>
<pre>&lt;servlet-mapping&gt;   </pre>
<pre> &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;    </pre>
<pre>&lt;url-pattern&gt;/dwr<font class="java-comment" color="#006400">/*&lt;/url-pattern&gt;  </font></pre>
<pre><font class="java-comment" color="#006400">&lt;/servlet-mapping&gt;</font><br />
dwr.xml中加入struts的設定,其中formBean的參數的value值,會對應到struts-config.xml中&lt;form-beans&gt;的設定 </pre>
<pre>&lt;dwr&gt;&nbsp;
<pre>&lt;allow&gt;    </pre>
<pre>&lt;create creator=<font class="java-string" color="#000080">"struts"</font> javascript=<font class="java-string" color="#000080">"testFrm"</font>&gt;      </pre>
<pre>&lt;param name=<font class="java-string" color="#000080">"formBean"</font> value=<font class="java-string" color="#000080">"testActionForm"</font>/&gt;    </pre>
<pre>&lt;/create&gt;  </pre>
<pre>&lt;/allow&gt;  </pre>
<pre>&lt;/dwr&gt;  </pre>
<pre><br />
<br />
struts-config.xml </pre>
<pre>&nbsp;</pre>
<pre>
<pre>&lt;struts-config&gt;  </pre>
<pre>&lt;form-beans&gt;    </pre>
<pre>&lt;form-bean name=<font class="java-string" color="#000080">"testActionForm"</font> type=<font class="java-string" color="#000080">"test.struts.testActionForm"</font> /&gt;  </pre>
<pre>&lt;/form-beans&gt;  </pre>
<pre>&lt;action-mappings&gt;    </pre>
<pre>&lt;action name=<font class="java-string" color="#000080">"testActionForm"</font> path=<font class="java-string" color="#000080">"/testAction"</font> scope=<font class="java-string" color="#000080">"session"</font> type=<font class="java-string" color="#000080">"test.struts.testAction"</font> validate=<font class="java-string" color="#000080">"false"</font>&gt;      </pre>
<pre>&lt;forward name=<font class="java-string" color="#000080">"display"</font> path=<font class="java-string" color="#000080">"/display.jsp"</font> /&gt;    </pre>
<pre>&lt;/action&gt;  </pre>
<pre>&lt;/action-mappings&gt;  </pre>
<pre>&lt;message-resources parameter=<font class="java-string" color="#000080">"ApplicationResources"</font> /&gt;</pre>
<pre>&lt;/struts-config&gt;</pre>
<pre><br />
<br />
testActionForm.java,getDate()會透過dwr,取得現在最新的日期 </pre>
<pre>&nbsp;</pre>
<pre>
<pre><font class="java-reserved_word" color="#000080"><strong>package</strong></font> test.struts;&nbsp;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>import</strong></font> org.apache.struts.action.*;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>import</strong></font> java.util.*;&nbsp;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>public</strong></font> <font class="java-reserved_word" color="#000080"><strong>class</strong></font> testActionForm <font class="java-reserved_word" color="#000080"><strong>extends</strong></font> ActionForm <font class="java-bracket" color="#000080">{</font>&nbsp;    </pre>
<pre><font class="java-reserved_word" color="#000080"><strong>private</strong></font> String strDate;&nbsp;    </pre>
<pre><font class="java-reserved_word" color="#000080"><strong>public</strong></font> <font class="java-reserved_word" color="#000080"><strong>void</strong></font> setStrDate(String strDate) <font class="java-bracket" color="#000080">{</font>        </pre>
<pre>this.strDate = strDate;    </pre>
<pre><font class="java-bracket" color="#000080">}</font>&nbsp;    </pre>
<pre><font class="java-reserved_word" color="#000080"><strong>public</strong></font> String getStrDate() <font class="java-bracket" color="#000080">{</font>        </pre>
<pre><font class="java-reserved_word" color="#000080"><strong>return</strong></font> strDate;    </pre>
<pre><font class="java-bracket" color="#000080">}</font>&nbsp;   </pre>
<pre> <font class="java-comment" color="#006400">//dwr</font>    <font class="java-reserved_word" color="#000080"><strong>public</strong></font> String getDate() <font class="java-bracket" color="#000080">{</font>        </pre>
<pre>Date date = <font class="java-reserved_word" color="#000080"><strong>new</strong></font> Date();        </pre>
<pre><font class="java-reserved_word" color="#000080"><strong>return</strong></font> date.toString();   </pre>
<pre> <font class="java-bracket" color="#000080">}</font>&nbsp;</pre>
<pre><font class="java-bracket" color="#000080">}</font></pre>
</pre>
</pre>
</pre>
<pre><br />
<br />
testAction.java </pre>
<pre>
<pre><font class="java-reserved_word" color="#000080"><strong>package</strong></font> test.struts;&nbsp;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>import</strong></font> org.apache.struts.action.ActionMapping;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>import</strong></font> org.apache.struts.action.ActionForm;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>import</strong></font> javax.servlet.http.HttpServletRequest;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>import</strong></font> javax.servlet.http.HttpServletResponse;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>import</strong></font> org.apache.struts.action.ActionForward;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>import</strong></font> org.apache.struts.action.Action;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>import</strong></font> org.apache.struts.action.*;&nbsp;</pre>
<pre><font class="java-reserved_word" color="#000080"><strong>public</strong></font> <font class="java-reserved_word" color="#000080"><strong>class</strong></font> testAction <font class="java-reserved_word" color="#000080"><strong>extends</strong></font> Action <font class="java-bracket" color="#000080">{</font>    </pre>
<pre>	<font class="java-reserved_word" color="#000080"><strong>public</strong></font> ActionForward execute(ActionMapping mapping, ActionForm form,                                 </pre>
<pre>HttpServletRequest request,                                 </pre>
<pre>HttpServletResponse response) <font class="java-bracket" color="#000080">{</font>&nbsp;        </pre>
<pre>testActionForm actionForm = (testActionForm) form;       </pre>
<pre> System.out.println(actionForm.getStrDate());        </pre>
<pre><font class="java-reserved_word" color="#000080"><strong>return</strong></font> mapping.findForward(<font class="java-string" color="#000080">"display"</font>);    </pre>
<pre><font class="java-bracket" color="#000080">}</font></pre>
<pre><font class="java-bracket" color="#000080">}</font></pre>
<br />
</pre>
<pre></pre>
<pre><br />
date.jsp,在form的部分,請用struts 的 tag library,我把&lt;html:text property="strDate" size="30" &gt;改成&lt;input type="text" name="strDate"&gt;後,無法正常的接受到值. </pre>
<pre>
<pre>&lt;%@ page contentType=<font class="java-string" color="#000080">"text/html; charset=Big5"</font> %&gt;</pre>
<pre>&lt;%@ taglib uri=<font class="java-string" color="#000080">"/WEB-INF/struts-bean.tld"</font> prefix=<font class="java-string" color="#000080">"bean"</font> %&gt;</pre>
<pre>&lt;%@ taglib uri=<font class="java-string" color="#000080">"/WEB-INF/struts-html.tld"</font> prefix=<font class="java-string" color="#000080">"html"</font> %&gt;</pre>
<pre>&lt;%@ taglib uri=<font class="java-string" color="#000080">"/WEB-INF/struts-logic.tld"</font> prefix=<font class="java-string" color="#000080">"logic"</font> %&gt;</pre>
<pre>&lt;html&gt;&lt;head&gt;</pre>
<pre>&lt;title&gt;title&lt;/title&gt;  </pre>
<pre>&lt;script type=<font class="java-string" color="#000080">'text/javascript'</font> src=<font class="java-string" color="#000080">'dwr/interface/testFrm.js'</font>&gt;&lt;/script&gt;  </pre>
<pre>&lt;script type=<font class="java-string" color="#000080">'text/javascript'</font> src=<font class="java-string" color="#000080">'dwr/engine.js'</font>&gt;&lt;/script&gt;  </pre>
<pre>&lt;script type=<font class="java-string" color="#000080">'text/javascript'</font> src=<font class="java-string" color="#000080">'dwr/util.js'</font>&gt;&lt;/script&gt;</pre>
<pre>&lt;/head&gt;</pre>
<pre>&lt;SCRIPT LANGUAGE=<font class="java-string" color="#000080">"JavaScript"</font> type=<font class="java-string" color="#000080">""</font>&gt;&nbsp;</pre>
<pre>function refreshDate() <font class="java-bracket" color="#000080">{</font>   </pre>
<pre> testFrm.getDate(populateDate)</pre>
<pre>;<font class="java-bracket" color="#000080">}</font>&nbsp;</pre>
<pre>function populateDate(data)<font class="java-bracket" color="#000080">{</font>   </pre>
<pre>DWRUtil.setValue(<font class="java-string" color="#000080">'strDate'</font>, data);</pre>
<pre><font class="java-bracket" color="#000080">}</font>&nbsp;</pre>
<pre>&lt;/script&gt;&nbsp;</pre>
<pre>&lt;body&gt;&nbsp;</pre>
<pre>&lt;html:form action=<font class="java-string" color="#000080">"testAction.do"</font>&gt;</pre>
<pre>date：&lt;html:text property=<font class="java-string" color="#000080">"strDate"</font> size=<font class="java-string" color="#000080">"30"</font> &gt;&lt;/html:text&gt;&nbsp;</pre>
<pre>&lt;input type=<font class="java-string" color="#000080">"button"</font> onclick=<font class="java-string" color="#000080">"refreshDate();"</font> value=<font class="java-string" color="#000080">"更新日期"</font>/&gt;&lt;br/&gt;&nbsp;  </pre>
<pre>&lt;html:submit&gt;送出  &lt;/html:submit&gt;</pre>
<pre>&lt;/html:form&gt;&lt;/body&gt;&lt;/html&gt;</pre>
<br />
</pre>
<pre><br />
<br />
display.jsp </pre>
<pre>
<pre>&lt;%@ page contentType=<font class="java-string" color="#000080">"text/html; charset=Big5"</font> %&gt;</pre>
<pre>&lt;%@ taglib uri=<font class="java-string" color="#000080">"/WEB-INF/struts-bean.tld"</font> prefix=<font class="java-string" color="#000080">"bean"</font> %&gt;</pre>
<pre><a href="mailto:%@page%20import=">%@page import=<font class="java-string" color="#000080">"test.struts.*"</font>%</a></pre>
<pre>&lt;html&gt;</pre>
<pre>&lt;head&gt;</pre>
<pre>&lt;title&gt;test&lt;/title&gt;</pre>
<pre>&lt;/head&gt;&lt;body bgcolor=<font class="java-string" color="#000080">"#ffffff"</font>&gt;&lt;h1&gt;您送出的日期:&lt;br&gt;</pre>
<pre>&lt;bean:write name=<font class="java-string" color="#000080">"testActionForm"</font> property=<font class="java-string" color="#000080">"strDate"</font>/&gt;&lt;/h1&gt;</pre>
<pre>&lt;/body&gt;</pre>
<pre>&lt;/html&gt;</pre>
<br />
</pre>
<pre></pre>
<pre>&nbsp;<br />
<br />
</pre>
<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1621900</p>
<br />
</div>
<div class="postFoot">&lt;script src="http://localhost:82/PromoteIcon.aspx?id=1621900"&gt;&lt;/script&gt;[<a title="功能强大的网络收藏夹，一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();">收藏到我的网摘</a>]&nbsp;&nbsp; 会上树的猪发表于 2007年05月23日 09:24:00 </div>
<img src ="http://www.blogjava.net/1504/aggbug/219703.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/1504/" target="_blank">weesun一米阳光</a> 2008-08-03 15:34 <a href="http://www.blogjava.net/1504/archive/2008/08/03/219703.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts+hibernate+spring+dwr的一个小小的DEMO【收藏】</title><link>http://www.blogjava.net/1504/archive/2008/08/03/219702.html</link><dc:creator>weesun一米阳光</dc:creator><author>weesun一米阳光</author><pubDate>Sun, 03 Aug 2008 07:31:00 GMT</pubDate><guid>http://www.blogjava.net/1504/archive/2008/08/03/219702.html</guid><wfw:comment>http://www.blogjava.net/1504/comments/219702.html</wfw:comment><comments>http://www.blogjava.net/1504/archive/2008/08/03/219702.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/1504/comments/commentRss/219702.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/1504/services/trackbacks/219702.html</trackback:ping><description><![CDATA[<p>最近无聊，做了一个<span class="hilite1">DWR</span>的验证和<font face="Arial">eXtremeTable的应用的例子</font></p>
<p>前期的系统创建、struts、hibernate、spring的集成工作就不用说了，一路下来&#8230;&#8230;&#8230;&#8230;</p>
<p>主要看<span class="hilite1">DWR</span>的应用，它用于表单验证：</p>
<p>1、先看它的配置：</p>
<p>（1）在web.xml里加上：</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt">&#160;&#160;<span class="tag">&lt;<span class="tag-name">servlet</span><span class="tag">></span>&#160;&#160;</span>
    </li>
    <li class="">&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">></span><span class="hilite1">dwr-invoker</span><span class="tag"><span class="tag-name">servlet-name</span><span class="tag">></span>&#160;&#160; &#160;&#160; </span>
    </li>
    <li class="alt">&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">servlet-class</span><span class="tag">></span>uk.ltd.getahead.<span class="hilite1">dwr.<span class="hilite1">DWR</span>Servlet</span><span class="tag"><span class="tag-name">servlet-class</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">init-param</span><span class="tag">></span>&#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">param-name</span><span class="tag">></span>debug<span class="tag"><span class="tag-name">param-name</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">param-value</span><span class="tag">></span>true<span class="tag"><span class="tag-name">param-value</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="alt">&#160;&#160;&#160;<span class="tag"><span class="tag-name">init-param</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="">&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">load-on-startup</span><span class="tag">></span>1<span class="tag"><span class="tag-name">load-on-startup</span><span class="tag">></span>&#160; &#160;&#160; </span>
    </li>
    <li class="alt">&#160;<span class="tag"><span class="tag-name">servlet</span><span class="tag">></span>&#160;&#160; &#160;&#160; </span>
    </li>
    <li class="">&#160; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">servlet-mapping</span><span class="tag">></span>&#160;&#160;
    </li>
    <li class="">&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">></span><span class="hilite1">dwr-invoker</span><span class="tag"><span class="tag-name">servlet-name</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="alt">&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">></span>/<span class="hilite1">dwr/*</span><span class="tag"><span class="tag-name">url-pattern</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class=""><span class="tag"><span class="tag-name">servlet-mapping</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="alt">&#160;&#160;&#160; </li>
</ol>
</div>
<p>&#160;</p>
<p>（2）再建一个类，用于获取验证输出信息的属性文件，这个文件是参考了良葛格 的<strong><font color="#ff0000"><span class="hilite1">DWR</span> 入門與應用（一）</font></strong></p>
<p>里的Book代码</p>
<p>java 代码</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span class="keyword">package&#160;test.common; &#160;&#160;</span>
    </li>
    <li class="">&#160;&#160;
    </li>
    <li class="alt"><span class="keyword">import</span>&#160;java.util.ResourceBundle; &#160;&#160;
    </li>
    <li class="">&#160;&#160;
    </li>
    <li class="alt"><span class="keyword">public</span>&#160;<span class="keyword">class</span>&#160;GetProperties{ &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;<span class="keyword">private</span>&#160;ResourceBundle&#160;resource; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;<span class="keyword">public</span>&#160;GetProperties() &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;{ &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;resource&#160;=&#160;ResourceBundle.getBundle(<span class="string">"<span class="hilite1">dwr</span>Pro"</span>); &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;} &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;<span class="keyword">public</span>&#160;String&#160;getDescription(String&#160;key)&#160; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;{ &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span class="keyword">return</span>&#160;resource.getString(key); &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;} &#160;&#160;
    </li>
    <li class="">&#160;&#160;
    </li>
    <li class="alt">}&#160;&#160; </li>
</ol>
</div>
<p>（3）编写属性文件<span class="hilite1">dwr</span>Pro_zh_CN.propertie（中文）和<span class="hilite1">dwr</span>_en.properties（英文）</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<ol class="dp-j">
    <li class="alt">username_hasUsed&#160;=&#160;用户名已用，请选择别的用户名 &#160;&#160;
    </li>
    <li class="">username_canUse&#160;&#160;=&#160;恭喜！用户名可以使用 &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;
    </li>
    <li class="">username_hasUsed&#160;=username&#160;has&#160;used! &#160;&#160;
    </li>
    <li class="alt">username_canUse&#160;&#160;=&#160;username&#160;can&#160;use!&#160;&#160; </li>
</ol>
</div>
<p>&#160;</p>
<p>（4）配置<span class="hilite1">dwr</span>.xml，里面用了spring的bean 和java类</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span class="tag">&lt;<span class="tag-name"><span class="hilite1">dwr</span></span><span class="tag">></span>&#160;&#160;</span>
    </li>
    <li class="">&#160;&#160;
    </li>
    <li class="alt">&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">allow</span><span class="tag">></span>&#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">create</span>&#160;<span class="attribute">creator</span>=<span class="attribute-value">"spring"</span>&#160;<span class="attribute">javascript</span>=<span class="attribute-value">"userManager"</span><span class="tag">></span>&#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">param</span>&#160;<span class="attribute">name</span>=<span class="attribute-value">"beanName"</span>&#160;<span class="attribute">value</span>=<span class="attribute-value">"userManager"</span><span class="tag">/></span>&#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">include</span>&#160;<span class="attribute">method</span>=<span class="attribute-value">"findUserIsExist"</span><span class="tag">/></span>&#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;<span class="tag"><span class="tag-name">create</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="">&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">create</span>&#160;<span class="attribute">creator</span>=<span class="attribute-value">"new"</span>&#160;<span class="attribute">javascript</span>=<span class="attribute-value">"User"</span>&#160;<span class="attribute">scope</span>=<span class="attribute-value">"application"</span><span class="tag">></span>&#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">param</span>&#160;<span class="attribute">name</span>=<span class="attribute-value">"class"</span>&#160;<span class="attribute">value</span>=<span class="attribute-value">"test.common.GetProperties"</span><span class="tag">/></span>&#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span class="tag"><span class="tag-name">create</span><span class="tag">></span>&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160; </span>
    </li>
    <li class="">&#160;&#160;<span class="tag"><span class="tag-name">allow</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="alt"><span class="tag"><span class="tag-name"><span class="hilite1">dwr</span></span><span class="tag">></span>&#160;&#160; </span></li>
</ol>
</div>
<p>spring beanName&#160; 的value =&#8220;userManager&#8221;从applicationContext.xml里取得</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span class="tag">&lt;<span class="tag-name">bean</span>&#160;<span class="attribute">id</span>=<span class="attribute-value">"userManagerTarget"</span>&#160;<span class="attribute">class</span>=<span class="attribute-value">"test.spring.serviceImpl.UserServiceImpl"</span><span class="tag">></span>&#160;&#160;</span>
    </li>
    <li class=""><span class="tag">&lt;</span><span class="tag-name">property</span>&#160;<span class="attribute">name</span>=<span class="attribute-value">"userDao"</span><span class="tag">></span>&#160;&#160;
    </li>
    <li class="alt">&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">ref</span>&#160;<span class="attribute">bean</span>=<span class="attribute-value">"userDao"</span><span class="tag">/></span>&#160;&#160;
    </li>
    <li class=""><span class="tag"><span class="tag-name">property</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="alt"><span class="tag"><span class="tag-name">bean</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="">&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="">&#160;<span class="tag">&lt;</span><span class="tag-name">bean</span>&#160;<span class="attribute">id</span>=<span class="attribute-value">"userManager"</span>&#160;<span class="attribute">class</span>=<span class="attribute-value">"org.springframework.aop.framework.ProxyFactoryBean"</span><span class="tag">></span>&#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">property</span>&#160;<span class="attribute">name</span>=<span class="attribute-value">"proxyInterfaces"</span><span class="tag">></span>&#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">></span>test.spring.service.IUserService<span class="tag"><span class="tag-name">value</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;<span class="tag"><span class="tag-name">property</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="">&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">property</span>&#160;<span class="attribute">name</span>=<span class="attribute-value">"interceptorNames"</span><span class="tag">></span>&#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">list</span><span class="tag">></span>&#160; &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">idref</span>&#160;<span class="attribute">bean</span>=<span class="attribute-value">"transactionInterceptor"</span><span class="tag">/></span>&#160; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span class="tag">&lt;</span><span class="tag-name">idref</span>&#160;<span class="attribute">bean</span>=<span class="attribute-value">"userManagerTarget"</span><span class="tag">/></span>&#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span class="tag"><span class="tag-name">list</span><span class="tag">></span>&#160;&#160; </span>
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;<span class="tag"><span class="tag-name">property</span><span class="tag">></span>&#160;&#160;&#160;&#160; &#160;&#160; </span>
    </li>
    <li class="">&#160;<span class="tag"><span class="tag-name">bean</span><span class="tag">></span>&#160;&#160;&#160; </span></li>
</ol>
</div>
<p>这里应该大家都懂，就不罗嗦了</p>
<p>&#160;</p>
<p>（5）配好了这些，就可以在页面里用了</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><!--page&#160;language=<span class="string">"java"&#160;pageEncoding=<span class="string">"UTF-8"</span><span-->&#160;&#160;</span></span>
    </li>
    <li class="">&#160;&#160;
    </li>
    <li class="alt">&#160;&#160;
    </li>
    <li class=""><!--ctype&#160;html&#160;public&#160;</sp--><span class="string">"-//W3C//DTD&#160;HTML&#160;4.01&#160;Transitional//EN"> &#160;&#160; </span>
    </li>
    <li class="alt">&#160;&#160;
    </li>
    <li class="">&#160;&#160; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="alt">&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;
    </li>
    <li class="">&#160;&#160;&#160;&#160;
    <script&#160;type='text javascript?&#160; src="dwr/</span"><span class="keyword">interface/userManager.js'&gt; &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;
    <script&#160;type='text javascript?&#160; src="dwr/engine.js"> &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;
    <script&#160;type='text javascript?&#160; src="dwr/</span"><span class="keyword">interface/GetProperties.js'&gt; &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;
    <script&#160;type='text javascript?>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">"0"&gt; &nbsp;&nbsp; </span>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <tr>
    </tr>
    &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <td>&nbsp;</td>
    Login: &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <td>&nbsp;</td>
    <span class="string">"text"&nbsp;name=<span class="string">"user.name"</span>&nbsp;id=<span class="string">"username"</span>&nbsp;onblur=<span class="string">"checkName()"</span>/&gt;<span class="string">"check_username"&gt; &nbsp;&nbsp;</span> </span>
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <tr>
    </tr>
    &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <td>&nbsp;</td>
    Password: &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <td>&nbsp;</td>
    <span class="string">"password"&nbsp;name=<span class="string">"user.password"</span>&nbsp;id=<span class="string">"username"</span>&nbsp;onblur=<span class="string">"checkpassword()"</span>/&gt;<span class="string">"check_password"&gt; &nbsp;&nbsp;</span> </span>
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <tr>
    </tr>
    &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">"2"&nbsp;align=<span class="string">"center"</span>&gt; &nbsp;&nbsp; </span>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;
    <li class="">&nbsp;&nbsp; &nbsp;&nbsp;
    <li class="alt"></li>
</ol>
</div>
<p>&nbsp;</p>
<p>这里当填了Login框，当光标从输入框移开时就实行了</p>
<div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-c">
    <li class="alt"><span class="keyword">function&nbsp;checkName() &nbsp;&nbsp;</span>
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span>&nbsp;username&nbsp;=&nbsp;document.userForm.username.value; &nbsp;&nbsp;
    <li class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userManager.findUserIsExist(username,callback); &nbsp;&nbsp;
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; </li>
</ol>
</div>
<p>&nbsp;</p>
<p><font face="Arial">userManager.findUserIsExist(username,callback)时关键，这里就用了</font></p>
<p><font face="Arial">&nbsp;
<script src="dwr/interface/userManager.js" type="text/javascript"></script>
<p>&#160;</p>
<p>读取<span class="hilite1">dwr</span>.xml的<font face="Arial">userManager，然后读取applicationContext.xml里<font face="Arial">userManager&#160; bean ，进而实行<font face="Arial">findUserIsExist方法。</font></font></font></p>
<p>&#160;</p>
</span></li>
</ol>
</div>
<img src ="http://www.blogjava.net/1504/aggbug/219702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/1504/" target="_blank">weesun一米阳光</a> 2008-08-03 15:31 <a href="http://www.blogjava.net/1504/archive/2008/08/03/219702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 CAS 在 Tomcat 中实现单点登录</title><link>http://www.blogjava.net/1504/archive/2008/08/03/219699.html</link><dc:creator>weesun一米阳光</dc:creator><author>weesun一米阳光</author><pubDate>Sun, 03 Aug 2008 07:19:00 GMT</pubDate><guid>http://www.blogjava.net/1504/archive/2008/08/03/219699.html</guid><wfw:comment>http://www.blogjava.net/1504/comments/219699.html</wfw:comment><comments>http://www.blogjava.net/1504/archive/2008/08/03/219699.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/1504/comments/commentRss/219699.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/1504/services/trackbacks/219699.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt;">转自：http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html<br />
<img alt="" src="http://www.ibm.com/i/c.gif" width="10" height="1" />
<table width="160" align="right" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td width="10"><img alt="" src="http://www.ibm.com/i/c.gif" width="10" height="1" /></td>
            <td>
            <table width="150" border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td>文档选项</td>
                    </tr>
                </tbody>
            </table>
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td width="150"><noscript>
                        <tr valign="top">
                            <td width="8"><img alt="" height="1" width="8" src="//www.ibm.com/i/c.gif"/ /></td>
                            <td width="16"><img alt="" width="16" height="16" src="//www.ibm.com/i/c.gif"/ /></td>
                            <td width="122">
                            <p>未显示需要 JavaScript 的文档选项</p>
                            </td>
                        </tr>
                        </noscript>
                        <table width="143" border="0" cellpadding="0" cellspacing="0">
                            <script language="JavaScript" type="text/javascript">
                            <!--
                            document.write('
                            <tr valign="top">
                                <td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/ /></td>
                                <td width="16"><img alt="将打印机的版面设置成横向打印模式" height="16" src="//www.ibm.com/i/v14/icons/printer.gif" width="16" vspace="3" /></td>
                                <td width="122">
                                <p><strong><a href="javascript:print()">打印本页</a></strong></p>
                                </td>
                            </tr>
                            ');
                            //-->
                            </script>
                            <tbody>
                                <tr valign="top">
                                    <td width="8"><img src="http://www.ibm.com/i/c.gif" alt="" width="8" height="1" /></td>
                                    <td width="16"><img alt="将打印机的版面设置成横向打印模式" src="http://www.ibm.com/i/v14/icons/printer.gif" vspace="3" width="16" height="16" /></td>
                                    <td width="122">
                                    <p><strong><a href="javascript:print()">打印本页</a></strong></p>
                                    </td>
                                </tr>
                                <input value="单点登录（Single Sign On , 简称 SSO
                                ）是目前比较流行的服务于企业业务整合的解决方案之一， SSO
                                使得在多个应用系统中，用户只需要登录一次就可以访问所有相互信任的应用系统。CAS(Central Authentication
                                Service)是一款不错的针对 Web 应用的单点登录框架，本文介绍了 CAS 的原理、协议、在 Tomcat 中的配置和使用，对于采用
                                CAS 实现轻量级单点登录解决方案的入门读者具有一定指导作用。" name="body" type="hidden" /><input value="使用 CAS 在 Tomcat 中实现单点登录" name="subject" type="hidden" /><input value="cn" name="lang" type="hidden" />
                                <script language="JavaScript" type="text/javascript">
                                <!--
                                document.write('
                                <tr valign="top">
                                    <td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/ /></td>
                                    <td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td>
                                    <td width="122">
                                    <p><a href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                    </td>
                                </tr>
                                ');
                                //-->
                                </script>
                                <tr valign="top">
                                    <td width="8"><img src="http://www.ibm.com/i/c.gif" alt="" width="8" height="1" /></td>
                                    <td width="16"><img src="http://www.ibm.com/i/v14/icons/em.gif" alt="将此页作为电子邮件发送" vspace="3" width="16" height="16" /></td>
                                    <td width="122">
                                    <p><a href="javascript:document.email.submit();"><strong>将此
                                    页作为电子邮件发送</strong></a></p>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            </td>
        </tr>
    </tbody>
</table>
<p>级
别： 初级</p>
<p><a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#author">张
涛</a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#122;&#104;&#97;&#110;&#103;&#116;&#64;&#99;&#110;&#46;&#105;&#98;&#109;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#37;&#69;&#52;&#37;&#66;&#68;&#37;&#66;&#70;&#37;&#69;&#55;&#37;&#57;&#52;&#37;&#65;&#56;&#37;&#50;&#48;&#67;&#65;&#83;&#37;&#50;&#48;&#37;&#69;&#53;&#37;&#57;&#67;&#37;&#65;&#56;&#37;&#50;&#48;&#84;&#111;&#109;&#99;&#97;&#116;&#37;&#50;&#48;&#37;&#69;&#52;&#37;&#66;&#56;&#37;&#65;&#68;&#37;&#69;&#53;&#37;&#65;&#69;&#37;&#57;&#69;&#37;&#69;&#55;&#37;&#56;&#69;&#37;&#66;&#48;&#37;&#69;&#53;&#37;&#56;&#68;&#37;&#57;&#53;&#37;&#69;&#55;&#37;&#56;&#50;&#37;&#66;&#57;&#37;&#69;&#55;&#37;&#57;&#57;&#37;&#66;&#66;&#37;&#69;&#53;&#37;&#66;&#68;&#37;&#57;&#53;">zzhangt@cn.ibm.com</a>),
软件工程师, IBM<br />
<a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#author">王
秉坤</a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#119;&#97;&#110;&#103;&#98;&#107;&#64;&#99;&#110;&#46;&#105;&#98;&#109;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#37;&#69;&#52;&#37;&#66;&#68;&#37;&#66;&#70;&#37;&#69;&#55;&#37;&#57;&#52;&#37;&#65;&#56;&#37;&#50;&#48;&#67;&#65;&#83;&#37;&#50;&#48;&#37;&#69;&#53;&#37;&#57;&#67;&#37;&#65;&#56;&#37;&#50;&#48;&#84;&#111;&#109;&#99;&#97;&#116;&#37;&#50;&#48;&#37;&#69;&#52;&#37;&#66;&#56;&#37;&#65;&#68;&#37;&#69;&#53;&#37;&#65;&#69;&#37;&#57;&#69;&#37;&#69;&#55;&#37;&#56;&#69;&#37;&#66;&#48;&#37;&#69;&#53;&#37;&#56;&#68;&#37;&#57;&#53;&#37;&#69;&#55;&#37;&#56;&#50;&#37;&#66;&#57;&#37;&#69;&#55;&#37;&#57;&#57;&#37;&#66;&#66;&#37;&#69;&#53;&#37;&#66;&#68;&#37;&#57;&#53;">wangbk@cn.ibm.com</a>),
软件工程师, IBM<br />
</p>
<p>2008 年  4 月  10 日</p>
<blockquote>单点登录（Single Sign
On , 简称 SSO ）是目前比较流行的服务于企业业务整合的解决方案之一， SSO
使得在多个应用系统中，用户只需要登录一次就可以访问所有相互信任的应用系统。CAS(Central Authentication
Service)是一款不错的针对 Web 应用的单点登录框架，本文介绍了 CAS 的原理、协议、在 Tomcat 中的配置和使用，对于采用
CAS 实现轻量级单点登录解决方案的入门读者具有一定指导作用。</blockquote>
<p><a name="2.CAS 介绍">CAS 介绍</a></p>
<p>CAS 是 Yale 大学发起的一个开源项目，旨在为 Web 应用系统提供一种可靠的单点登录方法，CAS 在
2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点：</p>
<ul>
    <li>
    开源的企业级单点登录解决方案。</li>
    <li>
    CAS Server 为需要独立部署的 Web 应用。</li>
    <li>
    CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用)，包括 Java, .Net, PHP, Perl,
    Apache, uPortal, Ruby 等。</li>
</ul>
<p><a name="N1008D">CAS 原理和协议</a></p>
<p>从结构上看，CAS 包含两个部分： CAS Server 和 CAS Client。CAS Server
需要独立部署，主要负责对用户的认证工作；CAS Client 负责处理对客户端受保护资源的访问请求，需要登录时，重定向到 CAS
Server。图1 是 CAS 最基本的协议过程：</p>
<br />
<a name="N10098"><strong>图 1. CAS 基础协议</strong></a><br />
<img alt="CAS 基础协议" src="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/images/image001.jpg" width="467" height="341" />
<br />
<p>CAS Client 与受保护的客户端应用部署在一起，以 Filter
方式保护受保护的资源。对于访问受保护资源的每个 Web 请求，CAS Client 会分析该请求的 Http 请求中是否包含 Service
Ticket，如果没有，则说明当前用户尚未登录，于是将请求重定向到指定好的 CAS  Server 登录地址，并传递 Service
（也就是要访问的目的资源地址），以便登录成功过后转回该地址。用户在第 3 步中输入认证信息，如果登录成功，CAS Server
随机产生一个相当长度、唯一、不可伪造的 Service Ticket，并缓存以待将来验证，之后系统自动重定向到 Service
所在地址，并为客户端浏览器设置一个 Ticket Granted Cookie（TGC），CAS Client 在拿到 Service
和新产生的 Ticket 过后，在第 5，6 步中与 CAS Server 进行身份合适，以确保 Service Ticket 的合法性。</p>
<p>在该协议中，所有与 CAS 的交互均采用 SSL 协议，确保，ST 和 TGC 的安全性。协议工作过程中会有 2
次重定向的过程，但是 CAS Client 与 CAS Server 之间进行 Ticket 验证的过程对于用户是透明的。</p>
<p>另外，CAS 协议中还提供了 Proxy （代理）模式，以适应更加高级、复杂的应用场景，具体介绍可以参考 CAS
官方网站上的相关文档。</p>
<p><a name="N100B0">准备工作</a></p>
<p>本文中的例子以 tomcat5.5 为例进行讲解，下载地址：</p>
<p>
<a href="http://tomcat.apache.org/download-55.cgi">http://tomcat.apache.org/download-55.cgi</a>
</p>
<p>到 CAS 官方网站下载 CAS Server 和 Client，地址分别为：</p>
<p>
<a href="http://www.ja-sig.org/downloads/cas/cas-server-3.1.1-release.zip">http://www.ja-sig.org/downloads/cas/cas-server-3.1.1-release.zip</a>
</p>
<p>
<a href="http://www.ja-sig.org/downloads/cas-clients/cas-client-java-2.1.1.zip">http://www.ja-sig.org/downloads/cas-clients/cas-client-java-2.1.1.zip</a>
</p>
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="3.部署 CAS Server">部署 CAS Server</a></p>
<p>CAS Server 是一套基于 Java 实现的服务，该服务以一个 Java Web Application
单独部署在与 servlet2.3 兼容的 Web 服务器上，另外，由于 Client 与 CAS Server 之间的交互采用 Https
协议，因此部署 CAS Server 的服务器还需要支持 SSL 协议。当 SSL 配置成功过后，像普通 Web 应用一样将 CAS
Server 部署在服务器上就能正常运行了，不过，在真正使用之前，还需要扩展验证用户的接口。</p>
<p>在 Tomcat 上部署一个完整的 CAS Server 主要按照以下几个步骤：</p>
<p><a name="N100DD"><span>配置 Tomcat 使用
Https 协议</span></a></p>
<p>如果希望 Tomcat 支持 Https，主要的工作是配置 SSL 协议，其配置过程和配置方法可以参考
Tomcat 的相关文档。不过在生成证书的过程中，会有需要用到主机名的地方，CAS 建议不要使用 IP 地址，而要使用机器名或域名。</p>
<p><a name="N100E6">部署 CAS Server</a></p>
<p>CAS Server 是一个 Web 应用包，将前面下载的
cas-server-3.1.1-release.zip 解开，把其中的 cas-server-webapp-3.1.1.war 拷贝到
tomcat的 webapps 目录，并更名为 cas.war。由于前面已配置好 tomcat 的 https 协议，可以重新启动
tomcat，然后访问：https://localhost:8443/cas ，如果能出现正常的 CAS 登录页面，则说明 CAS Server
已经部署成功。</p>
<p>虽然 CAS Server
已经部署成功，但这只是一个缺省的实现，在实际使用的时候，还需要根据实际概况做扩展和定制，最主要的是扩展认证 (Authentication)
接口和 CAS Server 的界面。</p>
<p><a name="N100F2">扩展认证接口</a></p>
<p>CAS Server 负责完成对用户的认证工作，它会处理登录时的用户凭证 (Credentials)
信息，用户名/密码对是最常见的凭证信息。CAS Server 可能需要到数据库检索一条用户帐号信息，也可能在 XML
文件中检索用户名/密码，还可能通过 LDAP Server 获取等，在这种情况下，CAS 提供了一种灵活但统一的接口和实现分离的方式，实际使用中
CAS 采用哪种方式认证是与 CAS 的基本协议分离开的，用户可以根据认证的接口去定制和扩展。</p>
<p>
<strong>扩展 AuthenticationHandler</strong>
</p>
<p>CAS 提供扩展认证的核心是 AuthenticationHandler 接口，该接口定义如清单 1 下：</p>
<br />
<a name="N10107"><strong>清单 1. AuthenticationHandler定义</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            public interface AuthenticationHandler {<br />
            /**<br />
            * Method to determine if the credentials supplied are valid.<br />
            * @param credentials The credentials to validate.<br />
            * @return true if valid, return false otherwise.<br />
            * @throws AuthenticationException An AuthenticationException can contain<br />
            * details about why a particular authentication request failed.<br />
            */<br />
            boolean authenticate(Credentials credentials) throws AuthenticationException;<br />
            /**<br />
            * Method to check if the handler knows how to handle the credentials<br />
            * provided. It may be a simple check of the Credentials class or something<br />
            * more complicated such as scanning the information contained in the<br />
            * Credentials object. <br />
            * @param credentials The credentials to check.<br />
            * @return true if the handler supports the Credentials, false othewrise.<br />
            */<br />
            boolean supports(Credentials credentials);<br />
            }<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>该接口定义了 2 个需要实现的方法，supports ()方法用于检查所给的包含认证信息的Credentials
是否受当前 AuthenticationHandler 支持；而 authenticate()
方法则担当验证认证信息的任务，这也是需要扩展的主要方法，根据情况与存储合法认证信息的介质进行交互，返回 boolean 类型的值，true
表示验证通过，false 表示验证失败。</p>
<p>CAS3中还提供了对AuthenticationHandler
接口的一些抽象实现，比如，可能需要在执行authenticate() 方法前后执行某些其他操作，那么可以让自己的认证类扩展自清单 2
中的抽象类：</p>
<br />
<a name="N10117"><strong>清单 2.
AbstractPreAndPostProcessingAuthenticationHandler定义</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            public abstract class AbstractPreAndPostProcessingAuthenticationHandler <br />
            implements AuthenticateHandler{<br />
            protected Log log = LogFactory.getLog(this.getClass());<br />
            protected boolean preAuthenticate(final Credentials credentials) {<br />
            return true;<br />
            }<br />
            protected boolean postAuthenticate(final Credentials credentials,<br />
            final boolean authenticated) {<br />
            return authenticated;<br />
            }<br />
            public final boolean authenticate(final Credentials credentials)<br />
            throws AuthenticationException {<br />
            if (!preAuthenticate(credentials)) {<br />
            return false;<br />
            }<br />
            final boolean authenticated = doAuthentication(credentials);<br />
            return postAuthenticate(credentials, authenticated);<br />
            }<br />
            protected abstract boolean doAuthentication(final Credentials credentials) <br />
            throws AuthenticationException;<br />
            }<br />
            <br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>AbstractPreAndPostProcessingAuthenticationHandler 类新定义了
preAuthenticate() 方法和 postAuthenticate() 方法，而实际的认证工作交由
doAuthentication() 方法来执行。因此，如果需要在认证前后执行一些额外的操作，可以分别扩展 preAuthenticate()和
ppstAuthenticate() 方法，而 doAuthentication() 取代 authenticate()
成为了子类必须要实现的方法。</p>
<p>由于实际运用中，最常用的是用户名和密码方式的认证，CAS3 提供了针对该方式的实现，如清单 3 所示：</p>
<br />
<a name="N10127"><strong>清单 3.
AbstractUsernamePasswordAuthenticationHandler 定义</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            public abstract class AbstractUsernamePasswordAuthenticationHandler extends <br />
            AbstractPreAndPostProcessingAuthenticationHandler{<br />
            ...<br />
            protected final boolean doAuthentication(final Credentials credentials)<br />
            throws AuthenticationException {<br />
            return authenticateUsernamePasswordInternal((UsernamePasswordCredentials) credentials);<br />
            }<br />
            protected abstract boolean authenticateUsernamePasswordInternal(<br />
            final UsernamePasswordCredentials credentials) throws AuthenticationException;   <br />
            protected final PasswordEncoder getPasswordEncoder() {<br />
            return this.passwordEncoder;<br />
            }<br />
            public final void setPasswordEncoder(final PasswordEncoder passwordEncoder) {<br />
            this.passwordEncoder = passwordEncoder;<br />
            }<br />
            ...<br />
            }<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>基于用户名密码的认证方式可直接扩展自
AbstractUsernamePasswordAuthenticationHandler，验证用户名密码的具体操作通过实现
authenticateUsernamePasswordInternal()
方法达到，另外，通常情况下密码会是加密过的，setPasswordEncoder() 方法就是用于指定适当的加密器。</p>
<p>从以上清单中可以看到，doAuthentication() 方法的参数是 Credentials
类型，这是包含用户认证信息的一个接口，对于用户名密码类型的认证信息，可以直接使用
UsernamePasswordCredentials，如果需要扩展其他类型的认证信息，需要实现Credentials接口，并且实现相应的
CredentialsToPrincipalResolver 接口，其具体方法可以借鉴 UsernamePasswordCredentials 和
UsernamePasswordCredentialsToPrincipalResolver。</p>
<p>
<strong>JDBC 认证方法</strong>
</p>
<p>用户的认证信息通常保存在数据库中，因此本文就选用这种情况来介绍。将前面下载的
cas-server-3.1.1-release.zip 包解开后，在 modules 目录下可以找到包
cas-server-support-jdbc-3.1.1.jar，其提供了通过 JDBC
连接数据库进行验证的缺省实现，基于该包的支持，我们只需要做一些配置工作即可实现 JDBC 认证。</p>
<p>JDBC 认证方法支持多种数据库，DB2, Oracle, MySql, Microsoft SQL Server
等均可，这里以 DB2 作为例子介绍。并且假设DB2数据库名： CASTest，数据库登录用户名： db2user，数据库登录密码：
db2password，用户信息表为： userTable，该表包含用户名和密码的两个数据项分别为 userName 和 password。</p>
<p>
<strong>1. </strong>
<strong>配置</strong>
<strong> DataStore</strong>
</p>
<p>打开文件
%CATALINA_HOME%/webapps/cas/WEB-INF/deployerConfigContext.xml，添加一个新的
bean 标签，对于 DB2，内容如清单 4 所示：</p>
<br />
<a name="N10152"><strong>清单 4. 配置 DataStore</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            &lt;bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource"&gt;<br />
            &lt;property name="driverClassName"&gt;<br />
            &lt;value&gt;com.ibm.db2.jcc.DB2Driver&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="url"&gt;<br />
            &lt;value&gt;jdbc:db2://9.125.65.134:50000/CASTest&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="username"&gt;<br />
            &lt;value&gt;db2user&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="password"&gt;<br />
            &lt;value&gt;db2password&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;/bean&gt;<br />
            <br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>其中 id 属性为该 DataStore 的标识，在后面配置 AuthenticationHandler
会被引用，另外，需要提供 DataStore 所必需的数据库驱动程序、连接地址、数据库登录用户名以及登录密码。</p>
<p>
<strong>2. 配置 AuthenticationHandler</strong>
</p>
<p>在 cas-server-support-jdbc-3.1.1.jar 包中，提供了 3 个基于 JDBC 的
AuthenticationHandler，分别为 BindModeSearchDatabaseAuthenticationHandler,
QueryDatabaseAuthenticationHandler,
SearchModeSearchDatabaseAuthenticationHandler。其中
BindModeSearchDatabaseAuthenticationHandler
是用所给的用户名和密码去建立数据库连接，根据连接建立是否成功来判断验证成功与
否；QueryDatabaseAuthenticationHandler 通过配置一个 SQL
语句查出密码，与所给密码匹配；SearchModeSearchDatabaseAuthenticationHandler
通过配置存放用户验证信息的表、用户名字段和密码字段，构造查询语句来验证。</p>
<p>使用哪个 AuthenticationHandler，需要在 deployerConfigContext.xml
中设置，默认情况下，CAS 使用一个简单的 username=password 的
AuthenticationHandler，在文件中可以找到如下一行：&lt;bean
class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePassword<br />
AuthenticationHandler"
/&gt;，我们可以将其注释掉，换成我们希望的一个
AuthenticationHandler，比如，使用QueryDatabaseAuthenticationHandler 或
SearchModeSearchDatabaseAuthenticationHandler 可以分别选取清单 5 或清单 6 的配置。</p>
<br />
<a name="N1016D"><strong>清单 5. 使用
QueryDatabaseAuthenticationHandler</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            &lt;bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"&gt;<br />
            &lt;property name="dataSource" ref=" casDataSource " /&gt;<br />
            &lt;property name="sql" <br />
            value="select password from userTable where lower(userName) = lower(?)" /&gt;<br />
            &lt;/bean&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<a name="N10177"><strong>清单 6. 使用
SearchModeSearchDatabaseAuthenticationHandler</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            &lt;bean id="SearchModeSearchDatabaseAuthenticationHandler"<br />
            class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler"<br />
            abstract="false" singleton="true" lazy-init="default" <br />
            autowire="default" dependency-check="default"&gt;<br />
            &lt;property  name="tableUsers"&gt;<br />
            &lt;value&gt;userTable&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="fieldUser"&gt;<br />
            &lt;value&gt;userName&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="fieldPassword"&gt;<br />
            &lt;value&gt;password&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="dataSource" ref=" casDataSource " /&gt;<br />
            &lt;/bean&gt;<br />
            <br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>另外，由于存放在数据库中的密码通常是加密过的，所以 AuthenticationHandler
在匹配时需要知道使用的加密方法，在 deployerConfigContext.xml 文件中我们可以为具体的
AuthenticationHandler 类配置一个 property，指定加密器类，比如对于
QueryDatabaseAuthenticationHandler，可以修改如清单7所示：</p>
<br />
<a name="N10184"><strong>清单 7. 添加 passwordEncoder</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            &lt;bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"&gt;<br />
            &lt;property name="dataSource" ref=" casDataSource " /&gt;<br />
            &lt;property name="sql" <br />
            value="select password from userTable where lower(userName) = lower(?)" /&gt;<br />
            &lt;property  name="passwordEncoder"  ref="myPasswordEncoder"/&gt;<br />
            &lt;/bean&gt;<br />
            <br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>其中 myPasswordEncoder 是对清单 8 中设置的实际加密器类的引用：</p>
<br />
<a name="N10191"><strong>清单 8. 指定具体加密器类</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            &lt;bean id="passwordEncoder" <br />
            class="org.jasig.cas.authentication.handler.MyPasswordEncoder"/&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>这里 MyPasswordEncoder 是根据实际情况自己定义的加密器，实现 PasswordEncoder
接口及其 encode() 方法。</p>
<p>
<strong>3. 部署依赖包</strong>
</p>
<p>在以上配置完成以后，需要拷贝几个依赖的包到 cas 应用下，包括：</p>
<ul>
    <li>
    将 cas-server-support-jdbc-3.1.1.jar 拷贝到 %CATALINA_HOME%/webapps/cas/
    WEB-INF/lib 目录。</li>
    <li>
    数据库驱动，由于这里使用 DB2，将 %DB2_HOME%/java 目录下的 db2java.zip （更名为 db2java.jar）,
    db2jcc.jar, db2jcc_license_cu.jar 拷贝到
    %CATALINA_HOME%/webapps/cas/WEB-INF/lib 目录。对于其他数据库，同样将相应数据库驱动程序拷贝到该目录。</li>
    <li>
    DataStore 依赖于 commons-collections-3.2.jar, commons-dbcp-1.2.1.jar,
    commons-pool-1.3.jar，需要到 apache 网站的 Commons 项目下载以上 3 个包放进
    %CATALINA_HOME%/webapps/cas/WEB-INF/lib 目录。</li>
</ul>
<p><a name="N101B0"><span>扩展 CAS Server
界面</span></a></p>
<p>CAS 提供了 2 套默认的页面，分别为&#8220; default &#8221;和&#8220; simple &#8221;，分别在目录&#8220;
cas/WEB-INF/view/jsp/default &#8221;和&#8220; cas/WEB-INF/view/jsp/simple &#8221;下。其中
default 是一个稍微复杂一些的页面，使用 CSS，而 simple 则是能让 CAS 正常工作的最简化的页面。</p>
<p>在部署 CAS 之前，我们可能需要定制一套新的 CAS Server
页面，添加一些个性化的内容。最简单的方法就是拷贝一份 default 或 simple 文件到&#8220; cas/WEB-INF/view/jsp
&#8221;目录下，比如命名为 newUI，接下来是实现和修改必要的页面，有 4 个页面是必须的：</p>
<ul>
    <li>
    casConfirmView.jsp: 当用户选择了&#8220; warn &#8221;时会看到的确认界面</li>
    <li>
    casGenericSuccess.jsp: 在用户成功通过认证而没有目的Service时会看到的界面</li>
    <li>
    casLoginView.jsp: 当需要用户提供认证信息时会出现的界面</li>
    <li>
    casLogoutView.jsp: 当用户结束 CAS 单点登录系统会话时出现的界面</li>
</ul>
<p>CAS 的页面采用 Spring 框架编写，对于不熟悉 Spring 的使用者，在修改之前需要熟悉该框架。</p>
<p>页面定制完过后，还需要做一些配置从而让 CAS 找到新的页面，拷贝&#8220;
cas/WEB-INF/classes/default_views.properties &#8221;，重命名为&#8220;
cas/WEB-INF/classes/ newUI_views.properties &#8221;，并修改其中所有的值到相应新页面。最后是更新&#8220;
cas/WEB-INF/cas-servlet.xml &#8221;文件中的 viewResolver，将其修改为如清单 9 中的内容。</p>
<br />
<a name="N101D4"><strong>清单 9. 指定 CAS 页面</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            &lt;bean id="viewResolver" <br />
            class="org.springframework.web.servlet.view.ResourceBundleViewResolver" p:order="0"&gt;<br />
            &lt;property name="basenames"&gt;<br />
            &lt;list&gt;<br />
            &lt;value&gt;${cas.viewResolver.basename}&lt;/value&gt;<br />
            &lt;value&gt; newUI_views&lt;/value&gt;<br />
            &lt;/list&gt;<br />
            &lt;/property&gt;<br />
            &lt;/bean&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="4.部署客户端应用">部署客户端应用</a></p>
<p>单点登录的目的是为了让多个相关联的应用使用相同的登录过程，本文在讲解过程中构造 2个简单的应用，分别以
casTest1 和 casTest2 来作为示例，它们均只有一个页面，显示欢迎信息和当前登录用户名。这 2
个应用使用同一套登录信息，并且只有登录过的用户才能访问，通过本文的配置，实现单点登录，即只需登录一次就可以访问这两个应用。</p>
<p><a name="N101E4"><span>与 CAS Server
建立信任关系</span></a></p>
<p>假设 CAS Server 单独部署在一台机器 A，而客户端应用部署在机器 B 上，由于客户端应用与 CAS
Server 的通信采用 SSL，因此，需要在 A 与 B 的 JRE 之间建立信任关系。</p>
<p>首先与 A 机器一样，要生成 B 机器上的证书，配置 Tomcat 的 SSL 协议。其次，下载<a href="http://blogs.sun.com/andreas/entry/no_more_unable_to_find">http://blogs.sun.com/andreas/entry/no_more_unable_to_find</a>
的 InstallCert.java，运行&#8220; java InstallCert compA:8443 &#8221;命令，并且在接下来出现的询问中输入
1。这样，就将 A 添加到了 B 的 trust store 中。如果多个客户端应用分别部署在不同机器上，那么每个机器都需要与 CAS
Server 所在机器建立信任关系。</p>
<p><a name="N101F4">配置 CAS Filter</a></p>
<p>准备好应用 casTest1 和 casTest2 过后，分别部署在 B 和 C 机器上，由于 casTest1
和casTest2，B 和 C 完全等同，我们以 casTest1 在 B 机器上的配置做介绍，假设 A 和 B 的域名分别为 domainA 和
domainB。</p>
<p>将 cas-client-java-2.1.1.zip 改名为 cas-client-java-2.1.1.jar
并拷贝到 casTest1/WEB-INF/lib目录下，修改 web.xml 文件，添加 CAS Filter，如清单 10 所示：</p>
<br />
<a name="N10203"><strong>清单 10. 添加 CAS Filter</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            &lt;web-app&gt;<br />
            ...<br />
            &lt;filter&gt;<br />
            &lt;filter-name&gt;CAS Filter&lt;/filter-name&gt;<br />
            &lt;filter-class&gt;edu.yale.its.tp.cas.client.filter.CASFilter&lt;/filter-class&gt;<br />
            &lt;init-param&gt;<br />
            &lt;param-name&gt;edu.yale.its.tp.cas.client.filter.loginUrl&lt;/param-name&gt;<br />
            &lt;param-value&gt;https://domainA:8443/cas/login&lt;/param-value&gt;<br />
            &lt;/init-param&gt;<br />
            &lt;init-param&gt;<br />
            &lt;param-name&gt;edu.yale.its.tp.cas.client.filter.validateUrl&lt;/param-name&gt;<br />
            &lt;param-value&gt;https://domainA:8443/cas/serviceValidate&lt;/param-value&gt;<br />
            &lt;/init-param&gt;<br />
            &lt;init-param&gt;<br />
            &lt;param-name&gt;edu.yale.its.tp.cas.client.filter.serverName&lt;/param-name&gt;<br />
            &lt;param-value&gt;domainB:8080&lt;/param-value&gt;<br />
            &lt;/init-param&gt;<br />
            &lt;/filter&gt;<br />
            &lt;filter-mapping&gt;<br />
            &lt;filter-name&gt;CAS Filter&lt;/filter-name&gt;<br />
            &lt;url-pattern&gt;/protected-pattern/*&lt;/url-pattern&gt;<br />
            &lt;/filter-mapping&gt;<br />
            ...<br />
            &lt;/web-app&gt;<br />
            <br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>对于所有访问满足 casTest1/protected-pattern/ 路径的资源时，都要求到 CAS
Server 登录，如果需要整个 casTest1 均受保护，可以将 url-pattern 指定为&#8220;/*&#8221;。</p>
<p>从清单 10 可以看到，我们可以为 CASFilter 指定一些参数，并且有些是必须的，<a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#_Ref188033615">表
格 1</a> 和<a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#_Ref188033632">表
格 2</a> 中分别是必需和可选的参数：</p>
<br />
<a name="表格1|table"><strong>表格 1. CASFilter 必需的参数</strong></a><br />
<table border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            <strong>参数名</strong>
            </td>
            <td style="text-align: left; vertical-align: top;">
            <strong>作用</strong>
            </td>
        </tr>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            edu.yale.its.tp.cas.client.filter.loginUrl
            </td>
            <td style="text-align: left; vertical-align: top;">
            指定 CAS 提供登录页面的 URL
            </td>
        </tr>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            edu.yale.its.tp.cas.client.filter.validateUrl
            </td>
            <td style="text-align: left; vertical-align: top;">
            指定 CAS 提供 service ticket 或 proxy ticket 验证服务的 URL
            </td>
        </tr>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            edu.yale.its.tp.cas.client.filter.serverName
            </td>
            <td style="text-align: left; vertical-align: top;">
            指定客户端的域名和端口，是指客户端应用所在机器而不是 CAS Server 所在机器，该参数或 serviceUrl 至少有一个必须指定
            </td>
        </tr>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            edu.yale.its.tp.cas.client.filter.serviceUrl
            </td>
            <td style="text-align: left; vertical-align: top;">
            该参数指定过后将覆盖 serverName 参数，成为登录成功过后重定向的目的地址
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<a name="表格2|table"><strong>表格 2. CASFilter 可选参数</strong></a><br />
<table border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            <strong>参数名</strong>
            </td>
            <td style="text-align: left; vertical-align: top;">
            <strong>作用</strong>
            </td>
        </tr>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            edu.yale.its.tp.cas.client.filter.proxyCallbackUrl
            </td>
            <td style="text-align: left; vertical-align: top;">
            用于当前应用需要作为其他服务的代理(proxy)时获取 Proxy Granting Ticket 的地址
            </td>
        </tr>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            edu.yale.its.tp.cas.client.filter.authorizedProxy
            </td>
            <td style="text-align: left; vertical-align: top;">
            用于允许当前应用从代理处获取 proxy tickets，该参数接受以空格分隔开的多个 proxy
            URLs，但实际使用只需要一个成功即可。当指定该参数过后，需要修改 validateUrl 到 proxyValidate，而不再是
            serviceValidate
            </td>
        </tr>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            edu.yale.its.tp.cas.client.filter.renew
            </td>
            <td style="text-align: left; vertical-align: top;">
            如果指定为 true，那么受保护的资源每次被访问时均要求用户重新进行验证，而不管之前是否已经通过
            </td>
        </tr>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            edu.yale.its.tp.cas.client.filter.wrapRequest
            </td>
            <td style="text-align: left; vertical-align: top;">
            如果指定为 true，那么 CASFilter 将重新包装 HttpRequest,并且使 getRemoteUser()
            方法返回当前登录用户的用户名
            </td>
        </tr>
        <tr>
            <td style="text-align: left; vertical-align: top;">
            edu.yale.its.tp.cas.client.filter.gateway
            </td>
            <td style="text-align: left; vertical-align: top;">
            指定 gateway 属性
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="N102BB">传递登录用户名</a></p>
<p>CAS 在登录成功过后，会给浏览器回传 Cookie，设置新的到的 Service
Ticket。但客户端应用拥有各自的 Session，我们要怎么在各个应用中获取当前登录用户的用户名呢？CAS Client 的 Filter
已经做好了处理，在登录成功后，就可以直接从 Session 的属性中获取，如清单 11 所示：</p>
<br />
<a name="N102C7"><strong>清单 11. 在 Java 中通过 Session 获取登录用户名</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            // 以下两者都可以<br />
            session.getAttribute(CASFilter.CAS_FILTER_USER);<br />
            session.getAttribute("edu.yale.its.tp.cas.client.filter.user");<br />
            <br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>在 JSTL 中获取用户名的方法如清单 12 所示：</p>
<br />
<a name="N102D4"><strong>清单 12. 通过 JSTL 获取登录用户名</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            &lt;c:out value="${sessionScope[CAS:'edu.yale.its.tp.cas.client.filter.user']}"/&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>另外，CAS 提供了一个 CASFilterRequestWrapper
类，该类继承自HttpServletRequestWrapper，主要是重写了 getRemoteUser() 方法，只要在前面配置
CASFilter 的时候为其设置&#8220; edu.yale.its.tp.cas.client.filter.wrapRequest &#8221;参数为
true，就可以通过 getRemoteUser（） 方法来获取登录用户名，具体方法如清单 13 所示：</p>
<br />
<a name="N102E1"><strong>清单 13. 通过 CASFilterRequestWrapper
获取登录用户名</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            CASFilterRequestWrapper  reqWrapper=new CASFilterRequestWrapper(request);<br />
            out.println("The logon user:" + reqWrapper.getRemoteUser());<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="5.效果">效果</a></p>
<p>在 casTest1 和 casTest2 中，都有一个简单 Servlet 作为欢迎页面
WelcomPage，且该页面必须登录过后才能访问，页面代码如清单 14 所示：</p>
<br />
<a name="N102F4"><strong>清单 14. WelcomePage 页面代码</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>                <br />
            public class WelcomePage extends HttpServlet {<br />
            public void doGet(HttpServletRequest request, HttpServletResponse response)<br />
            throws IOException, ServletException<br />
            {<br />
            response.setContentType("text/html");<br />
            PrintWriter out = response.getWriter();<br />
            out.println("&lt;html&gt;");<br />
            out.println("&lt;head&gt;");<br />
            out.println("&lt;title&gt;Welcome to casTest2 sample System!&lt;/title&gt;");<br />
            out.println("&lt;/head&gt;");<br />
            out.println("&lt;body&gt;");<br />
            out.println("&lt;h1&gt;Welcome to casTest1 sample System!&lt;/h1&gt;");<br />
            CASFilterRequestWrapper  reqWrapper=new CASFilterRequestWrapper(request);<br />
            out.println("&lt;p&gt;The logon user:" + reqWrapper.getRemoteUser() + "&lt;/p&gt;");<br />
            HttpSession session=request.getSession();<br />
            out.println("&lt;p&gt;The logon user:" + <br />
            session.getAttribute(CASFilter.CAS_FILTER_USER)  + "&lt;/p&gt;");<br />
            out.println("&lt;p&gt;The logon user:" + <br />
            session.getAttribute("edu.yale.its.tp.cas.client.filter.user") + "&lt;/p&gt;");<br />
            out.println("&lt;/body&gt;");<br />
            out.println("&lt;/html&gt;");<br />
            }<br />
            }<br />
            <br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>在上面所有配置结束过后，分别在 A， B， C上启动 cas， casTest1 和
casTest2，按照下面步骤来访问 casTest1 和 casTest2：</p>
<ol type="1">
    <li>
    打开浏览器，访问 <a href="http://domainb:8080/casTest1/WelcomePage">http://domainB:8080/casTest1/WelcomePage</a>
    ，浏览器会弹出安全提示，接受后即转到 CAS 的登录页面，如图 2 所示：</li>
</ol>
<br />
<a name="_Ref188554660"><strong>图 2. CAS 登录页面</strong></a><br />
<img alt="CAS 登录页面" src="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/images/image002.jpg" width="553" height="351" />
<br />
<ol type="1">
    <li>
    登录成功后，再重定向到 casTest1 的 WelcomePage 页面，如<a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#_Ref188552289">图
    </a> 所示：</li>
</ol>
<br />
<a name="_Ref188552289"><strong>图 3. 登录后访问 casTest1 的效果</strong></a><br />
<img alt="登录后访问 casTest1 的效果" src="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/images/image003.jpg" width="554" height="315" />
<br />
<p>可以看到<a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#_Ref188552289">图
</a> 中地址栏里的地址多出了一个 ticket 参数，这就是 CAS 分配给当前应用的 ST(Service Ticket)。</p>
<ol type="1">
    <li>
    再在同一个浏览器的地址栏中输入 <a href="http://domainb:8080/casTest1/WelcomePage">http://domainC:8080/casTest2/WelcomePage</a>
    ，系统不再提示用户登录，而直接出现如图 4 所示的页面，并且显示在 casTest1 中已经登录过的用户。</li>
</ol>
<br />
<a name="N1034A"><strong>图 4. 在 casTest1 中登录过后访问 casTest2
的效果</strong></a><br />
<img alt="在 casTest1 中登录过后访问 casTest2 的效果" src="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/images/image004.jpg" width="553" height="307" />
<br />
<ol type="1">
    <li>
    重新打开一个浏览器窗口，先输入 <a href="http://domainb:8080/casTest1/WelcomePage">http://domainC:8080/casTest2/WelcomePage</a>
    ，系统要求登录，在登录成功过后，正确显示 casTest2 的页面。之后再在地址栏重新输入 <a href="http://domainb:8080/casTest1/WelcomePage">http://domainB:8080/casTest1/WelcomePage</a>
    ，会直接显示 casTest1 的页面而无需再次登录。</li>
</ol>
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="6.结束语">结束语</a></p>
<p>本文介绍了 CAS 单点登录解决方案的原理，并结合实例讲解了在 Tomcat 中使用 CAS
的配置、部署方法以及效果。CAS 是作为开源单点登录解决方案的一个不错选择，更多的使用细节可以参考 CAS 官方网站。</p>
<br />
<br />
<p><a name="resources">参考资料 </a></p>
<ul>
    <li>
    有关 CAS 方面的信息， 请参考<a href="http://www.ja-sig.org/products/cas">CAS 官方网站</a>。
    <br />
    <br />
    </li>
    <li>
    浏览<a href="http://www.ja-sig.org/facebook/">JA-SIG 社区</a>，与社区分享 Java 技术。
    </li>
</ul>
<br />
<br />
<p><a name="author">作者简介</a></p>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td colspan="3"><img alt="" src="http://www.ibm.com/i/c.gif" width="100%" height="5" /></td>
        </tr>
        <tr valign="top" align="left">
            <td><br />
            </td>
            <td><img alt="" src="http://www.ibm.com/i/c.gif" width="4" height="5" /></td>
            <td width="100%">
            <p>张涛，IBM 中国软件开发实验室工程师，目前主要致力于基于 Rational 平台解决方案的开发。</p>
            </td>
        </tr>
    </tbody>
</table>
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td colspan="3"><img alt="" src="http://www.ibm.com/i/c.gif" width="100%" height="5" /></td>
        </tr>
        <tr valign="top" align="left">
            <td><br />
            </td>
            <td><img alt="" src="http://www.ibm.com/i/c.gif" width="4" height="5" /></td>
            <td width="100%">
            <p>王秉坤，IBM 中国软件开发实验室工程师，目前主要致力于基于 Rational 平台解决方案的开发。</p>
            </td>
        </tr>
    </tbody>
</table>
<br />
</span>
<img src ="http://www.blogjava.net/1504/aggbug/219699.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/1504/" target="_blank">weesun一米阳光</a> 2008-08-03 15:19 <a href="http://www.blogjava.net/1504/archive/2008/08/03/219699.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>中国电信设备采购评分系统</title><link>http://www.blogjava.net/1504/archive/2008/07/17/215528.html</link><dc:creator>weesun一米阳光</dc:creator><author>weesun一米阳光</author><pubDate>Thu, 17 Jul 2008 08:21:00 GMT</pubDate><guid>http://www.blogjava.net/1504/archive/2008/07/17/215528.html</guid><wfw:comment>http://www.blogjava.net/1504/comments/215528.html</wfw:comment><comments>http://www.blogjava.net/1504/archive/2008/07/17/215528.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/1504/comments/commentRss/215528.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/1504/services/trackbacks/215528.html</trackback:ping><description><![CDATA[&nbsp;
将项目截几张图，作为自己成长的见证！<br />
go go!<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/1504/gdtel.jpg" width="702" height="319" /><br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/1504/gdtel1_1.jpg" width="702" height="417" /><br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/1504/gdtel2.jpg" width="706" height="432" /><br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/1504/gdtel4.jpg" width="707" height="392" /><br />
<br />
<br />
<br />
<br />
<span style="color: #0010ff;"><span style="font-size: 10pt;">后记：<br />
中国电信设备采购评分系统是中国电信集团公司在奥运前的一个重要项目，也算是咱为奥运做贡献吧！自己亲身经历了项目开始到技术的每一个忙碌的日日夜夜，项目后期，汶川大地震发生，5月12日当时正在18楼开会，讨论项目相关的事情，至今记忆深刻。<br />
突然接到北京的朋友发来的短信说地震了，问我有没有感觉到，说实话，当时并没有感觉到，后来看报纸说广州30层以上才有觉察，本以为是虚惊一场，没有想到
顷刻间无数生命逝去。<br />
一小时后，网上全是关于汶川大地震的报道，才知道出大事了。赶紧打给在成都和西安的朋友，却一个都没有打通，都是不在服务区，自己从心底里印证这可能是一
场我们都没有想到的巨大的灾难性地震。<br />
晚上会到家，打开电视，印证了猜测的正确性。<br />
之后电视，网络全是关于汶川地震的报道，和全国人民聚全国之力赈灾的事情，真想去灾区救灾的冲动。<br />
5月15日早上6点爬起来，跟同事一起去体育中心献血，排了半个多小时的队伍，被告在血库已经满了，我们只能先登记，留下联系方式，待缺乏时通知。很遗
憾，没有能尽上一点微薄的力量，但是还是很高兴，因为明白，全民都在尽力！<br />
5月15日下午，捐了100块，公司的所有同事都捐了，并且都是自愿的，能力有限，尽一份能尽的力量吧！<br />
5月19日，全国哀悼日，我们也暂时停下项目工作，公司全体同事一起气力默哀，整个城市沉浸在汽笛马达响起的哀思中。<br />
愿死者安息，生者更加坚强!<br />
这是我毕业一年之际经历的项目，工作了一年，在公司结识好多朋友，大家周末一起打篮球，一起玩，学到了很多东西，为人处事，也从刚毕业的毛头小子逐渐的长
大。<br />
都说小公司学做事，大公司学做人，目前还没有进过大公司，没有发言权，但是在自己的公司，却是过的很开心，也很充实，我想公司的大与小都不最重要，重要的
是你能学到什么，你能做什么，你可以做到什么。<br />
我有自己的理想，我也有自己的目标，感谢这一年里朋友们和同事们的帮助，我会努力的，加油！<br />
我深爱我的公司！这是我的一个家</span></span>！
<img src ="http://www.blogjava.net/1504/aggbug/215528.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/1504/" target="_blank">weesun一米阳光</a> 2008-07-17 16:21 <a href="http://www.blogjava.net/1504/archive/2008/07/17/215528.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>