public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // String token = TokenHelper.getFromReq(request); String token = request.getHeader(Authentication.TOKEN_NAME); if (StringUtils.isEmpty(token)) { // mute for OPTIONS if (!request.getMethod().equalsIgnoreCase(HttpMethod.OPTIONS.name())) { // need log return true; } return false; } UserContext userContext = Authentication.verify(token); if (userContext == null) { log.error(""); return false; } UserContextHolder.set(userContext); return true; } 这段代码干什么的
时间: 2024-02-14 09:27:45 浏览: 31
这段代码是一个拦截器(Interceptor)中的方法,用于在请求处理之前进行预处理。具体功能如下:
1. 获取请求中的 token 值。在这段代码中,使用 `request.getHeader(Authentication.TOKEN_NAME)` 方法从请求头中获取 token。
2. 检查 token 是否为空,如果为空,则判断请求方法是否为 OPTIONS。如果是 OPTIONS 请求,则直接返回 false,表示允许跨域请求的预检请求通过;如果不是 OPTIONS 请求,则需要记录日志,并返回 true。
3. 如果 token 不为空,则调用 `Authentication.verify(token)` 方法进行验证。如果验证成功,返回一个包含用户上下文信息的 `UserContext` 对象;如果验证失败,则记录错误日志,并返回 false。
4. 如果验证成功,将用户上下文信息存储到 `UserContextHolder` 中,以便后续代码可以获取到用户上下文信息。
5. 最后,返回 true 表示请求预处理通过,可以继续处理该请求。
相关问题
优化这段代码: public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); if (annotation != null) { if (this.isRepeatSubmit(request, annotation)) { AjaxResult ajaxResult = AjaxResult.error(annotation.message()); ServletUtils.renderString(response, JSON.toJSONString(ajaxResult)); return false; } } } boolean flag = false; TokenService tokenService = SpringUtils.getBean(TokenService.class); LoginAppUser loginUser = tokenService.getLoginUser(request); if (loginUser != null && loginUser.getGuest() != null && loginUser.getGuest().getGuestNum() != null) { tokenService.verifyToken(loginUser); String guestNum = loginUser.getGuest().getGuestNum(); HttpSession httpSession = request.getSession(); RedisCache redisUtil = SpringUtils.getBean(RedisCache.class); Guest guest = redisUtil.getCacheMapValue(RedisConstants.GUEST_MAP, guestNum); SysGuest sysGuest = JSON.parseObject(JSON.toJSONString(guest), SysGuest.class); if (sysGuest == null) { flag = false; httpSession.removeAttribute(Constants.SERVER_TYPE_APP); } else { if (httpSession.getAttribute(Constants.SERVER_TYPE_APP) == null) { httpSession.setAttribute(Constants.SERVER_TYPE_APP , sysGuest); } return true; } } //获取网名 也就是/login String servletPath = request.getServletPath(); if(servletPath.contains("/app/card/isCard") || servletPath.contains("/app/bank/signingBankCard") || servletPath.contains("/app/bank/sendMessage") || servletPath.contains("/app/bank/sendSysMessage") || servletPath.contains("/app/bank/login") || servletPath.contains("/app/card/guestIdAndPhone") || servletPath.contains("/app/family/isDevice") || servletPath.contains("/websocket/") || servletPath.contains("/upload/") || servletPath.contains("/app/deviceSocket/toSocket")) { flag = true; } if (!flag) { noLogin(response); } return flag; }
首先,可以将比较长的 if 语句拆分成多个小的 if 语句,这样可以使代码更易读。例如,可以将 `if (loginUser != null && loginUser.getGuest() != null && loginUser.getGuest().getGuestNum() != null)` 拆分成三个 if 语句。
其次,可以使用常量或者枚举类型来表示一些常用的字符串,例如 Constants.SERVER_TYPE_APP 和 RedisConstants.GUEST_MAP。
最后,可以使用 try-with-resources 语句来自动关闭资源,例如 redisUtil。这样可以避免因为忘记关闭资源而导致的内存泄漏问题。
以下是优化后的代码:
```
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
if (annotation != null) {
if (this.isRepeatSubmit(request, annotation)) {
AjaxResult ajaxResult = AjaxResult.error(annotation.message());
ServletUtils.renderString(response, JSON.toJSONString(ajaxResult));
return false;
}
}
}
boolean flag = false;
TokenService tokenService = SpringUtils.getBean(TokenService.class);
LoginAppUser loginUser = tokenService.getLoginUser(request);
if (loginUser != null) {
Guest guest = loginUser.getGuest();
if (guest != null) {
String guestNum = guest.getGuestNum();
tokenService.verifyToken(loginUser);
HttpSession httpSession = request.getSession();
RedisCache redisUtil = SpringUtils.getBean(RedisCache.class);
try (redisUtil) {
Guest cacheGuest = redisUtil.getCacheMapValue(RedisConstants.GUEST_MAP, guestNum);
SysGuest sysGuest = JSON.parseObject(JSON.toJSONString(cacheGuest), SysGuest.class);
if (sysGuest != null) {
if (httpSession.getAttribute(Constants.SERVER_TYPE_APP) == null) {
httpSession.setAttribute(Constants.SERVER_TYPE_APP, sysGuest);
}
return true;
}
}
}
}
String servletPath = request.getServletPath();
if (servletPath.contains("/app/card/isCard")
|| servletPath.contains("/app/bank/signingBankCard")
|| servletPath.contains("/app/bank/sendMessage")
|| servletPath.contains("/app/bank/sendSysMessage")
|| servletPath.contains("/app/bank/login")
|| servletPath.contains("/app/card/guestIdAndPhone")
|| servletPath.contains("/app/family/isDevice")
|| servletPath.contains("/websocket/")
|| servletPath.contains("/upload/")
|| servletPath.contains("/app/deviceSocket/toSocket")) {
flag = true;
}
if (!flag) {
noLogin(response);
}
return flag;
}
```
修改一下这个inceptor,我要求查看请求访问”/user/api"的用户的role_id是否为2(通过token),否则拒绝访问:public class MyInceptor implements HandlerInterceptor { // 处理指定接口 private static final String TOKEN_LOGIN = "/user/token"; private static final String USER_NO_URL = "/user/no"; // 拦截不存在的接口路径 // 不要要校验的接口 private static final List<String> NO_NEED_LOGIN = new ArrayList<>(Arrays.asList("/user/health", "/logout")); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求处理之前执行的操作 System.out.println("=====preHandle====="); return true; // 返回true表示继续处理请求,返回false表示终止请求处理 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 在请求处理之后,视图渲染之前执行的操作 System.out.println("=====postHandle====="); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在请求完成之后执行的操作,即视图渲染完成后 System.out.println("=====afterCompletion====="); } }
好的,您可以按照以下方式修改 MyInceptor 类的 preHandle 方法来实现您的要求:
```java
public class MyInceptor implements HandlerInterceptor {
// 处理指定接口
private static final String TOKEN_LOGIN = "/user/token";
private static final String USER_NO_URL = "/user/no"; // 拦截不存在的接口路径
// 不需要校验的接口
private static final List<String> NO_NEED_LOGIN = new ArrayList<>(Arrays.asList("/user/health", "/logout"));
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 在请求处理之前执行的操作
System.out.println("=====preHandle=====");
// 获取请求的路径
String requestURI = request.getRequestURI();
// 如果请求的路径是 /user/api,则需要进行校验
if ("/user/api".equals(requestURI)) {
// 获取请求头中的 token
String token = request.getHeader("token");
// 判断 token 是否有效,如果无效则拒绝访问
if (!isValidToken(token)) {
response.sendError(401, "Unauthorized");
return false;
}
// 获取 token 中的 role_id
int roleId = getRoleIdFromToken(token);
// 判断 role_id 是否为 2,如果不是则拒绝访问
if (roleId != 2) {
response.sendError(403, "Forbidden");
return false;
}
}
return true; // 返回true表示继续处理请求,返回false表示终止请求处理
}
private boolean isValidToken(String token) {
// TODO: 判断 token 是否有效
return true;
}
private int getRoleIdFromToken(String token) {
// TODO: 从 token 中获取 role_id
return 0;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// 在请求处理之后,视图渲染之前执行的操作
System.out.println("=====postHandle=====");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) throws Exception {
// 在请求完成之后执行的操作,即视图渲染完成后
System.out.println("=====afterCompletion=====");
}
}
```
在 preHandle 方法中,首先判断请求的路径是否为 /user/api。如果是,则获取请求头中的 token,并判断其是否有效。如果 token 无效,则返回 401 错误(未授权)。如果 token 有效,则从中获取 role_id,并判断其是否为 2。如果 role_id 不为 2,则返回 403 错误(禁止访问)。如果请求的路径不是 /user/api,则直接返回 true,继续处理请求。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)