??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产一成人久久精品,亚洲一本到无码av中文字幕 ,久久久久亚洲AV无码专区体验http://m.tkk7.com/snowolf/articles/40856.htmlsnowolfsnowolfThu, 13 Apr 2006 04:28:00 GMThttp://m.tkk7.com/snowolf/articles/40856.htmlhttp://m.tkk7.com/snowolf/comments/40856.htmlhttp://m.tkk7.com/snowolf/articles/40856.html#Feedback0http://m.tkk7.com/snowolf/comments/commentRss/40856.htmlhttp://m.tkk7.com/snowolf/services/trackbacks/40856.html displayTag学习摘要
qiqijava



1.tableTag中name属性:值默认作用域Qrequest
<display:table name="accList">
如果作用域ؓsessionQ则<display:table name="sessionScope.accList">
tableTag中指定ID属性会把该对象加入到pageContext对象中去。如ID="test"
<%int cate=((Role)pageContext.getAttribute("test")).getCategory();%>
生成表格的序列号 例如Q?lt;display:table id="row" name="mylist">
<display:column title="序列?><%=pageContext.getAttribute("row_rowNum")%></display:column>
如行Prow_rowNum <c:out value="${row_rowNum}"/>
firstName:row.firstName   <c:out value="${row.firstName}"/>
lastName: row.lastName  全部由ID来取?br />
2.限制面昄的结果集?/b>
1)全部<display:table name="accList" class="its" id="test">
2)??lt;display:table name="accList" class="its" id="test" length="5">
3)从第二个开始,昄??lt;display:table name="accList" class="its" id="test" offset="2" length="5">

3.包装器decorators,有行包装?必须l承TableDecorator)和列包装?必须实现ColumnDecorator)
  在tableTag中显ClistӞdecorators中的Ҏ会在list前调用,如果decorators实现cM有相关的getXXX()ҎӞ调用此方法,如果没有Q则直接调用list
  在columnTag中显CvalueӞdecorators中的Ҏ会先调用Q?应该重用)

4.传递参敎ͼ有两U方式,
  一。struts方式Q有以下几个属?br />  1)href 基本的超q接
  2)paramId d到url上的参数?br />  <display:column property="status" href="details.jsp" paramId="id" paramProperty="id" />
  3)paramName 传递容器内的其它bean当作参数 如:request.setAttribute("testparam", "sendamail");
  <display:column property="email" href="details.jsp" paramId="action" paramName="testparam" paramScope="request" />
  4)paramScope 指定bean的作用域
  二。decorators方式
  cWrapperҎQ?br />
public String getLink1()
        {
                ListObject lObject= (ListObject)getCurrentRowObject();
                int lIndex= getListIndex();
                return "<a href=\"details.jsp?index=" + lIndex + "\">" + lObject.getId() + "</a>";
        }


标签Q?br />
<display:table name="sessionScope.details" decorator="org.displaytag.sample.Wrapper" >
  <display:column property="link1" title="ID" />
  <display:column property="email" />
</display:table>


5.分页
  指定属?pagesize="10" 每页昄10条记?br />
6.排序
1)在list中封装的对象的属性要实现Comparable接口,(一般均实现?
2) 在columnTag中指定sortable="true"
  可指定默认排序的?defaultsort="1" 数gؓW几列默认排?defaultorder="descending" 指定默认为降?br />
7.导出 支持下列格式Q?html', 'xml', 'csv', and 'excel'.
  属性:export="true",注意导出无效Q当使用jsp:include or the RequestDispatcher
  <display:column media="csv excel" title="URL" property="url"/>
  指定该url属性值只能在csv、excel中导?br />  需要指定export filter.

8.更改默认讄
  1)通过<display:setProperty name=... value=...> 标签Q可以覆盖一些默认设|?br />  2)创徏displaytag.properties文gQ所有时区共用,Z文编码则创徏displaytag_zh_cn.propertiesQ放到类路径?jar包内共有两个默认的属性文件TableTag.propertiesQmessage.properties

9其它
  1)当多个表在一|C时Q每个表都想要有分页、排序、导出等功能Ӟ只需为每个table指定一个不同的ID卛_?br />  2)增加表头<display:caption>角色理</display:caption>
  3)增加表尾  <display:footer><tr><td colspan="6" align="center" >国瑞数码版权所?lt;/td></tr></display:footer>
  4)http和email自动链接功能Q指定autolink="true"
  5)指定一列显C的最大长度,避免太长把表格变?maxLength="10" style="whitespace: nowrap;"
  6)当列的gؓnullQ用nulls="false"属性把null转ؓI白

snowolf 2006-04-13 12:28 发表评论
]]>
DisplayTag应用指南 http://m.tkk7.com/snowolf/articles/40855.htmlsnowolfsnowolfThu, 13 Apr 2006 04:27:00 GMThttp://m.tkk7.com/snowolf/articles/40855.htmlhttp://m.tkk7.com/snowolf/comments/40855.htmlhttp://m.tkk7.com/snowolf/articles/40855.html#Feedback0http://m.tkk7.com/snowolf/comments/commentRss/40855.htmlhttp://m.tkk7.com/snowolf/services/trackbacks/40855.html  
  一、最单的情况Q未使用<display:column/>标签
  
  <%request.setAttribute( "test", new ReportList(6) );%>
  <display:table name="test" />
  
  标签遍历List里的每一个对象,q将对象里的所有属性显C出来。一般用于开发的时候检查对象数据的完整性?br />  
  二、?lt;display:column/>标签的情?/b>
  
  <display:table name="test">
  <display:column property="id" title="ID" />
  <display:column property="name" />
  <display:column property="email" />
  <display:column property="status" />
  <display:column property="description" title="Comments"/>
  </display:table>
  
  property对应List里对象的属性(用getXXX()Ҏ取得Q,title则对应表D头里的列名。定义列有两U方式:
  
  A?lt;display:column property="email" />
  
  使用<display:column/>标签里的property属性来定义
  
  B?lt;display:column title="email">email@it.com</display:column>
  
  ?lt;display:column/>标签体里增加内容Q可以是帔RQ也可以用其他标{{?br />  
  两种方式比较Q用property属性来定义更加快速和利于排序?br />  
  三、表格显C样式的定义
  
  A、在<display:table/>?lt;display:column/>标签里指定标准的html属性,烦琐
  
  B、修Ҏ式表
  <display:table name="test" class="mars">
  <display:column property="id" title="ID" class="idcol"/>
  <display:column property="name" />
  <display:column property="email" />
  <display:column property="status" class="tableCellError" />
  <display:column property="description" title="Comments"/>
  </display:table>
  
  通过class属性来指定所要应用的样式。可以在光认样式表里(./css/screen.cssQ直接修?br />  
  四、标{֏得数据的数据?/b>
  
  有四U范?br />  
  pageScope
  requestScope (默认) <display:table name="test2" >
  sessionScope <display:table name="sessionScope.holder.list" > 注意Q这里要指定范围Q非默认
  applicationScope
  
  五、通过增加id属性创建隐含的对象
  
  <display:table name="test" id="testit">
  <display:column property="id" title="ID" />
  <display:column property="name" />
  <display:column title="static value">static</display:column>
  <display:column title="row number (testit_rowNum)"><%=pageContext.getAttribute("testit_rowNum")%></display:column>
  <display:column title="((ListObject)testit).getMoney()"><%=((ListObject)pageContext.getAttribute("testit")).getMoney()%></display:column>
  </display:table>
  
  注意到在<display:table/>里增加了id属性,q时在page context里创Z一个隐含对象,指向List里的当前对象Q?br />  
  可以通过(ListObject)pageContext.getAttribute("id")来捕莯个对象。同时还创徏了一个id_rowNum对象Q同P?br />  
  通过pageContext.getAttribute("testit_rowNum")来捕P它仅仅代表当前行的行数?br />  
  有了q两个隐含对象,可以通过其他标签来访问,例如Jstl:
  
  <display:table id="row" name="mylist">
  <display:column title="row number" >
  <c:out value="${row_rowNum}"/>
  </display:column>
  <display:column title="name" >
  <c:out value="${row.first_name}"/>
  <c:out value="${row.last_name}"/>
  </display:column>
  </display:table>
  
  六、显C部分数?/b>
  
  昄开始五条数据:通过讑֮length属?br />  
  <display:table name="test" length="5">
  <display:column property="id" title="ID" />
  <display:column property="email" />
  <display:column property="status" />
  </display:table>
  
  昄W三到第八条数据Q通过讑֮offset和length属?br />  
  <display:table name="test" offset="3" length="5">
  <display:column property="id" title="ID" />
  <display:column property="email" />
  <display:column property="status" />
  </display:table>
  
  七、对email和url地址的直接连?/b>
  
  <display:table name="test" >
  <display:column property="id" title="ID" />
  <display:column property="email" autolink="true" />
  <display:column property="url" autolink="true" />
  </display:table>
  
  如果要显C的对象里包含email和url地址Q则可以在display:column里直接设定autolink="true"来直接连?br />  
  八、用装饰模式{换数据显C(写自q decorator Q?/b>
  
  A、对整个表格应用decorator
  
  <display:table name="test" decorator="org.displaytag.sample.Wrapper" >
  <display:column property="id" title="ID" />
  <display:column property="email" />
  <display:column property="status" />
  <display:column property="date" />
  <display:column property="money" />
  </display:table>
  org.displaytag.sample.Wrapper卌己写的decoratorQ它要承TableDecoratorc,看看它的一个方法:
  public String getMoney()
  {
  return this.moneyFormat.format(((ListObject) this.getCurrentRowObject()).getMoney());
  }
  
  很明显,它通过父类的getCurrentRowObject()Ҏ获得当前对象Q然后对其getMoney()Ҏq行‘a漆?br />  
  B、对单独的column应用decorator
  
  <display:table name="test">
  <display:column property="id" title="ID" />
  <display:column property="email" />
  <display:column property="status" />
  <display:column property="date" decorator="org.displaytag.sample.LongDateWrapper" />
  </display:table>
  org.displaytag.sample.LongDateWrapper要实现ColumnDecorator接口Q它的方法:
  public final String decorate(Object columnValue)
  {
  Date date = (Date) columnValue;
  return this.dateFormat.format(date);
  }
  
  昄Q它获得不了当前对象Q因为它实现的是接口Q,仅仅是获得该对象的columnValueQ然后‘a漆?br />  
  九、创建动态连?/b>
  
  有两U方法创建动态连接:
  
  A、在<display:column/>里通过增加href、paramId、paramName、paramScope、paramProperty属?br />  
  href       基本的URL 地址
  paramId     加在URL 地址后的参数名称
  paramName    数据bean的名Uͼ一般ؓnullQ即使用当前List里的对象Q?br />  paramScope    数据bean的范_一般ؓnull
  paramProperty  数据bean的属性名Uͼ用来填充URL 地址后的参数?br />  <display:table name="sessionScope.details">
  <display:column property="id" title="ID" href="details.jsp" paramId="id" />
  <display:column property="email" href="details.jsp" paramId="action" paramName="testparam" paramScope="request" />
  <display:column property="status" href="details.jsp" paramId="id" paramProperty="id" />
  </display:table>
  
  q种Ҏ便直接,但缺Ҏ无法产生cMdetails.jsp?id=xx&action=xx的复合URL
  
  B、应用decorator 创徏动态连接:
  
  <display:table name="sessionScope.details" decorator="org.displaytag.sample.Wrapper" >
  <display:column property="link1" title="ID" />
  <display:column property="email" />
  <display:column property="link2" title="Actions" />
  </display:table>
  org.displaytag.sample.Wrapper里的ҎQ?br />  public String getLink1()
  {
  ListObject lObject= (ListObject)getCurrentRowObject();
  int lIndex= getListIndex();
  return "<a href=\"details.jsp?index=" + lIndex + "\">" + lObject.getId() + "</a>";
  }
  
  public String getLink2()
  {
  ListObject lObject= (ListObject)getCurrentRowObject();
  int lId= lObject.getId();
  
  return "<a href=\"details.jsp?id=" + lId
  + "&action=view\">View</a> | "
  + "<a href=\"details.jsp?id=" + lId
  + "&action=edit\">Edit</a> | "
  + "<a href=\"details.jsp?id=" + lId
  + "&action=delete\">Delete</a>";
  }
  
  十、分?/b>
  
  实现分页非常的简单,增加一个pagesize属性指定一ơ想昄的行数即?br />  
  <display:table name="sessionScope.test" pagesize="10">
  <display:column property="id" title="ID" />
  <display:column property="name" />
  <display:column property="email" />
  <display:column property="status" />
  </display:table>
  
  十一、排?/b>
  
  排序实现也是很简单,在需要排序的column里增加sortable="true"属性,headerClass="sortable"仅仅?br />  
  指定昄的样式。column里的属性对象要实现Comparable接口Q如果没有的话可以应用decorator
  
  defaultsort="1"       默认W一个column排序
  defaultorder="descending"  默认递减排序
  <display:table name="sessionScope.stest" defaultsort="1" defaultorder="descending">
  <display:column property="id" title="ID" sortable="true" headerClass="sortable" />
  <display:column property="name" sortable="true" headerClass="sortable"/>
  <display:column property="email" />
  <display:column property="status" sortable="true" headerClass="sortable"/>
  </display:table>
  
  注意的是Q当同时存在分页时排序仅仅针对的是当前页面,而不是整个List都进行排?br />  
  十二、column 分组
  
  分组只是需要在column里增加group属?br />  
  <display:table name="test" class="simple">
  <display:column property="city" title="CITY" group="1"/>
  <display:column property="project" title="PROJECT" group="2"/>
  <display:column property="amount" title="HOURS"/>
  <display:column property="task" title="TASK"/>
  </display:table>
  
  十三、导出数据到其他格式Q页面溢出filter??Q?/b>
  
  ?lt;display:table/>里设定export="true"
  
  ?lt;display:column/>里设定media="csv excel xml pdf" 军_该字D在导出到其他格式时被包不包含,不设定则都包?br />  
  <display:setProperty name="export.csv" value="false" />
  
  军_该种格式能不能在面中导?br />  
  <display:table name="test" export="true" id="currentRowObject">
  <display:column property="id" title="ID"/>
  <display:column property="email" />
  <display:column property="status" />
  <display:column property="longDescription" media="csv excel xml pdf" title="Not On HTML"/>
  <display:column media="csv excel" title="URL" property="url"/>
  <display:setProperty name="export.pdf" value="true" />
  <display:setProperty name="export.csv" value="false" />
  </display:table>
  
  十四、配|属性,覆盖默认
  
  两种ҎQ?br />  
  A、在E序classpath下新建displaytag.properties文g
  
  B、对于单个表|应用<display:setProperty>标签
  
  具体可配|的属性:http://displaytag.sourceforge.net/configuration.html
  
  十五、一个完整的例子
  
  <display:table name="test" export="true" sort="list" pagesize="8">
  <display:column property="city" title="CITY" group="1" sortable="true" headerClass="sortable"/>
  <display:column property="project" title="PROJECT" group="2" sortable="true" headerClass="sortable"/>
  <display:column property="amount" title="HOURS"/>
  <display:column property="task" title="TASK"/>
  </display:table>
  
  sort="list" Ҏ个listq行排序
  
  导出数据到其他格式时Qgroup无效

snowolf 2006-04-13 12:27 发表评论
]]>
利用HttpSessionListener实现|站在线人数l计功能http://m.tkk7.com/snowolf/articles/32293.htmlsnowolfsnowolfFri, 24 Feb 2006 06:51:00 GMThttp://m.tkk7.com/snowolf/articles/32293.htmlhttp://m.tkk7.com/snowolf/comments/32293.htmlhttp://m.tkk7.com/snowolf/articles/32293.html#Feedback0http://m.tkk7.com/snowolf/comments/commentRss/32293.htmlhttp://m.tkk7.com/snowolf/services/trackbacks/32293.html  我们可以利用Servlet规范中定义的事g监听器(ListenerQ来解决q个问题Q实现更准确的在Uh数统计功能。对每一个正在访问的用户QJ2EE应用服务器会为其建立一个对应的HttpSession对象。当一个浏览器W一ơ访问网站的时候,J2EE应用服务器会新徏一个HttpSession对象Qƈ触发HttpSession创徏事gQ如果注册了HttpSessionListener事g监听器,则会调用HttpSessionListener事g监听器的sessionCreatedҎ。相反,当这个浏览器讉Kl束时的时候,J2EE应用服务器会销毁相应的HttpSession对象Q触发HttpSession销毁事Ӟ同时调用所注册HttpSessionListener事g监听器的sessionDestroyedҎ?BR>  可见Q对应于一个用戯问的开始和l束Q相应的有sessionCreatedҎ和sessionDestroyedҎ执行。这P我们只需要在HttpSessionListener实现cȝsessionCreatedҎ中让计数器加1Q在sessionDestroyedҎ中让计数器减1Q就L实现了网站在Uh数的l计功能?BR>  下面是利用HttpSessionListener实现在线人数l计的一个例子,q个例子已经在中创Y件的J2EE应用服务器InforWeb中测试通过?BR>  首先Q编写一个简单的计数器,代码如下Q?BR>
  1. package gongfei.cmc.articles.onlinecounter;
  2. public class OnlineCounter {
  3.     private static long online = 0;    
  4.     public static long getOnline() {
  5.         return online;
  6.     }    
  7.     public static void raise(){
  8.         online++;
  9.     } 
  10.     public static void reduce(){
  11.         online--;
  12.    }
  13. }

  然后Q编写HttpSessionListener实现c,在这个实现类的sessionCreatedҎ中调用OnlineCounter的raiseҎQ在sessionDestroyedҎ中调用OnlineCounter的reduceҎQ代码如下:
  1. package gongfei.cmc.articles.onlinecounter;
  2. import javax.servlet.http.HttpSessionEvent;
  3. import javax.servlet.http.HttpSessionListener;
  4. public class OnlineCounterListener implements HttpSessionListener {
  5.     public void sessionCreated(HttpSessionEvent hse) {
  6.         OnlineCounter.raise();
  7.     }
  8.     public void sessionDestroyed(HttpSessionEvent hse) {
  9.         OnlineCounter.reduce();
  10.     }
  11. }

  再然后,把这个HttpSessionListener实现cL册到|站应用中,也就是在|站应用的web.xml中加入如下内容:
  1. <web-app>
  2.     …?
  3.     <listener>
  4.         <listener-class>
  5.             gongfei.cmc.articles.example.OnlineCounterListener
  6.         </listener-class>
  7.     </listener>
  8.     …?
  9. </web-app>

  OKQ在Uh数统计功能已l实玎ͼ只要在JSP面中加入下面这L脚本p昄但前在线人数了:
  1. <%@ page language="java" pageEncoding="GB2312" %>
  2. <%@ page import="gongfei.cmc.articles.onlinecounter.OnlineCounter" %>
  3. <html>
  4.     <head><title>On Line Counert</title></head>
  5.     <body bgcolor="#FFFFFF">
  6.         On line:<%=OnlineCounter.getOnline()%>
  7.     </body>
  8. </html>





snowolf 2006-02-24 14:51 发表评论
]]>
JSP里request变量列表http://m.tkk7.com/snowolf/articles/31953.htmlsnowolfsnowolfWed, 22 Feb 2006 05:17:00 GMThttp://m.tkk7.com/snowolf/articles/31953.htmlhttp://m.tkk7.com/snowolf/comments/31953.htmlhttp://m.tkk7.com/snowolf/articles/31953.html#Feedback1http://m.tkk7.com/snowolf/comments/commentRss/31953.htmlhttp://m.tkk7.com/snowolf/services/trackbacks/31953.htmlout.println("Protocol: " + request.getProtocol() + "<br>");
out.println("Scheme: " + request.getScheme() + "<br>");
out.println("Server Name: " + request.getServerName() + "<br>" );
out.println("Server Port: " + request.getServerPort() + "<br>");
out.println("Protocol: " + request.getProtocol() + "<br>");
out.println("Server Info: " + getServletConfig().getServletContext().getServerInfo() + "<br>");
out.println("Remote Addr: " + request.getRemoteAddr() + "<br>");
out.println("Remote Host: " + request.getRemoteHost() + "<br>");
out.println("Character Encoding: " + request.getCharacterEncoding() + "<br>");
out.println("Content Length: " + request.getContentLength() + "<br>");
out.println("Content Type: "+ request.getContentType() + "<br>");
out.println("Auth Type: " + request.getAuthType() + "<br>");
out.println("HTTP Method: " + request.getMethod() + "<br>");
out.println("Path Info: " + request.getPathInfo() + "<br>");
out.println("Path Trans: " + request.getPathTranslated() + "<br>");
out.println("Query String: " + request.getQueryString() + "<br>");
out.println("Remote User: " + request.getRemoteUser() + "<br>");
out.println("Session Id: " + request.getRequestedSessionId() + "<br>");
out.println("Request URI: " + request.getRequestURI() + "<br>");
out.println("Servlet Path: " + request.getServletPath() + "<br>");
out.println("Accept: " + request.getHeader("Accept") + "<br>");
out.println("Host: " + request.getHeader("Host") + "<br>");      
out.println("Referer : " + request.getHeader("Referer") + "<br>");      
out.println("Accept-Language : " + request.getHeader("Accept-Language") + "<br>");      
out.println("Accept-Encoding : " + request.getHeader("Accept-Encoding") + "<br>");      
out.println("User-Agent : " + request.getHeader("User-Agent") + "<br>");      
out.println("Connection : " + request.getHeader("Connection") + "<br>");      
out.println("Cookie : " + request.getHeader("Cookie") + "<br>");      
out.println("Created : " + session.getCreationTime() + "<br>");      
out.println("LastAccessed : " + session.getLastAccessedTime() + "<br>");      

        
%>

q行l果Q?BR>
Protocol: HTTP/1.1
Scheme: http
Server Name: 192.168.0.1
Server Port: 8080
Protocol: HTTP/1.1
Server Info: JavaServer Web Dev Kit/1.0 EA (JSP 1.0; Servlet 2.1; Java 1.2; Windows NT 5.0 x86; java.vendor=Sun Microsystems Inc.)
Remote Addr: 192.168.0.106
Remote Host: abc
Character Encoding: null
Content Length: -1
Content Type: null
Auth Type: null
HTTP Method: GET
Path Info: null
Path Trans: null
Query String: null
Remote User: null
Session Id: To1010mC466113890241879At
Request URI: /c.jsp
Servlet Path: /c.jsp
Accept: */*
Host: 192.168.0.1:8080
Referer : null
Accept-Language : zh-cn
Accept-Encoding : gzip, deflate
User-Agent : Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)
Connection : Keep-Alive
Cookie : SESSIONID=To1010mC466113890241879At
Created : 965764522168
LastAccessed : 965775587088


snowolf 2006-02-22 13:17 发表评论
]]>
Java Servlet API说明文档http://m.tkk7.com/snowolf/articles/31942.htmlsnowolfsnowolfWed, 22 Feb 2006 05:02:00 GMThttp://m.tkk7.com/snowolf/articles/31942.htmlhttp://m.tkk7.com/snowolf/comments/31942.htmlhttp://m.tkk7.com/snowolf/articles/31942.html#Feedback0http://m.tkk7.com/snowolf/comments/commentRss/31942.htmlhttp://m.tkk7.com/snowolf/services/trackbacks/31942.html译者前aQ?
q来在整理有关Servlet资料时发玎ͼ在网上竟然找不到一份中文的Java Servlet API的说明文档,而在有一本有关JSP的书后面附的Java Servlet API说明竟然不全Q而这份文档的2.1a版在1998q的11月䆾已定稿。所以我军_译一份中文的文档Q其中一些与技术关pM大的部分已被略去Q,有兴的读者可以从http://java.sun.com/products/servlet/2.1/servletspec-2.1.zip下蝲原文阅读?


Java Servlet API说明文档Q?.1a版)
1998q?1?


l言
q是一份关?.1版Java Servlet API的说明文档,作ؓ对这本文档的补充Q你可以到http://java.sun.com/products/servlet/index.html下面下蝲Javadoc格式的文档?

谁需要读q䆾文档
q䆾文档描述了Java Servlet API的最新版?.1版。所以,q本书对于Servlet的开发者及servlet引擎的开发者同样适用?

Java Servlet API的组?
Java Servlet API׃个Y件包l成Q一个是对应HTTP的Y件包Q另一个是不对应HTTP的通用的Y件包。这两个软g包的同时存在使得Java Servlet API能够适应来的其他请?响应的协议?
q䆾文档以及刚才提及的Javadoc格式的文档都描述了这两个软g包,Javadoc格式的文档还描述了你应该如何使用q两个Y件包中的所有方法?

有关规范
你也许对下面的这些Internet规范感兴,q些规范直接媄响到Servlet API的发展和执行。你可以从http://info.internet.isi.edu/7c/in-notes/rfc/.cache 扑ֈ下面提到的所有这些RFC规范?
RFC 1738 l一资源定位?URL)
RFC 1808 相关l一资源定位?
RFC 1945 文本传输协?-HTTP/1.0
RFC 2045 多用途Internet邮g扩展(多用途网际邮件扩充协?MIME))W一部分:Internet信息体格?
RFC 2046 多用途Internet邮g扩展(多用途网际邮件扩充协?MIME))W二部分:媒体cd
RFC 2047 多用途网际邮件扩充协?MIME)(多用途Internet邮g扩展)W三部分:信息标题扩展用于非ASCII文本
RFC 2048 多用途Internet邮g扩展(多用途网际邮件扩充协?MIME))W四部分: 注册步骤
RFC 2049 多用途Internet邮g扩展(多用途网际邮件扩充协?MIME))W五部分:一致性标准和例子
RFC 2068 文本传输协?-- HTTP/1.1
RFC 2069 一个扩展HTTP:摘要讉K鉴定
RFC 2109 HTTP状态管理机?
RFC 2145 HTTP 版本L使用和解?
RFC 2324 文本Coffee Pot控制协议 (HTCPCP/1.0)
万维|协会(http://www.w3.orgQ管理着q些协议的规范和执行?


有关Java Servlets
JavaTM servlets是一个不受^台约束的Java程序,它可以被用来通过多种Ҏ扩充一个Web服务器的功能。你可以把Servlet理解成Server上的appletsQ它被编译成字节码,q样它就可以被动态地载入q用效地扩展L的处理能力?
Servlet与applets不同的地ҎQ它不运行在Web览器或其他囑Ş化的用户界面上。Servlet通过servlet引擎q行在Web服务器中Q以执行h和响应,h、响应的典型范例是HTTP协议?
一个客LE序Q可以是一个Web览器,或者是非其他的可以q接上Internet的程序,它会讉KWeb服务器ƈ发出h。这个请求被q行在Web服务器上的Servlet引擎处理Qƈq回响应到Servlet。Servlet通过HTTP这个响应{发到客户端?
在功能上QServlet与CGI、NSAPI有点cMQ但是,与他们不同的是:Servlethq_无关性?

Java Servlet概论
Servlet与其他普通的server扩展机制有以下进步:
因ؓ它采用了不同的进E处理模式,所以它比CGI更快?
它用了许多Web服务器都支持的标准的API?
它承了Java的所有优势,包括易升U以及^台无x?
它可以调用Java所提供的大量的API的功能模块?
q䆾文档说明了Java Servlet API的类和接口的Ҏ。有x多的信息Q请参看下面的API说明?

Servlet的生命周?
一个Java servleth一个生命周期,q个生命周期定义了一个Servlet如何被蝲入ƈ被初始化Q如何接收请求ƈ作出对请求的响应Q如何被从服务中清除。Servlet的生命周期被javax.servlet.Servletq个接口所定义?
所有的Java Servlet都会直接地或间接地执行javax.servlet.Servlet接口Q这样它才能在一个Servlet引擎中运行。Servlet引擎是Web 服务器按照Java Servlet API定制的扩展。Servlet引擎提供|络服务Q能够理解MIMEhQƈ提供一个运行Servlet的容器?
javax.servlet.Servlet接口定义了在Servlet的生命周期中特定旉以及特定序被调用的Ҏ?

Servlet的解析和载入\r
Servlet引擎解析q蝲入一个ServletQ这个过E可以发生在引擎启动Ӟ需要一个Servletd应请求时Q以及在此之间的M时候?
Servlet引擎利用Javac蝲入工兯入一个ServletQServlet引擎可以从一个本地的文gpȝ、一个远E的文gpȝ以及|络载入Servlet?

Servlet的初始化
Servlet引擎载入Servlet后,Servlet引擎必须对Servletq行初始化,在这一q程中,你可以读取一些固定存储的数据、初始化JDBC的连接以及徏立与其他资源的连接?
在初始化q程中,javax.servlet.Servlet接口的init()Ҏ提供了Servlet的初始化信息。这PServlet可以对自p行配|?
init()Ҏ获得了一个Servlet配置对象QServletConfigQ。这个对象在Servlet引擎中执行,q允许Servlet通过它获处相兛_数。这个对象得Servlet能够讉KServletContext对象?

Servlet处理h\r
Servlet被初始化之后Q它已经可以处理来自客户端的hQ每一个来自客L的请求都被描q成一个ServletRequest对象QServlet的响应被描述成一个ServletResponse对象?
当客L发出hӞServlet引擎传递给Servlet一个ServletRequest对象和一个ServletResponse对象Q这两个对象作ؓ参数传递到service()Ҏ中?
Servlet也可以执行ServletRequest接口和ServletResponse接口。ServletRequest接口使得Servlet有权使用客户端发出的h。Servlet可以通过ServletInputStream对象dh信息?
ServletResponse接口允许Servlet建立响应头和状态代码。通过执行q个接口QServlet有权使用ServletOutputStreamcL向客Lq回数据?

多线E和映射\r
在多U程的环境下QServlet必须能处理许多同时发生的h。例外的情况是这个Servlet执行了SingleThreadModel接口Q如果是那样的话QServlet只能同时处理一个请求?
Servlet依照Servlet引擎的映来响应客户端的h。一个映对包括一个Servlet实例以及一个Servletq回数据的URLQ例如:HelloServlet with /hello/index.html?
然而,一个映可能是׃个URL和许多Servlet实例l成Q例如:一个分布式的Servlet引擎可能q行在不止一个的服务器中Q这L话,每一个服务器中都可能有一个Servlet实例Q以qq程的蝲入。作Z个Servlet的开发者,你不能假定一个Servlet只有一个实例?

Servlet的卸?
Servlet引擎q不必需保证一个Servlet在Q何时候或在服务开启的M时候都被蝲入。Servlet引擎可以自由的在M时候用或清除一个Servlet。因此,我们不能依赖一个类或实例来存储重要的信息?
当Servlet引擎军_卸蝲一个ServletӞ例如Q如果这个引擎被关闭或者需要让资源Q,q个引擎必须允许Servlet释放正在使用的资源ƈ存储有关资料。ؓ了完成以上工作,引擎会调用Servlet的destroy()Ҏ?
在卸载一个Servlet之前QServlet引擎必须{待所有的service()Ҏ完成或超时结束(Servlet引擎会对时作出定义Q。当一个Servlet被卸载时Q引擎将不能lServlet发送Q何请求。引擎必释放Servletq完成无用存储单元的攉

Servlet映射技术\r
作ؓ一个Servlet引擎的开发者,你必d于如何映客L的请求到Servlet有大量的适应性。这份说明文档不规定映射如何发生。但是,你必能够自由地q用下面的所有技术:

映射一个ServletC个URL
例如Q你可以指定一个特D的Servlet它仅被来?feedback/index.html的请求调用?

映射一个ServletC一个指定的目录名开始的所有URL
例如Q你可以映射一个Servlet?catalogQ这h?catalog/?/catalog/garden?catalog/housewares/index.html的请求都会被映射到这个Servlet。但是来?catalogtwo ?catalog.html的请求没被映?

映射一个Servlet到所有以一个特定的字段l尾的所有URL
例如Q你可以映射一个来自于所有以in.thtmll尾的请求到一个特定的Servlet?

映射一个ServletC个特D的URL /servlet/servlet_name?
例如Q如果你建立了一个名叫listattributes的ServletQ你可以通过使用/servlet/listattributes来访问这个Servlet?

通过cd调用Servlet
例如Q如果Servlet引擎接收了来?servlet/com.foo.servlet.MailServlet的请求,Servlet引擎会蝲入这个com.foo.servlet.MailServletc,建立实例Qƈ通过q个Servlet来处理请求?

Servlet环境
ServletContext接口定义了一个Servlet环境对象Q这个对象定义了一个在Servlet引擎上的Servlet的视图。通过使用q个对象QServlet可以记录事g、得到资源ƈ得到来自Servlet引擎的类Q例如RequestDispatcher对象Q。一个Servlet只能q行在一个Servlet环境中,但是不同的Servlet可以在Servlet引擎上有不同的视图?
如果Servlet引擎支持虚拟LQ每个虚拟主机有一个Servlet环境。一个Servlet环境不能在虚拟主Z间共享?
Servlet引擎能够允许一个Servlet环境有它自己的活动范围?
例如Q一个Servlet环境是属于bank应用的,它将被映到/bank目录下。在q种情况下,一个对getContextҎ的调用会q回/bank的Servlet环境?

HTTP会话
HTTP是一个没有状态的协议。要建立一个有效的Web服务应用Q你必须能够识别一个连l的来自q端的客h的唯一的请求。随着旉的过去,发展了许多会话跟t的技术,但是使用h都比较麻烦?
Java Servlet API提供了一个简单的接口Q通过q个接口QServlet引擎可以有效地跟t用L会话?

建立Session
因ؓHTTP是一个请?响应协议Q一个会话在客户机加入之前会被认为是一个新的会话。加入的意思是q回会话跟踪信息到服务器中,指出会话已被建立。在客户端加入之前,我们不能判断下一个客Lh是目前会话的一部分?
在下面的情况下,Session会被认ؓ是新的Session?
客户端的Session在此之前q不知道
客户端选择不加入SessionQ例如,如果客户端拒l接收来自服务器的cookie
作ؓ一个Servlet的开发者,你必d定你的Web应用是否处理客户Z加入或不能加入Session。服务器会在Web服务器或Servlet规定的时间内l持一个Session对象。当Sessionl止Ӟ服务器会释放Session对象以及所有绑定在Session上的对象?
l定对象到Session?
如果有助于你处理应用的数据需求,你也讔R要绑定对象到Session中,你可以通过一个唯一的名字绑定Q何的对象到Session中,q时Q你需要用HttpSession对象。Q何绑定到Session上的对象都可以被处理同一会话的Servlet调用?
有些对象可能需要你知道什么时候会被放|到Session中或从Session中移开。你可以通过使用HttpSessionBindingListener接口获得q些信息。当你的应用存储数据到Session中,或从Session中清除数据,Servlet都会通过HttpSessionBindingListener杳什么类被绑定或被取消绑定。这个接口的Ҏ会通报被绑定或被取消绑定的对象?



API对象的说?BR>q一部分包含了对Java Servlet API的全部类和接口的详细说明。这个说明与Javadoc API差不多,但是q䆾文档提供了更多的信息?
API包含了两个Y件包Q十二个接口和九个类?
软g包:javax.servlet
所包含的接口:RequestDispatcherQServletQServletConfigQServletContextQServletRequestQServletResponseQSingleThreadModel?
所包含的类QGenericServletQServletInputStreamQServletOutputStreamQServletExceptionQUnavailableException?

一、RequestDispatcher接口Q?
定义Q?
public interface RequestDispatcher;
定义一个对象,从客L接收hQ然后将它发l服务器的可用资源(例如Servlet、CGI、HTML文g、JSP文gQ。Servlet引擎创徏request dispatcher对象Q用于封装由一个特定的URL定义的服务器资源?
q个接口是专用于装Servlet的,但是一个Servlet引擎可以创徏request dispatcher对象用于装Mcd的资源?
request dispatcher对象是由Servlet引擎建立的,而不是由Servlet开发者徏立的?
Ҏ
1、forward
public void forward(ServletRequest request, ServletResponse response)
throws ServletException, IOException;
被用来从q个Servlet向其它服务器资源传递请求。当一个Servlet对响应作了初步的处理Qƈ要求其它的对象对此做出响应时Q可以用这个方法?
当request对象被传递到目标对象Ӟh的URL路径和其他\径参C被调整ؓ反映目标对象的目标URL路径?
如果已经通过响应q回了一个ServletOutputStream对象或PrintWriter对象Q这个方法将不能使用Q否则,q个Ҏ会抛Z个IllegalStateException?
2、include
public void include(ServletRequest request, ServletResponse response)
throws ServletException, IOException
用来包括发送给其他服务器资源的响应的内宏V本质上来说Q这个方法反映了服务器端的内宏V?
h对象传到目标对象后会反映调用h的请求URL路径和\径信息。这个响应对象只能调用这个Servlet的ServletOutputStream对象和PrintWriter对象?
一个调用include的Servlet不能讄头域Q如果这个Servlet调用了必设|头域的ҎQ例如cookieQ,q个Ҏ不能保证正怋用。作Z个Servlet开发者,你必d善地解决那些可能直接存储头域的方法。例如,即你用会话跟t,Z保证session的正常工作,你必d一个调用include的Servlet之外开始你的session

二、Servlet接口?
定义\r
public interface Servlet
q个接口定义了一个ServletQ一个在Web服务器上l承了这个功能的JavacR?
Ҏ
1、init
public void init(ServletConfig config) throws ServletException;
Servlet引擎会在Servlet实例化之后,|入服务之前_地调用initҎ。在调用serviceҎ之前QinitҎ必须成功退出?
如果initҎ抛出一个ServletExceptionQ你不能这个Servlet|入服务中,如果initҎ在超时范围内没完成,我们也可以假定这个Servlet是不具备功能的,也不能置入服务中?
2、service
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException;
Servlet引擎调用q个Ҏ以允许Servlet响应h。这个方法在Servlet未成功初始化之前无法调用。在Servlet被初始化之前QServlet引擎能够锁未决的请求?
在一个Servlet对象被卸载后Q直C个新的Servlet被初始化QServlet引擎不能调用q个Ҏ
3、destroy
public void destroy();
当一个Servlet被从服务中去除时QServlet引擎调用q个Ҏ。在q个对象的serviceҎ所有线E未全部退出或者没被引擎认为发生超时操作时QdestroyҎ不能被调用?
4、getServletConfig
public ServletConfig getServletConfig();
q回一个ServletConfig对象Q作Z个Servlet的开发者,你应该通过initҎ存储ServletConfig对象以便q个Ҏ能返回这个对象。ؓ了你的便利,GenericServlet在执行这个接口时Q已l这样做了?
5、getServletInfo
public String getServletInfo();
允许Servlet向主机的Servletq行者提供有兛_本n的信息。返回的字符串应该是U文本格式而不应有M标志Q例如HTMLQXML{)?

三、ServletConfig接口
定义\r
public interface ServletConfig
q个接口定义了一个对象,通过q个对象QServlet引擎配置一个Servletq且允许Servlet获得一个有兛_的ServletContext接口的说明。每一个ServletConfig对象对应着一个唯一的Servlet?
Ҏ
1、getInitParameter
public String getInitParameter(String name);
q个Ҏq回一个包含Servlet指定的初始化参数的String。如果这个参C存在Q返加空倹{?
2、getInitParameterNames
public Enumeration getInitParameterNames();
q个Ҏq回一个列表String对象Q该对象包括Servlet的所有初始化参数名。如果Servlet没有初始化参敎ͼgetInitParameterNamesq回一个空的列表?
3、getServletContext
public ServletContext getServletContext();
q回q个Servlet的ServletContext对象?

四、ServletContext接口
定义\r
public interface ServletContext
定义了一个Servlet的环境对象,通过q个对象QServlet引擎向Servlet提供环境信息?
一个Servlet的环境对象必至与它所ȝ的主机是一一对应的。在一个处理多个虚拟主机的Servlet引擎中(例如Q用了HTTP1.1的主机头域)Q每一个虚拟主机必被视ؓ一个单独的环境。此外,Servlet引擎q可以创建对应于一lServlet的环境对象?
Ҏ
1、getAttribute
public Object getAttribute(String name);
q回Servlet环境对象中指定的属性对象。如果该属性对象不存在Q返回空倹{这个方法允许访问有兌个Servlet引擎的在该接口的其他Ҏ中尚未提供的附加信息?
2、getAttributeNames
public Enumeration getAttributeNames();
q回一个Servlet环境对象中可用的属性名的列表?
3、getContext
public ServletContext getContext(String uripath);
q回一个Servlet环境对象Q这个对象包括了特定URI路径的Servlets和资源,如果该\径不存在Q则q回一个空倹{URI路径格式?dir/dir/filename.ext?
Z安全Q如果通过q个Ҏ讉K一个受限制的Servlet的环境对象,会返回一个空倹{?
4、getMajorVersion
public int getMajorVersion();
q回Servlet引擎支持的Servlet API的主版本受例如对?.1版,q个Ҏ会返回一个整??
5、getMinorVersion
public int getMinorVersion();
q回Servlet引擎支持的Servlet API的次版本受例如对?.1版,q个Ҏ会返回一个整??
6、getMimeType
public String getMimeType(String file);
q回指定文g的MIMEcdQ如果这UMIMEcd未知Q则q回一个空倹{MIMEcd是由Servlet引擎的配|决定的?
7、getRealPath
public String getRealPath(String path);
一个符合URL路径格式的指定的虚拟路径的格式是Q?dir/dir/filename.ext。用q个ҎQ可以返回与一个符合该格式的虚拟\径相对应的真实\径的String。这个真实\径的格式应该适合于运行这个Servlet引擎的计机Q包括其相应的\径解析器Q?
不管是什么原因,如果q一从虚拟\径{换成实际路径的过E不能执行,该方法将会返回一个空倹{?
8、getResource
public URL getResource(String uripath);
q回一个URL对象Q该对象反映位于l定的URL地址Q格式:/dir/dir/filename.extQ的Servlet环境对象已知的资源。无论URLStreamHandlers对于讉Kl定的环境是不是必须的,Servlet引擎都必L行。如果给定的路径的Servlet环境没有已知的资源,该方法会q回一个空倹{?
q个Ҏ和java.lang.Class的getResourceҎ不完全相同。java.lang.Class的getResourceҎ通过装蝲cLL资源。而这个方法允许服务器产生环境变量lQ何资源的MServletQ而不必依赖于装蝲cR特定区域等{?
9、getResourceAsStream
public InputStream getResourceAsStream(String uripath);
q回一个InputStream对象Q该对象引用指定的URL的Servlet环境对象的内宏V如果没扑ֈServlet环境变量Q就会返回空|URL路径应该hq种格式Q?dir/dir/filename.ext?
q个Ҏ是一个通过getResourceҎ获得URL对象的方便的途径。请注意Q当你用这个方法时Qmeta-informationQ例如内定w度、内容类型)会丢失?
10、getRequestDispatcher
public RequestDispatcher getRequestDispatcher(String uripath);
如果q个指定的\径下能够扑ֈzd的资?例如一个ServletQJSP面QCGI{等)p回一个特定URL的RequestDispatcher对象Q否则,p回一个空|Servlet引擎负责用一个request dispatcher对象装目标路径。这个request dispatcher对象可以用来完全h的传送?
11、getServerInfo
public String getServerInfo();
q回一个String对象Q该对象臛_包括Servlet引擎的名字和版本受?
12、log
public void log(String msg);
public void log(String msg, Throwable t);
public void log(Exception exception, String msg); // q种用法被取消\r
写指定的信息C个Servlet环境对象的log文g中。被写入的log文g由Servlet引擎指定Q但是通常q是一个事件log。当q个Ҏ被一个异常调用时Qlog中将包括堆栈跟踪?
13、setAttribute
public void setAttribute(String name, Object o);
l予Servlet环境对象中你所指定的对象一个名U?
14、removeAttribute
public void removeAttribute(String name);
从指定的Servlet环境对象中删除一个属性?
注:以下几个Ҏ被取消\r
15、getServlet
public Servlet getServlet(String name) throws ServletException;
最初用来返回一个指定名U的ServletQ如果没扑ֈp回一个空倹{如果这个Servlet能够q回Q这意味着它已l被初始化,而且已经可以接受serviceh。这是一个危险的Ҏ。当调用q个ҎӞ可能q不知道Servlet的状态,q就可能D有关服务器状态的问题。而允怸个Servlet讉K其他Servlet的这个方法也同样的危险?
现在q个Ҏq回一个空|Z保持和以前版本的兼容性,现在q个Ҏq没有被取消。在以后的API版本中,该方法将被取消?
16、getServletNames
public Enumeration getServletNames();
最初用来返回一个String对象的列表,该列表表CZ在这个Servlet环境下所有已知的Servlet对象名。这个列表L包含q个Servlet自n?
Z与上一个方法同L理由Q这也是一个危险的Ҏ?
现在q个Ҏq回一个空的列表。ؓ了保持和以前版本的兼Ҏ,现在q个Ҏq没有被取消。在以后的API版本中,该方法将被取消?
17、getServlets
public Enumeration getServlets();
最初用来返回在q个Servelet环境下所有已知的Servlet对象的列表。这个列表L包含q个Servlet自n?
Z与getServletҎ同样的理由,q也是一个危险的Ҏ?
现在q个Ҏq回一个空的列表。ؓ了保持和以前版本的兼Ҏ,现在q个Ҏq没有被取消。在以后的API版本中,该方法将被取消?

五、ServletRequest接口
定义\r
public interface ServletRequest
定义一个Servlet引擎产生的对象,通过q个对象QServlet可以获得客户端请求的数据。这个对象通过dh体的数据提供包括参数的名U、值和属性以及输入流的所有数据?
Ҏ
1、getAttribute
public Object getAttribute(String name);
q回h中指定属性的|如果q个属性不存在Q就q回一个空倹{这个方法允许访问一些不提供l这个接口中其他Ҏ的请求信息以及其他Servlet攄在这个请求对象内的数据?
2、getAttributeNames
public Enumeration getAttributeNames();
q回包含在这个请求中的所有属性名的列表?
3、getCharacterEncoding
public String getCharacterEncoding();
q回h中输入内容的字符~码cdQ如果没有定义字W编码类型就q回I倹{?
4、getContentLength
public int getContentLength();
h内容的长度,如果长度未知p?1?
5、getContentType
public String getContentType();
q回h数据体的MIMEcdQ如果类型未知返回空倹{?
6、getInputStream
public ServletInputStream getInputStream() throws IOException;
q回一个输入流用来从请求体d二进制数据。如果在此之前已l通过getReaderҎ获得了要d的结果,q个Ҏ会抛Z个IllegalStateException?
7、getParameter
public String getParameter(String name);
以一个Stringq回指定的参数的|如果q个参数不存在返回空倹{例如,在一个HTTP Servlet中,q个Ҏ会返回一个指定的查询语句产生的参数的值或一个被提交的表单中的参数倹{如果一个参数名对应着几个参数|q个Ҏ只能q回通过getParameterValuesҎq回的数l中的第一个倹{因此,如果q个参数有(或者可能有Q多个|你只能用getParameterValuesҎ?
8、getParameterNames
public Enumeration getParameterNames();
q回所有参数名的String对象列表Q如果没有输入参敎ͼ该方法返回一个空倹{?
9、getParameterValues
public String[] getParameterValues(String name);
通过一个String对象的数l返回指定参数的|如果q个参数不存在,该方法返回一个空倹{?
10、getProtocol
public String getProtocol();
q回q个h所用的协议Q其形式是协?ȝ本号.ơ版本号。例如对于一个HTTP1.0的请求,该方法返回HTTP/1.0?
11、getReader
public BufferedReader getReader() throws IOException;
q个Ҏq回一个buffered reader用来dh体的实体Q其~码方式依照h数据的编码方式。如果这个请求的输入已l被getInputStream调用获得Q这个方法会抛出一个IllegalStateException?
12、getRemoteAddr
public String getRemoteAddr();
q回发送请求者的IP地址?
13、getRemoteHost
public String getRemoteHost();
q回发送请求者的L名称。如果引擎不能或者选择不解析主机名Qؓ了改善性能Q,q个Ҏ会直接返回IP地址?
14、getScheme
public String getScheme();
q回h所使用的URL的模式。例如,对于一个HTTPhQ这个模式就是http?
15、getServerName
public String getServerName();
q回接收h的服务器的主机名?
16、getServerPort
public int getServerPort();
q回接收h的端口号?
17、setAttribute
public void setAttribute(String name, Object object);
q个Ҏ在请求中d一个属性,q个属性可以被其他可以讉Kq个h对象的对象(例如一个嵌套的ServletQ用?
注:以下Ҏ被取消\r
getRealPath
public String getRealPath(String path);
q回与虚拟\径相对应的真实\径,如果因ؓ某种原因Q这一q程不能q行Q该Ҏ返回一个空倹{?
q个Ҏ和ServletContext接口中的getRealPathҎ重复。在2.1版中QServletContext接口阐明一个Servlet所能用的所有的路径的映。该Ҏ执行的结果将会与ServletContext中getRealPathҎ的结果完全一栗?

六、ServletResponse接口
定义\r
public interface ServletResponse
定义一个Servlet引擎产生的对象,通过q个对象QServlet对客L的请求作出响应。这个响应应该是一个MIME实体Q可能是一个HTMLc图象数据或其他MIME的格式?
Ҏ
1、getCharacterEncoding
public String getCharacterEncoding();
q回MIME实体的字W编码。这个字W编码可以是指定的类型,也可以是与请求头域所反映的客L所能接受的字符~码最匚w的类型。在HTTP协议中,q个信息被通过Accept-Charset传送到Servlet引擎?
有关字符~码和MIME的更多信息请参看RFC 2047?
2、getOutputStream
public ServletOutputStream getOutputStream() throws IOException;
q回一个记录二q制的响应数据的输出?
如果q个响应对象已经调用getWriterQ将会抛出IllegalStateException?
3、getWriter
public PrintWriter getWriter throws IOException;
q个Ҏq回一个PrintWriter对象用来记录格式化的响应实体。如果要反映使用的字W编码,必须修改响应的MIMEcd。在调用q个Ҏ之前Q必设定响应的contentcd?
如果没有提供q样的编码类型,会抛Z个UnsupportedEncodingExceptionQ如果这个响应对象已调用getOutputStreamQ会抛出一个getOutputStream?
4、setContentLength
public void setContentLength(int length);
讄响应的内容的长度Q这个方法会覆盖以前对内定w度的讑֮?
Z保证成功地设定响应头的内定w度,在响应被提交到输出流之前必须调用q个Ҏ?
5、setContentType
public void setContentType(String type);
q个Ҏ用来讑֮响应的contentcd。这个类型以后可能会在另外的一些情况下被隐式地修改Q这里所说的另外的情况可能当服务器发现有必要的情况下对MIME的字W设|?
Z保证成功地设定响应头的contentcdQ在响应被提交到输出之前必调用这个方法?

七、SingleThreadModel接口
定义\r
public interface SingleThreadModel;
q是一个空接口Q它指定了系l如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的serviceҎ中将不会有两个线E被同时执行?
Servlet可以通过l持一个各自独立的Servlet实例池,或者通过只让Servlet的service中只有一个线E的Ҏ来实现这个保证?

八、GenericServletc\r
public abstract class GenericServlet implements Servlet,
ServletConfig, Serializable;
q个cȝ存在使得~写Servlet更加方便。它提供了一个简单的ҎQ这个方案用来执行有关Servlet生命周期的方法以及在初始化时对ServletConfig对象和ServletContext对象q行说明?
Ҏ
1、destroy
public void destroy();
在这里destroyҎ不做M其他的工作?
2、getInitParameter
public String getInitParameter(String name);
q是一个简便的途径Q它会调用ServletConfig对象的同名的Ҏ?
3、getInitParameterNames
public Enumeration getInitParameterNames();
q是一个简便的途径Q它会调用ServletConfig对象的同名的Ҏ?
4、getServletConfig
public ServletConfig getServletConfig();
q回一个通过q个cȝinitҎ产生的ServletConfig对象的说明?
5、getServletContext
public ServletContext getServletContext();
q是一个简便的途径Q它会调用ServletConfig对象的同名的Ҏ?
6、getServletInfo
public String getServletInfo();
q回一个反映Servlet版本的String?
7、init
public void init() throws ServletException;
public void init(ServletConfig config) throws ServletException;
init(ServletConfig config)Ҏ是一个对q个Servlet的生命周期进行初始化的简便的途径?
init()Ҏ是用来让你对GenericServletc进行扩充的Q用这个方法时Q你不需要存储config对象Q也不需要调用super.init(config)?
init(ServletConfig config)Ҏ会存储config对象然后调用init()。如果你重蝲了这个方法,你必调用super.init(config)Q这样GenericServletcȝ其他Ҏ才能正常工作?
8、log
public void log(String msg);
public void log(String msg, Throwable cause);
通过Servlet content对象Servlet的类名和l定的信息写入log文g中?
9、service
public abstract void service(ServletRequest request, ServletResponse
response) throws ServletException, IOException;
q是一个抽象的ҎQ当你扩展这个类ӞZ执行|络hQ你必须执行它?

九、ServletInputStreamc\r
定义\r
public abstract class ServletInputStream extends InputStream
q个cd义了一个用来读取客L的请求信息的输入。这是一个Servlet引擎提供的抽象类。一个Servlet通过使用ServletRequest接口获得了对一个ServletInputStream对象的说明?
q个cȝ子类必须提供一个从InputStream接口d有关信息的方法?
Ҏ
1、readLine
public int readLine(byte[] b, int off, int len) throws IOException;
从输入流的指定的偏移量开始将指定长度的字节读入到指定的数l中。如果该行所有请求的内容都已被读取,q个d的过E将l束。如果是遇到了新的一行,新的一行的首个字符也将被读入到数组中?

十、ServletOutputStreamc\r
定义\r
public abstract class ServletOutputStream extends OutputStream
q是一个由Servlet引擎使用的抽象类。Servlet通过使用ServletResponse接口的用获得了对一个这U类型的对象的说明。利用这个输出流可以数据返回到客户端?
q个cȝ子类必须提供一个向OutputStream接口写入有关信息的方法?
在这个接口中Q当一个刷新或关闭的方法被调用时。所有数据缓冲区的信息将会被发送到客户端,也就是说响应被提交了。请注意Q关闭这U类型的对象时不一定要关闭隐含的socket?
Ҏ
1、print
public void print(String s) throws IOException;
public void print(boolean b) throws IOException;
public void print(char c) throws IOException;
public void print(int i) throws IOException;
public void print(long l) throws IOException;
public void print(float f) throws IOException;
public void print(double d) throws IOException;
输出变量到输出流?
2、println
public void println() throws IOException;
public void println(String s) throws IOException;
public void println(boolean b) throws IOException;
public void println(char c) throws IOException;
public void println(int i) throws IOException;
public void println(long l) throws IOException;
public void println(float f) throws IOException;
public void println(double d) throws IOException;
输出变量到输出流中,q增加一个回车换行符\r

十一、ServletExceptionc\r
定义\r
public class ServletException extends Exception
当Servlet遇到问题时抛出的一个异常?
构造函?
public ServletException();
public ServletException(String message);
public ServletException(String message, Throwable cause);
public ServletException(Throwable cause);
构造一个新的ServletExceptionQ如果这个构造函数包括一个Throwable参数Q这个Throwable对象被作ؓ可能抛出q个异常的原因?
Ҏ
1、getRootCause
public Throwable getRootCause();
如果配置了抛个异常的原因Q这个方法将q回q个原因Q否则返回一个空倹{?

十二、UnavailableExceptionc\r
定义\r
public class UnavailableException extends ServletException
不论一个Servlet是永久地q是临时地无效,都会抛出q个异常。Servlet会记录这个异总及Servlet引擎所要采取的相应措施?
临时的无效是指Servlet在某一旉׃一个时的问题而不能处理请求。例如,在另一个不同的应用层的服务Q可能是数据库)无法使用。这个问题可能会自行U正或者需要采取其他的U正措施?
怹的无效是指除非管理员采取措施Q这个Servlet不能处理客L的请求。例如,q个Servlet配置信息丢失或Servlet的状态被破坏?
Servlet引擎可以安全地处理包括永久无效在内的q两U异常,但是对时无效的正常处理可以使得Servlet引擎更健壮。特别的Q这时对Servlet的请求只是被LQ或者是被g期)一D|_q显然要比在service自己重新启动前完全拒l请求更为科学?
构造函?
public UnavailableException(Servlet servlet, String message);
public UnavailableException(int seconds, Servlet servlet,
String message);
构造一个包含指定的描述信息的新的异常。如果这个构造函数有一个关于秒数的参数Q这给出Servlet发生临时无效后,能够重新处理h的估计时间。如果不包含q个参数Q这意味着q个Servlet怹无效?
Ҏ
1、getServlet
public Servlet getServlet();
q回报告无效的Servlet。这被Servlet引擎用来识别受到影响的Servlet?
2、getUnavailableSeconds
public int getUnavailableSeconds();
q回Servlet预期的无效时_如果q个Servlet是永久无效,q回-1?
3、isPermanent
public boolean isPermanent();
如果q个Servlet怹无效Q返回布值trueQ指C必采取一些管理行动以使得q个Servlet可用?

Java Servlet API说明文档Q?.1a版)Q三Q?
软g包:javax.servlet.http
所包含的接口:HttpServletRequestQHttpServletResponseQHttpSessionQHttpSessionBindingListenerQHttpSessionContext?
所包含的类QCookieQHttpServletQHttpSessionBindingEventQHttpUtils?

一、HttpServletRequest接口
定义\
public interface HttpServletRequest extends ServletRequest;
用来处理一个对Servlet的HTTP格式的请求信息?
Ҏ
1、getAuthType
public String getAuthType();
q回q个h的n份验证模式?
2、getCookies
public Cookie[] getCookies();
q回一个数l,该数l包含这个请求中当前的所有cookie。如果这个请求中没有cookieQ返回一个空数组?
3、getDateHeader
public long getDateHeader(String name);
q回指定的请求头域的|q个D转换成一个反映自1970-1-1日(GMTQ以来的_到毫U的长整数?
如果头域不能转换Q抛Z个IllegalArgumentException。如果这个请求头域不存在Q这个方法返?1?
4、getHeader
public String getHeader(String name);
q回一个请求头域的倹{(译者注Q与上一个方法不同的是,该方法返回一个字W串Q?
如果q个h头域不存在,q个Ҏq回-1?
5、getHeaderNames
public Enumeration getHeaderNames();
该方法返回一个String对象的列表,该列表反映请求的所有头域名?
有的引擎可能不允讔R过q种Ҏ讉K头域Q在q种情况下,q个Ҏq回一个空的列表?
6、getIntHeader
public int getIntHeader(String name);
q回指定的请求头域的|q个D转换成一个整数?
如果头域不能转换Q抛Z个IllegalArgumentException。如果这个请求头域不存在Q这个方法返?1?
7、getMethod
public String getMethod();
q回q个h使用的HTTPҎQ例如:GET、POST、PUTQ?
8、getPathInfo
public String getPathInfo();
q个Ҏq回在这个请求的URL的Servlet路径之后的请求URL的额外的路径信息。如果这个请求URL包括一个查询字W串Q在q回值内不包括q个查询字符丌Ӏ这个\径在q回之前必须l过URL解码。如果在q个h的URL的Servlet路径之后没有路径信息。这个方法返回空倹{?
9、getPathTranslated
public String getPathTranslated();
q个Ҏ获得q个h的URL的Servlet路径之后的额外的路径信息Qƈ它转换成一个真实的路径。在q行转换前,q个h的URL必须l过URL解码。如果在q个URL的Servlet路径之后没有附加路径信息。这个方法返回空倹{?
10、getQueryString
public String getQueryString();
q回q个hURL所包含的查询字W串。一个查询字串符在一个URL中由一个“?”引出。如果没有查询字W串Q这个方法返回空倹{?
11、getRemoteUser
public String getRemoteUser
q回作了h的用户名Q这个信息用来作HTTP用户?
如果在请求中没有用户名信息,q个Ҏq回I倹{?
12、getRequestedSessionId
public String getRequestedSessionId();
q回q个h相应的session id。如果由于某U原因客L提供的session id是无效的Q这个session id与在当前session中的session id不同Q与此同Ӟ徏立一个新的session?
如果q个h没与一个session兌Q这个方法返回空倹{?
13、getRequestURI
public String getRequestURI();
从HTTPh的第一行返回请求的URL中定义被h的资源的部分。如果有一个查询字W串存在Q这个查询字W串不包括在返回值当中。例如,一个请求通过/catalog/books?id=1q样的URL路径讉KQ这个方法将q回/catalog/books。这个方法的q回值包括了Servlet路径和\径信息?
如果q个URL路径中的的一部分l过了URL~码Q这个方法的q回值在q回之前必须l过解码?
14、getServletPath
public String getServletPath();
q个Ҏq回hURL反映调用Servlet的部分。例如,一个Servlet被映到/catalog/summerq个URL路径Q而一个请求用了/catalog/summer/casualq样的\径。所谓的反映调用Servlet的部分就是指/catalog/summer?
如果q个Servlet不是通过路径匚w来调用。这个方法将q回一个空倹{?
15、getSession
public HttpSession getSession();
public HttpSession getSession(boolean create);
q回与这个请求关联的当前的有效的session。如果调用这个方法时没带参数Q那么在没有session与这个请求关联的情况下,会新徏一个session。如果调用这个方法时带入了一个布型的参敎ͼ只有当这个参Cؓ真时Qsession才会被徏立?
Z保session能够被完全维持。Servlet开发者必d响应被提交之前调用该Ҏ?
如果带入的参Cؓ假,而且没有session与这个请求关联。这个方法会q回I倹{?
16、isRequestedSessionIdValid
public boolean isRequestedSessionIdValid();
q个Ҏ查与此请求关联的session当前是不是有效。如果当前请求中使用的session无效Q它不能通过getSessionҎq回?
17、isRequestedSessionIdFromCookie
public boolean isRequestedSessionIdFromCookie();
如果q个h的session id是通过客户端的一个cookie提供的,该方法返回真Q否则返回假?
18、isRequestedSessionIdFromURL
public boolean isRequestedSessionIdFromURL();
如果q个h的session id是通过客户端的URL的一部分提供的,该方法返回真Q否则返回假。请注意此方法与isRequestedSessionIdFromUrl在URL的拼写上不同?
以下Ҏ被取消\\r

19、isRequestedSessionIdFromUrl
public boolean isRequestedSessionIdFromUrl();
该方法被isRequestedSessionIdFromURL代替?

二、HttpServletResponse接口
定义\\r

public interface HttpServletResponse extends ServletResponse
描述一个返回到客户端的HTTP回应。这个接口允许ServletE序员利用HTTP协议规定的头信息?
成员变量
public static final int SC_CONTINUE = 100;
public static final int SC_SWITCHING_PROTOCOLS = 101;
public static final int SC_OK = 200;
public static final int SC_CREATED = 201;
public static final int SC_ACCEPTED = 202;
public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
public static final int SC_NO_CONTENT = 204;
public static final int SC_RESET_CONTENT = 205;
public static final int SC_PARTIAL_CONTENT = 206;
public static final int SC_MULTIPLE_CHOICES = 300;
public static final int SC_MOVED_PERMANENTLY = 301;
public static final int SC_MOVED_TEMPORARILY = 302;
public static final int SC_SEE_OTHER = 303;
public static final int SC_NOT_MODIFIED = 304;
public static final int SC_USE_PROXY = 305;
public static final int SC_BAD_REQUEST = 400;
public static final int SC_UNAUTHORIZED = 401;
public static final int SC_PAYMENT_REQUIRED = 402;
public static final int SC_FORBIDDEN = 403;
public static final int SC_NOT_FOUND = 404;
public static final int SC_METHOD_NOT_ALLOWED = 405;
public static final int SC_NOT_ACCEPTABLE = 406;
public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
public static final int SC_REQUEST_TIMEOUT = 408;
public static final int SC_CONFLICT = 409;
public static final int SC_GONE = 410;
public static final int SC_LENGTH_REQUIRED = 411;
public static final int SC_PRECONDITION_FAILED = 412;
public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
public static final int SC_REQUEST_URI_TOO_LONG = 414;
public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
public static final int SC_INTERNAL_SERVER_ERROR = 500;
public static final int SC_NOT_IMPLEMENTED = 501;
public static final int SC_BAD_GATEWAY = 502;
public static final int SC_SERVICE_UNAVAILABLE = 503;
public static final int SC_GATEWAY_TIMEOUT = 504;
public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
以上HTTP产状态码是由HTTP/1.1定义的?
Ҏ
1、addCookie
public void addCookie(Cookie cookie);
在响应中增加一个指定的cookie。可多次调用该方法以定义多个cookie。ؓ了设|适当的头域,该方法应该在响应被提交之前调用?
2、containsHeader
public boolean containsHeader(String name);
查是否设|了指定的响应头?
3、encodeRedirectURL
public String encodeRedirectURL(String url);
对sendRedirectҎ使用的指定URLq行~码。如果不需要编码,q接返回这个URL。之所以提供这个附加的~码ҎQ是因ؓ在redirect的情况下Q决定是否对URLq行~码的规则和一般情冉|所不同。所l的URL必须是一个绝对URL。相对URL不能被接Ӟ会抛Z个IllegalArgumentException?
所有提供给sendRedirectҎ的URL都应通过q个Ҏq行Q这h能确保会话跟t能够在所有浏览器中正常运行?
4、encodeURL
public String encodeURL(String url);
对包含session ID的URLq行~码。如果不需要编码,q接返回这个URL。Servlet引擎必须提供URL~码ҎQ因为在有些情况下,我们不得不重写URLQ例如,在响应对应的h中包含一个有效的sessionQ但是这个session不能被非URL的(例如cookieQ的手段来维持?
所有提供给Servlet的URL都应通过q个Ҏq行Q这h能确保会话跟t能够在所有浏览器中正常运行?
5、sendError
public void sendError(int statusCode) throws IOException;
public void sendError(int statusCode, String message) throws
IOException;
用给定的状态码发给客户端一个错误响应。如果提供了一个message参数Q这作为响应体的一部分被发出,否则Q服务器会返回错误代码所对应的标准信息?
调用q个Ҏ后,响应立即被提交。在调用q个Ҏ后,Servlet不会再有更多的输出?
6、sendRedirect
public void sendRedirect(String location) throws IOException;
使用l定的\径,l客L发出一个时{向的响应QSC_MOVED_TEMPORARILYQ。给定的路径必须是绝对URL。相对URL不能被接收Q会抛出一个IllegalArgumentException?
q个Ҏ必须在响应被提交之前调用。调用这个方法后Q响应立卌提交。在调用q个Ҏ后,Servlet不会再有更多的输出?
7、setDateHeader
public void setDateHeader(String name, long date);
用一个给定的名称和日期D|响应头Q这里的日期值应该是反映?970-1-1日(GMTQ以来的_到毫U的长整数。如果响应头已经被设|,新的值将覆盖当前的倹{?
8、setHeader
public void setHeader(String name, String value);
用一个给定的名称和域讄响应头。如果响应头已经被设|,新的值将覆盖当前的倹{?
9、setIntHeader
public void setIntHeader(String name, int value);
用一个给定的名称和整形D|响应头。如果响应头已经被设|,新的值将覆盖当前的倹{?
10、setStatus
public void setStatus(int statusCode);
q个Ҏ讄了响应的状态码Q如果状态码已经被设|,新的值将覆盖当前的倹{?
以下的几个方法将被取消\
11、encodeRedirectUrl
public String encodeRedirectUrl(String url);
该方法被encodeRedirectURL取代?
12、encodeUrl
public String encodeUrl(String url);
该方法被encodeURL取代?
13、setStatus
public void setStatus(int statusCode, String message);
q个Ҏ讄了响应的状态码Q如果状态码已经被设|,新的值将覆盖当前的倹{如果提供了一个messageQ它也将会被作ؓ响应体的一部分被发送?

三、HttpSession接口
定义\
public interface HttpSession
q个接口被Servlet引擎用来实现在HTTP客户端和HTTP会话两者的兌。这U关联可能在多外q接和请求中持箋一D늻定的旉。session用来在无状态的HTTP协议下越q多个请求页面来l持状态和识别用户?
一个session可以通过cookie或重写URL来维持?
Ҏ
1、getCreationTime
public long getCreationTime();
q回建立session的时_q个旉表示1970-1-1日(GMTQ以来的毫秒数?
2、getId
public String getId();
q回分配l这个session的标识符。一个HTTP session的标识符是一个由服务器来建立和维持的唯一的字W串?
3、getLastAccessedTime
public long getLastAccessedTime();
q回客户端最后一ơ发Zq个session有关的请求的旉Q如果这个session是新建立的,q回-1。这个时间表CZؓ?970-1-1日(GMTQ以来的毫秒数?
4、getMaxInactiveInterval
public int getMaxInactiveInterval();
q加一个秒敎ͼq个U数表示客户端在不发求时Qsession被Servlet引擎l持的最长时间。在q个旉之后QServlet引擎可能被Servlet引擎l止。如果这个session不会被终止,q个Ҏq回-1?
当session无效后再调用q个Ҏ会抛Z个IllegalStateException?
5、getValue
public Object getValue(String name);
q回一个以l定的名字绑定到session上的对象。如果不存在q样的绑定,q回I倹{?
当session无效后再调用q个Ҏ会抛Z个IllegalStateException?
6、getValueNames
public String[] getValueNames();
以一个数l返回绑定到session上的所有数据的名称?
当session无效后再调用q个Ҏ会抛Z个IllegalStateException?
7、invalidate
public void invalidate();
q个Ҏ会终止这个session。所有绑定在q个session上的数据都会被清除。ƈ通过HttpSessionBindingListener接口的valueUnboundҎ发出通告?
8、isNew
public boolean isNew();
q回一个布g判断q个session是不是新的。如果一个session已经被服务器建立但是q没有收到相应的客户端的hQ这个session被认ؓ是新的。这意味着Q这个客Lq没有加入会话或没有被会话公认。在他发Z一个请求时q不能返回适当的session认证信息?
当session无效后再调用q个Ҏ会抛Z个IllegalStateException?
9、putValue
public void putValue(String name, Object value);
以给定的名字Q绑定给定的对象到session中。已存在的同名的l定会被重置。这时会调用HttpSessionBindingListener接口的valueBoundҎ?
当session无效后再调用q个Ҏ会抛Z个IllegalStateException?
10、removeValue
public void removeValue(String name);
取消l定名字的对象在session上的l定。如果未扑ֈl定名字的绑定的对象Q这个方法什么也不做?q时会调用HttpSessionBindingListener接口的valueUnboundҎ?
当session无效后再调用q个Ҏ会抛Z个IllegalStateException?
11、setMaxInactiveInterval
public int setMaxInactiveInterval(int interval);
讄一个秒敎ͼq个U数表示客户端在不发求时Qsession被Servlet引擎l持的最长时间?
以下q个Ҏ被取消\
12、getSessionContext
public HttpSessionContext getSessionContext();
q回session在其中得以保持的环境变量。这个方法和其他所有HttpSessionContext的方法一栯取消了?

四、HttpSessionBindingListener接口
定义\
public interface HttpSessionBindingListener
q个对象被加入到HTTP的session中,执行q个接口会通告有没有什么对象被l定到这个HTTP session中或被从q个HTTP session中取消绑定?
Ҏ
1、valueBound
public void valueBound(HttpSessionBindingEvent event);
当一个对象被l定到session中,调用此方法。HttpSession.putValueҎ被调用时QServlet引擎应该调用此方法?
2、valueUnbound
public void valueUnbound(HttpSessionBindingEvent event);
当一个对象被从session中取消绑定,调用此方法。HttpSession.removeValueҎ被调用时QServlet引擎应该调用此方法?

五、HttpSessionContext接口
定义\
此接口将被取消\
public interface HttpSessionContext
q个对象是与一lHTTP session兌的单一的实体?
q个接口׃安全的原因被取消Q它出现在目前的版本中仅仅是Z兼容性的原因。这个接口的Ҏ模拟以前的版本的定义返回相应的倹{?
Ҏ
1、getSession
public HttpSession getSession(String sessionId);
当初用来q回与这个session id相关的session。现在返回空倹{?
2、getIds
public Enumeration getIds();
当初用来q回q个环境下所有session id的列表。现在返回空的列表?

六、Cookiec\
定义\
public class Cookie implements Cloneable
q个cLqC一个cookieQ有关cookie的定义你可以参照Netscape Communications Corporation的说明,也可以参照RFC 2109?
构造函?
public Cookie(String name, String value);
用一个name-value对定义一个cookie。这个name必须能被HTTP/1.1所接受?
以字W?开头的name被RFC 2109保留?
l定的name如果不能被HTTP/1.1所接受Q该Ҏ抛出一个IllegalArgumentException?
Ҏ
1、getComment
public String getComment();
q回描述q个cookie目的的说明,如果未定义这个说明,q回I倹{?
2、getDomain
public String getDomain();
q回q个cookie可以出现的区域,如果未定义区域,q回I倹{?
3、getMaxAge
public int getMaxAge();
q个Ҏq回q个cookie指定的最长存zL期。如果未定义q个最长存zL期,该方法返?1?
4、getName
public String getName();
该方法返回cookie名?
5、getPath
public String getPath();
q回q个cookie有效的所有URL路径的前~Q如果未定义Q返回空倹{?
6、getSecure
public boolean getSecure();
如果q个cookie只通过安全通道传输q回真,否则q回假?
7、getValue
public String getValue();
该方法返回cookie的倹{?
8、getVersion
public int getVersion();
q回cookie的版本。版?由RFC 2109解释。版?由Netscape Communications Corporation的说明解释。新构造的cookie默认使用版本0?
9、setComment
public void setComment(String purpose);
如果一个用户将q个cookie提交l另一个用P必须通过q个说明描述q个cookie的目的。版?不支持这个属性?
10、setDomain
public void setDomain(String pattern);
q个Ҏ讄cookie的有效域的属性。这个属性指定了cookie可以出现的区域。一个有效域以一个点开_.foo.comQ,q意味着在指定的域名解析pȝ的区域中Q可能是www.foo.com但不是a.b.foo.comQ的L可以看到q个cookie。默认情冉|Qcookie只能q回保存它的L?
11、setMaxAge
public void setMaxAge(int expiry);
q个Ҏ讑֮q个cookie的最长存zL期。在该存zL期之后,cookie会被l目。负数表C个cookie不会生效Q?从客户端删除这个cookie?
12、setPath
public void setPath(String uri);
q个Ҏ讄cookie的\径属性。客L只能向以q个l定的\径String开头的路径q回cookie?
13、setSecure
public void setSecure(boolean flag);
指出q个cookie只能通过安全通道Q例如HTTPSQ发送。只有当产生q个cookie的服务器使用安全协议发送这个cookie值时才能q样讄?
14、setValue
public void setValue(String newValue);
讄q个cookie的|对于二进制数据采用BASE64~码?
版本0不能使用I格、{}?)?、,、“”??、@、:以及Q?
15、setVersion
public void setVersion(int v);
讄cookie的版本号

七、HttpServletc\
定义\
public class HttpServlet extends GenericServlet implements
Serializable
q是一个抽象类Q用来简化HTTP Servlet写作的过E。它是GenericServletcȝ扩充Q提供了一个处理HTTP协议的框架?
在这个类中的serviceҎ支持例如GET、POSTq样的标准的HTTPҎ。这一支持q程是通过分配他们到适当的方法(例如doGet、doPostQ来实现的?
Ҏ
1、doDelete
protected void doDelete(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
被这个类的serviceҎ调用Q用来处理一个HTTP DELETE操作。这个操作允许客Lh从服务器上删除URL。这一操作可能有负面媄响,Ҏ用户p赯仅R?
q一Ҏ的默认执行结果是q回一个HTTP BAD_REQUEST错误。当你要处理DELETEhӞ你必重载这一Ҏ?
2、doGet
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
被这个类的serviceҎ调用Q用来处理一个HTTP GET操作。这个操作允许客L单地从一个HTTP服务器“获得”资源。对q个Ҏ的重载将自动地支持HEADҎ?
GET操作应该是安全而且没有负面影响的。这个操作也应该可以安全地重复?
q一Ҏ的默认执行结果是q回一个HTTP BAD_REQUEST错误?
3、doHead
protected void doHead(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
被这个类的serviceҎ调用Q用来处理一个HTTP HEAD操作。默认的情况是,q个操作会按照一个无条g的GETҎ来执行,该操作不向客Lq回M数据Q而仅仅是q回包含内容长度的头信息?
与GET操作一Pq个操作应该是安全而且没有负面影响的。这个操作也应该可以安全地重复?
q个Ҏ的默认执行结果是自动处理HTTP HEAD操作Q这个方法不需要被一个子cL行?
4、doOptions
protected void doOptions(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
被这个类的serviceҎ调用Q用来处理一个HTTP OPTION操作。这个操作自动地军_支持哪一UHTTPҎ。例如,一个Servlet写了一个HttpServlet的子cdƈ重蝲了doGetҎQdoOption会返回下面的_
Allow: GET,HEAD,TRACE,OPTIONS
你一般不需要重载这个方法?
5、doPost
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
被这个类的serviceҎ调用Q用来处理一个HTTP POST操作。这个操作包含请求体的数据,Servlet应该按照他行事?
q个操作可能有负面媄响。例如更新存储的数据或在U购物?
q一Ҏ的默认执行结果是q回一个HTTP BAD_REQUEST错误。当你要处理POST操作Ӟ你必dHttpServlet的子cM重蝲q一Ҏ?
6、doPut
protected void doPut(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
被这个类的serviceҎ调用Q用来处理一个HTTP PUT操作。这个操作类g通过FTP发送文件?
q个操作可能有负面媄响。例如更新存储的数据或在U购物?
q一Ҏ的默认执行结果是q回一个HTTP BAD_REQUEST错误。当你要处理PUT操作Ӟ你必dHttpServlet的子cM重蝲q一Ҏ?
7、doTrace
protected void doTrace(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
被这个类的serviceҎ调用Q用来处理一个HTTP TRACE操作。这个操作的默认执行l果是生一个响应,q个响应包含一个反映traceh中发送的所有头域的信息?
当你开发ServletӞ在多数情况下你需要重载这个方法?
8、getLastModified
protected long getLastModified(HttpServletRequest request);
q回q个h实体的最后修Ҏ间。ؓ了支持GET操作Q你必须重蝲q一ҎQ以_地反映最后修改的旉。这有助于览器和代理服务器减装载服务器和网l资源,从而更加有效地工作。返回的数值是?970-1-1日(GMTQ以来的毫秒数?
默认的执行结果是q回一个负敎ͼq标志着最后修Ҏ间未知,它也不能被一个有条g的GET操作使用?
9、service
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException;
q是一个Servlet的HTTP-specificҎQ它分配h到这个类的支持这个请求的其他Ҏ?
当你开发ServletӞ在多数情况下你不必重载这个方法?

八、HttpSessionBindingEventc\
定义\
public class HttpSessionBindingEvent extends EventObject
q个事g是在监听到HttpSession发生l定和取消绑定的情况时连通HttpSessionBindingListener的。这可能是一个session被终止或被认定无效的l果?
事g源是HttpSession.putValue或HttpSession.removeValue?
构造函?
public HttpSessionBindingEvent(HttpSession session, String name);
通过引vq个事g的Session和发生绑定或取消l定的对象名构造一个新的HttpSessionBindingEvent?
Ҏ
1、getName
public String getName();
q回发生l定和取消绑定的对象的名字?
2、getSession
public HttpSession getSession();
q回发生l定和取消绑定的session的名字?

九、HttpUtilsc\
定义\
public class HttpUtils
攉HTTP Servlet使用的静态的有效的方法?
Ҏ
1、getRequestURL
public static StringBuffer getRequestURL(HttpServletRequest
request);
在服务器上重建客L用来建立h的URL。这个方法反映了不同的协议(例如http和httpsQ和端口Q但不包含查询字W串?
q个Ҏq回一个StringBuffer而不是一个StringQ这样URL可以被Servlet开发者有效地修改?
2、parsePostData
public static Hashtable parsePostData(int len,
ServletInputstream in);
解析一个包含MIMEcdapplication/x-www-form-urlencoded的数据的,q创Z个具有关键?数据对的hash table。这里的关键值是字符Ԍ数据是该字符串所对应的值的列表。一个关键值可以在POST的数据中出现一ơ或多次。这个关键值每出现一ơ,它的相应的值就被加入到hash table中的字符串所对应的值的列表中?
从POST数据d的数据将l过URL解码Q?被转换为空g十六q制传送的数据Q例?xxQ将被{换成字符?
当POST数据无效Ӟ该方法抛Z个IllegalArgumentException?
3、parseQueryString
public static Hashtable parseQueryString(String s);
解析一个查询字W串Qƈ创徏一个具有关键?数据对的hash table。这里的数据是该字符串所对应的值的列表。一个关键值可以出Cơ或多次。这个关键值每出现一ơ,它的相应的值就被加入到hash table中的字符串所对应的值的列表中?
从查询字W串d的数据将l过URL解码Q?被转换为空g十六q制传送的数据Q例?xxQ将被{换成字符?
当查询字W串无效Ӟ该方法抛Z个IllegalArgumentException?

Java Servlet API说明文档Q?.1a版)Q四Q?
术语表\r
bytecode
字节码:由Java~译器和Java解释E序生成的机器代码?
cookie
由Web服务器徏立的数据Q该数据存储在用L计算ZQ提供了一个Web站点跟踪用户的参数ƈ存储在用戯q盘上的方法?
HTTP
文本传输协议。一个请求响应协议用来连接WWW服务器向客户端浏览器传输HTML面?
输入对象\r
一个对象,由ServletInputStreamcd义,被Servlet用来从客Ldh?
映射\r
由Servlet实例和Servletq回数据的URLl成的一对,例如QHelloServlet?hello/index.html?
输出对象\r
一个对象,由ServletOutputStream classcd义,被Servlet用来向客Lq回数据?
request dispatcher object
由RequestDispatcher接口定义的一个对象,用来从客L接收hQƈ其发送到Web服务器上可用的其他资源(例如Servlet、CGI、HTML文g或JSP文gQ?
sandboxed servlet
在一个安全性约束下q行的Servlet?
servlet
一个小的,hq_无关性的Q没有图形用L面的JavaE序。它可以在许多方面扩充Web服务的功能?
servlet configuration object
ServletConfig接口定义的一个对象,用来配置一个Servlet?
servlet context object
ServletContext接口定义的一个对象。给予Servlet有关Servlet引擎的信息?
servlet引擎\r
由Web服务器提供商制作的一个环境,可以允许Servlet在具体的Web服务器上q行?
servleth对象
由ServletRequest接口定义的一个对象,允许Servlet获得用关客户端请求的数据?
servlet response object
由ServletResponse接口定义的一个对象,允许Servlet作出响应?
servlet runner
Java Servlet Developer’s Kit (JSDK)中的sun.servlet.http.HttpServerq程Q它使得Servlet得以q行?
会话跟踪
在一个Web应用E序中,识别一个从同一个客L发出的连l的唯一的请求的能力?
SSL
加密套接字协议层。一个安全协议,用来在Iternet上的客户端浏览器和服务器交换密钥和加密数据?
URI
l一资源标识。定义一个Internet地址Q它是一个URL的超集?
URL
l一资源路径。这个地址定义了到达一个WWW上的文g的\U,通常由协议前~、域名、目录名和文件名l成?


snowolf 2006-02-22 13:02 发表评论
]]>
J2EE 全面?/title><link>http://m.tkk7.com/snowolf/articles/30193.html</link><dc:creator>snowolf</dc:creator><author>snowolf</author><pubDate>Fri, 10 Feb 2006 10:08:00 GMT</pubDate><guid>http://m.tkk7.com/snowolf/articles/30193.html</guid><wfw:comment>http://m.tkk7.com/snowolf/comments/30193.html</wfw:comment><comments>http://m.tkk7.com/snowolf/articles/30193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/snowolf/comments/commentRss/30193.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/snowolf/services/trackbacks/30193.html</trackback:ping><description><![CDATA[本文从五个方面对J2EEq行了比较全面的介绍。从J2EE的概念说P到它的优势,到J2EE典型的四层模型,和它的框架结构,最后是J2EE十三U核心技术的一个简介。本文分门别cȝ对J2EE中的服务Q组Ӟ层次Q容器,API都做了比较详l的介绍Q相信看完此文,读者会对J2EE有一个更清晰的认识?BR><BR>一. J2EE的概?BR>目前QJava 2q_?个版本,它们是适用于小型设备和卡的Java 2q_Micro版(Java 2 Platform Micro EditionQJ2MEQ、适用于桌面系l的Java 2q_标准版(Java 2 Platform Standard EditionQJ2SEQ、适用于创建服务器应用E序和服务的Java2q_企业版(Java 2 Platform Enterprise EditionQJ2EEQ?BR>J2EE是一U利用Java 2q_来简化企业解x案的开发、部|和理相关的复杂问题的体系l构。J2EE技术的基础是核心Javaq_或Java 2q_的标准版QJ2EE不仅巩固了标准版中的许多优点Q例?~写一ơ、随处运?的特性、方便存取数据库的JDBC API、CORBA技术以及能够在Internet应用中保护数据的安全模式{等Q同时还提供了对 EJBQEnterprise JavaBeansQ、Java Servlets API、JSPQJava Server PagesQ以及XML技术的全面支持。其最l目的就是成Z个能够企业开发者大q羃短投攑ָ场时间的<BR>体系l构?BR>J2EE体系l构提供中间层集成框架用来满x需太多费用而又需要高可用性、高可靠性以及可扩展性的应用的需求。通过提供l一的开发^収ͼJ2EE降低了开发多层应用的费用和复杂性,同时提供对现有应用程序集成强有力支持Q完全支持Enterprise JavaBeansQ有良好的向导支持打包和部v应用Q添加目录支持,增强了安全机Ӟ提高了性能?BR><BR>? J2EE的优?BR>J2EE为搭建具有可伸羃性、灵zL、易l护性的商务pȝ提供了良好的机制:<BR>保留现存的IT资: ׃企业必须适应新的商业需求,利用已有的企业信息系l方面的投资Q而不是重新制定全盘方案就变得很重要。这P一个以渐进的(而不是激q的Q全盘否定的Q方式徏立在已有pȝ之上的服务器端^台机制是公司所需求的。J2EE架构可以充分利用用户原有的投资,如一些公怋用的BEA Tuxedo、IBM CICS, IBM Encina,、Inprise VisiBroker 以及Netscape Application Server。这之所以成为可能是因ؓJ2EE拥有q泛的业界支持和一些重要的'企业计算'领域供应商的参与。每一个供应商都对现有的客h供了不用废弃已有投资Q进入可UL的J2EE领域的升U途径。由于基于J2EEq_的品几乎能够在M操作pȝ和硬仉|上q行Q现有的操作pȝ和硬件也<BR>能被保留使用?BR>高效的开? J2EE允许公司把一些通用的、很J琐的服务端d交给中间件供应商d成。这样开发h员可以集中精力在如何创徏商业逻辑上,相应地羃短了开发时间。高U中间g供应商提供以下这些复杂的中间件服?<BR>状态管理服?-- 让开发h员写更少的代码,不用兛_如何理状态,q样能够更快地完成程序开发?BR>持箋性服?-- 让开发h员不用对数据讉K逻辑q行~码p~写应用E序Q能生成?BR>dyQ与数据库无关的应用E序Q这U应用程序更易于开发与l护?BR>分布式共享数据对象CACHE服务 -- 让开发h员编刉性能的系l,极大提高整体部v?BR>伸羃性?BR>支持异构环境: J2EE能够开发部|在异构环境中的可移植程序。基于J2EE的应用程序不<BR>依赖M特定操作pȝ、中间g、硬件。因此设计合理的ZJ2EE的程序只需开发一?BR>可部v到各U^台。这在典型的异构企业计算环境中是十分关键的。J2EE标准也允?BR>客户订购与J2EE兼容的第三方的现成的lgQ把他们部v到异构环境中Q节省了p?BR>制订整个Ҏ所需的费用?BR>可׾~? 企业必须要选择一U服务器端^収ͼq种q_应能提供极佳的可伸羃性去满那些在他们系l上q行商业q作的大Ҏ客户。基于J2EEq_的应用程序可被部|到各种操作pȝ上。例如可被部|到高端UNIX与大型机pȝQ这U系l单机可支持64?56个处理器。(q是NT服务器所望尘莫及的)J2EE领域的供应商提供了更为广泛的负蝲q{略。能消除pȝ中的瓉Q允许多台服务器集成部v。这U部|可达数千个处理器,实现可高度׾~的pȝQ满x来商业应用的需要?BR>E_的可用? 一个服务器端^台必能全天候运转以满公司客户、合作伙伴的需要。因为INTERNET是全球化的、无处不在的Q即使在夜间按计划停Z可能造成严重损失。若是意外停机,那会有灾难性后果。J2EE部v到可靠的操作环境中,他们支持长期的可用性。一些J2EE部v在WINDOWS环境中,客户也可选择健壮性能更好的操作系l如Sun Solaris、IBM OS/390。最健壮的操作系l可辑ֈ99.999%的可用性或每年只需5分钟停机旉。这是实时性很强商业系l理想的选择?BR><BR><BR>? J2EE 的四层模?BR>J2EE使用多层的分布式应用模型Q应用逻辑按功能划分ؓlgQ各个应用组件根据他?BR>所在的层分布在不同的机器上。事实上Qsun设计J2EE的初h是ؓ了解决两层模?cl<BR>ient/server)的弊端,在传l模式中Q客L担当了过多的角色而显得臃肿,在这U模<BR>式中Q第一ơ部|的时候比较容易,但难于升U或改进Q可伸展性也不理惻I而且l常<BR>Z某种专有的协议――通常是某U数据库协议。它使得重用业务逻辑和界面逻辑非常<BR>困难。现在J2EE 的多层企业应用模型两层化模型中的不同层面切分成许多层。一?BR>多层化应用能够ؓ不同的每U服务提供一个独立的层,以下?J2EE 典型的四层结?<BR>q行在客L机器上的客户层组?BR>q行在J2EE服务器上的Web层组?BR>q行在J2EE服务器上的业务逻辑层组?BR>q行在EIS服务器上的企业信息系l?Enterprise information system)层Y?BR>J2EE应用E序lg<BR>J2EE应用E序是由lg构成?J2EElg是具有独立功能的软g单元Q它们通过相关的类<BR>和文件组装成J2EE应用E序Qƈ与其他组件交互。J2EE说明书中定义了以下的J2EElg<BR>:<BR>应用客户端程序和applets是客户层lg.<BR>Java Servlet和JavaServer Pages(JSP)是web层组?<BR>Enterprise JavaBeans(EJB)是业务层lg.<BR>客户层组?BR>J2EE应用E序可以是基于web方式?也可以是Z传统方式?<BR>web 层组件J2EE web层组件可以是JSP 面或Servlets.按照J2EE规范Q静态的HTML面<BR><BR><BR>和Applets不算是web层组件?BR>正如下图所C的客户层那Pweb层可能包含某?JavaBean 对象来处理用戯入,q把<BR>输入发送给q行在业务层上的enterprise bean 来进行处理?BR>业务层组?BR>业务层代码的逻辑用来满银行Q零售,金融{特D商务领域的需?p行在业务层上<BR>的enterprise bean q行处理. 下图表明了一个enterprise bean 是如何从客户端程?BR>接收数据Q进行处?如果必要的话), q发送到EIS 层储存的Q这个过E也可以逆向q?BR>行?BR>有三U企业的bean: 会话(session) beans, 实体(entity) beans, ?消息驱动(mes<BR>sage-driven) beans. 会话bean 表示与客LE序的时交? 当客LE序执行完后<BR>, 会话bean 和相x据就会消? 相反, 实体bean 表示数据库的表中一行永久的记录<BR>. 当客LE序中止或服务器关闭? ׃有潜在的服务保证实体bean 的数据得以保?BR>.消息驱动 bean l合了会话bean ?JMS的消息监听器的特? 允许一个业务层lg?BR>步接收JMS 消息.<BR>企业信息pȝ?BR>企业信息pȝ层处理企业信息系lY件包括企业基pȝ例如企业资源计划 (ERP)<BR>, 大型Z务处? 数据库系l?和其它的遗留信息pȝ. 例如QJ2EE 应用lg可能?BR>了数据库q接需要访问企业信息系l?BR>? J2EE 的结?BR>q种ZlgQ具有^台无x的J2EE l构使得J2EE E序的编写十分简单,因ؓ业务<BR>逻辑被封装成可复用的lgQƈ且J2EE 服务器以容器的Ş式ؓ所有的lgcd提供后台<BR>服务. 因ؓ你不用自己开发这U服? 所以你可以集中_֊解决手头的业务问?<BR><BR><BR>容器和服?BR>容器讄定制了J2EE服务器所提供得内在支持,包括安全Q事务管理,JNDI(Java Nami<BR>ng and Directory Interface)d,q程q接{服务,以下列出最重要的几U服务:<BR>J2EE安全(Security)模型可以让你配置 web lg或enterprise bean ,q样只有被授?BR>的用h能访问系l资? 每一客户属于一个特别的角色Q而每个角色只允许Ȁzȝ?BR>的方法。你应在enterprise bean的布|描qC声明角色和可被激zȝҎ。由于这U声<BR>明性的ҎQ你不必~写加强安全性的规则?BR>J2EE 事务理QTransaction ManagementQ模型让你指定组成一个事务中所有方法间?BR>关系Q这样一个事务中的所有方法被当成一个单一的单? 当客LȀzM个enterpri<BR>se bean中的ҎQ容器介入一理事务。因有容器管理事务,在enterprise bean中不<BR>必对事务的边界进行编码。要求控制分布式事务的代码会非常复杂。你只需在布|描q?BR>文g中声明enterprise bean的事务属性,而不用编写ƈ调试复杂的代码。容器将L?BR>件ƈZ处理此enterprise bean的事务?BR>JNDI d(JNDI Lookup)服务向企业内的多重名字和目录服务提供了一个统一的接?q?BR>样应用程序组件可以访问名字和目录服务.<BR>J2EEq程q接QRemote Client ConnectivityQ模型管理客L和enterprise bean间的<BR>低层交互. 当一个enterprise bean创徏? 一个客L可以调用它的Ҏp它和客户<BR>端位于同一虚拟Z一?<BR>生存周期理QLife Cycle ManagementQ模型管理enterprise bean的创建和U除,一?BR>enterprise bean在其生存周期中将会历l几U状态。容器创建enterprise beanQƈ?BR>可用实例池与zd状态中Ud他,而最l将其从容器中移除。即使可以调用enterprise<BR>bean的create及removeҎQ容器也会在后台执行这些Q务?BR><BR><BR>数据库连接池QDatabase Connection PoolingQ模型是一个有价值的资源。获取数据库<BR>q接是一耗时的工作,而且q接数非常有限。容器通过理q接池来~和q些问题?BR>enterprise bean可从池中q速获取连接。在bean释放q接之可为其他bean使用?BR>容器cd<BR>J2EE应用lg可以安装部vC下几U容器中?<BR>EJB 容器理所有J2EE 应用E序中企业bean 的执? enterprise bean 和它们的?BR>器运行在J2EE 服务器上.<BR>Web 容器理所有J2EE 应用E序中JSP面和Servletlg的执? Web lg和它们的?BR>器运行在J2EE 服务器上.<BR>应用E序客户端容器管理所有J2EE应用E序中应用程序客Llg的执? 应用E序?BR>L和它们的容器q行在J2EE 服务器上.<BR>Applet 容器是运行在客户端机器上的web览器和 Java 插g的结?<BR>? J2EE的核心API与组?BR>J2EEq_׃整套服务QServicesQ、应用程序接口(APIsQ和协议构成Q它对开发基<BR>于Web的多层应用提供了功能支持Q下面对J2EE中的13U技术规范进行简单的描述(限于<BR>幅Q这里只能进行简单的描述):<BR>JDBC(Java Database Connectivity):<BR>JDBC API问不同的数据库提供了一U统一的途径Q象ODBC一PJDBC对开发者屏?BR>了一些细节问题,另外QJDCBҎ据库的访问也hq_无关性?BR>JNDI(Java Name and Directory Interface):<BR>JNDI API被用于执行名字和目录服务。它提供了一致的模型来存取和操作企业U的资源<BR>如DNS和LDAPQ本地文件系l,或应用服务器中的对象?BR><BR><BR>EJB(Enterprise JavaBean):<BR>J2EE技术之所以赢得某体广泛重视的原因之一是EJB。它们提供了一个框架来开发和?BR>施分布式商务逻辑Q由此很显著地简化了h可׾~性和高度复杂的企业应用的开?BR>。EJB规范定义了EJBlg在何时如何与它们的容器进行交互作用。容器负责提供公用的<BR>服务Q例如目录服务、事务管理、安全性、资源缓冲池以及定w性。但q里值得注意?BR>是,EJBq不是实现J2EE的唯一途径。正是由于J2EE的开放性,使得有的厂商能够以一U?BR>和EJBq的方式来辑ֈ同样的目的?BR>RMI(Remote Method Invoke):<BR>正如其名字所表示的那PRMI协议调用q程对象上方法。它使用了序列化方式在客L<BR>和服务器端传递数据。RMI是一U被EJB使用的更底层的协议?BR>Java IDL/CORBA:<BR>在Java IDL的支持下Q开发h员可以将Java和CORBA集成在一赗?他们可以创徏Java?BR>象ƈ使之可在CORBA ORB中展开, 或者他们还可以创徏Javacdƈ作ؓ和其它ORB一起展开<BR>的CORBA对象的客戗后一U方法提供了另外一U途径Q通过它Java可以被用于将你的?BR>的应用和旧的pȝ盔R成?BR>JSP(Java Server Pages):<BR>JSP面由HTML代码和嵌入其中的Java代码所l成。服务器在页面被客户端所h以后?BR>q些Java代码q行处理Q然后将生成的HTML面q回l客L的浏览器?BR>Java Servlet:<BR>Servlet是一U小型的JavaE序Q它扩展了Web服务器的功能。作ZU服务器端的应用<BR>Q当被请求时开始执行,q和CGI Perl脚本很相伹{Servlet提供的功能大多与JSPcM<BR>Q不q实现的方式不同。JSP通常是大多数HTML代码中嵌入少量的Java代码Q而servlet<BR><BR><BR>s全部由Java写成q且生成HTML?BR>XML(Extensible Markup Language):<BR>XML是一U可以用来定义其它标记语a的语a。它被用来在不同的商务过E中׃n数据?BR>XML的发展和Java是相互独立的Q但是,它和Javah的相同目标正是^台独立性。通过<BR>Java和XML的组合,您可以得C个完的hq_独立性的解决Ҏ?BR>JMS(Java Message Service):<BR>MS是用于和面向消息的中间g怺通信的应用程序接?API)。它既支持点对点的域Q有<BR>支持发布/订阅(publish/subscribe)cd的域Qƈ且提供对下列cd的支持:l认可的<BR>消息传?事务型消息的传递,一致性消息和h持久性的订阅者支持。JMSq提供了?BR>一U方式来Ҏ的应用与旧的后台pȝ盔R成?BR>JTA(Java Transaction Architecture):<BR>JTA定义了一U标准的APIQ应用系l由此可以访问各U事务监控?BR>JTS(Java Transaction Service):<BR>JTS是CORBA OTS事务监控的基本的实现。JTS规定了事务管理器的实现方式。该事务理<BR>器是在高层支持Java Transaction API (JTA)规范Qƈ且在较底层实现OMG OTS specif<BR>ication的Java映像。JTS事务理器ؓ应用服务器、资源管理器、独立的应用以及通信<BR>资源理器提供了事务服务?BR>JavaMail:<BR>JavaMail是用于存取邮件服务器的APIQ它提供了一套邮件服务器的抽象类。不仅支持S<BR>MTP服务器,也支持IMAP服务器?BR>JTA(JavaBeans Activation Framework):<BR>JavaMail利用JAF来处理MIME~码的邮仉件。MIME的字节流可以被{换成Java对象Q或<BR><BR><BR>参考资料:<BR>《Develop n-tier application using J2EE? Steven Gould<BR>《The Business Benefits of EJB and J2EE Technologies over COM+ and Windows D<BR>NA?BR>《The J2EE Tutorial》chapter overview - Monica Pawlan<BR>本文所用图片由《The J2EE Tutorial》中的英文图片修改而成.<BR><img src ="http://m.tkk7.com/snowolf/aggbug/30193.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/snowolf/" target="_blank">snowolf</a> 2006-02-10 18:08 <a href="http://m.tkk7.com/snowolf/articles/30193.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vectorq是ArrayListq是个问?/title><link>http://m.tkk7.com/snowolf/articles/30184.html</link><dc:creator>snowolf</dc:creator><author>snowolf</author><pubDate>Fri, 10 Feb 2006 09:46:00 GMT</pubDate><guid>http://m.tkk7.com/snowolf/articles/30184.html</guid><wfw:comment>http://m.tkk7.com/snowolf/comments/30184.html</wfw:comment><comments>http://m.tkk7.com/snowolf/articles/30184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/snowolf/comments/commentRss/30184.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/snowolf/services/trackbacks/30184.html</trackback:ping><description><![CDATA[<EM>原文Qhttp://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html? <BR></EM><B>Vector q是ArrayList――哪一个更好,Z么?</B><BR>要回{这个问题不能一概而论Q有时候用Vector比较好;有时是ArrayListQ有时候这两个都不是最好的选择。你别指望能够获得一个简单肯定答案,因ؓq要看你用它们干什么。下面有4个要考虑的因素:<BR>l        API<BR>l        同步处理<BR>l        数据增长?BR>l        使用模式<BR>下面针对q?个方面进行一一探讨<BR><B>API </B><BR>在由Ken Arnold{编著的《Java Programming Language?Addison-Wesley, June 2000)一书中有这L描述QVectorcM于ArrayList.。所有从API的角度来看这两个c非常相<B>伹{但他们之间也还是有一些主要的区别的?BR><BR>[b]同步?/B><BR>Vector是同步的。这个类中的一些方法保证了Vector中的对象是线E安全的。而ArrayList则是异步的,因此ArrayList中的对象q不是线E安全的。因为同步的要求会媄响执行的效率Q所以如果你不需要线E安全的集合那么使用ArrayList是一个很好的选择Q这样可以避免由于同步带来的不必要的性能开销?BR><B>数据增长</B><BR>从内部实现机制来讲ArrayList和Vector都是使用数组(Array)来控刉合中的对象。当你向q两U类型中增加元素的时候,如果元素的数目超Z内部数组目前的长度它们都需要扩展内部数l的长度QVector~省情况下自动增长原来一倍的数组长度QArrayList是原来的50%,所以最后你获得的这个集合所占的I间L比你实际需要的要大。所以如果你要在集合中保存大量的数据那么使用Vector有一些优势,因ؓ你可以通过讄集合的初始化大小来避免不必要的资源开销?BR><B>使用模式</B><BR>在ArrayList和Vector中,从一个指定的位置Q通过索引Q查找数据或是在集合的末֢加、移除一个元素所p的时间是一LQ这个时间我们用O(1)表示。但是,如果在集合的其他位置增加或移除元素那么花费的旉会呈UŞ增长QO(n-i)Q其中n代表集合中元素的个数Qi代表元素增加或移除元素的索引位置。ؓ什么会q样呢?以ؓ在进行上q操作的时候集合中Wi和第i个元素之后的所有元素都要执行位Uȝ操作。这一切意味着什么呢Q?BR>q意味着Q你只是查找特定位置的元素或只在集合的末端增加、移除元素,那么使用Vector或ArrayList都可以。如果是其他操作Q你最好选择其他的集合操作类。比如,LinkList集合cd增加或移除集合中M位置的元素所p的时间都是一L—O(1)Q但它在索引一个元素的使用~比较慢QO(i),其中i是烦引的位置.使用ArrayList也很ҎQ因Z可以单的使用索引来代替创建iterator对象的操作。LinkList也会为每个插入的元素创徏对象Q所有你要明白它也会带来额外的开销?BR>最后,在《Practical Java》一书中Peter Haggar使用一个简单的数组QArrayQ来代替Vector或ArrayList。尤其是对于执行效率要求高的E序更应如此。因Z用数l?Array)避免了同步、额外的Ҏ调用和不必要的重新分配空间的操作?BR><BR><B>相关资源Q?/B><BR>·        《Java~程语言?作者:Ken Arnold, James Gosling, and David Holmes http://www.amazon.com/exec/obidos/ASIN/0201704331/javaworld/ <BR>·        《实?Java》作者: Peter Haggar  <BR>http://www.amazon.com/exec/obidos/ASIN/0201616467/javaworld/ <BR>·        更多内容L Java Q&A : <BR>http://www.javaworld.com/javaworld/javaqa/javaqa-index.html <BR><img src ="http://m.tkk7.com/snowolf/aggbug/30184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/snowolf/" target="_blank">snowolf</a> 2006-02-10 17:46 <a href="http://m.tkk7.com/snowolf/articles/30184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Annotations设计一个MVC框架http://m.tkk7.com/snowolf/articles/30169.htmlsnowolfsnowolfFri, 10 Feb 2006 07:56:00 GMThttp://m.tkk7.com/snowolf/articles/30169.htmlhttp://m.tkk7.com/snowolf/comments/30169.htmlhttp://m.tkk7.com/snowolf/articles/30169.html#Feedback0http://m.tkk7.com/snowolf/comments/commentRss/30169.htmlhttp://m.tkk7.com/snowolf/services/trackbacks/30169.htmlAnnotations能够帮助你去掉应用组件之间的耦合

摘要

Model-View-Controller (MVC)是一UY件架?它可以将应用E序的数据模?用户接口,以及控制逻辑分开, 使其成ؓ独立的组?q样一?对其中一个组件的修改而生的对其他组件的影响能够被降到最? 在这文章中,你将学习到如何用annotation来设计一个几乎能够完全去掉model和view之间耦合的承的MVC的框?

版权声明QQ何获得Matrix授权的网站,转蝲时请务必保留以下作者信息和链接
作?Riccardo Govoni;wenzi_33
原文:http://www.matrix.org.cn/resource/article/44/44204_Annotations+MVC.html
关键?annotations;MVC;Framework

当设计一个应用程序时, 清晰的分该E序的不同逻辑lg, L被证明是有益? 同时也存在许多不同的模式来帮助开发者实现这个目标。其中最有名同时也最常用的自然是Model-View-Controller (MVC)? 它能够将每个应用E序(或者应用程序的一部分)分成三个不同功能的组?q且定义了把他们联结在一L规则。Swing本n是Zq个模式?而且每个使用Struts,q个行的开发Web应用框架的h也都了解隐藏在MVC后面的理?

q篇文章介绍了怎么样通过使用annotation而增加一个新的组件来加强MVC,使其能够更加方便地去掉models跟views之间的耦合。这文章介l了一个叫Stamps的开源库, 它是ZMVClg之上?但它去除了所有在开发MVC时所需? 在models, views和controllers之间建立联系的负担?BR>
基础知识: MVC和annotations

正如MVCq个名字所指出? Model-View-Controller模式一个应用程序分成以下三个组?
·Model: 包含了数据模型和所有用来确定应用程序状态的信息?它一般来说是有条理的q且独立于其他组件的?BR>·View: 从不同于model的角度出?它定义了存储在模型中数据的展现方式。它通常被认为是你的应用E序的用L?或者GUI),或者以Web应用Z,场景是你通过览器看到的面?BR>·Controller: 它代表应用程序的逻辑部分。在q里,它定义了一个用户如何和应用E序q行交互q且也定义了用户行ؓ是如何映到model的改变?BR>
q些lg紧密的联pd一? 用户影响view, 反过来view通知controller来更新model.最lmodel又更新view来反映它的新状态。图1展Cq种典型的MVCl构?BR>
2006_02_08_232846_XtnRHlDmNe.jpg
?. 一个典型的MVCl构

作ؓJ2SE 5.0所提供的一个新的功能,annotations允许开发者往classesQmethodsQfieldsQ和其他E序元素中增加元数据。就像反机制一P之后很多应用E序Z某些原因能在q行时期获取q用那些元数据。因为J2SE 5.0只是定义了怎么L写和dannotationsQƈ没有说明在哪里用他们(象@Overrideq样的用于提前定义的例外Q,开发者拥有无I多的在许多不同场合使用他们的可能性:文档~写Q与对象相关的映,代码生成Q等{?. Annotations已经变的十分行Q以至于大多数框架和库都更新自己来支持他们。至于更多的关于MVC和annotations的信息请参见资源?BR>
越MVC: dispatcher

像前文提到的一Pmodels和views之间的一些耦合是必要的因ؓ后者必d映前者的状态。普通JavaE序使用直接或间接的耦合组件绑定在一赗直接耦合发生在当view和model之间有一个直接相关的时候,model包含一列需要维持的views。间接耦合通常发生在一个基于事件分z机制中。Model会在它状态改变时Ȁ发事Ӟ同时一些独立的views会将他们自己注册成事件侦听器?BR>
通常我们比较青睐间接耦合因ؓ它model完全不知道view的存在,相反view必须和model保持一定的联系从而将自己注册到model上。在q篇文章里我介l的框架是使用间接耦合Q但是ؓ了更好的降低lg之间的耦合Qview必须不知道model的存在;也就是说Qmodel和view没有被绑定在一赗?BR>
Z实现q个目标Q我已经定义了一个新的组Ӟ是dispatcherQ它能作Z个存在于views和models之间的分d。它能处理models和views双方之间的注册ƈ且分zmodelȀ发的事g到注册的views上。它使用java.beans.PropertyChangeEvent对象来表现由model传送到view的事Ӟ然而,q个框架的设计是_开攄Q它可以支持不同事gcd的实现?BR>
理注册的views列表的负担于是就从model上移开了,同时Q因为view只和q个独立于应用程序的dispatcher有关Qview不知道model的存在。如果你熟悉Struts内部Q你也许能够看出Struts的controller是在行这样一个Q务,它将Actions和他们关联的JSP(JavaServer Pages)表现面联系在一赗?BR>
现在Q我们所设计的MVC框架像?所描述的一栗Dispatcher在其中担当了一个于controller相称的角艌Ӏ?BR>
2006_02_08_233016_NNAtmqYNNs.jpg
?.拥有额外dispatcherlg的改q的MVC框架

׃dispatcher必须是独立于应用E序的,所以必d义一些通用的联lmodels和views的规范。我们将使用annotations来实现这U联l,它将会被用来标注viewsq且定哪个view是受哪个model的媄响的Q及q种影响是怎么L。通过q种方式Qannotations像是脓在明信片上的邮票一P驱动dispatcher来执行传递model事g的Q?q就是这一框架名字的由??BR>

应用实例

我们用一个简单的计秒器应用程序做该框架的一个应用实例:它允许用戯|时间周期来记数和启?停止q个定时器?一旦过去规定的旉Q用户将会被询问是否取消或者重启这个定时器。这个应用程序的完全源代码可以从目主页上找到?BR>
2006_02_08_233211_otZImPhZpB.jpg
?.一个简单的应用E序

q个modle是非常简单的Q它只存储两个属性:周期和已l过ȝU数。注意当它其中一个属性发生变化时它是如何使用java.beans.PropertyChangeSuppor来激发事件?BR>
public class TimeModel {

   public static final int DEFAULT_PERIOD = 60;

   private Timer timer;
   private boolean running;

   private int period;
   private int seconds;

   private PropertyChangeSupport propSupport;

   /**
    * Getters and setters for model properties.
    */

   /**
    * Returns the number of counted seconds.
    *
    * @return the number of counted seconds.
    */
   public int getSeconds() {
      return seconds;
   }

   /**
    * Sets the number of counted seconds. propSupport is an instance of PropertyChangeSupport
    * used to dispatch model state change events.
    *
    * @param seconds the number of counted seconds.
    */
   public void setSeconds(int seconds) {
      propSupport.firePropertyChange("seconds",this.seconds,seconds);
      this.seconds = seconds;
   }

   /**
    * Sets the period that the timer will count. propSupport is an instance of PropertyChangeSupport
    * used to dispatch model state change events.
    *
    * @param period the period that the timer will count.
    */
   public void setPeriod(Integer period){
      propSupport.firePropertyChange("period",this.period,period);
      this.period = period;
   }

   /**
    * Returns the period that the timer will count.
    *
    * @return the period that the timer will count.
    */
   public int getPeriod() {
      return period;
   }

   /**
    * Decides if the timer must restart, depending on the user answer. This method
    * is invoked by the controller once the view has been notified that the timer has
    * counted all the seconds defined in the period.
    *
    * @param answer the user answer.
    */
   public void questionAnswer(boolean answer){
      if (answer) {
         timer = new Timer();
         timer.schedule(new SecondsTask(this),1000,1000);
         running = true;
      }
   }

   /**
    * Starts/stop the timer. This method is invoked by the controller on user input.
    */
   public void setTimer(){
      if (running) {
         timer.cancel();
         timer.purge();
      }
      else {
         setSeconds(0);
         timer = new Timer();
         timer.schedule(new SecondsTask(this),1000,1000);
      }

      running = !running;
   }

   /**
    * The task that counts the seconds.
    */
   private class SecondsTask extends TimerTask {

      /**
       * We're not interested in the implementation so I omit it.
       */

   }
}


Controller只定义了用户可以执行的ƈ且能够从下列接口抽象出来的actions?BR>
public interface TimeController {

   /**
    * Action invoked when the user wants to start/stop the timer
    */
   void userStartStopTimer();

   /**
    * Action invoked when the user wants to restart the timer
    */
   void userRestartTimer();

   /**
    * Action invoked when the user wants to modify the timer period
    *
    * @param newPeriod the new period
    */
   void userModifyPeriod(Integer newPeriod);
}


你可以用你自己喜欢的GUI~辑器来画这个view。出于我们自w的情况Q我们只需要几个公qmethods可以提供够的功能来更新view的fieldsQ如下面的这个例子所C:
/**
    * Updates the GUI seconds fields
    */
   public void setScnFld(Integer sec){
      // scnFld is a Swing text field
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            scnFld.setText(sec.toString());
         }
      });
   }


