Spring Boot + vue-element 开发个人博客项目实战教程(十八、操作日志功能实现)2

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
日志服务 SLS,月写入数据量 50GB 1个月
简介: Spring Boot + vue-element 开发个人博客项目实战教程(十八、操作日志功能实现)2

4、添加注解

下面我们写完了注解,接下来我们肯定要使用这个注解,但是在什么地方引用呢,当然在我们程序的入库,那就是Controller层,这个是前端操作第一个进来的入口。例如:我们在分类的Controller中添加分类的方法上添加一个注解。

@OperationLogSys(desc = "添加分类", operationType = OperationType.INSERT)

完整代码:

  /**
     * 添加分类
     * @return
     */
    @ApiOperation(value = "添加分类")
    @PostMapping("/create")
    @OperationLogSys(desc = "添加分类", operationType = OperationType.INSERT)
    public JsonResult<Object> categoryCreate(@RequestBody @Valid Category category) {
        int isStatus = categoryService.saveCategory(category);
        if (isStatus == 0) {
            return JsonResult.error("添加分类失败");
        }
        return JsonResult.success();
    }

我们先测试一下这个注解是否有用,操作数据是否保存到了数据中。

打开postman,因为我们上一篇加了登录验证,所以我们在操作其他接口时,要先登录,重启项目之后也要重新登录。

我们先进行登录:登录成功之后,然后我们打开添加分类的接口,新添加一个分类。

看着添加成功了,我们去看下数据库,操作日志有没有数据。看到有数据,也是我们添加的分类,就说明我们添加成功了。好啦,我只添加一个操作日志,大家把所有的增加、删除、修改都进行添加一下,查询数据比较多可加可不加。

接下来我们写一下操作日志,操作日志就比较简单啦,不用写注解啦,直接添加即可。

四、登录日志

接下来我们写一下登录日志,我们只需要再登录的接口的地方写一个插入登录操作的日志即可,由于我们设计的登录日志和操作日志是两张表,所以我们还得写一套登录日志的CRDU操作,废话不多说,开整。

下面我直接写了,大家应该可以看懂。

1、建表语句

DROP TABLE IF EXISTS `person_login_log`;
CREATE TABLE `person_login_log` (
  `id`                BIGINT(20)         NOT NULL   PRIMARY KEY AUTO_INCREMENT        COMMENT '登录访问id',
  `login_name`        VARCHAR(50)        NULL   DEFAULT ''                    COMMENT '登录账号',
  `ip_address`        VARCHAR(128)       NULL   DEFAULT ''                    COMMENT '登录IP地址',
  `login_location`    VARCHAR(255)       NULL       DEFAULT ''                    COMMENT '登录地点',
  `browser_type`      VARCHAR(50)        NULL       DEFAULT ''                    COMMENT '浏览器类型',
  `os`                VARCHAR(50)        NULL       DEFAULT ''                    COMMENT '操作系统',
  `login_status`      TINYINT            NULL       DEFAULT 0                   COMMENT '登录状态,默认0, 0-成功, 1-失败',
  `create_time`       DATETIME               NULL       DEFAULT CURRENT_TIMESTAMP       COMMENT '创建时间'
) ENGINE = InnoDB
  CHARACTER SET = utf8mb4
  COLLATE = utf8mb4_bin
  ROW_FORMAT = Dynamic
  COMMENT '登录日志表';

2、实体类

新建一个LoginOperationLog.java

package com.blog.personalblog.entity;
import lombok.Data;
import java.time.LocalDateTime;
/**
 * @author: SuperMan
 * @create: 2022-04-05
 **/
@Data
public class LoginOperationLog {
    /**
     * 主键id
     */
    private Integer id;
    /**
     * 登录账号
     */
    private String loginName;
    /**
     * 登录IP地址
     */
    private String ipAddress;
    /**
     * 登录地点
     */
    private String loginLocation;
    /**
     * 浏览器类型
     */
    private String browserType;
    /**
     * 操作系统
     */
    private String os;
    /**
     * 登录状态,默认0, 0-成功, 1-失败
     */
    private Integer loginStatus;
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
}

