獲取用戶登錄信息


在上一篇博客中,實現了登錄、登錄憑證模塊的開發,今天,通過昨天session中的登錄憑證,是的其他請求可以持有用戶信息。主要利用攔截器以及ThreadLocal。

重寫攔截器的三個方法preHandle、postHandle、afterCompletion。分別實現獲取用戶信息,並保存到ThreadLocal中、向ModelAndView 中傳入用戶信息、以及清空ThreadLocal中用戶的功能。通過HostHolder工具類封裝起ThreadLocal的相應操作。 

 1 package com.nowcoder.community.controller.interceptor;
 2 
 3 import com.nowcoder.community.entity.LoginTicket;
 4 import com.nowcoder.community.entity.User;
 5 import com.nowcoder.community.service.UserService;
 6 import com.nowcoder.community.util.CookieUtil;
 7 import com.nowcoder.community.util.HostHolder;
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.stereotype.Component;
10 import org.springframework.web.servlet.HandlerInterceptor;
11 import org.springframework.web.servlet.ModelAndView;
12 
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15 import java.util.Date;
16 
17 @Component
18 public class LoginTicketInterceptor implements HandlerInterceptor {
19 
20     @Autowired
21     private UserService userService;
22 
23     @Autowired
24     private HostHolder hostHolder;
25 
26     @Override
27     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
28         // 從cookie中獲取憑證
29         String ticket = CookieUtil.getValue(request, "ticket");
30 
31         if (ticket != null) {
32             // 查詢憑證
33             LoginTicket loginTicket = userService.findLoginTicket(ticket);
34             // 檢查憑證是否有效
35             if (loginTicket != null && loginTicket.getStatus() == 0 && loginTicket.getExpired().after(new Date())) {
36                 // 根據憑證查詢用戶
37                 User user = userService.findUserById(loginTicket.getUserId());
38                 // 在本次請求中持有用戶
39                 hostHolder.setUser(user);
40             }
41         }
42 
43         return true;
44     }
45 
46     @Override
47     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
48         User user = hostHolder.getUser();
49         if (user != null && modelAndView != null) {
50             modelAndView.addObject("loginUser", user);
51         }
52     }
53 
54     @Override
55     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
56         hostHolder.clear();
57     }
58 }
 
         
package com.nowcoder.community.util;

import com.nowcoder.community.entity.User;
import org.springframework.stereotype.Component;

/**
* 持有用戶信息,用於代替session對象.
*/
@Component
public class HostHolder {

private ThreadLocal<User> users = new ThreadLocal<>();

public void setUser(User user) {
users.set(user);
}

public User getUser() {
return users.get();
}

public void clear() {
users.remove();
}

}
 

此外,寫了一個注解。通過攔截器對方法判斷是否有@LoginRequired注解,若有改注解則需要先登錄。

注解聲明很簡單,只需通過元注解標明注解作用的目標和注解的保留位置。

package com.nowcoder.community.annotation;

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 LoginRequired {



}

再寫一個攔截器檢驗是否有@LoginRequired注解

 1 package com.nowcoder.community.controller.interceptor;
 2 
 3 import com.nowcoder.community.annotation.LoginRequired;
 4 import com.nowcoder.community.util.HostHolder;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Component;
 7 import org.springframework.web.method.HandlerMethod;
 8 import org.springframework.web.servlet.HandlerInterceptor;
 9 
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 import java.lang.reflect.Method;
13 
14 @Component
15 public class LoginRequiredInterceptor implements HandlerInterceptor {
16 
17     @Autowired
18     private HostHolder hostHolder;
19 
20     @Override
21     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
22         if (handler instanceof HandlerMethod) {
23             HandlerMethod handlerMethod = (HandlerMethod) handler;
24             Method method = handlerMethod.getMethod();
25             LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);
26             if (loginRequired != null && hostHolder.getUser() == null) {
27                 response.sendRedirect(request.getContextPath() + "/login");
28                 return false;
29             }
30         }
31         return true;
32     }
33 }

攔截器配置類代碼如下

package com.nowcoder.community.config;

import com.nowcoder.community.controller.interceptor.AlphaInterceptor;
import com.nowcoder.community.controller.interceptor.LoginRequiredInterceptor;
import com.nowcoder.community.controller.interceptor.LoginTicketInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private LoginTicketInterceptor loginTicketInterceptor;

    @Autowired
    private LoginRequiredInterceptor loginRequiredInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(loginTicketInterceptor)
                .excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");

        registry.addInterceptor(loginRequiredInterceptor)
                .excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM