老版本springboot项目本地部署大模型并实现后端调用
我只是一个菜鸟程序员,不过希望这篇博客可以给同行一些参考,笑料也行,毕竟我还不强。
1,前言
由于博主最近刚改造完一个非常老的springboot项目,因为项目配置太老无法使用springAI还有langchain4j这些主流ai开发框架,所以使用这种方式。
同时也作为我第一篇文章的扩展。
2,操作基本流程
1,下载ollama 并且进行本地大模型拉取
可以参考我的第一篇文章:
https://blog.csdn.net/2301_78290338/article/details/149461004?spm=1011.2124.3001.6209
2,下载anythingLLM,熟悉基本操作,并且熟悉它的api文档
3,编写后端代码实现调用api功能
4,测试
3,一些基本知识
3.1 RESTful API。
它的核心思想是将软件的功能抽象为资源,并通过标准的HTTP方法(如GET、POST、PUT、DELETE)来操作这些资源
工作原理:
每个资源都有一个唯一的地址(URL)。例如,GET https://api.example.com/users 可能用于获取用户列表,而 POST https://api.example.com/users 可能用于创建一个新用户。
3.2 ollama。
一个本地化的“模型服务引擎”,它负责让大模型在你的电脑上跑起来并提供API。
3.3 AnythingLLM
一个“功能应用平台”,它可以直接使用Ollama提供的模型能力,并为你提供诸如与文档对话等更高级和易用的功能。
4,环境准备,与正式操作
4.1下载ollama并且拉取模型
4.1.1下载ollama
ollama是用来本地部署大模型的平台(如果对隐蔽性要求不高或者不打算本地部署可以忽略此步),可以前往官网下载:

4.1.2配置环境变量
在Windows开始菜单栏输入环境变量

点击环境变量进行环境变量编辑
OLLAMA_HOST=0.0.0.0:11434:让虚拟机里的程序能访问本机上运行的 Ollama 模型 RAGFlow是部署在虚拟机里的,默认情况下,Ollama 只能允许本机访问(监听 localhost:11434),其他设备(比如虚拟机)是无法连接的。 可能存在的问题:如果配置后虚拟机无法访问,可能是你的本机防火墙拦截了端口 11434,需要放行它。 如果你的 Ollama 只想给自己的虚拟机使用,而不想直接暴露 11434 端口让任何设备都能访问,你可以通过SSH 端口转发来实现;
OLLAMA_MODELS :默认模型下载到C盘,如果希望下载到其他盘可以配置,最好选一个大一点的盘; 注意配置之后保险起见一定要重启电脑;
结果示例

4.1.3,拉取模型:
拉取deepseek开源模型:

以内存最小的版本为例:
复制模型拉取命令

终端(win+r,然后输入cmd回车)拉取模型:
我这里由于之前以及下载好了直接就能对话,初次下载的可能要花一些时间等待模型下载

tip:初次下载的可能要等待模型下载,刚开始会有慢是正常的,不过如果非常慢,可以CTRL+c打断,然后再次输入命令继续下载。(这样并不会使我们的下载进度重新从零开始)
4.2下载anythingLLM,熟悉基本操作
前往官网:https://anythingllm.com/desktop
根据你的系统下载,我这里使用的是wingdowsx64,所以下载上面那个,下载拿到安装包之后,双击运行,将会进入这个页面:
点击搜索框旁边的加号,新建一个工作区:yourWorkspace(也可命名为其他,操作前确保ollama已经启动)。

点击save,之后出现这个新工作区就代表成功创建,
点击工作区旁边的齿轮图案进入设置
将聊天设置里的工作区 LLM 提供者,选择为刚下载的ollama,

工作区聊天模型切换为你之前下载的本地大模型

然后点击旁边的黑色按钮updete workspace,更新工作区设置使代码生效,现在你就可以在工作区用本地模型对话了
可点击工作区旁边的上传图标按钮,上传你的资料进入工作区知识库,

一定要点击保存并嵌入,负责你的本地模型无法解析它,
然后点击工作区传入文件旁边纺锤图案的annual,进行资料的固定,确保ai访问时能够直接访问到
资料