3、业务类

(1)新建一个LoginOperationLogService.java业务接口类

package com.blog.personalblog.service;
import com.blog.personalblog.config.page.PageRequest;
import com.blog.personalblog.entity.LoginOperationLog;
import java.util.List;
/**
 * @author: SuperMan
 * @create: 2022-04-05
 **/
public interface LoginOperationLogService {
    /**
     * 添加登录日志
     *
     * @param loginOperationLog
     * @return
     */
    void saveOperationLog(LoginOperationLog loginOperationLog);
    /**
     * 登录日志列表(分页)
     *
     * @param pageRequest
     * @return
     */
    List<LoginOperationLog> getLoginOperationLogPage(PageRequest pageRequest);
}

(2)新建一个LoginOperationLogServiceImpl.java业务实现类

package com.blog.personalblog.service.Impl;
import com.blog.personalblog.config.page.PageRequest;
import com.blog.personalblog.entity.LoginOperationLog;
import com.blog.personalblog.mapper.LoginOperationLogMapper;
import com.blog.personalblog.service.LoginOperationLogService;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
 *
 * @author: SuperMan
 * @create: 2022-04-05
 **/
@Service
public class LoginOperationLogServiceImpl implements LoginOperationLogService {
    @Resource
    private LoginOperationLogMapper loginOperationLogMapper;
    @Override
    public void saveOperationLog(LoginOperationLog loginOperationLog) {
        loginOperationLogMapper.createLoginOperationLog(loginOperationLog);
    }
    @Override
    public List<LoginOperationLog> getLoginOperationLogPage(PageRequest pageRequest) {
        int pageNum = pageRequest.getPageNum();
        int pageSize = pageRequest.getPageSize();
        PageHelper.startPage(pageNum,pageSize);
        List<LoginOperationLog> loginOperationLogList = loginOperationLogMapper.getLoginOperationLogPage();
        return loginOperationLogList;
    }
}

4、数据接口Mapper

新建一个LoginOperationLogMapper.java接口

package com.blog.personalblog.mapper;
import com.blog.personalblog.entity.LoginOperationLog;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
 *
 * @author: SuperMan
 * @create: 2022-04-06
 **/
@Repository
public interface LoginOperationLogMapper {
    /**
     * 创建登录日志
     * @param loginOperationLog
     * @return
     */
    int createLoginOperationLog(LoginOperationLog loginOperationLog);
    /**
     * 分类列表(分页)
     * @return
     */
    List<LoginOperationLog> getLoginOperationLogPage();
}

5、xml文件

