您的位置:首页 > 编程语言 > Java开发

struts2 与 spring 使用aop处理Action异常

2013-05-02 15:43 459 查看
首先:系统有自定义异常类(当业务逻辑发生错误,就抛出该异常)

/**
* 自定义异常
* @author zhoufeng
*
*/
public abstract class TFException extends RuntimeException{

private static final long serialVersionUID = 9071885224386474480L;

public TFException(String message){
super(message) ;
}

}


该异常是在service层用来抛出的。

示例:

public void modifyPrice(DisinfoRoomPrice drp) {
DisinfoRoomPrice dbDrp = disinfoRoomPriceDao.findById(drp.getId());
if(dbDrp.getQuantity() >= drp.getQuantity()){
disinfoRoomPriceDao.updateEntityFields(drp,
"price" ,"currency" ,"quantity" , "beSure" ,"status");
}else{
throw new TFRollbackException("日期:" +
df.format(dbDrp.getDate()) +"的剩余房间数量只能减少,不能增加!");
}
}
如果出现了逻辑上的错误,就可以抛出自定义异常。

下面来看Action层的代码

一般情况下Action方法内的代码如下:

public String doBuy(){
List<Price> price = BFBPrices.prices ;
Integer totalPrice = 0, totalSl = 0 ;
for (int i = 0; i < buynos.length; i++) {
totalPrice += (price.get(i).getPrice().intValue() * buynos[i]);
totalSl += (price.get(i).getQuantity() * buynos[i]);
}
try {
bfCoinService.addBFCoin(totalSl,
totalPrice ,
getCurrentDisuser().getDisinfo().getId() ,
getCurrentDisuser().getId());
addSessionMessage(new TipMessage("购买成功", TipMessage.SUCCESS)) ;
} catch(TFException e ){
addSessionMessage(new TipMessage(e.getMessage(), TipMessage.ERROR)) ;
}catch (Exception e) {
addSessionMessage(new TipMessage("系统忙", TipMessage.ERROR)) ;
}
return "buybaofangbi"	;
}


每一个方法,几乎都要try catch 自定义的TFException 与 Exception 。这样实在是太麻烦了。

为了解决这样的问题。可以使用AOP对所有的Action方法进行拦截。当发生异常就return到指定的result,如果运行成功也return到指定的result

所以,先定义下面这样一个自定义注解:

/**
* Struts2 视图页面
* @author zhoufeng
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface StrutsResult {

/**
* 方法执行成功返回的result名称
*/
public String success();

/**
* 方法执行失败返回的result名称
*/
public String fail();

/**
* 系统错误返回的result名称
*/
public String error() default "system_error";
}


然后在Action方法上面加上该注解:

@StrutsResult(success = "redirect_list_room_prices" , fail = "redirect_list_room_prices")
public String modifyRoomPrice(){
disinfoRoomPriceService.modifyPrice(priceid, drp);
addSessionMessage(new TipMessage("修改成功", TipMessage.SUCCESS)) ;
return SUCCESS ;
}


然后定义AOP对拥有@StrutsResult注解的方法进行拦截

/**
* 对Action的全局异常处理
* @author zhoufeng
*
*/
@Aspect
@Component
public class GloabExceptionHandler {

@Around("@annotation(com.tuanfang.aop.annotation.StrutsResult)")
public Object actionAround(ProceedingJoinPoint joinPoint) {
BaseAction ba = ((BaseAction)joinPoint.getTarget()) ;
StrutsResult sr = obtainStrutsResultAnnotation(joinPoint.getSignature() , joinPoint.getTarget());
try {
joinPoint.proceed(joinPoint.getArgs());
return sr.success() ;
} catch (TFException e) {
ba.addSessionMessage(
new TipMessage(e.getMessage() , TipMessage.FAIL)
) ;
return sr.fail() ;
}catch(Exception e){
ba.addSessionMessage(
new TipMessage("操作失败,系统忙!" , TipMessage.ERROR)
) ;
return sr.error() ;
}catch(Throwable e){
ba.addSessionMessage(
new TipMessage("操作失败,系统忙!" , TipMessage.ERROR)
) ;
return sr.error() ;
}
}

/**
* 获取StrutsResult对象,根据方法签名
* @return
*/
public StrutsResult obtainStrutsResultAnnotation(Signature sig , Object target){
try {
String methodName = sig.getName();
Method method = target.getClass().getMethod(methodName) ;
StrutsResult sr = method.getAnnotation(StrutsResult.class);
return sr ;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return null ;
}

}


这样就简化了很多,每个Action方法就不必重复的try catch了。 但是每个Action方法都需要使用@StrutsResult注解

既然返回的result都是在@StrutsResult注解中指定的,那么Action将返回值类型设置为void呢?

答案是No 。 但是在Action方法中返回的返回值是无效的。因为正真返回的result,是在拦截器中返回的,也就是事先定义在@StrutsResult注解中的。 所以可以在每个Action方法中return一个null 或者 ,return SUCESS ; 都可以。 反正是没有用的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: