AOP记录异常邮件发送记录

简介: 一般我们的异常都会抛出到控制层,如果使用struts2也就是action。然后try{//正确代码实现}catch{//在里面记录错误日志},这样咋一看是不错,代码很完美。

一般我们的异常都会抛出到控制层,如果使用struts2也就是action。然后try{//正确代码实现}catch{//在里面记录错误日志},这样咋一看是不错,代码很完美。但是如果项目中有成千上万个项目怎么办?难道在每个action的catch里面都要加入异常记录代码?很显然工作量是很大的。7 `, X, R" [  \1 [2 D

0 S+ I4 X, f& F) \, L  C/ Y$ t
; P6 ~# Q4 g- Q4 v) H" M       鉴于项目中配置了数据库事务,其实也是使用了AOP 详见applicationContext-service.xml配置文件。由于配置文件的局限性这里采用注释的方式实现。之所有使用注释是可以自定义参数并实现日志的详细记录。既然使用注释,现成的没有,只有自己定义来实现需求。其实spring 注释实现的注入、hibernate的model类注释实现与数据库关联以及我们最常见Override。
. t1 t; z# z( Q7 x0 p       资料:java如何实现自定义注释http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
1 ^. G4 }4 R% D7 R
% r5 E' J7 N7 ~; z6 ^6 z一、 记录日志并发送邮件通知

(1)、定义注解:
9 k9 S. Y4 n# U) S9 j0 A7 m9 ^1.ServiceLog.java(各种参数类型详见上面的资料)

0 D" K3 ~3 f2 ?( h

  1. import java.lang.annotation.*;
    - S. w$ {) Z3 E# t: J' }& @
  2. /**
    ! }, O0 m4 n) A# Y9 I# A3 ~
  3. * 自定义注解 拦截service  
    5 [  G& I1 R& B  E/ x
  4. * 创建者        张志朋
    . v9 C8 s$ }, K8 x
  5. * 创建时间        2015年6月3日  
  6. */
    - o. R; b, I2 Z
  7. @Target({ElementType.PARAMETER, ElementType.METHOD})   
    0 r0 w" j: w" ?& C- r$ _* }! U
  8. @Retention(RetentionPolicy.RUNTIME)   
  9. @Documented   
  10. public  @interface ServiceLog {
    % V) K# P. z; |& y- j1 i
  11.          String description()  default "";
    3 |9 v# K6 p" V, L, ]" T) c5 S% c
  12. }
