十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Spring Boot新闻系统四层架构与安全实践

Spring Boot新闻系统四层架构与安全实践 简介这是一套面向Java初学者与毕业设计学生的Spring Boot实战项目源码聚焦新闻内容管理场景适用于企事业单位、高校等组织的内部信息发布与维护需求。资源包共592个文件涵盖80个Java后端业务类、106个Vue前端组件、39个HTML页面及31个JS交互脚本辅以MySQL建表SQL、Spring Boot配置yml、Maven构建bat脚本等关键文件完整呈现前后端分离架构下的开发闭环压缩包大小为13.59MB结构清晰含环境配置、运行部署、数据库初始化等实用工具。已有117人学习下载读者可直接获取可运行的全功能新闻系统包含用户权限管理、多级新闻CRUD、评论审核、轮播图与公告配置、响应式前端适配等六大模块并附带一键运行脚本如运行.bat、安装maven环境.bat大幅降低本地部署门槛是理解Spring Boot企业级开发流程的优质入门范例。1. 这不是又一个“Spring Boot CRUD”模板而是一套可落地的新闻内容生产闭环系统你下载的(源码)基于Spring Boot框架的新闻管理系统.zip表面看是教学级项目实际藏着新闻类业务最典型的四层架构落地细节从编辑端富文本提交、后台多级审核流控制、前端响应式列表渲染到数据库层面的热点新闻缓存穿透防护。它不依赖任何云服务或第三方 CMS所有功能都由 Spring Boot 原生组件驱动——JPA 处理稿件元数据与分类关系Spring Security 实现角色分级记者/编辑/主编/管理员Thymeleaf 或 Vue CLI热词中隐含前端构建线索完成静态资源编译与路由隔离。尤其注意browserslistrc和sass的存在说明该项目已预置现代 CSS 工程化能力能直接支持 IE11 到 Chrome 120 的渐进式兼容策略。适合两类人刚学完 Spring Boot 基础想验证真实业务分层逻辑的开发者以及需要快速搭建内部新闻简报平台的中小团队技术负责人。它不解决“如何做爆款”但能让你看清一条新闻从草稿到上线的每一道权限闸门和数据流转路径。2. 拆解项目结构为什么用 Spring Boot 而不是纯 Spring MVC四层架构如何对应源码目录2.1 Spring Boot 的核心价值用自动配置规避重复造轮子而非简化 CRUD传统 Spring MVC 项目需手动配置 DispatcherServlet、ViewResolver、DataSource、TransactionManager 等 10 Bean而本项目通过spring-boot-starter-web、spring-boot-starter-data-jpa、spring-boot-starter-security三个 starter将这些配置压缩为application.yml中 5 行代码。例如# application.yml 片段 spring: datasource: url: jdbc:mysql://localhost:3306/news_db?useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true提示ddl-auto: update仅用于开发环境。生产部署必须改为validate并配合 Flyway 或 Liquibase 执行 SQL 脚本否则表结构变更会丢失历史版本记录。该配置背后是 Spring Boot 的DataSourceAutoConfiguration和HibernateJpaAutoConfiguration自动装配机制——它扫描 classpath 下的DataSource类型 Bean若存在且未被ConditionalOnMissingBean排除则注入默认 HikariCP 连接池再根据spring.jpa.*属性生成LocalContainerEntityManagerFactoryBean。这种“约定优于配置”大幅降低新成员上手成本但代价是调试时需理解AutoConfigureAfter的加载顺序。比如SpringBootWebSecurityConfiguration必须在DataSourceAutoConfiguration之后执行否则无法注入UserDetailsService所需的 JPA Repository。2.2 四层架构在源码中的物理映射controller → service → repository → entity项目目录严格遵循 Spring Boot 四层分层规范每一层职责边界清晰目录路径核心职责关键实现特征com.example.news.controller接收 HTTP 请求校验参数调用 Service使用Valid注解绑定NewsFormDTO返回ResponseEntityNewsDTO统一格式com.example.news.service封装业务逻辑协调多个 Repository 操作NewsService包含publish()方法内部调用newsRepository.save()和auditLogRepository.save()两个事务性操作com.example.news.repository定义数据访问接口继承JpaRepositoryNewsRepository声明findByStatusAndPublishTimeBetween()方法Spring Data JPA 自动生成 JPQL 查询com.example.news.entity映射数据库表定义 JPA 注解News类使用Entity、Table(namet_news)、Lob标注正文字段避免TEXT类型被误映射为VARCHAR(255)特别注意News实体中的Lob注解Entity Table(name t_news) public class News { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; Column(name title, length 200) private String title; Lob // 关键声明 content 为大对象适配 MySQL TEXT / PostgreSQL BYTEA Column(name content) private String content; Column(name status) Enumerated(EnumType.STRING) private NewsStatus status; // 枚举类型值为 DRAFT/PENDING/PUBLISHED/REJECTED }若忽略LobSpring Data JPA 默认将String映射为VARCHAR(255)当新闻正文超长时触发DataTruncation异常。这是新手在导入新闻数据时最常见的失败点。2.3 Maven 作为构建中枢依赖管理、插件编排与多环境打包pom.xml是整个项目的构建契约。本项目依赖项明确区分三类运行时依赖spring-boot-starter-web、spring-boot-starter-data-jpa、mysql-connector-java注意热词中com.mysql:mysql-connector-j:release报错提示说明版本需匹配 MySQL 8.x编译期依赖lombok减少getter/setter模板代码、validation-api支持NotBlank校验构建插件maven-compiler-plugin指定 Java 17、spring-boot-maven-plugin生成可执行 fat jar关键插件配置如下plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration image builderpaketobuildpacks/builder:tiny/builder /image /configuration /plugin注意此配置启用 Spring Boot 3.x 的 Cloud Native Buildpacks 打包方式生成 OCI 镜像而非传统 jar。若你的环境未安装 Docker需注释掉image块改用默认 jar 打包。Maven 仓库配置也影响构建稳定性。国内用户应修改~/.m2/settings.xml添加阿里云镜像mirrors mirror idaliyunmaven/id mirrorOf*/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirror /mirrors否则mvn clean install可能因spring-boot-starter-parent下载超时而失败——这正是热词中高频出现的maven下载、maven配置阿里云仓库的真实场景。3. 前端工程化落地Sass 编译链路与 browserslistrc 的兼容性控制3.1 Sass 不是“写 CSS 的另一种写法”而是构建时样式逻辑的封装层项目中src/main/resources/static/css下的.scss文件并非直接被浏览器解析而是通过 Maven 插件或 Node.js 工具链编译为标准 CSS。常见两种集成方式Maven 方式使用sass-maven-plugin在pom.xml中声明plugin groupIdnl.geodienstencentrum.maven/groupId artifactIdsass-maven-plugin/artifactId version3.9.2/version executions execution goals goalupdate-stylesheets/goal /goals /execution /executions configuration sassSourceDirectory${project.basedir}/src/main/resources/static/scss/sassSourceDirectory outputDirectory${project.basedir}/src/main/resources/static/css/outputDirectory /configuration /pluginNode.js 方式更主流依赖package.json中的sass包。热词中dart sass安装、node18对应的sass版本指向此路径{ devDependencies: { sass: ^1.70.0, sass-loader: ^13.3.2 } }提示Node 18 对应的 Dart Sass 最低版本为1.60.0低于此版本在use规则解析时会报错。执行npm install前务必确认node -v输出为v18.x。无论哪种方式Sass 的核心价值在于变量复用与嵌套逻辑。例如variables.scss定义主题色// src/main/resources/static/scss/_variables.scss $primary-color: #2c3e50; $secondary-color: #3498db; $font-size-base: 16px; // src/main/resources/static/scss/main.scss use variables; .news-list { background-color: variables.$primary-color; font-size: variables.$font-size-base; __item { color: variables.$secondary-color; } }编译后生成标准 CSS无运行时开销。3.2 browserslistrc 是前端兼容性的宪法不是可有可无的配置文件.browserslistrc内容直接决定 Babel、Autoprefixer、CSS Nano 的处理范围。本项目典型配置如下 1% last 2 versions not dead not ie 11这意味着覆盖全球使用率超 1% 的浏览器版本如 Chrome 115、Firefox 116包含最新两个主版本Chrome 120/119、Edge 120/119排除已停止安全更新的浏览器IE 11 及更旧版本当执行npm run build时Webpack 会读取此文件触发 Autoprefixer 插件为flex、grid等特性自动添加-webkit-、-ms-前缀。若删除该文件构建产物可能在 Safari 15.6 上因缺少-webkit-flex而布局错乱——这正是热词中sass编译后仍需验证的实际问题。3.3 Thymeleaf 与 Vue 的混合渲染服务端模板与客户端 SPA 的边界在哪里项目前端采用“服务端渲染为主局部增强为辅”策略新闻列表页、详情页由 Thymeleaf 渲染URL 为/news/list、/news/detail/{id}富文本编辑器、图片上传组件使用 Vue 3 Composition API通过div ideditor-app/div挂载关键整合点在news-edit.html!-- Thymeleaf 模板 -- div th:fragmentcontent div ideditor-app >management: endpoints: web: exposure: include: health,info,metrics,prometheus # 仅暴露必要端点 endpoint: health: show-details: when_authorized # 详情仅对认证用户可见 endpoints: web: base-path: /manage # 修改根路径增加探测难度同时配合 Spring Security 配置Configuration Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER) public class ActuatorSecurityConfig { Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.requestMatcher(EndpointRequest.toAnyEndpoint()) .authorizeHttpRequests(authz - authz .requestMatchers(EndpointRequest.to(health, info)).permitAll() .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole(ADMIN) ); return http.build(); } }4.2 JPA 层防 SQL 注入为什么Query比字符串拼接更安全新闻搜索功能常需动态条件易引发注入漏洞。错误写法// 危险字符串拼接导致注入 Query(SELECT n FROM News n WHERE n.title LIKE % keyword %) ListNews searchByTitle(String keyword);正确做法是使用参数化查询// 安全JPA 自动转义参数 Query(SELECT n FROM News n WHERE n.title LIKE %:keyword%) ListNews searchByTitle(Param(keyword) String keyword); // 或使用方法名查询推荐 ListNews findByTitleContaining(String keyword);Spring Data JPA 将keyword作为 PreparedStatement 参数传入数据库驱动自动处理引号转义。即使传入keyword ; DROP TABLE t_news; --最终执行的 SQL 也是SELECT * FROM t_news WHERE title LIKE %\; DROP TABLE t_news; --%4.3 文件上传的双重校验ContentType 检查 后缀白名单新闻配图上传需防范 WebShell 注入。NewsController中的上传方法应包含PostMapping(/upload) public ResponseEntityString uploadImage( RequestParam(file) MultipartFile file, HttpServletRequest request) { // 1. Content-Type 白名单 String contentType file.getContentType(); if (!Arrays.asList(image/jpeg, image/png, image/gif).contains(contentType)) { return ResponseEntity.badRequest().body(不支持的图片格式); } // 2. 文件后缀二次校验防止伪造 Content-Type String originalFilename file.getOriginalFilename(); String extension FilenameUtils.getExtension(originalFilename).toLowerCase(); if (!Arrays.asList(jpg, jpeg, png, gif).contains(extension)) { return ResponseEntity.badRequest().body(文件扩展名非法); } // 3. 重命名存储避免路径遍历 String newFilename UUID.randomUUID() . extension; Path uploadPath Paths.get(uploads, newFilename); Files.createDirectories(uploadPath.getParent()); Files.write(uploadPath, file.getBytes()); return ResponseEntity.ok(/uploads/ newFilename); }提示FilenameUtils来自 Apache Commons IO需在pom.xml中添加依赖dependency groupIdcommons-io/groupId artifactIdcommons-io/artifactId version2.11.0/version /dependency5. 生产部署调优JVM 参数、连接池配置与热点新闻缓存穿透防护5.1 JVM 参数设置为什么 -Xmx 不等于可用堆内存Spring Boot 应用默认使用-Xmx指定最大堆但新闻系统需额外预留元空间与直接内存。推荐启动参数java -Xms512m -Xmx1024m \ -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m \ -XX:UseG1GC -XX:MaxGCPauseMillis200 \ -Dfile.encodingUTF-8 \ -jar news-system.jar-XX:MetaspaceSize避免频繁触发 Metaspace GC新闻系统加载大量 Controller/Service 类-XX:UseG1GCG1 垃圾收集器适合大堆4GB且停顿可控但本项目 1GB 堆已足够-Dfile.encodingUTF-8强制文件读写编码防止 Linux 环境下中文乱码5.2 HikariCP 连接池关键参数空闲连接与最大生命周期application.yml中的数据库连接池配置需精细化spring: datasource: hikari: maximum-pool-size: 20 # 并发请求峰值预估新闻首页 QPS × 2 minimum-idle: 5 # 保持 5 个空闲连接避免冷启动延迟 idle-timeout: 600000 # 空闲 10 分钟后释放 max-lifetime: 1800000 # 连接最长存活 30 分钟强制重连防 DB 连接超时 connection-timeout: 30000 # 获取连接超时 30 秒 validation-timeout: 3000 # 连接校验超时 3 秒 leak-detection-threshold: 60000 # 60 秒未归还连接触发泄漏告警5.3 缓存穿透防护热点新闻查询的布隆过滤器实践当黑客构造大量不存在的newsId如/news/detail/999999999发起请求数据库将承受无效查询压力。解决方案是在 Redis 层前置布隆过滤器Component public class NewsBloomFilter { private static final int EXPECTED_INSERTIONS 100000; private static final double FPP 0.01; // 1% 误判率 private final BloomFilterLong bloomFilter; public NewsBloomFilter(RedisTemplateString, Object redisTemplate) { // 从 Redis 加载已有 ID 构建布隆过滤器首次启动时 SetString ids redisTemplate.opsForSet().members(news:all:ids); this.bloomFilter BloomFilter.create( Funnels.longFunnel(), EXPECTED_INSERTIONS, FPP ); ids.forEach(id - bloomFilter.put(Long.parseLong(id))); } public boolean mightContain(Long newsId) { return bloomFilter.mightContain(newsId); } }在NewsService.findById()中调用public News findById(Long id) { // 1. 先查布隆过滤器 if (!newsBloomFilter.mightContain(id)) { throw new NewsNotFoundException(新闻不存在); } // 2. 再查 Redis 缓存 String cacheKey news: id; News news redisTemplate.opsForValue().get(cacheKey); if (news ! null) return news; // 3. 最后查数据库 news newsRepository.findById(id) .orElseThrow(() - new NewsNotFoundException(新闻不存在)); // 4. 写入缓存与布隆过滤器 redisTemplate.opsForValue().set(cacheKey, news, 1, TimeUnit.HOURS); return news; }布隆过滤器空间效率极高10 万 ID 仅需 125KB 内存且误判率可控。这是应对新闻系统突发流量的底层防御手段。本文还有配套的精品资源点击获取
返回列表