??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲制服丝袜中文字幕,亚洲精品无码久久久久A片苍井空,中文字幕不卡亚洲http://www.tkk7.com/doulei/zh-cnMon, 12 May 2025 14:30:34 GMTMon, 12 May 2025 14:30:34 GMT60一个用于J2EE应用E序的异常处理框?转蝲)http://www.tkk7.com/doulei/archive/2006/07/04/56495.htmlHello JavaHello JavaTue, 04 Jul 2006 03:15:00 GMThttp://www.tkk7.com/doulei/archive/2006/07/04/56495.htmlhttp://www.tkk7.com/doulei/comments/56495.htmlhttp://www.tkk7.com/doulei/archive/2006/07/04/56495.html#Feedback0http://www.tkk7.com/doulei/comments/commentRss/56495.htmlhttp://www.tkk7.com/doulei/services/trackbacks/56495.html 转自Qhttp://dev2dev.bea.com.cn/techdoc/20060601803.html
一个用于J2EE应用E序的异常处理框?/span>

旉Q?006-06-01
作者:(x)ShriKant Vashishtha
览ơ数Q? 1184
本文关键字:(x)J2EE, (tng)Struts, (tng)RuntimeException, (tng)design patterns, (tng)最?jng)_?/a>, (tng)异常处理, (tng)包装, (tng)设计模式, (tng)外观, (tng)模板Ҏ(gu)
文章工具
推荐l朋? align= (tng)推荐l朋?/a>
打印文章 (tng)
打印文章

  在大多数Java目中,大部分代码都是样板代码。异常处理就属于此类代码。即使业务逻辑只有3?行代码,用于异常处理的代码也要占10? 20行。本文将讨论如何让异常处理保持简单和直观Q开发h员可以专?j)于开发业务逻辑Q而不是把旉费在编写异常处理的h代码上。本文还说明用于在 J2EE环境中创建和处理异常的基知识和指导原则,q提Z(jin)一些可以用异常解决的业务问题。本文将使用Struts框架作ؓ(f)表示实现Q但该方法适用于Q何表C实现?/p>

使用checked和unchecked异常的场?/h3>

  (zhn)是否曾l想q,Z么要在编写好的代码块周围攄一个try-catch块,即便明知道无法对q些异常q行什么处理,而只满于把它们攑֜ catch块中Q?zhn)可能想知道,Z么不能把q项工作攑֜一个集中的地方完成Q在大多数情况下Q这个地方对于J2EE应用E序来说是一?a target="_blank">前端控制?/a>? 换句话说Q开发h员(sh)?x)因为它们而受到干扎ͼ因ؓ(f)Ҏ(gu)不必很多地过问它们。但是,如果一个方法名U包含一个throws子句Q会(x)出现什么情况呢Q开发h? 或者必L捉这些异常,或者把它们攑֜自己的方法的throws子句中。这是痛苦的根源!q运的是QJava API有一cd做unchecked exception的异常,它们不必捕捉。但是,仍然存在一个问题:(x)Ҏ(gu)什么来军_哪些是checked异常Q哪些是unchecked异常Q下面给Z 些指导原则:(x)

  • l端用户无法采取有效操作的异常应该作为unchecked异常。例如,致命的和不可恢复的异常就应该 是unchecked。把XMLParseExceptionQ在解析XML文g时抛出)(j)作ؓ(f)checked异常没有M意义Q因为惟一能够采取的措施就 是基于异常跟t来解决Ҏ(gu)问题。通过扩展java.lang.RuntimeExceptionQ可以创定义的unchecked异常?/li>
  • ? 应用E序中,与用h作相关的异常应该是checked异常。checked异常要求客户端来捕捉它们。?zhn)可能会(x)问Qؓ(f)什么不把所有异帔R当作? unchecked。这样做的问题在于,其中一些异常无法在正确的位|被捕捉到。这?x)带来更大的问题Q因为错误只有在q行时才能被识别。checked? 常的例子有业务确认异常、安全性异常等{?/li>

异常抛出{略

只捕捉基本应用程序异常(假定为BaseAppExceptionQƈ在throws子句中声?/h4>

  在大多数J2EE应用E序中,关于针对某个异常应该在哪一界面上显C哪条错误消息的决策只能在表C层中做出。这?x)带来另一个问题:(x)Z么我们不能把q种决策攑֜一个公q地方呢?在J2EE应用E序中,前端控制?/a>是一个进行常见处理的集中位置?/p>

   此外Q必L一U用于传播异常的通用机制。异怹需要以一U普适的方式得到处理。ؓ(f)此,我们始终需要在控制器端捕捉基本应用E序异常 BaseAppException。这意味着我们需要把BaseAppException异常Q只有这个异常)(j)攑օ可以抛出checked异常的每个方? 的throws子句中。这里的概念是用多态来隐藏异常的实际实现。我们在控制器中捕捉BaseAppExceptionQ但是所抛出的特定异常实例可? 是几个派生异常类中的L一个。借助于这U方法,可以获得许多异常处理斚w的灵zL:(x)

  • 不需要在throws子句中放入大量的checked异常。throws子句中只需要有一个异常?/li>
  • 不需要再对应用程序异怋用؜qcatch块。如果需要处理它们,一个catch块(用于BaseAppExceptionQ就_?jin)?/li>
  • 开发h员(sh)需要亲自进行异常处理(日志记录以及(qing)获取错误代码Q。这U抽象是由ExceptionHandler完成的,E后本文?x)就此点q行讨论?/li>
  • 即ɽE后把更多异常引入到Ҏ(gu)实现中,Ҏ(gu)名称也不?x)改变,因此也不需要修改客L(fng)代码Q否则就?x)引赯锁反应。然而,抛出的异帔R要在Ҏ(gu)的Javadoc中指定,以便让客L(fng)可以看到Ҏ(gu)U束?/li>

  下面l出抛出checked异常的一个例子:(x)