复制代码
2.ControllerLog.java 3 \' t* L! E! d0 \% b* s( N2 N
  1. import java.lang.annotation.*; 1 O6 b$ f+ A5 N  G5 R
  2. /**
    ; ~: V2 S4 G$ T+ C% R' |
  3. * 自定义注解 拦截Controller: g' a) s9 S- b- [% Z+ v" s
  4. * 创建者        张志朋
    - d3 R* O8 u" t
  5. * 创建时间        2015年6月3日
    / E5 N% e$ c6 z# q. A+ X+ b$ {
  6. *
    : ~* v& ?. ]! T
  7. */
    6 M/ `8 H( \) J+ K. u0 K) n
  8. @Target({ElementType.PARAMETER, ElementType.METHOD})   
    # V" N/ Z6 _, o, v4 i: M- J
  9. @Retention(RetentionPolicy.RUNTIME)    * D. u, W' W3 d. P9 J! h
  10. @Documented
      f3 w* U. f  r- Z4 w4 L3 r
  11. public @interface ControllerLog {
      S3 X. f9 i# w) E5 R9 Q
  12.         String description()  default "";
      ?: A, M" a3 c! H% J- g
  13. }
复制代码
(2)、定义切面以及切入点$ {9 ^) C" G! |6 V' ?
1.LogAspect.java

( `# e- e( r6 U, |( I1 |
  1. /**
    $ c/ W4 ]. r" ~$ L2 ]) H6 ]
  2. * 日志记录AOP+ ~# G$ `. M' W+ b
  3. * 创建者        张志朋* U3 Q. a' V* d' c+ {1 |' Q  i/ H" A
  4. * 创建时间        2015年6月3日
    - V+ o' ]) K0 x
  5. *
    4 ?4 h( H% d- e! [, }3 u
  6. */* a& I5 G, i9 [
  7. @Component
    / C% s$ F* b  l- r, I6 o9 m
  8. @Scope$ w& p0 A1 g7 h5 |: V# p! ?2 T7 P
  9. @Aspect
    ) L/ Y. @8 X7 t' R' [0 s
  10. public class LogAspect {. n  [5 j- F( q( ^8 Q& i3 X7 [
  11.         //Service层切点     用于记录错误日志
    ' `' \6 [8 d# Y, ~
  12.         @Pointcut("@annotation(com.web.aop.ServiceLog)")  
    ( J% V, a, ~* z9 y' z9 i
  13.         public void serviceAspect() {$ g: a. u5 m. Y" w
  14.                 6 C9 [5 x" }3 m2 z
  15.         }; ]7 {, \" L1 }) [  l1 t' i
  16.     /**
    * a) S) D4 p/ v% A: R$ V& T0 X* ?4 U
  17.      * 异常通知 用于拦截service层记录异常日志  ! J( E: g* X' T  ~  c5 Y
  18.      * @Author        张志朋
    ( }: D! e. F- X  O3 T3 K
  19.      * @param joinPoint- L3 l7 g* T1 F$ H  z- m
  20.      * @param e  void  B- K3 D" I. H3 D) `
  21.      * @Date        2015年6月3日
    8 ]8 g" ?" O$ M3 K* _6 e
  22.      * 更新日志9 N- S: z6 {2 B* q5 K: C! ^, H$ w
  23.      * 2015年6月3日 张志朋  首次创建/ f( k# a5 t/ X7 p( r, f
  24.      *
    1 @' ~* t1 g( @
  25.      */! ^' U; k, B- G2 u" y; U4 v- R) x
  26.     @AfterThrowing(pointcut = "serviceAspect()", throwing = "e")    * X0 K5 m! P' l( }# \- w
  27.     public  void doAfterThrowing(JoinPoint joinPoint, Throwable e) { 2 X; e8 [$ n8 `; l
  28.                 HttpServletRequest request = ServletActionContext.getRequest();1 w4 k0 ?4 h( O6 ~1 h8 p) w7 D/ n
  29.                 TeacherEntity user = CommonUtil.getUser();
    ! B0 S4 H7 k+ }" e% R4 c
  30.                 String ip = AddressUtils.getIpAddr(request);
    6 \& v' p: u8 J
  31.                 try {( L* R+ }4 E: g- p2 |5 p1 I
  32.                         String params = "";4 F2 u- c  b7 v5 x: q) w
  33.                         if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {
    . X3 M$ m% [/ s( i1 M  k. C: {3 Y! m: l" J
  34.                                 for (int i = 0; i < joinPoint.getArgs().length; i++) {
    , |& ~/ _. c0 w& i; ~/ F
  35.                                         params += JSONUtil.toJSONstring(joinPoint.getArgs()[i]) + ";";- m4 ^8 \* @9 c% `8 a
  36.                                 }
    , ~/ y. l) l  {& f
  37.                         }; {7 t9 m$ K$ T! R1 P0 h2 C
  38.                         String description = getServiceMthodDescription(joinPoint);//用户操作
    3 b! m: A8 I: G: x! k! w; f3 ?
  39.                         String exceptionCode  =e.getClass().getName();//异常类型代码* D" q% b# H1 P1 N
  40.                         String exceptionDetail = e.getMessage();//异常详细信息
    , _+ }& J4 I5 J
  41.                         String method = joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()";//异常方法
    1 ?/ {0 _" @( j4 q" p( O
  42.                         /*==========记录数据库异常日志==========*/  4 P* G$ z, O& F
  43.                         Log log = new Log();
    5 ~1 x( J  G6 u
  44.                         log.setDescription(description);
    * ?+ ]: w2 M7 p, C& F3 J1 z
  45.                         log.setExceptionCode(exceptionCode);
    ( k5 Z* j3 _' ^
  46.                         log.setExceptionDetail(exceptionDetail);
    4 E0 K7 l* @, B6 ^
  47.                         log.setMethod(method);2 ~/ g: N' F4 j# ?
  48.                         log.setType(Constants.LOG_ERROE);// 日志类型
    $ v* q4 l( v( M+ K: O
  49.                         log.setRequestIp(ip);// 请求IP2 E4 ~- N, E. s2 Z
  50.                         log.setParams(params);//请求参数
    " i, w4 R& o- E8 h
  51.                         if(null!=user){' N# l6 h/ r3 I2 D/ }' q) ~
  52.                     log.setCreateUid(user.getUid());//用户ID
    # O; [+ e7 x- d9 I
  53.                     log.setCreateName(user.getNickname());//用户昵称
    ( E" a) d: s) J% o4 U
  54.             }# C& ?  ?7 f2 {) I
  55.                         log.setPlatFrom(Constants.SUBJECT_CODE);. ]8 `3 x3 F& k' L, ]: o: }7 Z) w
  56.                         /*==========记录数本地异常日志==========*/  , O' ~) z+ t- z4 ~* b
  57.                         //LogUtil.error(description, e);
    : |& q" l. I* g+ V
  58.                         /*==========发送异常日志到邮箱==========*/
    1 ]3 U% s2 f; v6 A3 m6 [8 p
  59.                         StringBuffer errorMsg = new StringBuffer();8 i! O' d, {. F) C0 d$ w
  60.                         errorMsg.append("异常方法:");* F; l& W8 J- V
  61.                         errorMsg.append(method);
    ; G$ |: v# L! L! s
  62.                         errorMsg.append("</br>");8 {7 i1 F$ b3 c, V. o
  63.                         errorMsg.append("异常类型代码:");
    9 C; j* \6 f6 s& x3 z9 s" j
  64.                         errorMsg.append(exceptionCode);% [# B0 Y/ S- P& i) d; m6 V3 B
  65.                         errorMsg.append("</br>");
    , j6 `$ W: _: _; w
  66.                         errorMsg.append("异常详细信息:");. p; r6 _5 q7 D* |8 T% q
  67.                         errorMsg.append(exceptionDetail);
    ; @3 M# D' d) T$ c1 L
  68.                         errorMsg.append("</br>");4 x" A' q3 l9 _0 I/ x8 n
  69.                         log.setErrorMsg(errorMsg.toString());; h& Y* b% O9 W0 W$ c
  70.                         WebServiceMathClient  Client = new WebServiceMathClient();; x7 h7 J2 c& F9 w2 t
  71.                         Client.sendError(log);. l+ b+ S5 J# J0 e% l+ ^, r
  72.                 } catch (Exception ex) {3 q% B/ R0 Z0 H0 S1 l8 U
  73.                         e.printStackTrace();; k' e3 l( |+ ~0 |3 c7 |+ ]* e
  74.                 }) J# A4 j# B4 x; q8 b4 N& v  D
  75.     }
    $ d0 Q2 r) c, Y- i6 _( I7 q
  76.      /**$ C$ j2 z7 z  @% g7 [, ^
  77.       * 获取注解中对方法的描述信息 用于service层注解  (基于反射)& \  r6 Y' c1 ~
  78.       * @Author        张志朋+ c% C7 k7 D4 x
  79.       * @param joinPoint5 }" U0 W, g' f$ S8 q
  80.       * @return/ y7 K5 y* w" m
  81.       * @throws Exception  String6 D1 `5 p" J  }+ B/ G
  82.       * @Date        2015年6月3日# h1 g7 Y; v! d
  83.       * 更新日志
    : P& s( `2 E! f( h  {% Z& Z
  84.       * 2015年6月3日 张志朋  首次创建
    - a+ j  r5 l# g0 S9 z' B" g0 j
  85.       *1 ]" @9 k' t% s, \
  86.       */1 B! U- |) f( \
  87.      @SuppressWarnings("rawtypes")
    ' }0 j* ?! T6 Y, _* `% v
  88.         public  static String getServiceMthodDescription(JoinPoint joinPoint)    ' g0 G6 P2 Q+ G5 ^+ S
  89.              throws Exception {    ( m* w& @% A0 k, v' ?, U
  90.         String targetName = joinPoint.getTarget().getClass().getName();      I: V# i5 i; j( l3 u
  91.         String methodName = joinPoint.getSignature().getName();    $ a9 t; `2 q( g3 K5 N
  92.         Object[] arguments = joinPoint.getArgs();   
    : u) \& M4 C& m" I7 E6 z
  93.         Class targetClass = Class.forName(targetName);    , I* G; G0 ?0 o
  94.         Method[] methods = targetClass.getMethods();    2 x1 P8 ~9 ^7 ~( r2 j. z8 f
  95.         String description = "";   
      m4 u# Z4 Y& L! s
  96.          for (Method method : methods) {    6 q0 X) I, F# P$ v
  97.              if (method.getName().equals(methodName)) {    ' d" n& `1 ]; U0 z, N
  98.                 Class[] clazzs = method.getParameterTypes();    8 z4 D* r+ T. n( e
  99.                  if (clazzs.length == arguments.length) {   
    ( `  k8 [: R: e
  100.                     description = method.getAnnotation(ServiceLog. class).description();   
      K6 E1 [& N9 |7 A9 u1 I2 h5 M. J% r
  101.                      break;   
    % y$ V4 X- h- M3 m( z/ Q$ ]% |
  102.                 }   
    + P* q  R- v, ^, _
  103.             }   
    % c% a( T9 C2 p
  104.         }    3 e& ~% G' z- I/ ]
  105.          return description;    , ~  v4 J7 A4 T: }2 S4 F8 p. Q
  106.     }
    : ?+ E2 P" ~$ D
  107.     }
复制代码
, T7 V% N3 B! B
这里说明一下  serviceAspect()方法 上面注释了 @Pointcut("@annotation(com.acts.web.aop.ServiceLog)")  、也就说明这是一个切入点,springAOP对其进行了封装。# u$ g! \5 u3 w' }7 W0 H4 t& j( _7 y0 f
doAfterThrowing()方法上面加入了@AfterThrowing(pointcut = "serviceAspect()", throwing = "e") 对切入点的所有异常信息进行处理(记录日志到数据库或者发送错误信息到指定邮箱等等等,可以做任何你想做的事情)。, Z7 h; x$ U* D. U, E

5 C3 `* u! D  m( c0 e2.QuesPerServiceImpl.java(注意此类必须实现接口 默认JDK的动态代理实现是基于接口实现的 否则会报错)

7 x% _8 P1 [- n- }3 J1 l4 o, `
  1. @ServiceLog(description="获取待审试题数量")
    ' C# V1 a3 Y9 t. E5 V  B
  2. public long getAuditQuesNum(TeacherEntity currentUser) throws Exception {5 \9 a& ~6 {4 `- |9 ?' E& L& c
  3.                 return quesPerDao.getAuditQuesNum(currentUser);
    . C( [! t( |/ V7 w5 w( k$ u
  4.         }
复制代码
' a( x0 ~+ c4 ]0 ^
之所以定义description 描述 是为了更好的记录错误日志 文字总是比方法名 更容易识别。1 C0 Z3 n7 v+ X# ^
二、AOP实现权限控制
0 _( Y' f! I- H+ R4 P3 k& J       上面说过使用动态代理的类 必须实现接口但是我们的action并没有实现接口。 JDK 的动态代理只能对实现了接口的目标类进行代理,而不实现接口的类就不能使用 JDK 的动态代理。$ F% v5 V( H" s. a' `0 }
        还好有第三方的包为我们解决了问题。项目中引入cglib.jar,CGLIB 是针对类来实现代理,当没有实现接口的类需要代理时就需要通过 CGLIB 来实现代理了,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但是因为采用的是继承,所以不能对 finall 类进行继承。( {, s  ]2 z  E! N7 U! ]) l* B
首先配置文件要引入这样一段配置(看注释说明):
& `2 m6 Q- q. p3 [7 e* ]  s
  1. <!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller(Action)-->
    * N% z4 |% b0 h: U" J$ s$ `% U
  2.         <aop:aspectj-autoproxy proxy-target-class="true"/>
复制代码

, F' X  o% r8 W* d3 P/ i (1)、定义注释:
0 F( W" ^- s9 a; k% w1.Permission.java

# A, I1 S0 h; T) m  C* R2 v
  1. /**/ N4 f: v' A" C1 X8 g6 d3 r( G& J
  2. * 自定义权限管理
    ; ~, [% }9 Y4 E$ ~. y; z
  3. * 创建者        张志朋
    3 w) N! C9 J+ `) r2 w( w
  4. * 创建时间        2015年6月30日6 h! R: f* O* W8 R) f* X8 V+ _
  5. *1 N* y; g7 u- ~5 J% m- R
  6. */$ t$ a- X- e( T) _
  7. @Target({ElementType.PARAMETER, ElementType.METHOD})   
    8 o/ U! L2 f/ }5 ~
  8. @Retention(RetentionPolicy.RUNTIME)   
    # s4 w5 l2 ]" h; b
  9. @Documented
    8 T* Z7 n8 I8 M+ {0 j
  10. public @interface Permission {
    * q: v# L- H% N: B1 {& Y/ ?( \1 o
  11.         String name()  default ""; //操作行为
    7 v0 M  K6 V: O4 ~2 ]* F
  12.         int id() default -1;//权限值
    5 o& M+ Q+ [5 _% S. O
  13. }
复制代码
(2)、定义切面以及切入点2 ~* o& }# H  m. j6 V! N0 t1 U8 N
1.PsemissionAspect.java
0 U+ g8 C+ _7 g6 K( T: V% }+ A
  1. /**% V/ {# B- w7 j8 z
  2. * 权限管理% f! C% F7 {; w) B( c
  3. * 创建者        张志朋
    " l" Q; A$ v5 m" }( W% n
  4. * 创建时间        2015年7月3日
    3 l- }$ F1 \: a/ s$ [( U2 n! x* }- O
  5. *% l2 Y! |8 y8 c/ Y. R. O
  6. */, h; k+ k7 X- I- A5 P  z  i
  7. @Component
    * \& L( a4 ]# n
  8. @Scope7 J/ [* j# j/ I" ]1 T% x6 N0 Q6 ^
  9. @Aspect" p  X9 T- |+ ?+ t- C2 b6 M
  10. public class PsemissionAspect {
    ) _% i0 V1 b/ l: S
  11.         
    ; z1 D1 B. h( E) j
  12.     //Controller层切点 用于权限控制
    4 v9 C; c4 Q0 B4 O0 {$ K- ~
  13.         @Pointcut("@annotation(com.acts.web.aop.Permission)")  ( l* c8 d* V4 E8 P
  14.         public void permissionAspect() {
    5 w  z/ Q  {% Z  M  u, I8 s
  15.                
    % Q( @. \" i4 `2 P# f+ s# n" U
  16.         }
    8 M, [5 B2 L" d6 z! B3 \
  17.         /**
    5 w3 k3 f5 T, I$ @" S
  18.          * 用于拦截Controller层用户操作权限(环绕通知)$ [% e5 v$ N. m* `) Y
  19.          * @Author        张志朋' f+ |; s' \1 m  x, o
  20.          * @param joinPoint  void
    & Z( j% N/ O. w7 P) g% X' K9 g- [
  21.          * @Date        2015年6月3日
    2 b  |- Z! T0 M( k
  22.          * 更新日志5 Q% }* O/ A- f
  23.          * 2015年6月3日 张志朋  首次创建/ u; i# F0 C5 g# S% [, b- q9 X
  24.          *' N/ T8 _: u( p) {" o, y0 X: A
  25.          */
    4 Y; {1 _8 t1 p, p. r$ ~* s
  26.     @Around("permissionAspect()")    ) x( w# {1 ?. w' l
  27.     public  Object permission(ProceedingJoinPoint  joinPoint)throws Throwable {  8 o) |) B0 V+ Z3 t
  28.         Object retVal = null;) ^8 U# G% D+ z7 s
  29.                 int role  =  getControllerMethodRole(joinPoint);! K1 [# g6 T5 W# F
  30.                 TeacherEntity user = CommonUtil.getUser();! f, y0 S+ q0 l/ W. m! f* S9 J
  31.                 if((user.getSpecRole()&role)==role){//没有权限6 T$ c1 \0 E( \+ J$ L  h
  32.                         retVal  = joinPoint.proceed();) z. _3 ?( l5 g% P+ B" q
  33.                 }else{/ O* W# X( ?: }" j4 |) ?
  34.                         noAuthorization();
    5 _' ~; |; L$ P$ n$ R
  35.                 }8 K+ T" f$ Y9 ~+ w$ s
  36.             return retVal;
    ! }7 F- o! h2 M9 y6 z0 T, d1 s% I
  37.     }& h2 k' S. q/ T! @
  38.     /**
    " r7 H  z7 r& U  b- a
  39.      * 没有权限 实现跳转/ o3 g, c6 N: _- B
  40.      * @Author        张志朋
    4 \* o( `2 q/ P. C- m
  41.      * @throws IOException  void
    " b* V7 {) k/ E% y( s& ?$ |; w
  42.      * @Date        2015年7月3日
    % F* W, a3 p. }
  43.      * 更新日志
    . l2 v8 d9 C- Y6 n$ h
  44.      * 2015年7月3日 张志朋  首次创建
    ) l+ G; i$ a+ |# a$ [
  45.      *
    , r- ?) H. ?  C
  46.      */# M! f  l3 `* e6 `
  47.     public void noAuthorization() throws IOException{& h) n% K0 r4 {$ F/ B( F
  48.             HttpServletRequest request = ServletActionContext.getRequest();/ |  k8 X0 [# M4 S4 p( y/ I
  49.                 String path =  request.getContextPath();+ r7 x" D4 v- p- R% E9 r" T
  50.                 HttpServletResponse response  = ServletActionContext.getResponse();
    9 o  s$ c8 a" m. S8 G6 n3 ]6 q
  51.                 response.sendRedirect(path+"/pages/noAuthorization.jsp");
    7 j, Y, C, q9 C- g
  52.     }/ V+ k% Q) m9 b+ W) f! |- p
  53.     /**4 o5 M  E. ?7 F( Q! a7 @" |
  54.      * 获取注解中对方法的权限值 用于Controller层注解  
    8 k( J2 ~; t  ^* K4 A
  55.      * @Author        张志朋
    2 [6 N. F9 V: M
  56.      * @param joinPoint
    + ^- R# }' s1 r  h  x
  57.      * @return
    . v* d9 G0 W, v5 z1 t) q5 c
  58.      * @throws Exception  int' r8 C3 [& v, z7 X, i
  59.      * @Date        2015年7月3日
    5 @' S% [" y: I; [! ]* s. x9 b! n5 I4 f
  60.      * 更新日志
    1 @( \) T. m) S, y' K; Z, c+ E* G
  61.      * 2015年7月3日 张志朋  首次创建7 U, T9 U( y2 Y! z
  62.      *2 Z4 ?2 c: Y8 o, T
  63.      */
    9 @8 Q9 C$ x8 R& o  K7 V7 ^( L
  64.     @SuppressWarnings("rawtypes")
    8 c' k& S" Z* |7 _9 l
  65.         public  static int getControllerMethodRole(JoinPoint joinPoint)  throws Exception {
    & o6 `9 D! I8 w. f
  66.         String targetName = joinPoint.getTarget().getClass().getName();    ! `' K; B2 l5 w
  67.         String methodName = joinPoint.getSignature().getName();    ( D* y9 w, o" V' E; W
  68.         Object[] arguments = joinPoint.getArgs();    , F* I# _8 K& H3 ^( ^; s
  69.         Class targetClass = Class.forName(targetName);    , r# D, w9 N, R8 S2 @2 A0 c
  70.         Method[] methods = targetClass.getMethods();   
    3 s7 H7 F4 H9 p% Z3 J# j
  71.         int role = -1;    * }' t8 i( O# ?% W# w
  72.          for (Method method : methods) {    + a# n, }0 f1 X5 E# t4 M( P, C
  73.              if (method.getName().equals(methodName)) {    * S9 C8 v/ G8 W5 @3 s8 G  y
  74.                 Class[] clazzs = method.getParameterTypes();   
    ! E% o" N; b3 U; P
  75.                  if (clazzs.length == arguments.length) {    - i* n; p5 M9 }: u) @
  76.                          role = method.getAnnotation(Permission. class).id();    5 u( i9 ~1 B2 ~
  77.                      break;   
    * B, g1 A4 i. A2 H# b
  78.                 }   
    3 G: E: Y( ?; f* }9 X
  79.             }    ( g* S9 u, x' O. v( D& B1 J& V4 I
  80.         }   
    " ~' p7 a& d8 _4 P! a
  81.          return role;   
    5 i% {4 P3 O- ?
  82.     }
复制代码

: X  N' a& G: o+ n 2.action层代码实现: 3 j. @6 G! b. H* z
  1. /**
    $ e4 K; e( u9 |: w. v" W0 J3 y
  2.          * 试题审核不通过
    3 Q- S' a8 g2 N* @. p# m8 ~
  3.          * @Author        张志朋  void
    , h6 F/ v% s( }
  4.          * @Date        2015年5月4日
    & [- w* s  k  O% c9 \" F0 \- A. r
  5.          * 更新日志. R5 [/ y4 i1 E) L/ P
  6.          * 2015年5月4日 张志朋  首次创建9 q' `2 s) k! k# r1 v! M$ R( O
  7.          *: }. L" Z! S  Q
  8.          */
    ; ]$ a  I- Q5 i1 l0 J& t
  9.         @Permission(name="审核试题权限(审核不通过)",id=Constants.ROLE_QUES_AUDIT)2 U, ]( e; H$ z
  10.         public void auditQuestions(){
    6 _! V+ i! M7 k
  11.                 try {
    $ F0 h; h' u+ ~) }0 c0 N5 h" P7 E
  12.                      //代码实现
    . \3 F. o8 r2 t& a- U2 q" u/ f$ u
  13.                 } catch (Exception e) {' b4 H' W+ @! i0 M
  14.                      e.printStackTrace();
    ) ]+ \5 j5 v# _# Z
  15.                 }- G& Y$ {* t" ~
  16. # {8 s$ ~+ |2 ~7 c; U2 l
  17.         }
复制代码
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4月前
|
XML Java 数据格式
spring-aop的切入表达式和JoinPoint的使用以及怎么返回通知获取结果和在异常通知中获取异常还有环绕通知
spring-aop的切入表达式和JoinPoint的使用以及怎么返回通知获取结果和在异常通知中获取异常还有环绕通知
30 0
|
10月前
|
Java Spring
spring基于 注解的 AOP 的前后置通知,异常通知,最终通知,环绕通知
spring基于 注解的 AOP 的前后置通知,异常通知,最终通知,环绕通知
|
10月前
|
XML Java 数据格式
spring基于 XML 的 AOP 的前后置通知,异常通知,最终通知
spring基于 XML 的 AOP 的前后置通知,异常通知,最终通知
|
开发框架 Java Spring
Spring AOP异常:Error creating bean with name ‘org.springframework.aop.aspectj.
Spring AOP异常:Error creating bean with name ‘org.springframework.aop.aspectj.
|
开发框架 Java Spring
Spring AOP异常:Error creating bean with name ‘org.springframework.aop.aspectj.
Spring AOP异常:Error creating bean with name ‘org.springframework.aop.aspectj.
174 0
Spring AOP异常:Error creating bean with name ‘org.springframework.aop.aspectj.
|
Java Spring
【框架】[Spring]纯Java方式实现AOP拦截-详解ThrowsAdvice异常通知
转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自【大学之旅_谙忆的博客】 这篇博客讲了AOP代理-通知的3种方式: 1、MethodBeforeAdvice-前置通知 2、AfterReturningAdvice-正常返回后通知 3、MethodInterceptor-环绕通知 【框架】[Spring]纯Java的方式实现AOP切面(拦截)技术 现在本篇博客再详细讲解一下ThrowsAdvice-异常通知。
1213 0
通过AOP 实现异常统一管理
package com.zhang.shine.cache; import java.lang.reflect.Method; import org.aspectj.lang.ProceedingJoinPoint; import org.
690 0
|
Java Spring Apache
Spring Aop开发过程中可能出现的异常(通过这些异常可以知道需要什么Jar包)
出现的问题解决: 问题1:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.springframework.util.ClassUtils.&lt;clinit&gt;(ClassUtils.java:67)   at org.sprin
1985 0
|
5月前
|
Java 编译器 数据安全/隐私保护
自定义注解与AOP结合使用
自定义注解与AOP结合使用
58 0