如果文章对你有帮助欢迎【关注❤️❤️❤️点赞👍👍👍收藏⭐⭐⭐】一键三连!一起努力!

一、UserAgentUtils简介

user-agent-utils 是一个用来解析 User-Agent 字符串的 Java 类库。

其能够识别的内容包括:

  • 超过150种不同的浏览器;
  • 7种不同的浏览器类型;
  • 超过60种不同的操作系统;
  • 6种不同的设备类型;
  • 9种不同的渲染引擎;
  • 9种不同的Web应用,如HttpClient、Bot。

在web应用中我们通过request获取用户的Agent并解析Agent字段 :

// 解析agent字符串
UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
// 获取浏览器对象
Browser browser = userAgent.getBrowser();
// 获取操作系统对象
OperatingSystem operatingSystem = userAgent.getOperatingSystem();
System.out.println("浏览器名:" + browser.getName());
System.out.println("浏览器类型:" + browser.getBrowserType());
System.out.println("浏览器家族:" + browser.getGroup());
System.out.println("浏览器生产厂商:" + browser.getManufacturer());
System.out.println("浏览器使用的渲染引擎:" + browser.getRenderingEngine());
System.out.println("浏览器版本:" + userAgent.getBrowserVersion());
System.out.println("==================================================" );
System.out.println("==================================================" );
System.out.println("操作系统名:" + operatingSystem.getName());
System.out.println("访问设备类型:" + operatingSystem.getDeviceType());
System.out.println("操作系统家族:" + operatingSystem.getGroup());
System.out.println("操作系统生产厂商:" + operatingSystem.getManufacturer());

输出:

浏览器名:Chrome 10
浏览器类型:WEB_BROWSER
浏览器家族:CHROME
浏览器生产厂商:GOOGLE
浏览器使用的渲染引擎:WEBKIT
浏览器版本:107.0.0.0
==================================================
==================================================
操作系统名:Windows 10
访问设备类型:COMPUTER
操作系统家族:WINDOWS
操作系统生产厂商:MICROSOFT

二、登录日志模块实现

实现后的样式:
在这里插入图片描述

1、创建数据库表

CREATE TABLE `sys_login_info` (
  `info_id` bigint NOT NULL AUTO_INCREMENT COMMENT '访问ID',
  `user_name` varchar(50) DEFAULT '' COMMENT '用户账号',
  `ipaddr` varchar(128) DEFAULT '' COMMENT '登录IP地址',
  `login_location` varchar(255) DEFAULT '' COMMENT '登录地点',
  `browser` varchar(50) DEFAULT '' COMMENT '浏览器类型',
  `os` varchar(50) DEFAULT '' COMMENT '操作系统',
  `status` tinyint(1) DEFAULT '1' COMMENT '登录状态(1成功 0失败)',
  `msg` varchar(255) DEFAULT '' COMMENT '提示消息',
  `login_time` datetime DEFAULT NULL COMMENT '访问时间',
  PRIMARY KEY (`info_id`)
) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='系统访问记录';

2、准备对应实体类

/**
 * <p>
 * 系统访问记录
 * </p>
 *
 * @author Xiong
 * @since 2022-12-06
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_login_info")
@ApiModel(value = "SysLoginInfo对象", description = "系统访问记录")
public class SysLoginInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty("访问ID")
    @TableId(value = "info_id", type = IdType.AUTO)
    private Long infoId;

    @ApiModelProperty("用户账号")
    private String userName;

    @ApiModelProperty("登录IP地址")
    private String ipaddr;

    @ApiModelProperty("登录地点")
    private String loginLocation;

    @ApiModelProperty("浏览器类型")
    private String browser;

    @ApiModelProperty("操作系统")
    private String os;

    @ApiModelProperty("登录状态(1成功 0失败)")
    private Boolean status;

    @ApiModelProperty("提示消息")
    private String msg;

    @ApiModelProperty("访问时间")
    private Date loginTime;
}

3、导入对应依赖

<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
    <groupId>eu.bitwalker</groupId>
    <artifactId>UserAgentUtils</artifactId>
    <version>1.21</version>
</dependency>

4、修改登录接口

@Override
public UserDTO login(UserDTO userDTO) {
    // 用户密码 md5加密
    userDTO.setPassword(SecureUtil.md5(userDTO.getPassword()));
    User one = getUser(userDTO);
    if (one != null) {
        BeanUtil.copyProperties(one, userDTO, true);
        // 设置token
        String token = TokenUtils.getToken(one.getUserId().toString(), one.getPassword());
        userDTO.setToken(token);
        // 设置菜单
        userDTO.setMenus(getRoleMenus(one));
        // 将用户信息存到redis
        stringRedisTemplate.opsForValue().set(USER_INFO, JSONUtil.toJsonStr(userDTO));
        // 记录登录日志
        AsyncManager.me().execute(AsyncFactory.recordLoginInfo(one.getUserName(), Constants.LOGIN_SUCCESS, "登录成功!"));
        return userDTO;
    } else {
        throw new ServiceException(HttpStatus.NO_CONTENT, "用户名或密码不正确");
    }
}

异步任务管理器:

/**
 * @description: 异步任务管理器
 * @author: Xiong
 * @date: 2022/12/7 10:58
 */
public class AsyncManager {
    /**
     * 操作延迟10毫秒
     */
    private static final int OPERATE_DELAY_TIME = 10;

    /**
     * 异步操作任务调度线程池
     */
    private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");

    /**
     * 单例模式
     */
    private AsyncManager() {
    }

    private static AsyncManager me = new AsyncManager();

    public static AsyncManager me() {
        return me;
    }

    /**
     * 执行任务
     *
     * @param task 任务
     */
    public void execute(TimerTask task) {
        executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
    }

    /**
     * 停止任务线程池
     */
    public void shutdown() {
        executor.shutdown();
    }
}

异步工厂:

/**
 * @description: 异步工厂(产生任务用)
 * @author: Xiong
 * @date: 2022/12/7 10:45
 */
public class AsyncFactory {
    private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user" );

    /**
     * 记录登录信息
     *
     * @param username 用户名
     * @param status   状态
     * @param message  消息
     * @param args     列表
     * @return 任务task
     */
    public static TimerTask recordLoginInfo(final String username, final String status, final String message,
                                            final Object... args) {
        final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent" ));
        final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        return new TimerTask() {
            @Override
            public void run() {
                String address = AddressUtils.getRealAddressByIP(ip);
                // 获取操作系统
                String os = userAgent.getOperatingSystem().getName();
                // 获取客户端浏览器
                String browser = userAgent.getBrowser().getName();
                // 封装对象
                SysLoginInfo loginInfo = new SysLoginInfo();
                loginInfo.setUserName(username);
                loginInfo.setIpaddr(ip);
                loginInfo.setLoginLocation(address);
                loginInfo.setBrowser(browser);
                loginInfo.setOs(os);
                loginInfo.setMsg(message);
                loginInfo.setLoginTime(new Date());
                // 日志状态
                if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
                    loginInfo.setStatus(Boolean.TRUE);
                } else if (Constants.LOGIN_FAIL.equals(status)) {
                    loginInfo.setStatus(Boolean.FALSE);
                }
                // 插入数据
                SpringUtils.getBean(ISysLoginInfoService.class).saveOrUpdate(loginInfo);
            }
        };
    }

}

其中涉及到很多工具类,大家可以根据自己的项目自行实现所需要信息的获取,这里不做过多的解释。

如果需要可以从项目中获取git地址如下:
https://gitee.com/mr_xiongs_gitee/Jesus

感谢各位家人的观看喜欢的话点帮忙点赞👍👍👍哦

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