目录
拦截器深入应用
Interceptor详解
HandlerInterceptor接口
public interface HandlerInterceptor {
// 请求处理前调用
boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler);
// 请求处理后,视图渲染前调用
void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView);
// 整个请求完成后调用
void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex);
}
认证拦截器实现
用户认证拦截器
@Component
public class AuthenticationInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(AuthenticationInterceptor.class);
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String requestURI = request.getRequestURI();
String method = request.getMethod();
logger.info("拦截请求: {} {}", method, requestURI);
// 检查公开URL
if (isPublicUrl(requestURI)) {
return true;
}
// 验证用户登录状态
HttpSession session = request.getSession(false);
if (session == null) {
redirectToLogin(request, response);
return false;
}
User user = (User) session.getAttribute("currentUser");
if (user == null) {
redirectToLogin(request, response);
return false;
}
// 检查用户状态
if (!user.isActive()) {
session.invalidate();
redirectToLogin(request, response, "账户已被禁用");
return false;
}
// 更新最后访问时间
updateLastAccessTime(request, user);
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
if (modelAndView != null) {
// 添加当前用户信息到模型
HttpSession session = request.getSession(false);
if (session != null) {
User currentUser = (User) session.getAttribute("currentUser");
if (currentUser != null) {
modelAndView.addObject("currentUser", currentUser);
modelAndView.addObject("userPermissions", getUserPermissions(currentUser));
}
}
// 添加通用数据
modelAndView.addObject("requestPath", request.getRequestURI());
modelAndView.addObject("timestamp", System.currentTimeMillis());
}
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
// 记录请求完成日志
if (ex != null) {
logger.error("请求处理异常: {} {}", request.getMethod(), request.getRequestURI(), ex);
} else {
logger.debug("请求完成: {} {} - {}",
request.getMethod(),
request.getRequestURI(),
response.getStatus());
}
}
private boolean isPublicUrl(String uri) {
String[] publicUrls = {
"/", "/login", "/register", "/public", "/static",
"/api/public", "/health", "/error"
};
for (String publicUrl : publicUrls) {
if (uri.startsWith(publicUrl)) {
return true;
}
}
return false;
}
private void redirectToLogin(HttpServletRequest request,
HttpServletResponse response,
String message) throws IOException {
String loginUrl = request.getContextPath() + "/login";
if (message != null) {
loginUrl += "?error=" + URLEncoder.encode(message, "UTF-8");
}
response.sendRedirect(loginUrl);
}
private void redirectToLogin(HttpServletRequest request,
HttpServletResponse response) throws IOException {
redirectToLogin(request, response, null);
}
private void updateLastAccessTime(HttpServletRequest request, User user) {
String userAgent = request.getHeader("User-Agent");
String clientIp = getClientIP(request);
// 异步更新用户访问信息
CompletableFuture.runAsync(() -> {
userService.updateLastAccess(user.getId(), userAgent, clientIp);
});
}
private String getClientIP(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
private Set<String> getUserPermissions(User user) {
// 获取用户权限
return userService.getUserPermissions(user.getId());
}
}
权限控制拦截器
基于角色的权限拦截器
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {
@Autowired
private PermissionService permissionService;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 获取当前用户
HttpSession session = request.getSession(false);
if (session == null) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
User user = (User) session.getAttribute("currentUser");
if (user == null) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
// 检查权限
String requestURI = request.getRequestURI();
String method = request.getMethod();
if (!hasPermission(user, requestURI, method)) {
logger.warn("用户{}访问资源{}被拒绝", user.getUsername(), requestURI);
response.sendError(HttpServletResponse.SC_FORBIDDEN, "权限不足");
return false;
}
return true;
}
private boolean hasPermission(User user, String uri, String method) {
try {
// 根据URL和HTTP方法检查权限
return permissionService.checkPermission(user.getId(), uri, method);
} catch (Exception e) {
logger.error("权限检查异常", e);
return false;
}
}
}
日志拦截器
请求日志拦截器
@Component
public class LoggingInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



