Article table of contents
- 1. Reproduce the problem
- 2. Analyze the problem
- 3. Problem solving
1. Reproduce the problem
When calling the /user/getAll
interface today, the following error is reported:
com.alibaba.fastjson.JSONException: write javaBean error, fastjson version 1.2.54, class org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl, fieldName : sourceLocation at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:523) at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:160) at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:310) at com.alibaba.fastjson.serializer.ASMSerializer_1_MethodInvocationProceedingJoinPoint.write(Unknown Source) at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:281) at com.alibaba.fastjson.JSON.toJSONString(JSON.java:676) at com.alibaba.fastjson.JSON.toJSONString(JSON.java:614) at com.alibaba.fastjson.JSON.toJSONString(JSON.java:579) at com.superjson.superjsonmanager.aop.log.RequestLogAspect.doBefore(RequestLogAspect.java:75) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:617) at org.springframework.aop.aspectj.AspectJMethodBeforeAdvice.before(AspectJMethodBeforeAdvice.java:44) at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:57) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89) at com.superjson.superjsonmanager.aop.log.RequestLogAspect.doAround(RequestLogAspect.java:95) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624) at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) at com.superjson.superjsonmanager.controller.UserController$$EnhancerBySpringCGLIB$$25c82d38.getAllUsers(<generated>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ......
That is, com.alibaba.fastjson.JSONException: write javaBean error,
, that is, fastjson
creates Javabean
object error, why does this happen What about the situation? The following analysis can only be done through breakpoints.
2. Analyze the problem
By analyzing the above other error messages class org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl, fieldName : sourceLocation
, the error occurs on the aspect property.
My aspect class is RequestLogAspect
, which is a global unified log class that uses the spring boot aop
aspect technology. The breakpoints are as follows:
Through breakpoints, the problem can be clearly located in joinPoint.proceed();
, and attributes.getRequest();
returns the ShiroHttpServletRequest
object .
Why does this object return instead of the spring boot aop
object? Because I configured shiro aop
as shown in the following code:
/** * To enable Shiro's annotations (such as @RequiresRoles, @RequiresPermissions), you need to use SpringAOP to scan classes annotated with Shiro, and perform security logic verification when necessary * Configure the following two beans (DefaultAdvisorAutoProxyCreator (optional) and AuthorizationAttributeSourceAdvisor) to achieve this function * * <p>creator.setUsePrefix(false); choose either creator.setProxyTargetClass(false); * * @return */ @Bean @DependsOn({<!-- -->"lifecycleBeanPostProcessor"}) public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {<!-- --> DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); creator.setUsePrefix(false); return creator; }
Why does configuring shiro aop
cause spring aop
to fail? The reason lies in the secondary proxy, as follows:
-
proxy-target-class
is enforced due to the use ofaop:aspectj-autoproxy
-
That is to say, the
CGLib
agent is used for theClass
(mainlyController
) of theWeb
layer. -
Then use
DefaultAdvisorAutoProxyCreator
whenShiro
is proxying -
Originally should judge
Controller
and found that there is no interface, so useCGLib
to proxy -
But because
Controller
has been delegated byCGLib
once -
DefaultAdvisorAutoProxyCreator
is notContoller
itself, but the proxy result of CGLib -
The proxy result of
CGLib
itself has an interface, which interferes with -
Internal judgment of
DefaultAdvisorAutoProxyCreator
-
Use
JDK
to proxy the results ofCGLib
-
As a result, when the function of
Controller
went to the interface ofCGLib
to find the method name, it was found that the method did not exist, causing the proxy to fail.
3. Solve the problem
According to the information on the Internet, we need to configure the following in application.yml
:
# spring configuration spring: aop: # Solve the conflict between spring aop and shiro proxy-target-class: true
But in fact, this configuration cannot solve the problem, and the above error is still reported.
Therefore, I need to modify the @Pointcut
annotation of the aspect class and use the annotation method to solve this problem, as follows:
// The original code, the scan controller // @Pointcut("execution(public * com.superjson.superjsonmanager.controller.*.*(..))") // public void requestLog() {} /** * New code: use annotations to resolve conflicts between shiro aop and spring aop * * @author is beautiful * @datetime 2022/8/22:11:32 * @return */ @Pointcut("@annotation(com.superjson.superjsonmanager.annotation.LogAnnotation)") public void requestLog() {<!-- -->}
My LogAnnotation
annotation class looks like this:
/** * @author is beautiful * @datetime 2022/8/22 10:05 * @desc log annotation */ @Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface LogAnnotation {<!-- --> }
Restart spring boot and call the /user/getAll
interface to successfully access and record logs, as shown in the following figure: