自定义注解
Login
package com.nasc.mis.auth;
import java.lang.annotation.*;
@Inherited // 允许子类继承父类中的注解
@Documented // 将注解包含在Javadoc中
@Target(value = ElementType.TYPE) // 注解可以用于什么地方
@Retention(value = RetentionPolicy.RUNTIME) // 表示需要在什么级别保存该注解信息
public @interface Login {
}
LoginUser
package com.nasc.mis.auth;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // 注解可以用于什么地方
@Retention(RetentionPolicy.RUNTIME) // 表示需要在什么级别保存该注解信息
public @interface LoginUser {
}
拦截器
AuthorizationInterceptor
package com.nasc.mis.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.nasc.base.component.Redis;
import com.nasc.base.entity.mis.AccountJoinEntity;
import com.nasc.mis.auth.Login;
import com.nasc.base.util.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
@Resource
private Redis redis;
public static final String USER_KEY = "id";
/**
* 14天后过期
*/
private final static int EXPIRE = 3600 * 336;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Login annotation;
if (handler instanceof HandlerMethod) {
annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class);
} else {
return true;
}
if (annotation == null) {
return true;
}
// 从header中获取token
String token = request.getHeader("token");
// 如果header中不存在token,则从参数中获取token
if (StringUtils.isEmpty(token)) {
token = request.getParameter("token");
}
// token为空
if (StringUtils.isEmpty(token)) {
throw new BusinessException(1, "token不能为空");
}
token = token.replace("\"", "");
// 查询token信息
JSONObject jsonObject = (JSONObject) redis.get(token);
String userId = "";
if (jsonObject == null) {
throw new BusinessException(1, "token失效,请重新登录");
} else {
//更新token
AccountJoinEntity user = jsonObject.toJavaObject(AccountJoinEntity.class);
userId = user.getId();
Long expireTime = redis.getExpire(token);
if (expireTime <= EXPIRE) {
redis.expire(token, EXPIRE);
}
}
// 设置userId到request里,后续根据userId,获取用户信息
request.setAttribute(USER_KEY, userId);
return true;
}
}
处理器
LoginUserHandlerMethodArgumentResolver
package com.nasc.mis.interceptor;
import com.nasc.base.entity.mis.AccountEntity;
import com.nasc.base.entity.mis.DataResEntity;
import com.nasc.mis.auth.LoginUser;
import com.nasc.mis.service.IAccountService;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.annotation.Resource;
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Resource
private IAccountService accountService;
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().isAssignableFrom(AccountEntity.class)
&& parameter.hasParameterAnnotation(LoginUser.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest request,
WebDataBinderFactory factory) throws Exception {
// 获取用户ID
Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
if (object == null) {
return null;
}
// 获取用户信息
DataResEntity<Object> res = accountService.getById(String.valueOf(object));
AccountEntity accountEntity = (AccountEntity) res.getResult();
return accountEntity;
}
}
异常处理类
BusinessException
package com.nasc.base.util.exception;
/**
* @description:
* @project: NASC
* @className: BusinessException.java
* @software: IntelliJ IDEA
* @author: hanleng
* @date: 2023/3/1 11:25
**/
public class BusinessException extends RuntimeException{
/**
* 返回code
*/
private Integer code;
/**
* 返回msg
*/
private String message;
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public Integer getCode() {
return code;
}
}