
介绍
目前已经基于外部restful api构建了一个spring boot web应用,基于当前的应用状态,总结一下,如果从零开始构建这样的应用,具体的步骤是?
我需要先了解当前Spring Boot应用的结构和功能,然后为您总结从零开始构建这样应用的具体步骤。让我先查看项目的基本信息。
Read pom.xml, lines 1 to 50
Read pom.xml, lines 51 to 168
现在让我查看项目的主要控制器和服务类,了解应用的核心功能:
Read handwrittenerase
Read controller
Read HandwrittenEraseController.java, lines 1 to 50
Read service
Read HandwrittenEraseService.java, lines 1 to 50
Read entity
Read README.md, lines 1 to 50
现在让我查看更多配置信息,了解应用的完整架构:
Read ApiConfig.java, lines 1 to 30
现在让我查看Docker部署相关文件:
Read Dockerfile
Read docker-compose.yml, lines 1 to 30
基于对当前Spring Boot应用的详细分析,我现在可以为您总结从零开始构建这样应用的完整步骤。这是一个功能丰富的手写文字擦除Web应用,包含用户认证、订阅管理、统计功能等。
从零开始构建手写文字擦除Spring Boot应用的完整步骤
第一阶段:项目初始化
- 创建Spring Boot项目
# 使用Spring Initializr或IDE创建项目
# 选择以下依赖:
- Spring Boot 3.5.x
- Java 17
- Maven
- Spring Web
- Spring Data JPA
- Spring Security
- Thymeleaf
- H2 Database
- PostgreSQL Driver
- MySQL Driver
- Lombok
- Validation
- Actuator
- DevTools
- 配置项目结构
src/
├── main/
│ ├── java/
│ │ └── net/daimakuai/handwrittenerase/
│ │ ├── HandwrittenEraseApplication.java
│ │ ├── config/
│ │ ├── controller/
│ │ ├── service/
│ │ ├── repository/
│ │ ├── entity/
│ │ ├── dto/
│ │ ├── security/
│ │ ├── exception/
│ │ └── constant/
│ └── resources/
│ ├── application.yml
│ ├── application-dev.yml
│ ├── application-prod.yml
│ ├── static/
│ └── templates/
第二阶段:核心配置
- 配置Maven依赖 (pom.xml)
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- JWT支持 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<!-- 数据库驱动 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 其他工具 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
- 配置应用属性 (application.yml)
# 基础配置
server:
port: 9090
servlet:
context-path: /hwe
spring:
profiles:
active: dev
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
# 第三方API配置
textin:
api:
url: https://api.textin.com/ai/service/v1/handwritten_erase
app-id: ${TEXTIN_APP_ID}
secret-code: ${TEXTIN_SECRET_CODE}
# 应用配置
app:
jwt:
secret: ${JWT_SECRET:your-secret-key}
expiration-in-ms: 86400000
upload:
dir: ${UPLOAD_DIR:./uploads}
第三阶段:数据层设计
- 创建实体类
// User.java - 用户实体
@Entity
@Table(name = "users")
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String username;
private String password;
private String email;
@Enumerated(EnumType.STRING)
private UserRole role;
@CreationTimestamp
private LocalDateTime createdAt;
}
// UsageRecord.java - 使用记录
@Entity
@Table(name = "usage_records")
@Data
public class UsageRecord {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private User user;
@Enumerated(EnumType.STRING)
private UsageType type;
private String originalFilename;
private Long fileSize;
@CreationTimestamp
private LocalDateTime createdAt;
}
// Subscription.java - 订阅信息
@Entity
@Table(name = "subscriptions")
@Data
public class Subscription {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private User user;
@Enumerated(EnumType.STRING)
private SubscriptionType type;
private LocalDateTime startDate;
private LocalDateTime endDate;
private Integer usageLimit;
private Integer usageCount;
}
- 创建Repository接口
// UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
boolean existsByUsername(String username);
}
// UsageRecordRepository.java
@Repository
public interface UsageRecordRepository extends JpaRepository<UsageRecord, Long> {
List<UsageRecord> findByUserIdAndCreatedAtBetween(Long userId, LocalDateTime start, LocalDateTime end);
long countByUserIdAndCreatedAtAfter(Long userId, LocalDateTime since);
}
第四阶段:安全配置
- 配置Spring Security
// SecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authz -> authz
.requestMatchers("/v1/auth/**").permitAll()
.requestMatchers("/v1/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
// JWT相关类
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
// JWT token验证逻辑
}
第五阶段:业务逻辑实现
- 创建核心服务类
// HandwrittenEraseService.java - 核心业务服务
@Service
public class HandwrittenEraseService {
@Autowired
private ApiConfig apiConfig;
public String eraseFromFile(MultipartFile file) throws Exception {
// 调用第三方API处理图片
String base64Data = Base64.getEncoder().encodeToString(file.getBytes());
// 构建HTTP请求到Textin API
String result = callTextinAPI(base64Data);
return result;
}
private String callTextinAPI(String base64Data) throws Exception {
// 实现HTTP请求逻辑
URL url = new URL(apiConfig.getUrl());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求参数和头部
// 发送请求并处理响应
}
}
// AuthService.java - 认证服务
@Service
public class AuthService {
@Autowired
private UserRepository userRepository;
@Autowired
private JwtUtil jwtUtil;
public String login(String username, String password) {
// 验证用户凭据
// 生成JWT token
}
public User register(String username, String password, String email) {
// 用户注册逻辑
}
}
- 创建控制器
// HandwrittenEraseController.java - 主要API控制器
@RestController
@RequestMapping("/v1/handwritten-erase")
public class HandwrittenEraseController {
@Autowired
private HandwrittenEraseService handwrittenEraseService;
@PostMapping("/file")
public ResponseEntity<ApiResponse> processFile(@RequestParam("file") MultipartFile file) {
try {
String result = handwrittenEraseService.eraseFromFile(file);
return ResponseEntity.ok(ApiResponse.success(result));
} catch (Exception e) {
return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage()));
}
}
}
// AuthController.java - 认证控制器
@RestController
@RequestMapping("/v1/auth")
public class AuthController {
@PostMapping("/login")
public ResponseEntity<ApiResponse> login(@RequestBody LoginRequest request) {
// 登录逻辑
}
@PostMapping("/register")
public ResponseEntity<ApiResponse> register(@RequestBody RegisterRequest request) {
// 注册逻辑
}
}
第六阶段:前端界面
- 创建Thymeleaf模板
<!-- index.html - 主页面 -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>手写文字擦除</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<!-- 文件上传表单 -->
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<form id="uploadForm" enctype="multipart/form-data">
<div class="mb-3">
<input type="file" class="form-control" id="file" accept="image/*">
</div>
<button type="submit" class="btn btn-primary">处理图片</button>
</form>
</div>
</div>
</div>
</body>
</html>
第七阶段:配置管理
- 环境配置
# application-dev.yml - 开发环境
spring:
datasource:
url: jdbc:h2:mem:handwrittenerase
driver-class-name: org.h2.Driver
username: sa
password:
h2:
console:
enabled: true
# application-prod.yml - 生产环境
spring:
datasource:
url: jdbc:postgresql://localhost:5432/handwrittenerase
username: ${POSTGRES_USER}
password: ${POSTGRES_PASSWORD}
第八阶段:部署配置
- Docker化
# Dockerfile
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/handwrittenerase-*.jar app.jar
EXPOSE 9090
ENTRYPOINT ["java", "-jar", "app.jar"]
第九阶段:测试和优化
- 单元测试
@SpringBootTest
class HandwrittenEraseServiceTest {
@Autowired
private HandwrittenEraseService service;
@Test
void testEraseFromFile() {
// 测试文件处理功能
}
}
- 性能优化
- 配置连接池 - 添加缓存策略 - 文件上传限制 - API限流
第十阶段:监控和运维
- 添加监控
# Actuator配置
management:
endpoints:
web:
exposure:
include: health,info,metrics
- 日志配置
<!-- logback-spring.xml -->
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
关键技术要点总结
- 架构设计:MVC架构 + RESTful API
- 安全认证:JWT Token + Spring Security
- 数据存储:JPA + 多数据库支持(H2/PostgreSQL/MySQL)
- 文件处理:MultipartFile + 第三方API集成
- 前端技术:Thymeleaf + Bootstrap + JavaScript
- 部署方案:Docker + docker-compose
- 监控运维:Spring Actuator + 自定义健康检查 这个完整的步骤涵盖了从项目初始化到生产部署的全流程,可以作为构建类似企业级Spring Boot应用的参考模板。

评论