新建一个登录日志的LoginOperationLogMapper.xml文件,用来写sql语句。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.blog.personalblog.mapper.LoginOperationLogMapper">
    <resultMap id="BaseResultMap" type="com.blog.personalblog.entity.LoginOperationLog">
        <result column="id" jdbcType="INTEGER" property="id"/>
        <result column="login_name" jdbcType="VARCHAR" property="loginName"/>
        <result column="ip_address" jdbcType="VARCHAR" property="ipAddress"/>
        <result column="login_location" jdbcType="VARCHAR" property="loginLocation"/>
        <result column="browser_type" jdbcType="VARCHAR" property="browserType"/>
        <result column="os" jdbcType="VARCHAR" property="os"/>
        <result column="login_status" jdbcType="INTEGER" property="loginStatus"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
    </resultMap>
    <insert id="createLoginOperationLog" parameterType="com.blog.personalblog.entity.LoginOperationLog" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO person_login_log (login_name, ip_address, login_location, browser_type, os, login_status)
        VALUES(#{loginName}, #{ipAddress}, #{loginLocation}, #{browserType}, #{os}, #{loginStatus})
    </insert>
    <select id="getLoginOperationLogPage" resultMap="BaseResultMap">
        select * from person_login_log
    </select>
</mapper>

6、接口层

新建一个日志的接口,我看了一下上边的操作日志我也没写接口层,所以我们将操作日志和登录日志写在一个Controller层中了。

先建一个OperationLogController.java

package com.blog.personalblog.controller;
import com.blog.personalblog.config.page.PageRequest;
import com.blog.personalblog.config.page.PageResult;
import com.blog.personalblog.entity.LoginOperationLog;
import com.blog.personalblog.entity.OperationLog;
import com.blog.personalblog.service.LoginOperationLogService;
import com.blog.personalblog.service.OperationLogService;
import com.blog.personalblog.util.JsonResult;
import com.blog.personalblog.util.PageUtil;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
/**
 *
 * @author: SuperMan
 * @create: 2022-04-06
 **/
@Api(tags = "操作日志")
@RestController
@RequestMapping("/log")
public class OperationLogController {
    @Resource
    private LoginOperationLogService loginOperationLogService;
    @Resource
    private OperationLogService operationLogService;
    /**
     * 操作日志列表
     * @param pageRequest
     * @return
     */
    @ApiOperation(value = "操作日志列表")
    @PostMapping("list")
    public JsonResult<Object> OperationLogListPage(@RequestBody @Valid PageRequest pageRequest) {
        List<OperationLog> operationLogPage = operationLogService.getOperationLogPage(pageRequest);
        PageInfo pageInfo = new PageInfo(operationLogPage);
        PageResult pageResult = PageUtil.getPageResult(pageRequest, pageInfo);
        return JsonResult.success(pageResult);
    }
    /**
     * 登录日志列表
     * @param pageRequest
     * @return
     */
    @ApiOperation(value = "登录日志列表")
    @PostMapping("list")
    public JsonResult<Object> LoginOperationLogListPage(@RequestBody @Valid PageRequest pageRequest) {
        List<LoginOperationLog> loginOperationLogPage = loginOperationLogService.getLoginOperationLogPage(pageRequest);
        PageInfo pageInfo = new PageInfo(loginOperationLogPage);
        PageResult pageResult = PageUtil.getPageResult(pageRequest, pageInfo);
        return JsonResult.success(pageResult);
    }
}

好啦,准备工作基本上完成了,接下来我们再登录的时候插入我们的登录日志即可。

7、登录日志编写

打开我们的UserController.java类,然后找到我们的登录方法,我们再UserController中新添加一个方法,用来获取登录信息并且将登录的信息插入到登录日志表中。我们设计的表里有要获取浏览器类型和操作系统,所以我们使用了user-agent-utils 是一个用来解析 User-Agent 字符串的 Java 类库。 其能够识别的内容包括: 超过150种不同的浏览器; 7种不同的浏览器类型; 超过60种不同的操作系统; 6种不同的设备类型; 9种不同的渲染引擎; 9种不同的Web应用,如HttpClient、Bot。


1、添加maven

<dependency>
    <groupId>eu.bitwalker</groupId>
    <artifactId>UserAgentUtils</artifactId>
    <version>1.21</version>
 </dependency>

2、客户端工具类

package com.blog.personalblog.util;
import cn.hutool.core.convert.Convert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
 * 客户端工具类
 *
 */
public class ServletUtils {
    /**
     * 获取String参数
     */
    public static String getParameter(String name)
    {
        return getRequest().getParameter(name);
    }
    /**
     * 获取String参数
     */
    public static String getParameter(String name, String defaultValue)
    {
        return Convert.toStr(getRequest().getParameter(name), defaultValue);
    }
    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name)
    {
        return Convert.toInt(getRequest().getParameter(name));
    }
    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name, Integer defaultValue)
    {
        return Convert.toInt(getRequest().getParameter(name), defaultValue);
    }
    /**
     * 获取request
     */
    public static HttpServletRequest getRequest()
    {
        return getRequestAttributes().getRequest();
    }
    /**
     * 获取response
     */
    public static HttpServletResponse getResponse()
    {
        return getRequestAttributes().getResponse();
    }
    /**
     * 获取session
     */
    public static HttpSession getSession()
    {
        return getRequest().getSession();
    }
    public static ServletRequestAttributes getRequestAttributes()
    {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }
}