在这里我们注意到我们正在使用POJOs (plain-old Java objects)Q同时我们不用遵守Q何编码习惯或者实现特定的接口(事gȀ发代码除?。剩下的只有定义组件之间的l定了?BR>
事g分派annotations

l定机制的核心就是@ModelDependent annotation的定义:
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD)
public @interface ModelDependent {

   String modelKey() default "";

   String propertyKey() default "";

   boolean runtimeModel() default false;

   boolean runtimeProperty() default false;

}


q个annotation能被用在view的methods上,同时dispatcher也会使用q些提供的参?即modelKey和propertyKey)来确定这个view会响应的model事g。这个view既用modelKey参数来指定它感兴的可利用的models又用propertyKey参数来匹配分配的java.beans.PropertyChangeEvents的属性名U?BR>
View method setScnFld()因此被标注以下信?q里QtimeModel提供了用来将model注册到dispatcher上的key):
/**
    * Updates the GUI seconds fields
    */
   @ModelDependent(modelKey = "timeModel", propertyKey = "seconds")
   public void setScnFld(final Integer sec){
      // scnFld is a Swing text field
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            scnFld.setText(sec.toString());
         }
      });
   }


׃dispatcher既知道modelȀ发的事g又知道事件本w-例如Q它知道兌的modelKey和propertyKeyQ这是唯一需要用来绑定views和models的信息。Model和view甚至不需要分享通信接口或者共用的数据库?BR>
借助我们讨论的绑定机Ӟ我们可以L的改变潜在的view而不改变其他M东西。下面的代码是按照用SWT(Standard Widget Toolkit)而不是Swing实现的同一个methodQ?BR>
@ModelDependent(modelKey = "timeModel", propertyKey = "seconds")
   public void setScnFld(final Integer sec){
      Display.getDefault().asyncExec(new Runnable() {
         public void run() {
            secondsField.setText(sec.toString());
         }
      });
   }


