本文最后更新于:2 小时前
1 Spingboot+Vue 前后端分离实战项目
1.1 项目简介
采用 SpringBoot 3 + Vue 3 实现的前后端分离模版项目,集成多种技术栈,并且基于 JWT 校验方案。
1.2 项目地址 项目已上传至 Github 仓库 ,如有需要可自行下载使用。
1 2 3 4 5 6 url: https://github.com/Alleyf/SpingBoot-Vue/tree/master title: "GitHub - Alleyf/SpingBoot-Vue: A Demo for SpringBoot with Vue." description: "A Demo for SpringBoot with Vue. Contribute to Alleyf/SpingBoot-Vue development by creating an account on GitHub." host: github.com favicon: https://github.githubassets.com/favicons/favicon.svg image: https://opengraph.githubassets.com/a9e35993db96532eecc54692cabfb8c305216983dce49278cab1b52a560daef6/Alleyf/SpingBoot-Vue
GitHub - Alleyf/SpingBoot-Vue: A Demo for SpringBoot with Vue.
1.3 后端功能 用户注册、用户登录、重置密码等基础功能以及对应接口
1.4 技术栈
前端
Vue 前端框架
ElementUI 前端 UI 组件库
Vue-Router 路由管理
Axios 异步请求框架
VueUse 适配黑暗模式
unplugin-auto-import 按需引入,减少打包后体积
后端
SpringBoot 后端框架
Mybatis 数据持久层框架
Redis 验证码存储、限流 IP、请求次数存储
Knife 4 j 接口文档生成
SpringSecurity 权限认证校验
JWT 生成 token 鉴权
RabbitMQ 积压邮件发送,由监听器统一处理
FastJson 后端统一用 Json 格式返回信息
Slf 4 j 日志打印实现
1.5 核心要点 1.5.1 限流 添加如下 filter,此处实现根据 ip 限流 3 秒内请求超过 10 次则限制访问 30 秒:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 @Component @Order(Const.ORDER_LIMIT) public class FlowLimitFilter extends HttpFilter { @Resource StringRedisTemplate stringRedisTemplate; @Override public void doFilter (HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String ip = request.getRemoteAddr(); if (this .limitFlowByIp(ip)) chain.doFilter(request, response); else { this .writeBlockMessage(response); } } private void writeBlockMessage (HttpServletResponse response) throws IOException { response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.setContentType("application/json;charset=UTF-8" ); response.getWriter().write(Result.forbidden("操作频繁,请稍后再试" ).toJson()); } private boolean limitFlowByIp (String ip) { synchronized (ip.intern()) { String countKey = Const.FLOW_LIMIT_COUNT + ip; String blockKey = Const.FLOW_LIMIT_BLOCK + ip; if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(blockKey))) { return false ; } else { if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(countKey))) { long increment = Optional.ofNullable(stringRedisTemplate.opsForValue().increment(countKey)).orElse(0L ); if (increment > 10 ) { stringRedisTemplate.opsForValue().set(blockKey, "" , 30 , TimeUnit.SECONDS); return false ; } } else { stringRedisTemplate.opsForValue().set(countKey, "1" , 3 , TimeUnit.SECONDS); } return true ; } } } }
1.5.2 接口文档 1.5.2.1 Swagger springboot 3 使用 swagger 版本接口文档配置:
pom. xml 引入依赖:
1 2 3 4 5 6 <dependency > <groupId > org. springdoc</groupId > <artifactId > springdoc-openapi-starter-webmvc-ui</artifactId > <version > 2.1.0</version > </dependency >
application. yml 配置静态资源:
1 2 3 4 springdoc: paths-to-match: /api/** swagger-ui: operations-sorter: alpha
SecurityConfiguration. java 设置接口文档相关静态资源放行:
1 2 3 4 5 6 return http .authorizeHttpRequests (conf -> conf .requestMatchers ("/api/auth/**" , "/error" ). permitAll () .requestMatchers ("/swagger-ui/**" , "/v 3/api-docs/**" ). permitAll () .anyRequest (). hasAnyRole (Const. ROLE_DEFAULT) )
添加 SwaggerConfig. java swagger 相关配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 @Configuration @SecurityScheme (type = SecuritySchemeType. HTTP, scheme = "Bearer" , name = "Authorization" , in = SecuritySchemeIn. HEADER)@OpenAPIDefinition (security = { @SecurityRequirement (name = "Authorization" ) })public class SwaggerConfiguration { @Bean public OpenAPI springShopOpenAPI () { return new OpenAPI () .info (new Info (). title ("示例项目 API 文档" ) .description ("欢迎来到本示例项目 API 测试文档,在这里可以快速进行接口调试" ) .version ("1.0" ) .license (new License () .name ("项目开源地址" ) .url (" https://github.com/Ketuer/SpringBoot-Vue-Template-Jwt" ) ) ) .externalDocs (new ExternalDocumentation () .description ("我们的官方网站" ) .url (" https://itbaima.net" ) ); } @Bean public OpenApiCustomizer customerGlobalHeaderOpenApiCustomizer () { return api -> this .authorizePathItems (). forEach (api.getPaths ()::addPathItem); } private Map<String, PathItem> authorizePathItems () { Map<String, PathItem> map = new HashMap <>(); map.put ("/api/auth/login" , new PathItem () .post (new Operation () .tags (List.of ("登录校验相关" )) .summary ("登录验证接口" ) .addParametersItem (new QueryParameter () .name ("username" ) .required (true ) ) .addParametersItem (new QueryParameter () .name ("password" ) .required (true ) ) .responses (new ApiResponses () .addApiResponse ("200" , new ApiResponse () .description ("OK" ) .content (new Content (). addMediaType ("*/*" , new MediaType () .example (RestBean.success (new AuthorizeVO ()). asJsonString ()) )) ) ) ) ); map.put ("/api/auth/logout" , new PathItem () .get (new Operation () .tags (List.of ("登录校验相关" )) .summary ("退出登录接口" ) .responses (new ApiResponses () .addApiResponse ("200" , new ApiResponse () .description ("OK" ) .content (new Content (). addMediaType ("*/*" , new MediaType () .example (RestBean.success ()) )) ) ) ) ); return map; } }
1.5.2.2 knife4j springboot 3 使用 knife 4.1.0 版本接口文档 配置:
pom. xml 引入依赖:
1 2 3 4 5 6 <dependency > <groupId > com.github.xiaoymin</groupId > <artifactId > knife4j-openapi3-jakarta-spring-boot-starter</artifactId > <version > 4.1.0</version > </dependency >
application. yml 配置静态资源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 --- springdoc: swagger-ui: path: /swagger-ui.html tags-sorter: alpha operations-sorter: alpha api-docs: path: /v3/api-docs group-configs: - group: 'default' paths-to-match: '/**' packages-to-scan: com.csdc.mshdcf knife4j: enable: true setting: language: zh_cn
SecurityConfiguration. java 设置接口文档相关静态资源放行:
1 2 3 4 5 6 7 return http .authorizeHttpRequests (conf -> { conf.requestMatchers ("/api/auth/**" , "/error" , "/doc. html" , "/webjars/**" , "/v 3/api-docs/**" ). permitAll () .anyRequest (). authenticated (); })
添加 Knife 4 jConfig. java knife 4 j 相关配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Configuration public class Knife4jConfig { @Bean public OpenAPI springShopOpenApi () { return new OpenAPI () .info(new Info ().title("MSHDCF" ) .description("多源异构数据汇聚融合接口文档" ) .version("v 1" ) .license(new License ().name("Apache 2.0" ).url(" https://springdoc.org" ))) .externalDocs(new ExternalDocumentation () .description("外部文档" ) .url(" https://springshop.wiki.github.org/docs" )); } }
swagger访问地址为: http://localhost:8081/swagger-ui/index.html knife4j访问地址为: http://localhost:8081/doc.html
1.5.3 踩坑
redis 本地安装好需要修改配置文件设置 requirepass password 密码,才可以在 idea 里远程连接使用。
vue 中的 form 表单一定要动态绑定 :model,如果添加了字段验证 :rules,还必须为每个 el-form-item 指定 prop 为 model 的键。
RabbitMQ 必须为监听器添加@Component 注解 才能自动注入的交换机和队列 bean 添加并绑定起来,否则 RabbitConfiguration 配置类不生效 。
RabbitMQ 发送 Map 等复杂消息时,需要添加(反)序列化消息转换器,否则刷屏消息转换报错,添加消息转换器步骤如下:
1 2 3 4 5 <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > </dependency >
在 MailQueueListener 中注册 MessageConverter bean:
1 2 3 4 5 @Bean public MessageConverter messageConverterer () { return new Jackson 2 JsonMessageConverter (); }
Bean 不要被循环或重复导入。
使用 mybatis 时由于没有给 DTO 实体的属性添加与数据表对应的字段注释 ,因此属性名必须与字段名 一致。
@RequestParam 一般用于 Get 请求路径传参,@RequestBody 一般用于 Post 请求 Json 传递请求体数据(也可以用@RequestParam 传参但必须请求头注明 url 编码或者表单格式 )。
内部结束 setInterval 定时器:
1 2 const coldTimer = setInterval (() => { coldTime. value > 0 ? coldTime. value-- : clearInterval (coldTimer) }, 1000 )
fastjson 2 在使用时,要注意返回 json 格式化的工具类 Result 必须加上 @Data、@AllArgsConstructor 注解才能使用,否则返回的 json 格式化数据一直为空(null)
SpringBoot 从 2.5. x 版本后开始支持 java17,采用 java17 才能使用 Map/List.of 快速创建哈希表或列表,才能在服务处显示端口号 并且开启 Actuator 后可以查看 Actuator 运行状态 。
test 测试类一定要和 src>main>java 下的软件包同名的软件包 下,否则会找不到配置类 报错。
springboot 最大并发数:SpringBoot 最大连接数及最大并发数是多少??? - 知乎
1 2 3 4 url: https://zhuanlan.zhihu.com/p/654602186 title: "SpringBoot 最大连接数及最大并发数是多少???" description: "每个 Spring Boot 版本和内置容器不同,结果也不同,这里以 Spring Boot 2.7.10 版本 + 内置 Tomcat 容器举例。概序在 SpringBoot 2.7.10 版本中内置 Tomcat 版本是 9.0.73,SpringBoot 内置 Tomcat 的默认设置如下: Tomcat 的…" host: zhuanlan. zhihu. com
1.6 效果 1.6.1 首页
1.6.2 注册
1.6.3 重置密码
1.6.4 黑暗模式
1.7 未来计划
1.8 Reference 1 2 3 4 url: https://itbaima.net/ title: "柏码 - 让每一行代码都闪耀智慧的光芒!" host: itbaima.net favicon: /favicon.ico
柏码 - 让每一行代码都闪耀智慧的光芒!