下面进行解析agent字符串

UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));

其他的也没有什么,下面就是我们添加登录日志的方法

    /**
     * 获取登录日志
     */
    public void getLoginInfoLog(LoginModel loginModel, Integer status) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) Objects.requireNonNull(requestAttributes).resolveReference(RequestAttributes.REFERENCE_REQUEST);
        //解析agent字符串
        UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        //登录账号
        LoginOperationLog loginOperationLog = new LoginOperationLog();
        loginOperationLog.setLoginName(loginModel.getUsername());
        //登录IP地址
        String ipAddr = IpUtil.getIpAddr(request);
        loginOperationLog.setIpAddress(ipAddr);
        //登录地点
        String ipInfo = IpUtil.getIpInfo(ipAddr);
        loginOperationLog.setLoginLocation(ipInfo);
        //浏览器类型
        String browser = userAgent.getBrowser().getName();
        loginOperationLog.setBrowserType(browser);
        //操作系统
        String os = userAgent.getOperatingSystem().getName();
        loginOperationLog.setOs(os);
        //登录状态
        loginOperationLog.setLoginStatus(status);
        loginOperationLogService.saveOperationLog(loginOperationLog);
    }

然后我们在登录的方法中添加这个方法,一共传了两个参数,其中status是登录的状态,成功是0,失败是1。

    /**
     * 登录
     * @param loginModel
     * @return
     */
    @ApiOperation(value = "登录")
    @PostMapping("/login")
    @OperationLogSys(desc = "登录", operationType = OperationType.LOGIN)
    public JsonResult<Object> login(@RequestBody LoginModel loginModel){
        logger.info("{} 在请求登录! ", loginModel.getUsername());
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(loginModel.getUsername(), loginModel.getPassword(), false);
        try {
            subject.login(token);
            Map<String, Object> ret = new HashedMap();
            ret.put("token", subject.getSession().getId());
            logger.info("{} login success", loginModel.getUsername());
            getLoginInfoLog(loginModel, 0);
            return JsonResult.success(ret);
        } catch (IncorrectCredentialsException e) {
            logger.info("login fail {}", e.getMessage());
            return JsonResult.error(ErrorCode.NOT_LOGIN);
        } catch (LockedAccountException e) {
            logger.info("login fail {}", e.getMessage());
            return JsonResult.error(ErrorCode.ERROR_CODE);
        } catch (AuthenticationException e) {
            logger.info("login fail {}", e.getMessage());
            return JsonResult.error(ErrorCode.USER_NOT_EXIST);
        } catch (Exception e) {
            e.printStackTrace();
            getLoginInfoLog(loginModel, 1);
            logger.info("login fail {}", e.getMessage());
            return JsonResult.error(ErrorCode.ERROR_CODE);
        }
    }

下面是UserController的完整代码:(有些地方改了一点,大家可以看一下)

package com.blog.personalblog.controller;
import cn.hutool.core.util.StrUtil;
import com.blog.personalblog.annotation.OperationLogSys;
import com.blog.personalblog.annotation.OperationType;
import com.blog.personalblog.entity.ErrorCode;
import com.blog.personalblog.entity.LoginModel;
import com.blog.personalblog.entity.LoginOperationLog;
import com.blog.personalblog.service.LoginOperationLogService;
import com.blog.personalblog.util.IpUtil;
import com.blog.personalblog.util.JsonResult;
import com.blog.personalblog.entity.User;
import com.blog.personalblog.service.UserService;
import com.blog.personalblog.util.MD5Util;
import com.blog.personalblog.util.PhoneUtil;
import com.blog.personalblog.util.ServletUtils;
import eu.bitwalker.useragentutils.UserAgent;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.map.HashedMap;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
 * @author: SuperMan
 * 欢迎关注我的公众号:码上言
 * @create: 2021-11-03
 */
