项目实训第一阶段:项目的Spring Boot后端骨架搭建与文件上传接口实现
目录
一、项目背景
近年以来,滥用AI换脸、语音克隆等高级伪造技术的诈骗案件层出不穷。普通用户缺乏专业的鉴别能力,而现有的检测工具大多都是单一模态且操作复杂。基于这种现状,我们团队开发了“诈骗克星——基于大模型智能体的AI反诈骗检测系统”,旨在集成音频伪造检测、视频换脸检测与大模型智能分析,为用户提供一站式反诈服务。同时还通过AI模拟诈骗场景,重现诈骗流程等提高大众反诈骗意识与能力。
我作为后端负责人,主要承担Spring Boot后端框架搭建、文件上传接口实现、检测服务调用封装以及后续大模型集成的一些相关工作。本文记录第一阶段的核心成果与经验。
二、技术选型
| 技术 | 版本/说明 |
|---|---|
| JDK | Microsoft OpenJDK 17.0.16 |
| Spring Boot | 4.0.4 |
| 构建工具 | Maven |
| 核心依赖 | Spring Web, Lombok, Validation, DevTools |
| 检测服务调用 | RestTemplate |
| 代码托管 | Gitee |
三、项目结构与关键代码
1. 项目初始化
在IntelliJ IDEA中使用Spring Initializr创建项目,选择Maven、JDK 17,依赖勾选Spring Web、Lombok、Validation、DevTools。项目坐标:
- Group:
com.sdu - Artifact:
SafeGuard
2. 目录结构
src/main/java/com/sdu/safeguard/
├──SafeGuardApplication.java
├──config/
│ ├──RestTemplateConfig.java //RestTemplate Bean
│ └──WebConfig.java //跨域配置(可选)
├──controller/
│ └──FileUploadController.java
├──dto/
│ ├──Result.java //统一响应格式
│ ├──FileUploadResponse.java
│ ├──AudioDetectionResult.java
│ └──VideoDetectionResult.java
└──service/
└──DetectionService.java
3. 核心 DTO 定义
统一响应格式Result<T>,便于前端统一处理:
@Data
public class Result<T> {
private Integer code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("success");
result.setData(data);
return result;
}
public static <T> Result<T> error(String message) {
Result<T> result = new Result<>();
result.setCode(500);
result.setMessage(message);
return result;
}
}
音频检测结果DTO
@Data
public class AudioDetectionResult {
private String type = "audio";
private Double fakeProbability;
private Double confidence;
private String fakeType;
private String details;
}
视频检测结果类似,增加了帧级分析frameAnalysis字段。
4. 文件上传接口实现
在FileUploadController中实现POST /api/upload:
@PostMapping
public Result<FileUploadResponse> uploadFile(@RequestParam("file") MultipartFile file,
@RequestParam("type") String type) {
//参数校验
if (file.isEmpty()) {
return Result.error("文件不能为空");
}
if (!"audio".equalsIgnoreCase(type) && !"video".equalsIgnoreCase(type)) {
return Result.error("type必须为audio或video");
}
try {
//创建临时目录(系统临时目录/safe_guard/)
File tempDir = new File(System.getProperty("java.io.tmpdir") + "/safe_guard/");
if (!tempDir.exists()) tempDir.mkdirs();
//生成唯一文件名
String originalName = file.getOriginalFilename();
String extension = "";
if (originalName != null && originalName.contains(".")) {
extension = originalName.substring(originalName.lastIndexOf("."));
}
String fileId = UUID.randomUUID().toString();
String fileName = fileId + extension;
File destFile = new File(tempDir, fileName);
file.transferTo(destFile);
FileUploadResponse response = new FileUploadResponse();
response.setFileId(fileId);
response.setOriginalName(originalName);
response.setFileType(type);
response.setSize(file.getSize());
log.info("文件上传成功: {}, 类型: {}", fileId, type);
return Result.success(response);
} catch (IOException e) {
log.error("文件上传失败", e);
return Result.error("文件上传失败: " + e.getMessage());
}
}
本接口支持音频视频上传,返回文件元数据(UUID、原始名、类型、大小),文件实际保存至临时目录,供后续检测服务调用。
5. 检测服务调用封装
创建RestTemplateConfig提供RestTemplate Bean,然后在DetectionService中封装调用逻辑:
@Service
@Slf4j
public class DetectionService {
@Autowired
private RestTemplate restTemplate;
@Value("${audio.service.url}")
private String audioServiceUrl;
@Value("${video.service.url}")
private String videoServiceUrl;
public AudioDetectionResult detectAudio(String filePath) {
return callDetection(filePath, audioServiceUrl, AudioDetectionResult.class);
}
public VideoDetectionResult detectVideo(String filePath) {
return callDetection(filePath, videoServiceUrl, VideoDetectionResult.class);
}
private <T> T callDetection(String filePath, String url, Class<T> responseType) {
File file = new File(filePath);
if (!file.exists()) {
throw new RuntimeException("文件不存在: " + filePath);
}
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource(file));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
try {
ResponseEntity<T> response = restTemplate.exchange(
url,
HttpMethod.POST,
requestEntity,
responseType
);
log.info("调用检测服务成功: {}", url);
return response.getBody();
} catch (Exception e) {
log.error("调用检测服务失败: {}", url, e);
throw new RuntimeException("检测服务调用失败: " + e.getMessage());
}
}
}
在application.yml中预留服务地址配置:(尚未匹配)
audio:
service:
url: http://localhost:5001/audio
video:
service:
url: http://localhost:5002/video
此外还提供了/api/upload/detect接口,用于测试上传后立即调用检测服务。
四、遇到的问题与解决方案
1.Lombok注解在IDEA中报红
问题:使用@Data、@Slf4j等注解时,IDEA提示“无法解析符号”,但编译运行正常。
请教Deepseek老师后:Lombok需要注解处理器支持,IDEA默认未开启。进入File→Settings→Build,Execution,Deployment→Compiler→Annotation Processors,勾选Enable annotation processing,重启IDEA即可。(可能存在IDEA版本不同导致按键不一致,仔细甄别)
2. Git推送时分支名不匹配
问题:本地分支为master,远程仓库主分支为main,直接git push报错:
fatal: The upstream branch of your current branch does not match the name of your current branch.
请教Deepseek老师后:
1.使用git push origin HEAD:main推送当前分支到远程main分支。后续可通过git branch -u origin/main设置上游分支
2.或使用git push -u origin master:main建立跟踪关系。
3. 跨域问题预配置
为方便前端微信小程序调用,我在WebConfig中配置了全局CORS,允许所有来源(仅开发阶段):
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(false);
}
}
其实应限制为具体域名
五、成果与后续计划
已完成
| √ | Spring Boot项目骨架搭建,成功启动在8080端口 |
| √ | 定义音频/视频检测结果的标准JSON格式(DTO) |
| √ | 实现文件上传接口,支持临时存储,使用Postman测试通过 |
| √ | 封装检测服务调用模块,准备联合调整 |
| √ | 代码已托管至Gitee仓库(https://gitee.com/sdu_-fzkx/456) |
下一步计划
-
对接大模型API(DeepSeek/千问),实现文本话术分析与多模态综合分析
-
设计模拟诈骗流程智能体,预设诈骗剧本
-
开发知识库接口,增强回答权威性
-
与前端勾连,完善交互体验
六、总结
在第一阶段我顺畅完成了后端基础框架的搭建,为后续大模型集成和多模态的检测奠定了坚实基础。在此过程中遇到的问题都通过查阅资料解决。接下来我将继续推进大模型调用模块的开发。
项目代码地址:https://gitee.com/sdu_-fzkx/456
加油!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)