java-web/docs/chapter07.md
2024-12-05 10:07:04 +08:00

11 KiB
Raw Permalink Blame History

7. 项目实践

基于开源项目 https://github.com/rocboss/paopao-ce , 使用spring boot完成后端服务程序。

7.1 项目准备

7.1.1 Git仓库

  • 创建远程项目仓库

http://123.249.84.124:8066/ 注册账号 创建仓库paopao

选择.gitignore文件模板 java

设置分支模型: 单分支模型分支名master

  • 在idea中clone项目

idea的菜单file -> new -> project from version control -> Repository URLurl输入框中输入项目的远程仓库地址点击clone

7.1.2 初始化spring boot项目

使用 Spring Initializr 创建项目

  • 访问 Spring Initializr

  • 选择以下选项:

    • Project: Gradle-Groovy
    • Language: Java
    • Spring Boot: 选择最新稳定版本
    • Group: 输入你的组织名称(例如 com.lk
    • Artifact: 输入项目名称(例如 paopao
    • Name: 项目名称(默认与 Artifact 相同)
    • Package name: 包名(默认与 Group 和 Artifact 相同)
    • Packaging: Jar
    • Java Version: 选择合适的 Java 版本17或21
  • 添加以下依赖:

    • Web
    • JPA
    • H2 Database
  • 点击 Generate 按钮,下载生成的项目压缩包。

解压并复制文件

  • 将下载的压缩包解压到一个临时目录。
  • 将解压后的目录中的所有文件复制到你的本地项目根目录下。
  • 确保 build.gradle 等文件位于项目根目录下。

在 IDEA 中设置项目

a. 打开项目

  • 打开 IntelliJ IDEA。
  • 选择 File -> Open,选择你的项目根目录,然后点击 OK

b. 设置项目使用的 JDK

  • 打开 File -> Project Structure
  • Project 标签页中,选择 Project SDK,选择你安装的 JDK 或者下载JDK再选择。

c. 配置 Gradle 使用的 JVM 版本

  • 打开 File -> Settings(或按 Ctrl+Alt+S)。
  • 导航到 Build, Execution, Deployment -> Build Tools -> Gradle
  • Gradle JVM 下拉菜单中,选择你安装的 JDK 版本, 保持使用的版本和项目jdk版本一致。如果看不到此项尝试下面的步骤d,重新导入项目)

d. 导入项目

  • 如果项目没有自动导入,可以手动导入:
    • 打开 File -> New -> Module from Existing Sources
    • 选择项目根目录下的 build.gradle 文件,然后按照提示完成导入。

完成以上步骤后应该能在idea的右侧插件栏中看到gradle的图标。

7.1.3 gradle配置

项目中的gradle/wrapper/gradle-wrapper.properties 文件中将下载的gradle地址修改为使用国内源。

distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-8.5-bin.zip

项目中build.gradle 文件中设置使用国内maven服务器添加如下配置

repositories {
    mavenLocal()
    maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven-public/' }
    maven { url 'https://maven.aliyun.com/repository/central' }
    maven { url 'https://maven.aliyun.com/repository/public' }
    mavenCentral()
}

项目中build.gradle 文件中修改h2数据库的依赖,指定版本号使用H2 V2(为了使用数据库工具dbeaver时比较方便设置)

runtimeOnly 'com.h2database:h2:2.1.214'

修改完成后刷新gradle, 等待gradle下载依赖。

下载完成在gradle插件的窗口中运行tasks,选择bootRun任务。项目应能正常运行。

在idea中使用git菜单,将项目所有更新提交到远程仓库.

7.1.4 ui部署

nginx中部署 paopao-web-ui.zip

  • 安装nginx

下载nginx https://nginx.org/download/nginx-1.26.2.zip

解压zip包在解压后的目录下运行nginx.exe, 即可启动nginx服务。

在浏览器中访问:http://localhost 应能看到nginx的欢迎界面。

  • 发布前端代码

前端代码压缩文件paopao-web-ui.zip解压, 将前端代码根目录下的所有文件拷贝到html目录下重启nginx服务。

浏览器访问:http://localhost/index.html

7.2 用户注册功能开发

基本上按照层次结构创建系统的包结构, 在com.lk.paopao包下创建子包controllerserviceentityrepositoryconfig

7.2.1 API设计

用户注册API.md

7.2.2 spring boot配置文件修改

在项目目录src/main/resources新建application.yml文件添加数据库相关配置


spring:
  jackson:
    property-naming-strategy: SNAKE_CASE # 驼峰转下划线,以适应数据库字段命名规则
  datasource:
    url: jdbc:h2:file:./db.h2 # 使用文件存储配置数据库连接URL
    driverClassName: org.h2.Driver # 指定数据库驱动类
    username: root # 数据库用户名
    password: root # 数据库密码
  h2:
    console: # 开启console访问 默认false提供数据库管理界面
      enabled: true # 启用H2控制台访问功能
      settings:
        trace: true # 开启h2 console 跟踪 方便调试  默认 false
        web-allow-others: true # 允许console 远程访问 默认false提高可用性
      path: /h2 #  h2 访问路径上下文,定义访问路由
  jpa:
    show-sql: true # 显示SQL查询便于调试和性能优化
    open-in-view: false # 禁用Open SessionInView避免性能问题和资源泄露
    defer-datasource-initialization: true # 延迟数据源初始化,确保配置加载完成
    database-platform: org.hibernate.dialect.H2Dialect # 指定数据库方言优化SQL生成
    hibernate:
      ddl-auto:  update # 自动更新数据库结构,适应实体模型变化

yml配置文件的格式需要注意缩进和空格是敏感的需要严格遵循格式。

7.2.3 实体类User和UserRepository接口

创建实体类User

创建User对应的数据库接口 UserRepository

7.2.3 创建服务类AuthService

创建service类处理用户注册和登录逻辑 AuthService

7.2.4 创建AuthController类

创建controller类处理用户注册和登录请求 AuthController

7.2.5 解决跨域问题

跨域问题是指在使用AJAX进行跨域请求时浏览器阻止访问不同源的Web资源的问题。跨域问题的本质是浏览器的一种安全机制称为同源策略Same-Origin Policy。同源策略限制了来自不同源的文档或脚本间的交互以防止恶意网站窃取数据或进行其他恶意操作

跨域问题的原因

跨域问题主要由以下几种情况引起:

协议不同例如http和https。
域名不同例如example.com和test.com。
端口不同例如80和8080。

目前最常用的解决方案:

CORSCross-Origin Resource Sharing服务器端设置CORS头部信息允许特定的域名或所有域名进行跨域请求。

在spring boot中可使用自己创建CorsFilter的bean实例的方式解决。

在项目config包中创建类CorsConfig,添加如下代码:

package com.lk.paopao.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.List;

/**
 * 配置类,用于设置跨域请求
 */
@Configuration
public class CorsConfig {

    /**
     * 创建并配置CorsFilter bean
     *
     * @return CorsFilter bean实例用于处理跨域请求
     */
    @Bean
    public CorsFilter corsFilter() {
        // 创建URL基于的Cors配置源
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 创建Cors配置实例
        CorsConfiguration config = new CorsConfiguration();

        // 配置允许的源
        config.setAllowedOrigins(List.of("http://localhost"));
        // 配置允许的方法
        config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
        // 配置允许的头部
        config.setAllowedHeaders(List.of("*"));
        // 允许凭据
        config.setAllowCredentials(true);

        // 在配置源中注册全局跨域配置
        source.registerCorsConfiguration("/**", config);
        // 返回CorsFilter实例
        return new CorsFilter(source);
    }
}

7.3 登录功能开发

7.3.1 登录接口API

用户登录接口

7.3.2 JWT介绍

JSON Web TokenJWT是一种开放标准RFC 7519用于在网络应用环境间安全地传输信息。JWT可以用于身份验证也可以用于信息交换。

每个JWT由三部分组成Header头部、Payload负载和Signature签名它们之间用点.)分隔。

  • Header头部通常包含两部分令牌的类型即JWT和所使用的签名算法如HMAC SHA256或RSA。
  • Payload负载包含所要传递的信息。负载可以包含多个声明claim它们是关于实体通常是用户和其他数据的声明。
  • Signature签名用于验证消息在传输过程中未被篡改并且对于使用私钥签名的令牌还可以验证发送者的身份。签名是使用头部指定的算法和密钥生成的。