public void updateUser(UserDTO userDTO) 
throws BaseAppException{
UserDAO userDAO = new UserDAO();
UserDAO.updateUser(userDTO);
...
if(...)
throw new RegionNotActiveException(
"Selected region is not active");
}

Controller Method:
...
try{
User user = new User();
user.updateUser(userDTO);
}catch(BaseAppException ex){
//ExceptionHandler is used to handle
//all exceptions derived from BaseAppException
}
...

  q今为止Q我们已l说明,对于所有可能抛出checked异常q被Controller调用的方法,其throws子句中应该只包含 checked异常。然而,q实际上暗示着我们在throws子句中不能包含其他Q何应用程序异常。但是,如果需要基于catch块中某种cd的异常来? 行业务逻辑Q那又该怎么办呢Q要处理q类情况Q方法还可以抛出一个特定异常。记住,q是一U特例,开发h员绝对不能认是理所当然的。同P此处讨论? 应用E序异常应该扩展BaseAppExceptioncR下面给Z个例子:(x)

CustomerDAO method:
//throws CustomerNotActiveException along with
//BaseAppException
public CustomerDTO getCustomer(InputDTO inputDTO)
throws BaseAppException,
CustomerNotActiveException {
. . .
//Make a DB call to fetch the customer
//details based on inputDTO
. . .
// if not details found
throw new CustomerNotActiveException(
"Customer is not active");
}

Client method:

//catch CustomerNotActiveException
//and continues its processing
public CustomerDTO getCustomerDetails(
UserDTO userDTO)
throws BaseAppException{
...
CustomerDTO custDTO = null;
try{
//Get customer details
//from local database
customerDAO.getCustomerFromLocalDB();
}catch(CustomerNotActiveException){
...
return customerDAO
.activateCustomerDetails();
}
}

在web应用E序层次上处理unchecked异常

  所有unchecked异常都应该在web应用E序层次上进行处理。可以在web.xml文g中配|web面Q以便当应用E序中出现unchecked异常Ӟ可以把这个web面昄l终端用戗?/p>

把第三方异常包装到特定于应用E序的异怸

  当一个异常v源于另一个外部接口(lgQ时Q应该把它包装到一个特定于应用E序的异怸Qƈq行相应处理?/p>

  例子Q?/p>

try {
BeanUtils.copyProperties(areaDTO, areaForm);
} catch (Exception se) {
throw new CopyPropertiesException(
"Exception occurred while using
copy properties", se);
}

  q里QCopyPropertiesException扩展?jin)java.lang.RuntimeExceptionQ我们将?x)记录它。我们捕 捉的是ExceptionQ而不是copyPropertiesҎ(gu)可以抛出的特定checked异常Q因为对于所有这些异常来_(d)我们都会(x)抛出同一? unchecked CopyPropertiesException异常?/p>

