从零开始一个完整的全栈项目(3) - 开始搭建后端项目以及其中遇到的问题

346 阅读2分钟

后端项目被命名为 quickstore-backend.

同时,在此之前,在Github上新建了quickstore-resources仓库,用于存储项目除代码之外的文件,比如数据库各字段定义解释,以及建表SQL语句。

(以下内容有重新编辑过,最终使用的Cursor。因为在后面user登录部分,chatGPT出现了无法解决的bug,所以转Cursor)

1. 框架搭建思路

Cursor为我构建了项目的大体框架,如下:

(好像我前几年写Java的时候只有controller、service、model这几层)

src/main/java/com/yourcompany/quickstore
├── controller/     <-- 接收 HTTP 请求 (C in MVC)
├── service/        <-- 业务逻辑层 (通常也叫 manager)
├── repository/     <-- 数据访问层 (DAO/Repository)
├── model/          <-- 实体类,数据库映射 (M in MVC)
├── security/       <-- JWT 登录、权限控制(可选)
├── exception/      <-- 
├── config/         <-- Spring 配置类,如 CORS、安全设置等
└── QuickstoreApplication.java

2. Cursor生成的项目初始代码

Cursor生成了项目结构,如下:

image.png

项目内容包括:

  • QuickstoreApplication.java 启动类
  • 标准分层结构(controller, service, model, repository 等)
  • 项目结构清晰、可立即扩展用户登录模块

主文件的代码如下(这个文件是main方法所在的文件):

package com.quickstore;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class QuickStoreApplication {
    public static void main(String[] args) {
        SpringApplication.run(QuickStoreApplication.class, args);
    }
} 

应用配置文件如下:

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/quickstore_db
    username: ${POSTGRES_USER:postgres}
    password: ${POSTGRES_PASSWORD:postgres}
    driver-class-name: org.postgresql.Driver
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: true
    properties:
      hibernate:
        format_sql: true
        dialect: org.hibernate.dialect.PostgreSQLDialect
  security:
    jwt:
      secret: ${JWT_SECRET:your-secret-key-here-minimum-256-bits}
      expiration: 86400000 # 24 hours in milliseconds

server:
  port: 8080
  servlet:
    context-path: /api

logging:
  level:
    com.quickstore: DEBUG
    org.springframework.security: INFO

里面的database的用户名、密码,JWT验证需要的秘钥,都必须后面自己配置。

3.配置项目依赖

项目需要我自己用Maven来配置项目依赖。

首先需要对Java和Maven进行版本升级。

使用java -version检测Java版本。因为项目是基于Java17以上,所以我电脑的Java 1.8.0.202需要进行升级。

使用mvn -v检测Maven版本。Maven也需要由现在的Maven 3.3.9 升级到Maven 3.6以上。

升级Java(安装Java17)

brew install openjdk@17

安装完成后,配置环境变量:

export JAVA_HOME="/opt/homebrew/opt/openjdk@17"
export PATH="$JAVA_HOME/bin:$PATH"

使其生效:

source ~/.zshrc

确认:

java -version

应显示:openjdk version "17.x.x"

升级Maven(使用homebrew)

brew install maven

升级完成后检查:

mvn -v

应显示:Apache Maven 3.8+

中途遇到的bug的记录

安装完Maven,使用mvn -v,发现还是老版本(点击可查看折叠内容)。 重新使用安装指令,出现提示:
Warning: maven 3.9.9 is already installed, it's just not linked.
To link this version, run:
  brew link maven

使用这个指令时,出现错误。

Linking /opt/homebrew/Cellar/maven/3.9.9... 
Error: Could not symlink bin/mvn
Target /opt/homebrew/bin/mvn
is a symlink belonging to maven@3.3. You can unlink it:
  brew unlink maven@3.3

于是使用指令brew unlink maven@3.3,然后再使用指令brew link maven

成功。

对 Java 17 的环境变量(`JAVA_HOME` 和 `PATH`)配置,只在“当前终端会话”生效,如果新开一个Terminal窗口,使用java -version, 只会显示老版本(点击可查看折叠内容)。 原因是:对 Java 17 的环境变量(`JAVA_HOME` 和 `PATH`)配置,没有写入到“全局配置文件”中。

解决办法:

打开配置文件:

nano ~/.zshrc

在文件末尾添加以下内容(或修改已有JAVA_HOME配置)(上下左右移动光标,到文件末尾即可修改):

export JAVA_HOME="/opt/homebrew/opt/openjdk@17"
export PATH="$JAVA_HOME/bin:$PATH"

保存并关闭此文件。(保存是ctrl+o,这里会要求确认文件名,回车确认即可。关闭是ctrl+x)。

让配置立即生效:

source ~/.zshrc

现在即可在不同Terminal窗口使用java -version检查。

至此,Java和Maven都更新/升级好了。

配置项目依赖

由Cursor生成一个pom.xml文件,这是Maven的项目配置文件。

折叠部分为pom.xml文件源码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.3</version>
        <relativePath/>
    </parent>

    <groupId>com.quickstore</groupId>
    <artifactId>quickstore-backend</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>quickstore-backend</name>
    <description>Backend for QuickStore Warehouse Management System</description>

    <properties>
        <java.version>17</java.version>
        <jjwt.version>0.11.5</jjwt.version>
    </properties>

    <dependencies>
        <!-- Spring Boot Starters -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <!-- PostgreSQL -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- JWT Support -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>${jjwt.version}</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>${jjwt.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>${jjwt.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project> 

将pom.xml放入项目根目录下。

quickstore-backend/
├── pom.xml          ✅ ← 就放在这里!
├── src/
│   ├── main/
│   │   ├── java/
│   │   └── resources/
│   └── test/
└── ...

进入项目目录,执行以下指令:

mvn clean install

如果显示BUILD SUCCESS,那就是Maven加载好了所有依赖了。

image.png

接下来,启动:

mvn spring-boot:run

如果能看到:

Started QuickstoreApplication in X.XXX seconds
Tomcat started on port(s): 8080

就是已经启动成功了。

如下图:

image.png 此时,访问localhost:8080会出现404页面,因为并没有页面生成。

image.png

如果没有使用mvn spring-boot:run,项目没有启动的时候,出现的是如下页面:

image.png

至此,项目后端部分就大体完成了框架的搭建。

========

下一步,完成后端user功能代码,并使用postman进行虚拟登录。