对话,验证是否能够正确使用和访问引入的文件:

你可以通过上传不同资料,创建你的专属知识库
4.3,编写后端代码实现调用ai
由于anythingllm提供了api供我们调用,因此我们可以通过调用它的api实现对话,上传文档等功能。我使用的是springboot2集成好的resrTemplate来调用。
4.3.1前置操作:
获取api-key:


复制密钥,输入到你的springboot项目到的yaml文件里:
controller层
import com.example.demo.Service.impl.AnythingLLMServiceAAA;
import com.example.demo.shiti.dto.request.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/ai")
@Slf4j
public class DocumentController {
@Autowired
private AnythingLLMServiceAAA anythingLLMService;
/**
* 上传文档 - 启用新的上传功能(带元数据)
*/
@PostMapping("/documents/upload")
public ApiResponse<String> uploadDocument(
@RequestParam("file") MultipartFile file,
@RequestParam(value = "workspaceId", required = false) String workspaceId,
@RequestParam(value = "documentName", required = false) String documentName,
@RequestParam(value = "title", required = false) String title,
@RequestParam(value = "docAuthor", required = false) String docAuthor,
@RequestParam(value = "description", required = false) String description,
@RequestParam(value = "docSource", required = false) String docSource
) {
try {
log.info("收到文档上传请求: workspaceId={}, fileName={}, size={}",
workspaceId, file.getOriginalFilename(), file.getSize());
if (file.isEmpty()) {
return ApiResponse.error("文件不能为空");
}
// 1. 构建元数据Map
Map<String, String> metadata = new HashMap<>();
if (title != null) metadata.put("title", title);
if (docAuthor != null) metadata.put("docAuthor", docAuthor);
if (description != null) metadata.put("description", description);
if (docSource != null) metadata.put("docSource", docSource);
// 2. 如果没有提供title,使用documentName或文件名
if (title == null && documentName != null) {
metadata.put("title", documentName);
} else if (title == null && file.getOriginalFilename() != null) {
// 从文件名中去除扩展名作为title
String originalName = file.getOriginalFilename();
int dotIndex = originalName.lastIndexOf('.');
String nameWithoutExt = dotIndex > 0 ? originalName.substring(0, dotIndex) : originalName;
metadata.put("title", nameWithoutExt);
}
// 3. 调用服务层方法
String result = anythingLLMService.uploadDocumentWithMetadata(file, workspaceId, documentName, metadata);
return ApiResponse.success("文档上传成功", result);
} catch (Exception e) {
log.error("文档上传失败", e);
return ApiResponse.error("文档上传失败: " + e.getMessage());
}
}
/**
* 与文档对话 - 使用更灵活的请求体处理
*/
@PostMapping("/chat")
public ApiResponse<String> chatWithDocument(@RequestBody Map<String, Object> request) {
try {
// 从请求体中提取参数
String workspaceId = (String) request.get("workspaceId");
String message = (String) request.get("message");
String mode = (String) request.get("mode");
if (message == null || message.trim().isEmpty()) {
return ApiResponse.error("消息内容不能为空");
}
log.info("收到对话请求: workspaceId={}, message={}", workspaceId, message);
String response = anythingLLMService.chatWithDocument(workspaceId, message, mode);
return ApiResponse.success("对话成功", response);
} catch (Exception e) {
log.error("文档对话失败", e);
return ApiResponse.error("文档对话失败: " + e.getMessage());
}
}
}
service层
package com.example.demo.Service.impl;
import com.example.demo.config.AppConfig;
import com.example.demo.shiti.dto.request.DocumentInfo;
import com.example.demo.shiti.dto.request.WorkspaceInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.*;
@Service
@Slf4j
public class AnythingLLMServiceAAA {
@Autowired
private RestTemplate restTemplate;
@Autowired
private AppConfig.AnythingLLMProperties properties;
/**
* 将 MultipartFile 转换为 File - 安全实现
*/
private File convertMultipartFileToFile(MultipartFile multipartFile) throws IOException {
// 获取原始文件名信息
String originalFileName = multipartFile.getOriginalFilename();
String safePrefix = "upload_";
String suffix = ".tmp";
// 如果有原始文件名,使用它来生成更有意义的临时文件名
if (originalFileName != null && !originalFileName.isEmpty()) {
// 提取前缀(文件名不含扩展名)
int dotIndex = originalFileName.lastIndexOf('.');
if (dotIndex > 0) {
safePrefix = originalFileName.substring(0, Math.min(dotIndex, 20)) + "_";
suffix = originalFileName.substring(dotIndex);
} else {
safePrefix = originalFileName + "_";
}
// 清理前缀中的非法字符
safePrefix = safePrefix.replaceAll("[^a-zA-Z0-9_-]", "_");
}
// 创建临时文件
File file = File.createTempFile(safePrefix, suffix);
// 将 MultipartFile 内容写入临时文件
multipartFile.transferTo(file);
log.debug("创建临时文件: {} (大小: {} bytes)", file.getAbsolutePath(), file.length());
return file;
}
/**
* 上传文档(带元数据)- 完整实现,包含文件清理
*/
public String uploadDocumentWithMetadata(MultipartFile file,
String workspaceId,
String documentName,
Map<String, String> metadata) {
File tempFile = null;
try {
// 1. 确定目标工作空间
String targetWorkspaceId = (workspaceId != null && !workspaceId.trim().isEmpty()) ?
workspaceId : getOrCreateDefaultWorkspace();
// 2. 构建上传URL
String url = "http://localhost:3001/api/v1/document/upload";
// 3. 创建请求头
HttpHeaders headers = createHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
// 4. 转换 MultipartFile 为 File
tempFile = convertMultipartFileToFile(file);
// 5. 构建表单数据体
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
// 添加文件部分
body.add("file", new FileSystemResource(tempFile));
// 添加工作空间ID(如果需要)
body.add("workspaceId", targetWorkspaceId);
// 如果提供了文档名称,添加到表单
if (documentName != null && !documentName.trim().isEmpty()) {
body.add("name", documentName);
}
// 6. 添加元数据部分 (如果存在)
if (metadata != null && !metadata.isEmpty()) {
ObjectMapper mapper = new ObjectMapper();
try {
String metadataJson = mapper.writeValueAsString(metadata);
body.add("metadata", metadataJson);
log.info("上传元数据: {}", metadataJson);
} catch (JsonProcessingException e) {
log.warn("元数据序列化失败,将不上传元数据。错误: {}", e.getMessage());
}
}
// 7. 发送请求
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
log.info("开始上传文档到工作空间: {}, 文件名: {}, URL: {}",
targetWorkspaceId, file.getOriginalFilename(), url);
ResponseEntity<String> response = restTemplate.exchange(
url, HttpMethod.POST, requestEntity, String.class);
if (response.getStatusCode().is2xxSuccessful()) {
log.info("文档上传成功");
return "文档及元数据上传成功至工作空间: " + targetWorkspaceId;
} else {
log.error("上传失败,状态码: {}, 响应: {}", response.getStatusCode(), response.getBody());
throw new RuntimeException("上传失败,状态码: " + response.getStatusCode());
}
} catch (IOException e) {
throw new RuntimeException("文件处理失败", e);
} catch (Exception e) {
throw new RuntimeException("上传文档时发生错误: " + e.getMessage(), e);
} finally {
// 8. 清理临时文件
if (tempFile != null && tempFile.exists()) {
boolean deleted = tempFile.delete();
if (!deleted) {
log.warn("临时文件删除失败: {}", tempFile.getAbsolutePath());
tempFile.deleteOnExit(); // 如果立即删除失败,注册在 JVM 退出时删除
} else {
log.debug("临时文件已清理: {}", tempFile.getAbsolutePath());
}
}
}
}
// 原有的 uploadDocument 方法可以调用新的 uploadDocumentWithMetadata 方法
/**
* 上传文档到指定工作空间 - 兼容旧版本,内部调用新方法
*/
public String uploadDocument(MultipartFile file, String workspaceId, String documentName) {
// 构建空的元数据Map,调用新方法
Map<String, String> metadata = new HashMap<>();
// 如果提供了文档名称,可以将其作为title
if (documentName != null && !documentName.trim().isEmpty()) {
metadata.put("title", documentName);
}
return uploadDocumentWithMetadata(file, workspaceId, documentName, metadata);
}
/**
* 获取或创建默认工作空间
*/
public String getOrCreateDefaultWorkspace() {
try {
// 首先尝试获取现有工作空间
List<WorkspaceInfo> workspaces = getAllWorkspaces();
if (!workspaces.isEmpty()) {
// 优先使用配置的默认工作空间
for (WorkspaceInfo workspace : workspaces) {
if (workspace.getName().equalsIgnoreCase(properties.getDefaultWorkspace()) ||
workspace.getSlug().equalsIgnoreCase(properties.getDefaultWorkspace())) {
return workspace.getSlug(); // 使用 slug 而不是 id
}
}
// 如果没有匹配的,返回第一个工作空间的 slug
return workspaces.get(0).getSlug();
}
// 如果没有工作空间,创建一个默认的
log.info("没有找到工作空间,创建默认工作空间");
WorkspaceInfo workspace = createWorkspace(properties.getDefaultWorkspace(), "系统自动创建的默认工作空间");
return workspace.getSlug();
} catch (Exception e) {
log.error("获取或创建工作空间失败", e);
// 如果所有方法都失败,返回配置的默认工作空间名称
return properties.getDefaultWorkspace().toLowerCase(); // 转换为小写,因为 slug 通常是全小写
}
}
/**
* 与文档对话 - 使用正确的 API 格式
*/
public String chatWithDocument(String workspaceId, String message, String mode) {
// 使用提供的工作空间ID或默认工作空间
String targetWorkspaceId = (workspaceId != null && !workspaceId.trim().isEmpty()) ?
workspaceId : getOrCreateDefaultWorkspace();
// 使用已知的正确聊天端点
String url = "http://localhost:3001/api/v1/workspace/" + targetWorkspaceId + "/chat";
HttpHeaders headers = createHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 使用正确的请求体格式
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("message", message);
requestBody.put("mode", mode != null ? mode : "query");
// 可选字段,根据需要添加
// requestBody.put("sessionId", "your-session-id");
// requestBody.put("reset", false);
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
try {
log.info("向工作空间 {} 发送消息,URL: {}", targetWorkspaceId, url);
log.info("请求体: {}", requestBody);
ResponseEntity<String> response = restTemplate.exchange(
url, HttpMethod.POST, requestEntity, String.class);
log.info("对话API响应状态: {}", response.getStatusCode());
if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
// 记录完整响应以便调试
log.info("完整响应: {}", response.getBody());
// 尝试解析JSON响应
try {
ResponseEntity<Map> jsonResponse = restTemplate.exchange(
url, HttpMethod.POST, requestEntity, Map.class);
String textResponse = extractTextResponse(jsonResponse.getBody());
if (textResponse != null) {
return textResponse;
}
} catch (Exception parseError) {
log.warn("JSON解析失败,返回原始响应: {}", parseError.getMessage());
}
// 返回原始响应
return response.getBody();
} else {
throw new RuntimeException("对话失败,状态码: " + response.getStatusCode());
}
} catch (Exception e) {
log.error("与文档对话时发生错误: {}", e.getMessage());
throw new RuntimeException("与文档对话时发生错误: " + e.getMessage(), e);
}
}
/**
* 从响应中提取文本回复
*/
private String extractTextResponse(Map<String, Object> responseBody) {
String[] possibleFields = {"textResponse", "response", "answer", "text", "content", "message"};
for (String field : possibleFields) {
if (responseBody.containsKey("field") && responseBody.get("field") != null) {
return responseBody.get("field").toString();
}
}
return null;
}
/**
* 创建工作空间 - 修复路径
*/
public WorkspaceInfo createWorkspace(String name, String description) {
String url = properties.getBaseUrl() + "/workspaces";
HttpHeaders headers = createHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("name", name);
requestBody.put("description", description);
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
try {
log.info("创建工作空间: {}", name);
ResponseEntity<Map> response = restTemplate.exchange(
url, HttpMethod.POST, requestEntity, Map.class);
if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
Map<String, Object> responseBody = response.getBody();
WorkspaceInfo workspace = new WorkspaceInfo();
// 安全地提取字段
if (responseBody.get("id") != null) {
workspace.setId(responseBody.get("id").toString());
}
if (responseBody.get("name") != null) {
workspace.setName(responseBody.get("name").toString());
}
if (responseBody.get("slug") != null) {
workspace.setSlug(responseBody.get("slug").toString());
}
if (responseBody.get("description") != null) {
workspace.setDescription(responseBody.get("description").toString());
}
log.info("创建工作空间成功: {}", workspace.getName());
return workspace;
} else {
throw new RuntimeException("创建工作空间失败,状态码: " + response.getStatusCode());
}
} catch (Exception e) {
throw new RuntimeException("创建工作空间时发生错误: " + e.getMessage(), e);
}
}
/**
* 获取所有工作空间 - 保持不变,这个工作正常
*/
public List<WorkspaceInfo> getAllWorkspaces() {
String url = properties.getBaseUrl() + "/workspaces";
HttpHeaders headers = createHeaders();
HttpEntity<String> requestEntity = new HttpEntity<>(headers);
try {
log.info("请求工作空间列表,URL: {}", url);
ResponseEntity<String> rawResponse = restTemplate.exchange(
url, HttpMethod.GET, requestEntity, String.class);
log.info("工作空间API响应状态: {}", rawResponse.getStatusCode());
if (rawResponse.getStatusCode().is2xxSuccessful() && rawResponse.getBody() != null) {
// 尝试解析为Map
try {
ResponseEntity<Map> response = restTemplate.exchange(
url, HttpMethod.GET, requestEntity, Map.class);
Map<String, Object> responseBody = response.getBody();
List<WorkspaceInfo> workspaces = new ArrayList<>();
if (responseBody != null && responseBody.containsKey("workspaces")) {
List<Map<String, Object>> workspacesData = (List<Map<String, Object>>) responseBody.get("workspaces");
for (Map<String, Object> workspaceData : workspacesData) {
workspaces.add(createWorkspaceInfoFromMap(workspaceData));
}
}
log.info("成功解析工作空间数量: {}", workspaces.size());
return workspaces;
} catch (Exception e) {
log.warn("解析工作空间响应失败: {}", e.getMessage());
return new ArrayList<>();
}
} else {
throw new RuntimeException("获取工作空间列表失败,状态码: " + rawResponse.getStatusCode());
}
} catch (Exception e) {
log.error("获取工作空间列表时发生错误", e);
throw new RuntimeException("获取工作空间列表时发生错误: " + e.getMessage(), e);
}
}
/**
* 从Map创建WorkspaceInfo对象 - 添加slug字段
*/
private WorkspaceInfo createWorkspaceInfoFromMap(Map<String, Object> workspaceData) {
WorkspaceInfo workspace = new WorkspaceInfo();
// 安全地提取字段,处理可能的null值
if (workspaceData.get("id") != null) {
workspace.setId(workspaceData.get("id").toString());
}
if (workspaceData.get("name") != null) {
workspace.setName(workspaceData.get("name").toString());
}
if (workspaceData.get("slug") != null) {
workspace.setSlug(workspaceData.get("slug").toString());
}
if (workspaceData.get("description") != null) {
workspace.setDescription(workspaceData.get("description").toString());
}
if (workspaceData.get("createdAt") != null) {
workspace.setCreatedAt(workspaceData.get("createdAt").toString());
}
return workspace;
}
/**
* 获取工作空间中的文档列表 - 修复路径
*/
public List<DocumentInfo> getWorkspaceDocuments(String workspaceId) {
String targetWorkspaceId = (workspaceId != null && !workspaceId.trim().isEmpty()) ?
workspaceId : getOrCreateDefaultWorkspace();
String url = properties.getBaseUrl() + "/workspace/" + targetWorkspaceId + "/documents";
HttpHeaders headers = createHeaders();
HttpEntity<String> requestEntity = new HttpEntity<>(headers);
try {
log.info("获取工作空间 {} 的文档列表,URL: {}", targetWorkspaceId, url);
ResponseEntity<String> rawResponse = restTemplate.exchange(
url, HttpMethod.GET, requestEntity, String.class);
log.info("文档列表API响应状态: {}", rawResponse.getStatusCode());
if (rawResponse.getStatusCode().is2xxSuccessful()) {
// 尝试解析响应
try {
ResponseEntity<List> listResponse = restTemplate.exchange(
url, HttpMethod.GET, requestEntity, List.class);
if (listResponse.getBody() != null) {
List<Map<String, Object>> documentsData = listResponse.getBody();
List<DocumentInfo> documents = new ArrayList<>();
for (Map<String, Object> documentData : documentsData) {
DocumentInfo document = new DocumentInfo();
document.setId(documentData.get("id") != null ?
documentData.get("id").toString() : "unknown");
document.setName(documentData.get("name") != null ?
documentData.get("name").toString() : "unknown");
document.setType(documentData.get("type") != null ?
documentData.get("type").toString() : "unknown");
document.setStatus(documentData.get("status") != null ?
documentData.get("status").toString() : "unknown");
documents.add(document);
}
return documents;
}
} catch (Exception e) {
log.warn("无法解析文档列表响应: {}", e.getMessage());
}
// 如果无法解析,返回空列表
return new ArrayList<>();
} else {
throw new RuntimeException("获取文档列表失败,状态码: " + rawResponse.getStatusCode());
}
} catch (Exception e) {
log.error("获取文档列表时发生错误", e);
throw new RuntimeException("获取文档列表时发生错误: " + e.getMessage(), e);
}
}
/**
* 删除文档 - 修复路径
*/
public String deleteDocument(String workspaceId, String documentId) {
String targetWorkspaceId = (workspaceId != null && !workspaceId.trim().isEmpty()) ?
workspaceId : getOrCreateDefaultWorkspace();
String url = properties.getBaseUrl() + "/workspace/" + targetWorkspaceId + "/document/" + documentId;
HttpHeaders headers = createHeaders();
HttpEntity<String> requestEntity = new HttpEntity<>(headers);
try {
log.info("删除文档,workspaceId: {}, documentId: {}, URL: {}",
targetWorkspaceId, documentId, url);
ResponseEntity<String> response = restTemplate.exchange(
url, HttpMethod.DELETE, requestEntity, String.class);
if (response.getStatusCode().is2xxSuccessful()) {
return "文档删除成功";
} else {
throw new RuntimeException("文档删除失败,状态码: " + response.getStatusCode());
}
} catch (Exception e) {
throw new RuntimeException("删除文档时发生错误: " + e.getMessage(), e);
}
}
/**
* 创建请求头
*/
private HttpHeaders createHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + properties.getApiKey());
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
return headers;
}
}
实体类
package com.example.demo.shiti.dto.request;
import lombok.Data;
@Data
public class ApiResponse<T> {
private boolean success;
private String message;
private T data;
private Long timestamp;
public ApiResponse() {
this.timestamp = System.currentTimeMillis();
}
public static <T> ApiResponse<T> success(T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setSuccess(true);
response.setMessage("操作成功");
response.setData(data);
return response;
}
public static <T> ApiResponse<T> success(String message, T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setSuccess(true);
response.setMessage(message);
response.setData(data);
return response;
}
public static <T> ApiResponse<T> error(String message) {
ApiResponse<T> response = new ApiResponse<>();
response.setSuccess(false);
response.setMessage(message);
return response;
}
}
成功调用

5,结语
我只是一个菜鸟程序员,不过希望这篇博客可以给同行一些参考,笑料也行,毕竟我还不强
。:.゚ヽ(。◕‿◕。)ノ゚.:。+゚
更多推荐




所有评论(0)