q多异常

  (zhn)可能想知道Q如果我们ؓ(f)每条错误消息创徏一个异常,异常c自w是否会(x)溢出呢?例如Q如果“Order not found”是OrderNotFoundException的一条错误消息,(zhn)肯定不?x)让CustomerNotFoundException的错误消 息ؓ(f)“Customer not found”,理由很明显:(x)q两个异总表同L(fng)意义Q惟一的区别在于用它们的上下文不同。所以,如果可以在处理异常时指定上下文,我们无疑可以把这? 异常合ƈZ个RecordNotFoundException。下面给Z个例子:(x)

try{
...
}catch(BaseAppException ex){
IExceptionHandler eh =ExceptionHandlerFactory
.getInstance().create();
ExceptionDTO exDto = eh.handleException(
"employee.addEmployee", userId, ex);
}

  在这里,employee.addEmployee上下文将被附加给一个上下文敏感的异常的错误代码Q从而生惟一的错误代码。例如,如果 RecordNotFoundException的错误代码是errorcode.recordnotfoundQ那么这个上下文的最l错误代码将变(sh)ؓ(f) errorcode.recordnotfound.employee.addEmployeeQ它对于q个上下文是惟一的错误代码?/p>

   然而,我们要给Z个警告:(x)如果(zhn)准备在同一个客L(fng)Ҏ(gu)中用多个接口,而且q些接口都可以抛出RecordNotFoundException异常Q? 那么惌知道是哪个实体引发了(jin)q个异常变得十分困难。如果业务接口是公共的,而且可以被各U外部客L(fng)使用Q那么徏议只使用特定的异常,而不使用? RecordNotFoundExceptionq样的一般性异常。特定于上下文的异常对于Z数据库的可恢复异常来说非常有用,因ؓ(f)在这U情况下Q异? cdl是相同的,不同的只有它们出现的上下文?/p>

J2EE应用E序的异常层ơ结?/h3>

  正如前面讨论的那P我们需要定义一个异常基c,叫做BaseAppExceptionQ它包含?jin)所有应用程序异常的默认行ؓ(f)。我们将把这个基 cL到所有可能抛出checked异常的方法的throws子句中。应用程序的所有checked异常都应该是q个基类的子cR有多种定义错误处理抽象? 方式。然而,其中的区别更多地是与业务c而不是与技术有兟뀂对错误处理的抽象可分ؓ(f)以下几类。所有这些异常类都是从BaseAppExceptionz 而来?/p>

checked异常

  • 业务异常Q执行业务逻辑时出现的异常。BaseBusinessException是这cd常的基类?/li>
  • 数据库异?/strong>Q与持久化机制进行交互时抛出的异常。BaseDBException是这cd常的基类?/li>
  • 安全性异?/strong>Q执行安全性操作时出现的异常。这cd常的基类是BaseSecurityException?/li>
  • 认异常Q在从终端用户处获得认以执行某个特定Q务时使用。这cd常的基类是BaseConfirmationException?/li>

unchecked异常

  • pȝ异常Q有时候我们希望用unchecked异常。例如下面的 情况Q不想亲自处理来自第三方库API的异常,而是希望把它们包装在unchecked异常中,然后抛出l控制器。有时会(x)出现配置问题Q这些问题(sh)不能? 客户端进行处理,而应该被当作unchecked异常。所有自定义的unchecked异常都应该扩展自 java.lang.RuntimeExceptioncR?/li>

表示层上的异常处?/h3>

  表示层独自负责决定对一个异帔R取什么操作。这U决{涉?qing)到识别抛出异常的错误代码。此外,我们q需要知道在处理错误之后应该把错误消息重定向到哪一界面?/p>

  我们需要对Z异常cd获得错误代码q个q程q行抽象。必要时q应该执行日志记录。我们把q种抽象UC为ExceptionHandler。它Z“四人帮?Gang of FourQGOF) 外观模式Q?a target="_blank">Design Patterns? 一书中_(d)该模式是用于“ؓ(f)子系l中的一l接口提供一个统一接口。外观定义了(jin)一个更高别的接口Q子系l变得更加易于用。”)(j)Q是用于处理所有派生自 BaseAppException的异常的整个异常处理pȝ的外观。下面给Z个在Struts ActionҎ(gu)中进行异常处理的例子Q?/p>