一个完全没有耦合的系l存在以下优点:View可以更加Ҏ地适应model地改变,管model通常都是E_圎ͼ相反view是经常被改变。加上系l可以通过使用GUI~辑器或者其他源码生成器来设计,避免了将生成C码与modelQview通信代码混合在一赗又׃modelQview的绑定信息是和源码关联的元数据,于是也相对容易把它应用到IDE生成的GUIs或者将已经存在的应用程序{化成q个框架。加之拥有单独的基础代码Qview和model可以被当作是独立lg来开发,q很可能化了应用E序的开发过E。组件测试也可以被简化,因ؓ每个lg可以被单独地试Qƈ且出于调试的目的Q我们可以用假的model和view来代替真实的lg?BR>
然而,q里也存在许多缺炏V因为现在当使用接口和公qclasses来绑定model和viewӞ我们不能再提供编译时期的安全性了Q可能出现的打字错误导致组件之间一个绑定的遗漏Q从而导致出现运行时期的错误?BR>
通过使用@ModelDependent的讨的modelKey和propertyKey元素Q你可以定义model和view之间静态的联系。然而,现实世界的应用程序证明view必须能够l常动态的适应变化的models和应用程序的状态:考虑到用L面的不同部分能够在应用程序的生命周期内被创造和删除。因此我介l怎么使用q个框架与其他常用技术一h处理此类情Ş?BR>
动态MVCl定

对于那些依赖XMLl定(或者其他一些基于配|文件的声明性绑?的框Ӟ存在一个问题那是静态绑定规则。在q些框架下,动态变化是不可能的Q于是通常开发者决定每ơ将冗余的绑定信息与一些用正绑定的判定法耦合在一赗?BR>
Z巧妙的解册个问题,Stamps框架提供了两U方式在q行时期改变l定?W一U方式是Qviews和models可以采用事g监听器与GUIH口部件联合的方式在dispatcher上注册和注销。这样允许特定的views只在需要他们的时候被通知到。例如,一个与应用E序有联pȝ监视控制台可以只在用戯求的时候与被它监视的对象绑定在一赗?BR>
W二U方式是利用@ModelDependent annotation提供的两个元素runtimeModel() ?runtimeProperty()。他们指明了某个定的model和它的分配事件会在运行时期被定。如果这两个讑֮中有一个是正确的,那么各自的key(modelKey 或propertyKey)会在view上被method调用来得到需要用的倹{例如:一个负责显CZl新channels (每个channel是一个model)的viewQ它׃赖于用户的输入来定需要绑定的channel?BR>
q种情Ş的实例如下:
// This method is invoked to display all the messages of one news channel
   @ModelDependent(modelKey = "dynamicChannel", propertyKey = "allmessages" , runtimeModel = true)
   public void setAllMessages(java.util.List messages) {
      // Updates the user interface
   }

   public String getDynamicChannel() {
      // Returns the channel requested by the user
   }


附加的annotations

׃世界q不完美Q一些附加的annotations被定义来帮助解决现实世界的案例。@Namespace允许开发者ؓ了更好的理model domain其再细分成不同的部分。由于单独一个dispatcher可以处理多个modelsQmodel keys中将出现的冲H。因此,它能成的models和相关的views分到不同的但同属一个namespace下的domains中去, q样一来,他们׃会干扰对斏V?BR>
@Transform annotation提供了on-the-fly对象转化, 从包含在model事g中的对象到被receiving views接受的对象的。因而,q个框架可以适应已存的代码而不需要做M的改动。这个annotation接受一个注册在有效转化上的单一参数(被定义成一个特D接口的实现)?BR>
@Refreshable annotation能通过标注model的属性来支持前面讨论的动态连接和分离views。用这个annotationQ该框架可以处理静态和动态的MVC布局Q在不同的时间把不同的viewsl定到model上?BR>
要理解@Refreshable的用,我们必须回到之前的那个监控控制台的例子。这个控制台(用MVC的术语来说就是一个view)可以动态地l定和离开modelQ取决于用户的需要。当控制器连接到model的时候@Refreshable annotation可以被用来让q个控制器随时了解其model的状态。当一个viewq接到这个框架时Q它必须在当前model的状态下被更新。因此,dispatcher扫描modelL@Refreshable annotationsq且生成与view它本w从model普通接受到的相同的事g。这些事件接着被之前讨的绑定机制分z?BR>
分布式MVC|络

Dispatcher有一个很重的负担那就是它负责处理事g的传送周期中所有重型信息的传递:
·        ModelȀ发一个事件用来确定它已经l历q的一些改? dispatcher处理通知model.
·        Dispatcher扫描所有注册在它那里的views, L@ModelDependent annotations, q些annotations明确了views希望通知的改变及当每个model事g发生?需要在views上调用的method.
·        如果需?转化会被用于事件数据上.
·        view method在被调用时会从被Ȁ发的事g里抽取参?接着view会更新自?

从另一个方面来?当一个新view在dispatcher上注册时:
·        View告诉dispatcher有关modelKey的信?modelkey能确定它被q接到哪一个model?该model的事件将负责l装view)
·        如果需要,dispatcher扫描modelL@Refreshable annotationsq用他们来生񔞮要及时更新view假的model事g
·        q些事g通过使用上述的顺序被分派, 接着view被更?

所有这些既不涉及view也不涉及model的工?他们站在他们各自的信息通信渠道的两?无所谓这些信息是在一个本地JVM内部传输q是在多个远E主Z的JVM之间传输.如果惛_本地应用E序转化成Client/Server应用E序所需的只是简单地改变dispatcher里面的逻辑,而model和view都不会受影响.下图是一个示? 

2006_02_08_233827_rlIDvGWfPI.jpg 
?. 一个基于分布式|\建立的MVC.

如上图所C?单一的dispatcher被一个与model处在同一个host上的transmitter(it.battlehorse.stamps.impl.BroadcastDispatcher的一个instance)和一?或多? 与view处在同一个host上的receiver(it.battlehorse.stamps.impl.FunnelDispatcher)所取代. Stamps 框架默认的实C用了一个创ZJGroups上的消息传送层, JGroups是一个可靠的多点传送通信的工具包,象网l传输机?但是不同的实现和使用)一样工? 通过使用它可以获得一个稳定可靠的, 多协议的, p|警觉的通信.

Ҏ们应用程?dispatcher)初步建立的一个改? 使我们从一个单一用户界面的独立运行的应用E序转移C个多用户分布式的应用E序.当modelq入或离开q个|络(惌一个通信p|)的时?框架可以通知无数的监听接? 于是q程views可以采取适当的响?例如,昄一个警告信息给用户. q个框架也可以提供有用的methods来帮助将本地的controllers转化成远E的.