JWT的优势在于其无状态和可扩展性它不需要在服务端存储会话信息这使得它非常适合分布式系统和跨域应用。同时JWT也可以被用于信息交换因为它可以包含任何需要的信息并且是自包含的不需要查询数据库来获取用户状态。

在登录功能中JWT通常用于在用户成功登录后生成一个令牌这个令牌随后被用于验证用户的身份以便用户可以访问受保护的资源。客户端将JWT存储在本地通常是在Cookie或LocalStorage中并在每次请求时将其作为请求头的一部分发送给服务器。服务器通过验证JWT的签名来确认用户的身份并允许或拒绝访问请求的资源。

体验JWT

jwt

参考: JSON Web Token 入门教程

7.3.3 代码实现

示例项目中的jwt包下实现了jwt的生成和验证方法。

AuthController类中添加登录方法实现用户登录接口。

AuthService类中添加登录方法实现用户登录功能。

7.3.4 实现获取用户个人信息功能

获取用户个人信息接口.md

7.4 发布文章功能开发

7.3.1 API

发布动态接口

获取指定id的动态接口

7.3.2 实体类和Repository接口

7.3.3 Controller和service

7.3.4 实现统一包装回应数据

7.3 附件上传功能开发

7.3.1 API

附件上传接口

7.3.2 实体类和Repository接口

7.3.3 Controller和service

7.4 文章相关功能开发

7.4.1 API设计

7.4.2 功能实现

文章查询、评论功能、点赞、收藏

7.4.3 DTO

7.4.4 lombok和mapstruct

7.5 部署