try{ 
...
DivisionDTO storeDTO = divisionBusinessDelegate
.getDivisionByNum(fromDivisionNum);
}catch(BaseAppException ex){
IExceptionHandler eh = ExceptionHandlerFactory
.getInstance().create();
String expContext = "divisionAction.searchDivision";
ExceptionDTO exDto = eh.handleException(
expContext , userId, ex);
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR
,new ActionError(
exDto.getMessageCode()));
saveErrors(request, errors);
return actionMapping.findForward(
"SearchAdjustmentPage");
}

  如果更仔l地观察我们刚刚~写的异常处理代码,(zhn)可能会(x)意识刎ͼ为每个StrutsҎ(gu)~写的代码是十分怼的,q也是一个问题。我们的目标是尽可能地去掉样板代码。我们需要再ơ对它进行抽象?/p>

  解决Ҏ(gu)是?a target="_blank">模板Ҏ(gu)QTemplate MethodQ设计模式(引自GOFQ“它用于实现一个算法的不变部分Qƈ把可变的法部分留给子类来实现。”)(j)。我们需要一个包含模板方法Ş式算法的? cR该法包含用于BaseAppException的try-catch块和对dispatchMethodҎ(gu)的调用,Ҏ(gu)实现Q委托给zc)(j)? 下面的基于Struts的Action中所C:(x)

public abstract class BaseAppDispatchAction 
extends DispatchAction{
...
protected static ThreadLocal
expDisplayDetails = new ThreadLocal();

public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception{
...
try{
String actionMethod = request
.getParameter(mapping.getParameter());
finalDestination =dispatchMethod(mapping,
form, request, response,actionMethod);
}catch (BaseAppException Ex) {
ExceptionDisplayDTO expDTO =
(ExceptionDisplayDTO)expDisplayDetails
.get();
IExceptionHandler expHandler =
ExceptionHandlerFactory
.getInstance().create();
ExceptionDTO exDto = expHandler
.handleException(
expDTO.getContext(), userId, Ex);
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError(exDto
.getMessageCode()));
saveErrors(request, errors);
return mapping.findForward(expDTO
.getActionForwardName());
} catch(Throwable ex){
//log the throwable
//throw ex;
} finally {
expDisplayDetails.set(null);
}

  在Struts中,DispatchAction::dispatchMethodҎ(gu)用于把请求{发给正确的ActionҎ(gu)Q叫做actionMethod?/p>

   我们假定从一个HTTPh获得searchDivision作ؓ(f)actionMethodQdispatchMethod在 BaseAppDispatchAction的派生ActioncM把请求分zsearchDivisionҎ(gu)。在q里Q?zhn)可以看到Q异常处理仅在基 cM完成Q而派生类则只实现ActionҎ(gu)。这采用?jin)模板方法设计模式,在该模式中,异常处理部分是保持不变的Q而dispatchMethodҎ(gu)? 实际实现Q可变部分)(j)则交由派生类完成?/p>

  修改后的Struts ActionҎ(gu)如下所C:(x)

... 
String exceptionActionForward =
"SearchAdjustmentPage";
String exceptionContext =
"divisionAction.searchDivision";

ExceptionDisplayDTO expDTO =
new ExceptionDisplayDTO(expActionForward,
exceptionContext);
expDisplayDetails.set(expDTO);
...
DivisionDTO divisionDTO =divisionBusinessDelegate
.getDivisionByNum(fromDivisionNum);
...

  现在它看h相当清晰。因为异常处理是在一个集中的位置?BaseAppDispatchAction)完成的,手动错误可能造成的媄(jing)响也降至最低?/p>

  然而,我们需要设|异怸下文和ActionForwardҎ(gu)的名Uͼ如果有异常出玎ͼh׃(x)被{发到该方法。我们将在ThreadLocal变量expDisplayDetails中设|这些内宏V?/p>

   但是Qؓ(f)什么要使用java.lang.ThreadLocal变量呢?expDisplayDetails? BaseAppDispatchActiioncM的一个受保护数据成员Q这也是它需要是U程安全的原因。java.lang.ThreadLocal? 象在q里便可z上用场?/p>

异常处理E序

  在上一部分中,我们讨论?jin)如何对异常处理q行抽象。下面给Z些应该满的U束Q?/p>

  • 识别异常cdq获得相应的错误代码Q该错误代码可用于显CZ条消息给l端用户?/li>
  • 记录异常。底层的日志记录机制被隐藏,可以Z一些环境属性对其进行配|?/li>

  (zhn)可能已l注意到?jin),我们在表C层中捕捉的惟一异常是BaseAppException。由于所有checked异常都是 BaseAppException的子c,q意味着我们要捕捉BaseAppException的所有派生类。基于类名称来识别错误代码再Ҏ(gu)不过?jin)?/p>

