本文目录导读:

我来为您提供一个基于Spring Boot的完整Java系统服务案例,这个案例演示了一个简单的用户管理系统,包含常见的业务逻辑。
项目结构
user-management-system/
├── pom.xml
├── src/main/java/com/example/usermanagement/
│ ├── UserManagementApplication.java
│ ├── controller/
│ │ └── UserController.java
│ ├── service/
│ │ ├── UserService.java
│ │ └── impl/
│ │ └── UserServiceImpl.java
│ ├── repository/
│ │ └── UserRepository.java
│ ├── entity/
│ │ └── User.java
│ ├── dto/
│ │ ├── UserDTO.java
│ │ └── UserCreateRequest.java
│ └── exception/
│ ├── GlobalExceptionHandler.java
│ └── UserNotFoundException.java
核心代码实现
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
http://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>2.7.14</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>user-management</artifactId>
<version>1.0.0</version>
<name>user-management-system</name>
<description>用户管理系统服务</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 数据校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- H2数据库(开发环境) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
实体类 User.java
package com.example.usermanagement.entity;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message = "用户名不能为空")
@Column(nullable = false, unique = true, length = 50)
private String username;
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
@Column(nullable = false, unique = true, length = 100)
private String email;
@Column(length = 20)
private String phone;
@Column(nullable = false)
private Boolean active = true;
@CreationTimestamp
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}
DTO类
UserDTO.java
package com.example.usermanagement.dto;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class UserDTO {
private Long id;
private String username;
private String email;
private String phone;
private Boolean active;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
UserCreateRequest.java
package com.example.usermanagement.dto;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
@Data
public class UserCreateRequest {
@NotBlank(message = "用户名不能为空")
@Pattern(regexp = "^[a-zA-Z0-9_]{3,20}$",
message = "用户名只能包含字母、数字和下划线,长度3-20")
private String username;
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
@Pattern(regexp = "^1[3-9]\\d{9}$",
message = "手机号格式不正确")
private String phone;
private Boolean active = true;
}
仓库接口
package com.example.usermanagement.repository;
import com.example.usermanagement.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
Optional<User> findByEmail(String email);
boolean existsByUsername(String username);
boolean existsByEmail(String email);
@Query("SELECT u FROM User u WHERE u.active = :active ORDER BY u.createdAt DESC")
List<User> findByActive(@Param("active") Boolean active);
@Query("SELECT u FROM User u WHERE LOWER(u.username) LIKE LOWER(CONCAT('%', :keyword, '%')) " +
"OR LOWER(u.email) LIKE LOWER(CONCAT('%', :keyword, '%'))")
List<User> searchUsers(@Param("keyword") String keyword);
}
服务层
UserService.java (接口)
package com.example.usermanagement.service;
import com.example.usermanagement.dto.UserCreateRequest;
import com.example.usermanagement.dto.UserDTO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
public interface UserService {
UserDTO createUser(UserCreateRequest request);
UserDTO getUserById(Long id);
UserDTO getUserByUsername(String username);
List<UserDTO> getAllUsers();
Page<UserDTO> getUsersByPage(Pageable pageable);
UserDTO updateUser(Long id, UserCreateRequest request);
void deleteUser(Long id);
List<UserDTO> searchUsers(String keyword);
UserDTO toggleUserStatus(Long id);
}
UserServiceImpl.java
package com.example.usermanagement.service.impl;
import com.example.usermanagement.dto.UserCreateRequest;
import com.example.usermanagement.dto.UserDTO;
import com.example.usermanagement.entity.User;
import com.example.usermanagement.exception.UserNotFoundException;
import com.example.usermanagement.exception.UsernameAlreadyExistsException;
import com.example.usermanagement.repository.UserRepository;
import com.example.usermanagement.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
@RequiredArgsConstructor
@Transactional
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
@Override
public UserDTO createUser(UserCreateRequest request) {
log.info("Creating new user: {}", request.getUsername());
// 检查用户名是否已存在
if (userRepository.existsByUsername(request.getUsername())) {
throw new UsernameAlreadyExistsException("用户名已存在: " + request.getUsername());
}
// 检查邮箱是否已存在
if (userRepository.existsByEmail(request.getEmail())) {
throw new RuntimeException("邮箱已存在: " + request.getEmail());
}
User user = new User();
BeanUtils.copyProperties(request, user);
User savedUser = userRepository.save(user);
log.info("User created successfully: {}", savedUser.getId());
return convertToDTO(savedUser);
}
@Override
@Transactional(readOnly = true)
public UserDTO getUserById(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("用户不存在: id=" + id));
return convertToDTO(user);
}
@Override
@Transactional(readOnly = true)
public UserDTO getUserByUsername(String username) {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UserNotFoundException("用户不存在: username=" + username));
return convertToDTO(user);
}
@Override
@Transactional(readOnly = true)
public List<UserDTO> getAllUsers() {
return userRepository.findAll()
.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
}
@Override
@Transactional(readOnly = true)
public Page<UserDTO> getUsersByPage(Pageable pageable) {
return userRepository.findAll(pageable)
.map(this::convertToDTO);
}
@Override
public UserDTO updateUser(Long id, UserCreateRequest request) {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("用户不存在: id=" + id));
// 检查用户名是否被其他用户使用
if (!user.getUsername().equals(request.getUsername()) &&
userRepository.existsByUsername(request.getUsername())) {
throw new UsernameAlreadyExistsException("用户名已存在: " + request.getUsername());
}
user.setUsername(request.getUsername());
user.setEmail(request.getEmail());
user.setPhone(request.getPhone());
User updatedUser = userRepository.save(user);
log.info("User updated successfully: {}", updatedUser.getId());
return convertToDTO(updatedUser);
}
@Override
public void deleteUser(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("用户不存在: id=" + id));
userRepository.delete(user);
log.info("User deleted successfully: {}", id);
}
@Override
@Transactional(readOnly = true)
public List<UserDTO> searchUsers(String keyword) {
return userRepository.searchUsers(keyword)
.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
}
@Override
public UserDTO toggleUserStatus(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("用户不存在: id=" + id));
user.setActive(!user.getActive());
User updatedUser = userRepository.save(user);
return convertToDTO(updatedUser);
}
private UserDTO convertToDTO(User user) {
UserDTO dto = new UserDTO();
BeanUtils.copyProperties(user, dto);
return dto;
}
}
控制器层
package com.example.usermanagement.controller;
import com.example.usermanagement.dto.UserCreateRequest;
import com.example.usermanagement.dto.UserDTO;
import com.example.usermanagement.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
@Validated
public class UserController {
private final UserService userService;
// 创建用户
@PostMapping
public ResponseEntity<UserDTO> createUser(@Valid @RequestBody UserCreateRequest request) {
UserDTO createdUser = userService.createUser(request);
return new ResponseEntity<>(createdUser, HttpStatus.CREATED);
}
// 获取所有用户
@GetMapping
public ResponseEntity<List<UserDTO>> getAllUsers() {
return ResponseEntity.ok(userService.getAllUsers());
}
// 分页查询用户
@GetMapping("/page")
public ResponseEntity<Page<UserDTO>> getUsersByPage(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "createdAt") String sortBy,
@RequestParam(defaultValue = "desc") String sortDirection) {
Sort.Direction direction = sortDirection.equalsIgnoreCase("desc") ?
Sort.Direction.DESC : Sort.Direction.ASC;
Pageable pageable = PageRequest.of(page, size, Sort.by(direction, sortBy));
return ResponseEntity.ok(userService.getUsersByPage(pageable));
}
// 搜索用户
@GetMapping("/search")
public ResponseEntity<List<UserDTO>> searchUsers(@RequestParam String keyword) {
return ResponseEntity.ok(userService.searchUsers(keyword));
}
// 获取用户详情
@GetMapping("/{id}")
public ResponseEntity<UserDTO> getUserById(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserById(id));
}
// 更新用户
@PutMapping("/{id}")
public ResponseEntity<UserDTO> updateUser(
@PathVariable Long id,
@Valid @RequestBody UserCreateRequest request) {
return ResponseEntity.ok(userService.updateUser(id, request));
}
// 切换用户状态
@PatchMapping("/{id}/status")
public ResponseEntity<UserDTO> toggleUserStatus(@PathVariable Long id) {
return ResponseEntity.ok(userService.toggleUserStatus(id));
}
// 删除用户
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
}
异常处理
package com.example.usermanagement.exception;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
log.error("User not found: {}", ex.getMessage());
ErrorResponse error = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
ex.getMessage(),
LocalDateTime.now()
);
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(UsernameAlreadyExistsException.class)
public ResponseEntity<ErrorResponse> handleUsernameExists(UsernameAlreadyExistsException ex) {
log.error("Username already exists: {}", ex.getMessage());
ErrorResponse error = new ErrorResponse(
HttpStatus.CONFLICT.value(),
ex.getMessage(),
LocalDateTime.now()
);
return new ResponseEntity<>(error, HttpStatus.CONFLICT);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationErrors(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
log.error("Unexpected error occurred", ex);
ErrorResponse error = new ErrorResponse(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"服务器内部错误",
LocalDateTime.now()
);
return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
record ErrorResponse(int status, String message, LocalDateTime timestamp) {}
}
配置文件 application.yml
# 服务器配置
server:
port: 8080
servlet:
context-path: /
# Spring配置
spring:
application:
name: user-management-service
# 数据库配置
datasource:
url: jdbc:h2:mem:userdb;DB_CLOSE_DELAY=-1
driver-class-name: org.h2.Driver
username: sa
password:
# JPA配置
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
properties:
hibernate:
format_sql: true
# H2控制台
h2:
console:
enabled: true
path: /h2-console
# 日志配置
logging:
level:
root: INFO
com.example.usermanagement: DEBUG
org.springframework.web: INFO
主启动类
package com.example.usermanagement;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication
@EnableJpaAuditing
public class UserManagementApplication {
public static void main(String[] args) {
SpringApplication.run(UserManagementApplication.class, args);
}
}
API测试示例
# 创建用户
POST http://localhost:8080/api/users
{
"username": "zhangsan",
"email": "zhangsan@example.com",
"phone": "13800138000",
"active": true
}
# 获取所有用户
GET http://localhost:8080/api/users
# 分页查询
GET http://localhost:8080/api/users/page?page=0&size=10&sortBy=createdAt&sortDirection=desc
# 搜索用户
GET http://localhost:8080/api/users/search?keyword=zhang
# 获取用户详情
GET http://localhost:8080/api/users/1
# 更新用户
PUT http://localhost:8080/api/users/1
{
"username": "zhangsan_updated",
"email": "zhangsan_updated@example.com",
"phone": "13800138001",
"active": true
}
# 切换用户状态
PATCH http://localhost:8080/api/users/1/status
# 删除用户
DELETE http://localhost:8080/api/users/1
这个案例包含了以下核心功能:
- RESTful API 设计
- 数据持久化 (JPA)
- 参数校验
- 异常处理
- 分页和搜索
- 事务管理
- 日志记录
这是一个完整的企业级系统服务案例,可以直接运行和测试。