日常踩坑系列(一)

日常踩坑系列(一)

记录生活中碰到的大大小小的坑,避免下次犯同样的错误。

1. AOP实现自定义注解

使用过滤器的时候想排除某些路径,但是网上搜了一下,好像没有这个功能,只能手动判断路径。我想更方便的使用,所有就准备自定义一个注解,实现排除路径的功能。

定义注解
@Target(ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface ExcludeReqPath {
    public String[] path();
}

1.@Target用来修饰注解,是注解的注解,称为元注解,表示当前定义的注解可以用在什么地方,类,方法或字段等。
2. @Retention也是元注解,表示定义的注解的生命周期。RetentionPolicy.SOURCE说明注解只保留在源文件,不会被编译成class文件。RetentionPolicy.CLASS说明注解会被编译成class文件,但运行时不存在。RetentionPolicy.RUNTIME说明注解会一直存在。
3. @Inherited是元注解,表示定义的注解可以被继承,即被定义的注解加在A类上,B类继承A类时会将被@Inherited标识过的注解一起继承。
4. @Documented表示该注解会被javadoc之类的工具记录,默认情况下javadoc不会记录注解。

AOP实现注解的功能
package com.knight.Utils.Annotation;

import com.alibaba.fastjson.JSONObject;
import com.knight.Bean.AjaxResponse;
import com.knight.Utils.MatchUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * Created by forget on 2019/9/8.
 * 实现ExcludeReqPath注解
 */
@Aspect
@Component
public class HandleExcludeReqPath {

    @Pointcut("@annotation(com.knight.Utils.Annotation.ExcludeReqPath)")
    public void handleAnnotation() throws ClassNotFoundException {

    }

    @Around("handleAnnotation()")
    public Object AroundHandler(ProceedingJoinPoint point) throws Throwable {

        boolean pass=false;
        Object object=null;
        HttpServletResponse response=null;
        HttpServletRequest request=null;
        FilterChain chain=null;
        for (Object o:point.getArgs()) {
            if(o instanceof ServletRequest)
            {
                request= (HttpServletRequest) o;
            }
            else if(o instanceof ServletResponse)
            {
                response= (HttpServletResponse) o;
            }
            else if(o instanceof FilterChain)
            {
                chain= (FilterChain) o;
            }
        }

        String path=request.getServletPath();
        Class tag=point.getTarget().getClass();
        for (Method m:tag.getMethods()) {

            if(m.getName().equals("doFilter"))
            {
                String[] args=m.getAnnotation(ExcludeReqPath.class).path();
                //匹配请求路径的方法
                pass = MatchUtil.MatchPath(path,args);
                break;
            }
        }
        if(pass)
        {
            //路径匹配通过,跳过当前过滤器
            chain.doFilter(request,response);
        }
        else
        {
            object= point.proceed();
        }
        return object;
    }
}

  1. 使用@Pointcut注解定义切点,参数@annotation用于匹配当前执行方法持有指定注解的方法。
  2. 通过ProceedingJoinPoint类型的参数获得被注解的对象及执行方法的参数。然后获取注解的参数,校验请求路径是否被排除。如果匹配成功,则不执行目标方法。直接在目标方法的响应参数中,返回处理结果。

2.无法查询到数据

碰到一个很隐蔽的坑,找了一晚上才找到。使用mybatis查询远程数据库的数据,一直查询不到数据。多次检查代码都没有发现问题。并且连接查询本地数据库可以正常查询到数据。最终排查发现只有带有中文的关键词不能查询到数据,初步确定是字符集的问题,查看了两个数据库的编码集,果然发现两个数据库的编码集不一致,远程数据库的编码集并不是UTF8。

解决办法:修改远程数据库的字符集编码。

修改数据库的配置文件
ubuntu环境下Mysql5.7版本可以执行以下命令打开配置文件

sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

在[mysqld]下添加一下代码

character-set-server=utf8

最后重启数据库即可。

你可能感兴趣的:(日常踩坑系列(一))