//exp is an object of BaseAppException
String className = exp.getClass().getName();

  可以Z异常cȝ名称在一个XML文gQexceptioninfo.xmlQ中寚w误代码进行配|。下面给出异帔R|的一个例子:(x)

<exception name="EmployeeConfirmationException">
<messagecode>messagecode.laborconfirmation</messagecode>
<confirmationind>true</confirmationind>
<loggingtype>nologging</loggingtype>
</exception>

  正如(zhn)看到的那样Q我们把q个异常变(sh)ؓ(f)昑ּQ要使用的消息代码是messagecode.employeeconfirmation。然后,Z(jin)实现国际化的目的Q可以从ResourceBundle提取实际的消息。我们很清楚Q不需要对q类异常执行日志记录Q因为它只是一条确认消息,而不是一个应用程序错误?/p>

  让我们看一看上下文敏感异常的一个例子:(x)

<exception name="RecordNotFoundException">
<messagecode>messagecode.recordnotfound</messagecode>
<confirmationind>false</confirmationind>
<contextind>true</contextind>
<loggingtype>error</loggingtype>
</exception>

  在这里,q个表达式的contextind为true。在handleExceptionҎ(gu)中传递的上下文可用于创徏惟一的错误代码。例如, 如果我们把order.getOrder当作一个上下文q行传递,l果得到的消息代码就是异常的消息代码和所传递的上下文的串联。因此,我们获得?jin)一个像 messagecode.recordnotfound.order.getOrderq样的惟一消息代码?/p>

  对于每个异常来说Q可以把 exceptioninfo.xml 中的数据装C个叫做ExceptionInfoDTO的数据传输对象(data transfer objectQDTOQ。现在,我们q需要一个占位符Q用于缓存这些对象,因ؓ(f)我们不想在异常出现时反复解析XML文g和创建对象。这工作可以委托给一 个叫做ExceptionInfoCache的类来完成,q个cd?x)在从exceptioninfo.xml文gdExceptionInfoDTO? 象信息之后缓存所有这些对象?/p>

  现在(zhn)是否弄清楚?jin)这整个q程Q这U方法的核心(j)部分是ExceptionHandler实现Q该实现 用封装在ExceptionInfoDTO中的数据来获取消息代码,创徏ExceptionDTO对象Q然后基于在l定异常? ExceptionInfoDTO中指定的日志记录cd来记录它?/p>

  下面是ExceptionHandler实现的handleExceptionҎ(gu)Q?/p>