ȝ和摘?/SPAN>
仍有许多元素需要被探烦,像设计controllers的方式一?它在目前和dispatchersh一致的普遍?该框架假设普通的controller-modell定,׃前者需要知道如何去驱动后?未来的开发方向将是支持不同类型的views,例如使用一个Web览? |络警觉的applets,和Java与JavaScript的通信.

已经讨论的Stamps库说明如何在一个MVC架构中降低views和models之间的耦合以及q个框架可以有效的利用Java annotations绑定信息从实际开发程序组件分d.拥有隔离的绑定逻辑允许你在物理上将元g分离开q且能提供一个本地和一个client/serverl构而不需要改变应用逻辑或者表C层. q些目标提供对由一个象MVC一样坚固的设计模式与由annotations提供的功能强大的元数据结合在一h提供的可能性的z察.  

关于作?/B>
Riccardo Govoni自从2003q开始就做ؓ一名J2EE的开发者在一家位于意大利北部的金融服务公司工?在那?他ؓ遗留的银行系l?数据库管?和繁重的数据处理d开发了许多Web前台. Govoni在J2EE多层应用E序斚w拥有丰富l验q且拥有关于Java GUI 库象Swing 和SWT详尽的知?他拥有物理学士学位.在闲暇时?Govoni在网l上四处L最新的Java新闻,或者与朋友?有时?他女朋友的狗一赯论新的项目主?