@Api(tags = "用户管理")
@RestController
@RequestMapping("/user")
public class UserController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Resource
    private UserService userService;
    @Resource
    private LoginOperationLogService loginOperationLogService;
    /**
     * 用户列表
     * @return
     */
    @ApiOperation(value = "用户列表")
    @PostMapping("/list")
    public JsonResult<Object> list() {
        List<User> userList = userService.findAll();
        return JsonResult.success(userList);
    }
    /**
     * 添加用户
     * @return
     */
    @ApiOperation(value = "添加用户")
    @PostMapping("/create")
    @OperationLogSys(desc = "添加用户", operationType = OperationType.INSERT)
    public JsonResult<Object> userCreate(@RequestBody @Valid User user) {
        if (StrUtil.isEmpty(user.getPassWord())) {
            return JsonResult.error("密码为空,请填写密码!");
        }
        //密码加密存储
        user.setPassWord(MD5Util.MD5(user.getPassWord()));
        //判断手机号,这里用hutool工具类也可以
        if (!PhoneUtil.checkMobile(user.getPhone())) {
            return JsonResult.error("手机号码格式错误!");
        }
        userService.createUser(user);
        return JsonResult.success();
    }
    /**
     *
     * 修改用户
     * @return
     */
    @ApiOperation(value = "修改用户")
    @PostMapping("/update")
    @OperationLogSys(desc = "修改用户", operationType = OperationType.UPDATE)
    public JsonResult<Object> userUpdate(@RequestBody @Valid User user) {
        if (StrUtil.isEmpty(user.getPassWord())) {
            return JsonResult.error("密码为空,请填写密码!");
        }
        //密码加密存储
        user.setPassWord(MD5Util.MD5(user.getPassWord()));
        //判断手机号,这里用hutool工具类也可以
        if (!PhoneUtil.checkMobile(user.getPhone())) {
            return JsonResult.error("手机号码格式错误!");
        }
        userService.updateUser(user);
        return JsonResult.success();
    }
    /**
     * 删除
     * @return
     */
    @ApiOperation(value = "删除用户")
    @PostMapping("/delete/{id}")
    @OperationLogSys(desc = "删除用户", operationType = OperationType.DELETE)
    public JsonResult<Object> userDelete(@PathVariable(value = "id") int id) {
        userService.deleteUser(id);
        return JsonResult.success();
    }
    /**
     * 登录
     * @param loginModel
     * @return
     */
    @ApiOperation(value = "登录")
    @PostMapping("/login")
    @OperationLogSys(desc = "登录", operationType = OperationType.LOGIN)
    public JsonResult<Object> login(@RequestBody LoginModel loginModel){
        logger.info("{} 在请求登录! ", loginModel.getUsername());
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(loginModel.getUsername(), loginModel.getPassword(), false);
        try {
            subject.login(token);
            Map<String, Object> ret = new HashedMap();
            ret.put("token", subject.getSession().getId());
            logger.info("{} login success", loginModel.getUsername());
            getLoginInfoLog(loginModel, 0);
            return JsonResult.success(ret);
        } catch (IncorrectCredentialsException e) {
            logger.info("login fail {}", e.getMessage());
            return JsonResult.error(ErrorCode.NOT_LOGIN);
        } catch (LockedAccountException e) {
            logger.info("login fail {}", e.getMessage());
            return JsonResult.error(ErrorCode.ERROR_CODE);
        } catch (AuthenticationException e) {
            logger.info("login fail {}", e.getMessage());
            return JsonResult.error(ErrorCode.USER_NOT_EXIST);
        } catch (Exception e) {
            e.printStackTrace();
            getLoginInfoLog(loginModel, 1);
            logger.info("login fail {}", e.getMessage());
            return JsonResult.error(ErrorCode.ERROR_CODE);
        }
    }
    /**
     * 登录info信息
     * @return
     */
    @GetMapping("/info")
    public JsonResult<Object> info(){
        Map<String, Object> ret = new HashMap<>(3);
        ret.put("roles", "[admin]");
        ret.put("name", "admin");
        ret.put("avatar","https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        return JsonResult.success(ret);
    }
    /**
     * 获取登录日志
     */
    public void getLoginInfoLog(LoginModel loginModel, Integer status) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) Objects.requireNonNull(requestAttributes).resolveReference(RequestAttributes.REFERENCE_REQUEST);
        //解析agent字符串
        UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        //登录账号
        LoginOperationLog loginOperationLog = new LoginOperationLog();
        loginOperationLog.setLoginName(loginModel.getUsername());
        //登录IP地址
        String ipAddr = IpUtil.getIpAddr(request);
        loginOperationLog.setIpAddress(ipAddr);
        //登录地点
        String ipInfo = IpUtil.getIpInfo(ipAddr);
        loginOperationLog.setLoginLocation(ipInfo);
        //浏览器类型
        String browser = userAgent.getBrowser().getName();
        loginOperationLog.setBrowserType(browser);
        //操作系统
        String os = userAgent.getOperatingSystem().getName();
        loginOperationLog.setOs(os);
        //登录状态
        loginOperationLog.setLoginStatus(status);
        loginOperationLogService.saveOperationLog(loginOperationLog);
    }
}