public ExceptionDTO handleException(String userId,
BaseAppException exp) {
ExceptionDTO exDTO = new ExceptionDTO();
ExceptionInfoCache ecache =
ExceptionInfoCache.getInstance();
ExceptionInfo exInfo = ecache
.getExceptionInfo(
ExceptionHelper.getClassName(exp));
String loggingType = null;
if (exInfo != null) {
loggingType = exInfo.getLoggingType();
exDTO.setConfirmation(exInfo
.isConfirmation());
exDTO.setMessageCode(exInfo
.getMessageCode());
}

FileLogger logger = new FileLoggerFactory()
.create();
logger.logException(exp, loggingType);

  Ҏ(gu)不同的业务需求,ExceptionHandler接口可以有多U实现。决定用何U实现的d可交由Factory来完成,特别是ExceptionHandlerFactorycR?/p>

l束?/h3>

  如果~Z全面的异常处理策略,一些特D的异常处理块便可能D出现非标准的错误处理和不可维护的代码。通过使用上面的方法,便可化J2EE应用E序中的异常处理q程?/p>

参考资?/h3>
  • 本文?a target="_blank">CZ代码?/li>
  • 设计模式Q外观和模板Ҏ(gu)模式的源代码?/li>

原文出处Q?/strong> http://www.onjava.com/pub/a/onjava/2006/01/11/exception-handling-framework-for-j2ee.html

 (tng)作者简?/span>

ShriKant Vashishtha 当前是印度Tata Consultancy Services Limited (TCS)公司的解x(chng)案架构师?/td>


Hello Java 2006-07-04 11:15 发表评论
]]>Servlet 2.4规范阅读W记(2-3?http://www.tkk7.com/doulei/archive/2006/06/14/52866.htmlHello JavaHello JavaWed, 14 Jun 2006 15:43:00 GMThttp://www.tkk7.com/doulei/archive/2006/06/14/52866.htmlhttp://www.tkk7.com/doulei/comments/52866.htmlhttp://www.tkk7.com/doulei/archive/2006/06/14/52866.html#Feedback1http://www.tkk7.com/doulei/comments/commentRss/52866.htmlhttp://www.tkk7.com/doulei/services/trackbacks/52866.html W??The servlet Interface
所有Servlet实现同一接口QServlet,它有两个直接的子c:(x)GenericServlet和HttpServlet.
2.1 Request Handle method
基本的Servlet使用service()Ҏ(gu)处理h,因ؓ(f)可能有多个客L(fng)h在service()中工作,所以开发者必要考虑到ƈ发的情况?span style="font-weight: bold;">
SRV.2.1.1 HTTP Specific Request Handling Methods
HttpServlet定义?jin)以?个方法:(x)

  • doGet for handling HTTP GET requests
  • doPost for handling HTTP POST requests
  • doPut for handling HTTP PUT requests
  • doDelete for handling HTTP DELETE requests
  • doHead for handling HTTP HEAD requests
  • doOptions for handling HTTP OPTIONS requests
  • doTrace for handling HTTP TRACE requests
SRV.2.1.2 Additional Methods
 (tng) (tng) (tng)
关于Http的几个附加命令HEAD,DELETE,PUT,OPTIONS,TRACE?br />SRV.2.1.3 Conditional GET Support
q个”Conditional GET“指的是q样的请求:(x)只有所h的资源在一个特定时间之后被修改q,才被发送给客户端?br /> HttpServlet里的getLastModified()Ҏ(gu)提供?jin)这斚w的支持?span style="font-weight: bold;">
SRV.2.2 Number of Instances
 (tng) (tng) (tng) ?.4之前的版本中QServlet有两U方式:(x)
 (tng) (tng) (tng) W一U方式是对于一个ServletQ只有一个实例,q个实例可以同时服务多个用户Q这是默认的?br />  (tng) (tng) (tng) 另一U方式是一个Servlet的实例只能服务一个客Pq样需要一个Servlet的PoolQ当多个用户q接Ӟ需要徏立多个Servlet实例。这U方式需要Servlet实现SingleThreadModel接口?br />  (tng) (tng) (tng) 以上两种方式的比较:(x)W一U方式需要考虑同步问题Q因Z个Servlet的实例服务多个用PServlet中的数据成员需要同?,W二U方式不需要考虑同步问题?br />  (tng) (tng) (tng)
SRV.2.3 Servlet Life Cycle
 (tng) (tng) (tng) 1.载入Q?tng) (tng)?/span>
 (tng) (tng) (tng) 应用服务器可能在启动时蝲入Servlet或者在W一个请求到来时延迟加蝲,载入的方式也是用类装蝲器,和普通的Java Object没有什么区别?br />  (tng) (tng) (tng) 2.初始化:(x)
 (tng) (tng) (tng) 初始化时可能遇到错误Q这时会(x)抛出ServletException或者UnaviliableException异常
 (tng) (tng) (tng) 3.多线E:(x)
 (tng) (tng) (tng) 需要注意的一Ҏ(gu)Q最好不要对service()Ҏ(gu)q行synchronize修饰。这L(fng)话就不能使用U程池,而必drequest序列?br />  (tng) (tng) (tng) 4.处理h时的错误处理Q?/span>
 (tng) (tng) (tng) 如果在这时发生异常,可以发送UnavailableException或者ServletException,如果发送了(jin) ServletException,服务器必要惛_法清除request。如果发送了(jin)UnavailableException,有两U选择Q如果是? 久的的无效,需要调用destroy()Qƈ摧毁ServletQ如果这时客L(fng)讉K此ServletQ它?yu)?x)收到404错误。如果是临时的无效,容器需 要拒lQ何到此Servlet的请求,q且q回503错误
 (tng) (tng) 5.U程安全的话?/span>
 (tng) (tng) (tng) request和responseq两个对象不是线E安全的Q所以不要在service()Ҏ(gu)外面使用它们Q它们的引用不应该传l另一个线E中的对象,如果一定要讉K它们Q必d使用q两个对象的代码q行同步?br style="font-weight: bold; text-decoration: underline;" /> (tng) (tng) (tng) 6.服务的结?/span>
 (tng) (tng) Servlet容器q不需要一直保持一个Servlet处于q行状态,在释放一个servletӞ?x)调用destroyҎ(gu)Q当调用destroyҎ(gu)之前Q容器会(x)一直等到所有的U程都完成了(jin)在service()Ҏ(gu)中的工作?br />
W??Servlet Context
SRV.3.1 Introduction to the ServletContext Interface
Servlet ContextQ从Servlet的角度来看,可以理解为它所属Web应用E序QServletContext是一个接口,Servlet容器的提供商必须要实现这个接口?br /> ServletContext能做什么呢Q它可以把事件记录到日志中,获得资源的URLQ还可以利用ServletContext存放一些所有Servlet都能׃n的数据?br /> ServletContext有一个\径,例如http://www.mycorp.com/catalogQ这里的cataqlog是ServletContext的\径,所有的对catalog的请求都?x)关联到q个ServletContext.
SRV.3.2 Scope of a ServletContext Interface

在Servlet容器中,每个ServletContext通常只有一个实例。当Web容器是分布式的部|在多台机器上时Q那一个ServletContext在每个JVM上都有一个实例?br /> 在Servlet容器中,但没有部|的Servlet也是允许的,q种Servlet属于一个缺省的ServletContextQ这U缺省的ServletContext不能被分布到多个JVM上?br />SRV.3.3 Initialization Parameters
在ServletContext接口中,有两个方法可以用来获得初始化参数Q?span style="font-weight: bold;">
?getInitParameter
?getInitParameterNames
SRV.3.4 Context Attributes
在ServletContext中,?个方法可以用来设|和理ServletContext的属性:(x)
?setAttribute
?getAttribute
?getAttributeNames
?removeAttribute
SRV.3.4.1 Context Attributes in a Distributed Container
ServletContext中的属性只在本地的JVM中有效,不能被分布式环境中运行于其它JVM中的Servlet讉KQ如果需要在分布式环境中׃n数据Q可以把数据存放在SessionQ数据库或EJB中?br />SRV.3.5 Resources
资源指的是在Web应用E序中的一些静(rn)态的内容Q如?rn)态HTML面Q图片等{。ServletContext提供?jin)两个方法来讉Kq些资源Q?br /> ?getResource
?getResourceAsStream
q两个方法都接受一个String型参敎ͼ它指定了(jin)一个以"/"开头的相对于这个ServletContext的资源\径。资源可以放在同一服务器上Q或者不同服务器上,或者在一个Web应用E序的WAR包中?br /> 需要注意的是,q两个方法不能用来获取动态内容,如果我们用这两个Ҏ(gu)d一个JSP面Q返回的是JSP面的源代码?br /> getResourcePaths(String path)Ҏ(gu)可以用来获取一个资源列表?br />SRV.3.6 Multiple Hosts and Servlet Contexts
Web服务器可能支持多个域名分享一个IP地址Q这U配|叫做“虚拟主机”。在q种情况下,每个虚拟L必须要有自己的ServletContextQ而不能共享一个ServletContext?br />SRV.3.7 Reloading Considerations
所有的Servlet和它们引用的cd都处于一个类装蝲器范围内?br />SRV.3.7.1 Temporary Working Directories
每一个ServletContext都需要一个(f)时目录,q且通过 javax.servlet.context.tempdir属性指定。Servlet容器不需要管理这个(f)时\径的内容Q但是要保一? ServletContext的(f)时目录对其他的ServletContext是不可见的?br />


Hello Java 2006-06-14 23:43 发表评论
]]>
动态代理和AOP的一点学?fn)?j)?/title><link>http://www.tkk7.com/doulei/archive/2006/06/14/52841.html</link><dc:creator>Hello Java</dc:creator><author>Hello Java</author><pubDate>Wed, 14 Jun 2006 12:38:00 GMT</pubDate><guid>http://www.tkk7.com/doulei/archive/2006/06/14/52841.html</guid><wfw:comment>http://www.tkk7.com/doulei/comments/52841.html</wfw:comment><comments>http://www.tkk7.com/doulei/archive/2006/06/14/52841.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/doulei/comments/commentRss/52841.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/doulei/services/trackbacks/52841.html</trackback:ping><description><![CDATA[     摘要: 一、最初的设计 有一个经营一家在U商店的客户Q在q个商店pȝ中,有一个供理员(sh)用的理定单的类Q代码如下:(x) 1 、接? Interface OrderService{  (tng)  (tng)  (tng) (tng) (tng) (tng) (tng) (tng) (tng) public boolean showOrders();// 察看定单 } Q、实...  <a href='http://www.tkk7.com/doulei/archive/2006/06/14/52841.html'>阅读全文</a><img src ="http://www.tkk7.com/doulei/aggbug/52841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/doulei/" target="_blank">Hello Java</a> 2006-06-14 20:38 <a href="http://www.tkk7.com/doulei/archive/2006/06/14/52841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://5g6z.com" target="_blank">޹˾þۺһ77</a>| <a href="http://www-15706.com" target="_blank">ŮȸͰƵѰ</a>| <a href="http://zaideqin.com" target="_blank">һëƬ</a>| <a href="http://www-8812.com" target="_blank">ëƬƵ</a>| <a href="http://yytengsheng.com" target="_blank">ѹۿһëƬa</a>| <a href="http://922eee.com" target="_blank">ԭƵ</a>| <a href="http://c2277.com" target="_blank">ŮƵ</a>| <a href="http://szybzc.com" target="_blank">AV˾Ʒһ</a>| <a href="http://w7759.com" target="_blank">һŮëƬ</a>| <a href="http://xzdlgp.com" target="_blank">ĻѲ</a>| <a href="http://www-2236444.com" target="_blank">ѿĿһ</a>| <a href="http://iguasheng.com" target="_blank">ŷŮƵ</a>| <a href="http://740740740.com" target="_blank">AVþþƷ</a>| <a href="http://wo93xyz.com" target="_blank">13ֽˮ</a>| <a href="http://www769393.com" target="_blank">һaƬþëƬ</a>| <a href="http://633223.com" target="_blank">þþþѾƷ</a>| <a href="http://www91pao.com" target="_blank">ëƬվ߹ۿ</a>| <a href="http://hgbookvip.com" target="_blank">պAvĻþþ޸ </a>| <a href="http://douhuowang.com" target="_blank">ҹƵ</a>| <a href="http://yimintech.com" target="_blank">޹רһ</a>| <a href="http://microston.com" target="_blank">޺ݺۺϾþ</a>| <a href="http://33a55.com" target="_blank">337pձŷ޴</a>| <a href="http://400209.com" target="_blank">91ѹƵ</a>| <a href="http://16lds.com" target="_blank">Ƭѿ</a>| <a href="http://jack-fx.com" target="_blank">޾ƷҹӰ</a>| <a href="http://zhnetbar.com" target="_blank">99þùۺ</a>| <a href="http://www-70074.com" target="_blank">޻Ƭֻѹۿ</a>| <a href="http://xxxxnii.com" target="_blank">69Ƶר</a>| <a href="http://llyysp.com" target="_blank">㽶þþƷ </a>| <a href="http://kmyake.com" target="_blank">ɫѿ</a>| <a href="http://shadaiym.com" target="_blank">91ѹۿ</a>| <a href="http://jiggybaby.com" target="_blank">޳AӰԺ߹ۿ</a>| <a href="http://43sihu.com" target="_blank">޹Ʒ˾Ʒ</a>| <a href="http://blbkl.com" target="_blank">ëƬؿ</a>| <a href="http://www-xg5777.com" target="_blank">ëƬ18ŮëƬ96</a>| <a href="http://szyxfhm.com" target="_blank">AVһ</a>| <a href="http://jdv6.com" target="_blank">߹ۿһ</a>| <a href="http://hdznzdh.com" target="_blank">aëƬȫƵ</a>| <a href="http://www66913.com" target="_blank">Ʒާѡ벥</a>| <a href="http://42329c.com" target="_blank">avӰԺһ</a>| <a href="http://boyipark.com" target="_blank">ƵĻȫ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>