本文不详细叙述什么是JWT(Json web token),谷歌百度上关于这个的文章很多了,这里主要讲具体的代码实现。

OnlineCounter.java

@Component
public class OnlineCounter {

    //每次打开此类只初始化一次countMap
    private static Map countMap = new ConcurrentHashMap<String,Object>();

    public void insertToken(String token){
        //获得当前时间(毫秒)
        long currentTime = System.currentTimeMillis();
        //解析token,获得签发时间
        Claims claims = null;
        try {
            claims = JWTUtils.parseJWT(token);
        } catch (Exception e) {
            throw new RuntimeException("token不存在或已过期");
        }
        Date issuedAt = claims.getIssuedAt();
        //以签发时间为key。当前时间+60s为value存入countMap中
        countMap.put(issuedAt.toString(),currentTime+60*1000);
    }

    public Integer getOnlineCount(){
        int onlineCount = 0;
        //获取countMap的迭代器
        Iterator iterator = countMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String,Object>  entry = (Map.Entry<String, Object>) iterator.next();
            Long value = (Long) entry.getValue();
            if (value > System.currentTimeMillis()) {
                //过期时间大于当前时间则没有过期
                onlineCount++;
            }
        }
        return onlineCount;
    }
}

AdminController.java

    @Autowired
    private OnlineCounter onlineCounter;

    @GetMapping(value = "/getOnlineCount")
    public int getRealOnlineCount() {
        Integer onlines = onlineCounter.getOnlineCount();
        return onlines;
    }

JWTInterceptor.java

    @Autowired
    private OnlineCounter onlineCounter;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 允许跨域
        response.setHeader("Access-Control-Allow-Origin", "*");
        //后台管理页面产生的token
        String token = request.getHeader("authorization");
        //判断是否过期
        Optional.ofNullable(token)
                .map(n -> {
                    try {
                        return JWTUtils.parseJWT(n);
                    } catch (Exception e) {
                        throw new RuntimeException("token不存在");
                    }
                })
                .map(n->{
                    //存储该token方便记录在线人数
                    try {
                        onlineCounter.insertToken(token);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return n.getExpiration();
                })
                .orElseThrow(()->new RuntimeException("token已过期!请用户重新登陆!"));

        return true;
    }

获取实时在线人数

    @GetMapping(value = "/getOnlineCount")
    public int getRealOnlineCount() {
        Integer onlines = onlineCounter.getOnlineCount();
        return onlines;
    }