资源
·        Stamps目主页,及相x码文件和文档:http://sourceforge.net/projects/stamps-mvc/
·        Wikipedia上关于MVC的定?http://en.wikipedia.org/wiki/MVC
·        最有名的MVC实现之一, Struts Web 应用框架:http://struts.apache.org/
·        JGoodies l定Q一个在Swing应用E序中解决model-view-controllerl定的不同方?https://binding.dev.java.net/
·        TikeSwing, 一个基于Swing之上的开源框? 通过扩展Swing widgets来引入MVC “与l合Swing来用高层次的MVC和POJOs?Tomi Tuomainen(JavaWorld, 2005q六?:http://www.javaworld.com/javaworld/jw-06-2005/jw-0620-tikeswing.html
·        Sun J2SE 5.0 annotations向导:http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
·        J2SE 5.0 annotations 入门介绍: “Taming Tiger, W三部分,?Tarak Modi(JavaWorld, 2004q七?:http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-tiger3.html
·        “零距离: J2SE 5.0 Annotations,?Kyle Downey (ONJava.com, 2004q十?:http://www.onjava.com/pub/a/onjava/2004/10/06/anno1.html
·        JGroups, 是一个可靠的多点传送通信的工具包, 在分布式Stamps MVC|络中象传输层一样工?http://www.jgroups.org/javagroupsnew/docs/index.html
·        “一个Swing架构的一般了解? 作? Amy Fowler(Sun开发者网l?讨论Swing’s MVC的根?http://java.sun.com/products/jfc/tsc/articles/architecture/

snowolf 2006-02-10 15:56 发表评论
]]>
վ֩ģ壺 þۺϸϾþù| ޾ƷۺϾþһ| ִӲִֻƵƵѿ | 2020þþƷۺһ| a vרav| Ƶ߹ۿѿƬ| 88avѹۿ| ˮƵ߹ۿѲŸ | ˳| þþƷAV鶹| ޹Ʒyw| Ʒѿþþ| һѹۿߵӰ| 99ƷƵѹۿ| aƬѹۿƵ| ԻAVƬѲŲ | ձһۺϾþa| ۺɫƵ| ѹվ߹ۿƵ| 99þó˹Ʒ| վ߹ۿ| Ʒպһ| ޹AV| vavavaֻ| ޳aƬվ| þAV˳׽ | ƷһƵ߹ۿ| ɫͷۺƵ| ѸһëƬ| ŷxƵ| ˾ҹƷƵ| ޾Ʒ| װɫƵ| һһͰһƵ| һƬѿ| һ| jŮjڲվ| Ȱ׽һ| ŷһëƬ| þþƷѹۿͬ | ɫרһ|