Error occurred, type mismatch, resulting in method not found
The parameter of the method is Model, and the container injects the BindingAwareModelMap class
Model, ExtendedModelMap, BindingAwareModelMap relationships
It can be seen from the figure that:
Parameters of the Model type are injected into the BindingAwareModelMap class, which is a subclass of the ExtendedModelMap class of the Model interface implementation class.
While getting the method
The classes in clazz.getMethod (methodName, classes) in are from the parameter loop args[i].getClass() of Object[] args = joinPoint.getArgs(); to clazz [i]. Bindingawaremodelmap.class will not be Model.class, so no method will be found. An exception occurred. So we just need to do the following:
for (int i = 0; i < args.length; i++) { //The parameter of Model type injects the BindingAwareModelMap class, which is a subclass of the ExtendedModelMap class of the Model interface implementation class if(args[i] instanceof BindingAwareModelMap){ //The subclass BindingAwareModelMap is forced to the parent class ExtendedModelMap, which is the implementation class of the Model interface, clazz.getMethod (methodName, classes); no type conversion exception will occur classes[i] = Model.class; continue; } classes[i] = args[i].getClass (); }
The log section classes are as follows:
package com.itheima.ssm.controller; import com.itheima.ssm.domain.SysLog; import com.itheima.ssm.service.SysLogService; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Component; import org.springframework.ui.ExtendedModelMap; import org.springframework.ui.Model; import org.springframework.validation.support.BindingAwareModelMap; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.Date; @Component @Aspect //Indicates that the current class is a tangent class public class SysLogAop { //Inject request @Autowired private HttpServletRequest request; //Inject service @Autowired private SysLogService sysLogService; private Date visitTime; //Access time private Class clazz; //Class of access private Method method; //Access method //Configuration entry point @Pointcut("execution(* com.itheima.ssm.controller.*.*(..))") public void pt() { } //Before advice @Before("pt()") public void doBefore(JoinPoint joinPoint) throws NoSuchMethodException { visitTime = new Date (); //Get access time clazz = joinPoint.getTarget ().getClass (); //Get the accessed class String methodName = joinPoint.getSignature ().getName (); //Gets the name of the accessed method //Get method parameters Object[] args = joinPoint.getArgs (); //Get Method by reflection if (args == null || args.length == 0) { method = clazz.getMethod (methodName); //Only methods without parameters can be obtained } else { Class[] classes = new Class[args.length]; for (int i = 0; i < args.length; i++) { //The parameter of Model type injects the BindingAwareModelMap class, which is a subclass of the ExtendedModelMap class of the Model interface implementation class if(args[i] instanceof BindingAwareModelMap){ //The subclass BindingAwareModelMap is forced to the parent class ExtendedModelMap, which is the implementation class of the Model interface, clazz.getMethod (methodName, classes); no type conversion exception will occur classes[i] = Model.class; continue; } classes[i] = args[i].getClass (); } method = clazz.getMethod (methodName, classes); } } //Post notification mainly obtains other information in the log, such as duration, ip, url @AfterReturning("pt()") public void doAfter() { //Get URL -- > / orders / findall.do String url = ""; if (clazz != null && method != null && clazz != SysLogAop.class) { //1. Get the value value in the @ RequestMapping("/product") annotation on the class RequestMapping clazzAnnotation = (RequestMapping) clazz.getAnnotation (RequestMapping.class); if (clazzAnnotation != null) { String[] classValue = clazzAnnotation.value (); //2. Get the value value in the @ RequestMapping("/findAll.do") annotation on the method RequestMapping methodAnnotation = method.getAnnotation (RequestMapping.class); if (methodAnnotation != null) { String[] methodValue = methodAnnotation.value (); //3. get URL if (classValue[0] != null && methodValue[0] != null) { url = classValue[0] + methodValue[0]; } // String uri = request.getRequestURI (); //Get execution time Long executionTime = new Date ().getTime () - visitTime.getTime (); //Get ip requires request get -- "get request requires configuring listener requestcontextlistener class in web.xml to inject HttpServletRequest String ip = request.getRemoteAddr (); //Get the user name of the operator (in two ways) 1. Get the login object from the context 2. You can also get it from request.getSession SecurityContext context = SecurityContextHolder.getContext (); // SecurityContext context = (SecurityContext) request.getSession ().getAttribute ("SPRING_SECURITY_CONTEXT"); Object principal = context.getAuthentication ().getPrincipal (); String username = ""; if(principal instanceof User){ User user = (User) context.getAuthentication ().getPrincipal (); username = user.getUsername (); }else { username = "Not yet logged in."; } //Encapsulating the log class SysLog SysLog sysLog = new SysLog (); sysLog.setVisitTime (visitTime); sysLog.setExecutionTime (executionTime); sysLog.setIp (ip); sysLog.setUrl (url); sysLog.setUsername (username); sysLog.setMethod ("[Class name]" + clazz.getName() + "[Method name]" + method.getName()); //Call service sysLogService.save(sysLog); } } } } }