AOP记录异常邮件发送记录

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 一般我们的异常都会抛出到控制层,如果使用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日志并进行多维度分析。
目录
相关文章
|
7月前
|
XML Java 数据格式
spring-aop的切入表达式和JoinPoint的使用以及怎么返回通知获取结果和在异常通知中获取异常还有环绕通知
spring-aop的切入表达式和JoinPoint的使用以及怎么返回通知获取结果和在异常通知中获取异常还有环绕通知
163 0
|
Java Spring
spring基于 注解的 AOP 的前后置通知,异常通知,最终通知,环绕通知
spring基于 注解的 AOP 的前后置通知,异常通知,最终通知,环绕通知
|
XML Java 数据格式
spring基于 XML 的 AOP 的前后置通知,异常通知,最终通知
spring基于 XML 的 AOP 的前后置通知,异常通知,最终通知
|
Java Spring
【框架】[Spring]纯Java方式实现AOP拦截-详解ThrowsAdvice异常通知
转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自【大学之旅_谙忆的博客】 这篇博客讲了AOP代理-通知的3种方式: 1、MethodBeforeAdvice-前置通知 2、AfterReturningAdvice-正常返回后通知 3、MethodInterceptor-环绕通知 【框架】[Spring]纯Java的方式实现AOP切面(拦截)技术 现在本篇博客再详细讲解一下ThrowsAdvice-异常通知。
1240 0
通过AOP 实现异常统一管理
package com.zhang.shine.cache; import java.lang.reflect.Method; import org.aspectj.lang.ProceedingJoinPoint; import org.
710 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
2044 0
|
3月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
AOP(面向切面编程)能够帮助我们在不修改现有代码的前提下,为应用程序添加新的功能或行为。Micronaut框架中的AOP模块通过动态代理机制实现了这一目标。AOP将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,提高模块化程度。在Micronaut中,带有特定注解的类会在启动时生成代理对象,在运行时拦截方法调用并执行额外逻辑。例如,可以通过创建切面类并在目标类上添加注解来记录方法调用信息,从而在不侵入原有代码的情况下增强应用功能,提高代码的可维护性和可扩展性。
64 1
|
26天前
|
安全 Java 编译器
什么是AOP面向切面编程?怎么简单理解?
本文介绍了面向切面编程(AOP)的基本概念和原理,解释了如何通过分离横切关注点(如日志、事务管理等)来增强代码的模块化和可维护性。AOP的核心概念包括切面、连接点、切入点、通知和织入。文章还提供了一个使用Spring AOP的简单示例,展示了如何定义和应用切面。
67 1
什么是AOP面向切面编程?怎么简单理解?
|
1月前
|
XML Java 开发者
论面向方面的编程技术及其应用(AOP)
【11月更文挑战第2天】随着软件系统的规模和复杂度不断增加,传统的面向过程编程和面向对象编程(OOP)在应对横切关注点(如日志记录、事务管理、安全性检查等)时显得力不从心。面向方面的编程(Aspect-Oriented Programming,简称AOP)作为一种新的编程范式,通过将横切关注点与业务逻辑分离,提高了代码的可维护性、可重用性和可读性。本文首先概述了AOP的基本概念和技术原理,然后结合一个实际项目,详细阐述了在项目实践中使用AOP技术开发的具体步骤,最后分析了使用AOP的原因、开发过程中存在的问题及所使用的技术带来的实际应用效果。
57 5