项目某些请求需要校验是否登录,习惯了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(){
}
}
如果有帮助到您,希望能留个言~