jfinal自定义登录校验注解

项目某些请求需要校验是否登录,习惯了spring的注解,所以写了个自定义登录的注解,虽然jfinal框架不推荐用注解

自定义注解文件 LoginRequired.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义登陆校验标签
 * @Date: 2020-04-04 12:02
 *      * @Author: Chat_Li
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface LoginRequired {

    /***
     * @Name: loginRequired
     * @Description:  是否需要登录,缺省为需要
     * @Return: boolean
     * @Date: 2020-04-04 12:02
     * @Author: Chat_Li
     *
     */
    boolean loginRequired() default true;
}

自定义登录异常,用于异常同一处理

LoginException.java

/**
 * @author : Chat_Li
 * create at:  2020-04-04  16:48
 * @description: 登陆异常类
 */
public class LoginException extends RuntimeException {

    @Override
    public String getMessage() {
        return super.getMessage();
    }

    public LoginException(String message) {
        super(message);
    }
}

编写拦截器

LoginInterceptor.java

import cn.hutool.core.util.ObjectUtil;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.taiwei.jiandao.annotation.LoginRequired;
import com.taiwei.jiandao.core.ResultGenerator;
import com.taiwei.jiandao.exception.LoginException;
import com.taiwei.jiandao.model.User;
import com.taiwei.jiandao.utils.TokenUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author : Chat_Li
 * create at:  2020-04-04  12:46
 * @description: 登陆拦截器
 */
public class LoginInterceptor implements Interceptor {
    /**
    *前端传入的token标识(这个是在登录的时候,需要去处理如何产生这个标识,
    *并返回给前端的,如果需要通过Redis判断用户是否超时,也需要把这个值放入Redis中,
    *具体得看登录那块逻辑)
    */
    public final static String ACCESS_TOKEN = "AccessToken";

    @Override
    public void intercept(Invocation inv) {
        //获取请求的方法对象
        Method method = inv.getMethod();
        Controller controller = inv.getController();
        controller.getClass().getDeclaredMethods();
        //判断请求的方法是有有@LoginRequired 的登录注解
        boolean hasAnnotation = method.isAnnotationPresent(LoginRequired.class);
        if (hasAnnotation) {
            //获取request对象
            HttpServletRequest request = controller.getRequest();
            //获取请求头登录的标识
            String token = request.getHeader(ACCESS_TOKEN);
            if (token == null) {
                throw new LoginException("无token,请重新登录");
            }
            int userId;
            try {
                userId = Integer.parseInt(TokenUtils.parseJWT(token).getId());
            } catch (Exception e) {
                throw new LoginException("token无效,请重新登录");
            }
            //通过ID查询用户信息
           User user = User.dao.findById(userId);
            if(ObjectUtil.isNull(user)){
                throw new LoginException("用户不存在,请重新登录");
            }
            //这里可以根据具体业务添加判断,如:通过Redis 判断用户是否超时登录等....
        }
        inv.invoke();
    }
}

然后在jfinal的Config文件内加上拦截器

@Override
    public void configInterceptor(Interceptors interceptors) {
        //异常处理
        interceptors.add(new ExceptionAndLogInterceptor());
        //登录校验
        interceptors.add(new LoginInterceptor());
        //数据校验
        interceptors.add(new ValidatorInterceptor());
    }

这里注意 异常处理的拦截器一定要在第一个位, 不然登录中抛出的登录异常统一异常处理的拦截器中捕获不到

统一异常处理类

ExceptionAndLogInterceptor.java
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.core.JFinal;
import com.jfinal.log.Log;
import com.taiwei.jiandao.core.ResultGenerator;
import com.taiwei.jiandao.exception.LoginException;

/**
 * 2 * @Author: Chat_Li
 * 3 * @Date: 2020/4/8 14:40
 * 4  日志/异常处理拦截器
 */
public class ExceptionAndLogInterceptor implements Interceptor {
    private static final Log log= Log.getLog(ExceptionAndLogInterceptor.class);
    @Override
    public void intercept(Invocation ai) {
        Controller controller = (Controller)ai.getController();
        try {
            ai.invoke();
        }catch (Exception e) {
            doLog(ai,e);
            //运行异常
            if(e instanceof RuntimeException){
                controller.renderJson(ResultGenerator.genFailResult("运行时异常:" + e.getMessage())) ;
            }
            //系统异常
            if(e instanceof Exception){
                controller.renderJson(ResultGenerator.genInternalServerErrorResult("服务器错误,请联系管理员"));
            }
            //登录异常
            if(e instanceof LoginException){
                controller.renderJson(ResultGenerator.genUnauthorizedResult(e.getMessage()));
            }
            //自定义各种异常
        }
    }
    /**
     * @Method  doLog
     * @Author LiChao
     * @Description 记录log4j日志
     * @param ai
     * @param e
     * @Return
     * @Date 2020/4/8 14:45
     */
    private void doLog(Invocation ai,Exception e) {
        //开发模式
        if(JFinal.me().getConstants().getDevMode()){
            e.printStackTrace();
        }
        StringBuilder sb =new StringBuilder("\n---Exception Log Begin---\n");
        sb.append("Controller:").append(ai.getController().getClass().getName()).append("\n");
        sb.append("Method:").append(ai.getMethodName()).append("\n");
        sb.append("Exception Type:").append(e.getClass().getName()).append("\n");
        sb.append("Exception Details:");
        log.error(sb.toString(), e);
    }
}

最后就是在控制层使用

@RequestMapping("/demo")
public class DemoController extends Controller {
    @LoginRequired
    public void test1(){
        User user =  User.dao.findById(1);
        renderJson(user);
    }
    public void test2(){
    }
}

如果有帮助到您,希望能留个言~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值