When getting method operation while doing system log, the method parameter has Model, and the error occurs

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);
                }

            }

        }
    }

}

 

 

 

 

 

 

 

79 original articles published, 3 praised, 10000 visitors+
Private letter follow

Keywords: Java xml

Added by mlla2 on Wed, 19 Feb 2020 17:47:36 +0200