struts2 与 spring 使用aop处理Action异常

首先:系统有自定义异常类(当业务逻辑发生错误,就抛出该异常)


/**
 * 自定义异常
 * @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 ; 都可以。 反正是没有用的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值