8、测试

我们在postman中模拟登录,然后我们在sql中查看有没有登录日志,这里要说一下,如果你是用的地址为localhost或者127.0.0.1进行请求,我们在获取ip归属地的时候会获取不到,我们可以使用电脑的ip就可以看到。好啦,到这里我们的操作日志就完成了,到此我们所有的后端功能都开发完了,下面我们就写前端代码,后端提供api即可,我们的项目开发2/3了,即将完成了,大家努力啊。

看到现在的阅读量,着实有点惨不忍睹,希望大家多多点赞、收藏、分享啊,大家帮我宣传一下,感谢感谢!

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
4月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
735 3
|
2月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
395 2
|
3月前
|
前端开发 安全 Java
基于springboot+vue开发的会议预约管理系统
一个完整的会议预约管理系统,包含前端用户界面、管理后台和后端API服务。 ### 后端 - **框架**: Spring Boot 2.7.18 - **数据库**: MySQL 5.6+ - **ORM**: MyBatis Plus 3.5.3.1 - **安全**: Spring Security + JWT - **Java版本**: Java 11 ### 前端 - **框架**: Vue 3.3.4 - **UI组件**: Element Plus 2.3.8 - **构建工具**: Vite 4.4.5 - **状态管理**: Pinia 2.1.6 - **HTTP客户端
370 4
基于springboot+vue开发的会议预约管理系统
|
3月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
568 5
|
4月前
|
前端开发 JavaScript Java
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
本系统基于SpringBoot与Vue3开发,实现校园食堂评价功能。前台支持用户注册登录、食堂浏览、菜品查看及评价发布;后台提供食堂、菜品与评价管理模块,支持权限控制与数据维护。技术栈涵盖SpringBoot、MyBatisPlus、Vue3、ElementUI等,适配响应式布局,提供完整源码与数据库脚本,可直接运行部署。
245 6
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
|
5月前
|
机器学习/深度学习 XML Java
【spring boot logback】日志logback格式解析
在 Spring Boot 中,Logback 是默认的日志框架,它支持灵活的日志格式配置。通过配置 logback.xml 文件,可以定义日志的输出格式、日志级别、日志文件路径等。
844 5
|
5月前
|
缓存 前端开发 Java
SpringBoot 实现动态菜单功能完整指南
本文介绍了一个动态菜单系统的实现方案,涵盖数据库设计、SpringBoot后端实现、Vue前端展示及权限控制等内容,适用于中后台系统的权限管理。
467 1
|
5月前
|
Java Linux 网络安全
Linux云端服务器上部署Spring Boot应用的教程。
此流程涉及Linux命令行操作、系统服务管理及网络安全知识,需要管理员权限以进行配置和服务管理。务必在一个测试环境中验证所有步骤,确保一切配置正确无误后,再将应用部署到生产环境中。也可以使用如Ansible、Chef等配置管理工具来自动化部署过程,提升效率和可靠性。
544 13

热门文章

最新文章