北京招聘网站设计师/佛山网站建设制作

北京招聘网站设计师,佛山网站建设制作,企业网页建设公司24小时接单,中国十大企业培训机构排名前言 首先介绍下MCP是什么? MCP是由开发了 Claude 模型的 Anthropic 公司2024年12月提出并开源的一项开放标准,全称:Model Context Protocol,它是一个开放协议,它使 LLM 应用与外部数据源和工具之间的无缝集成成为可能…

前言

首先介绍下MCP是什么?

MCP是由开发了 Claude 模型的 Anthropic 公司2024年12月提出并开源的一项开放标准,全称:Model Context Protocol,它是一个开放协议,它使 LLM 应用与外部数据源和工具之间的无缝集成成为可能。无论你是构建 AI 驱动的 IDE、改善chat 交互,还是构建自定义的 AI 工作流,MCP 提供了一种标准化的方式,将 LLM 与它们所需的上下文连接起来。

大白话

如果不使用 MCP 是什么样的?

就像自己(LLM大模型)学做菜,首先需要学会如何使用刀、锅、锅铲、炉灶,甚至需要自己生火,每一个步骤都需要从头摸索工具,无法专注烹饪本身。​

使用 MCP

MCP 协议相当于给大模型配了一个服务员(MCP Client),当食客(LLM大模型)需要吃什么菜时,可以直接根据菜单上的菜品告诉服务员(MCP Client),知道菜品后,服务员(MCP Client)根据菜品是哪个菜系找不同菜系的厨师(MCP Server),厨师(MCP Server)接到炒菜的任务就使用冰箱、食材、锅、锅铲等(工具)完成菜品制作任务,并将菜品(结果)精准端给服务员(MCP Client),让大模型无需直接操作工具就能完成复杂任务。

初衷

最近接触到 MCP 协议,我觉得它在未来AI实际应用中潜力巨大,很可能成为行业趋势。不过,我留意到mcp.so网站上,大部分 MCP Server 是用 Python 编写的,用 Java 开发的极为少见。就连 Spring AI,也是在 2025 年 2 月才开始支持并封装 MCP 协议的大部分逻辑。所以,我希望有更多从事 Java 开发的人员能够关注这项技术,将其广泛运用到实际项目里 。

正文

流程图

在这里插入图片描述

环境准备

  • Jenkins(需启用「远程访问API」权限)
  • JDK 17
  • SpringBoot 3.3.6
  • IDEA
  • Maven 3
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-mcp-server-spring-boot-starter</artifactId><version>1.0.0-M6</version>
</dependency>
<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.0</version>
</dependency>
<dependency><groupId>com.google.inject</groupId><artifactId>guice</artifactId><version>5.1.0</version>
</dependency>
<dependency><groupId>io.github.cdancy</groupId><artifactId>jenkins-rest</artifactId><version>1.0.2</version><exclusions><exclusion><artifactId>guice</artifactId><groupId>com.google.inject</groupId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.36</version><scope>provided</scope></dependency>

核心代码

  • JenkinsMcpServerConfig.java

MCP Server必须的配置类

package com.agua.ai.mcp.server.config;import com.agua.ai.mcp.server.service.JenkinsApiService;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class JenkinsMcpServerConfig {@Beanpublic ToolCallbackProvider jenkinsTools(JenkinsApiService jenkinsApiService) {return MethodToolCallbackProvider.builder().toolObjects(jenkinsApiService).build();}
}
  • JenkinsProperties.java

定义Jenkins的配置

package com.agua.ai.mcp.server.properties;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@Component
@ConfigurationProperties("jenkins")
public class JenkinsProperties {/*** 服务URI*/private String serverUri;/*** 用户名*/private String username;/*** 密码/token*/private String password;
}
  • JenkinsTemplate.java

对com.cdancy.jenkins(封装了Jenkins Rest API的工具类)已经集成的方法进行再次封装,方便调用

package com.agua.ai.mcp.server.util;import com.cdancy.jenkins.rest.JenkinsClient;
import com.cdancy.jenkins.rest.domain.common.IntegerResponse;
import com.cdancy.jenkins.rest.domain.common.RequestStatus;
import com.cdancy.jenkins.rest.domain.job.BuildInfo;
import com.cdancy.jenkins.rest.domain.job.JobInfo;
import com.cdancy.jenkins.rest.domain.job.JobList;
import com.cdancy.jenkins.rest.domain.job.ProgressiveText;
import com.cdancy.jenkins.rest.features.JobsApi;
import com.agua.ai.mcp.server.properties.JenkinsProperties;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Map;/*** Jenkins 模板类,用于封装 Jenkins API 的调用*/
@Component
public class JenkinsTemplate {private final JenkinsClient jenkinsClient;private JobsApi jobsApi;@Autowiredpublic JenkinsTemplate(JenkinsProperties jenkinsProperties) {this.jenkinsClient = JenkinsClient.builder().endPoint(jenkinsProperties.getServerUri()).credentials(jenkinsProperties.getUsername() + ":" + jenkinsProperties.getPassword()).build();}@PostConstructpublic void init() {this.jobsApi = jenkinsClient.api().jobsApi();}/*** 获取任务列表** @param optionalFolderPath 可选的文件夹路径* @return 任务列表*/public JobList getJobList(String optionalFolderPath) {return jobsApi.jobList(optionalFolderPath);}/*** 获取任务信息** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @return 任务信息*/public JobInfo getJobInfo(String optionalFolderPath, String jobName) {return jobsApi.jobInfo(optionalFolderPath, jobName);}/*** 使用 XML 文件创建任务** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @param configXML 任务的配置 XML* @return 请求状态*/public RequestStatus createJob(String optionalFolderPath, String jobName, String configXML) {return jobsApi.create(optionalFolderPath, jobName, configXML);}/*** 删除任务** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @return 请求状态*/public RequestStatus deleteJob(String optionalFolderPath, String jobName) {return jobsApi.delete(optionalFolderPath, jobName);}/*** 启用任务** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @return 是否成功*/public boolean enableJob(String optionalFolderPath, String jobName) {return jobsApi.enable(optionalFolderPath, jobName);}/*** 禁用任务** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @return 是否成功*/public boolean disableJob(String optionalFolderPath, String jobName) {return jobsApi.disable(optionalFolderPath, jobName);}/*** 获取任务配置文件内容** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @return 配置文件内容*/public String getJobConfig(String optionalFolderPath, String jobName) {return jobsApi.config(optionalFolderPath, jobName);}/*** 更新任务配置文件内容** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @param configXML 新的配置 XML* @return 是否成功*/public boolean updateJobConfig(String optionalFolderPath, String jobName, String configXML) {return jobsApi.config(optionalFolderPath, jobName, configXML);}/*** 构建任务** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @return 构建响应*/public IntegerResponse buildJob(String optionalFolderPath, String jobName) {return jobsApi.build(optionalFolderPath, jobName);}/*** 构建带参数的任务** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @param properties 参数列表* @return 构建响应*/public IntegerResponse buildJobWithParams(String optionalFolderPath, String jobName, Map<String, List<String>> properties) {return jobsApi.buildWithParameters(optionalFolderPath, jobName, properties);}/*** 获取任务上次构建序号** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @return 构建序号*/public Integer getLastBuildNumber(String optionalFolderPath, String jobName) {return jobsApi.lastBuildNumber(optionalFolderPath, jobName);}/*** 获取任务上次构建时间戳** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @return 时间戳*/public String getLastBuildTimestamp(String optionalFolderPath, String jobName) {return jobsApi.lastBuildTimestamp(optionalFolderPath, jobName);}/*** 获取构建信息** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @param buildNumber 构建编号* @return 构建信息*/public BuildInfo getBuildInfo(String optionalFolderPath, String jobName, int buildNumber) {return jobsApi.buildInfo(optionalFolderPath, jobName, buildNumber);}/*** 获取构建控制台输出内容** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @param buildNumber 构建编号* @param start 开始位置* @return 控制台输出内容*/public ProgressiveText getBuildLog(String optionalFolderPath, String jobName, int buildNumber, int start) {return jobsApi.progressiveText(optionalFolderPath, jobName, buildNumber, start);}/*** 重命名任务** @param optionalFolderPath 可选的文件夹路径* @param currentJobName 当前任务名称* @param newJobName 新任务名称* @return 是否成功*/public boolean renameJob(String optionalFolderPath, String currentJobName, String newJobName) {return jobsApi.rename(optionalFolderPath, currentJobName, newJobName);}/*** 停止任务** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @param buildNumber 构建编号* @return 是否成功*/public RequestStatus killJob(String optionalFolderPath, String jobName, int buildNumber) {return jobsApi.kill(optionalFolderPath, jobName, buildNumber);}/*** 查看执行日志** @param optionalFolderPath 可选的文件夹路径* @param jobName 任务名称* @param start 开始位置* @return 是否成功*/public ProgressiveText progressiveTextJob(String optionalFolderPath, String jobName, int start) {return jobsApi.progressiveText(optionalFolderPath, jobName, start);}
}
  • JenkinsApiService.java

直接暴露给LLM大模型的可调用的工具的Service

package com.agua.ai.mcp.server.service;import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.agua.ai.mcp.server.util.JenkinsTemplate;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;@Service
@AllArgsConstructor
public class JenkinsApiService {private final JenkinsTemplate jenkinsTemplate;@Tool(description = "获取任务列表")public String getJobList(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.getJobList(optionalFolderPath));}@Tool(description = "获取任务信息")public String getJobInfo(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.getJobInfo(optionalFolderPath, jobName));}@Tool(description = "使用 XML 文件创建任务")public String createJob(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName,@ToolParam(description = "任务的配置 XML") String configXML) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.createJob(optionalFolderPath, jobName, configXML));}@Tool(description = "删除任务")public String deleteJob(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.deleteJob(optionalFolderPath, jobName));}@Tool(description = "启用任务")public String enableJob(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.enableJob(optionalFolderPath, jobName));}@Tool(description = "禁用任务")public String disableJob(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.disableJob(optionalFolderPath, jobName));}@Tool(description = "获取任务配置文件内容")public String getJobConfig(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.getJobConfig(optionalFolderPath, jobName));}@Tool(description = "更新任务配置文件内容")public String updateJobConfig(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName,@ToolParam(description = "新的配置 XML") String configXML) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.updateJobConfig(optionalFolderPath, jobName, configXML));}@Tool(description = "构建任务")public String buildJob(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.buildJob(optionalFolderPath, jobName));}@Tool(description = "构建带参数的任务")public String buildJobWithParams(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName,@Schema(description = "参数列表(格式:Map<String, List<String>>)") String properties) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.buildJobWithParams(optionalFolderPath, jobName, JSON.parseObject(properties, new TypeReference<>() {})));}@Tool(description = "获取任务上次构建序号")public String getLastBuildNumber(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.getLastBuildNumber(optionalFolderPath, jobName));}@Tool(description = "获取任务上次构建时间戳")public String getLastBuildTimestamp(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.getLastBuildTimestamp(optionalFolderPath, jobName));}@Tool(description = "获取构建信息")public String getBuildInfo(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName,@ToolParam(description = "构建编号(必须是整数)") String buildNumber,@ToolParam(description = "是否返回变更历史(boolean类型)") String changeSetFlag) {Gson gson = new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() {@Overridepublic boolean shouldSkipField(FieldAttributes f) {return Boolean.parseBoolean(changeSetFlag) && "changeSet".equals(f.getName());}@Overridepublic boolean shouldSkipClass(Class<?> clazz) {return false;}}).create();return gson.toJson(jenkinsTemplate.getBuildInfo(optionalFolderPath, jobName, Integer.parseInt(buildNumber)));}@Tool(description = "获取构建控制台输出内容")public String getBuildLog(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName,@ToolParam(description = "构建编号(必须是整数)") String buildNumber,@ToolParam(description = "开始位置(必须是整数)") String start) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.getBuildLog(optionalFolderPath, jobName, Integer.parseInt(buildNumber), Integer.parseInt(start)));}@Tool(description = "重命名任务")public String renameJob(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "当前任务名称") String currentJobName,@ToolParam(description = "新任务名称") String newJobName) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.renameJob(optionalFolderPath, currentJobName, newJobName));}@Tool(description = "停止任务(必须二次确认)")public String killJob(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName,@ToolParam(description = "构建编号(必须是整数)") String buildNumber) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.killJob(optionalFolderPath, jobName, Integer.parseInt(buildNumber)));}@Tool(description = "查看执行日志")public String progressiveTextJob(@ToolParam(description = "可选的文件夹路径") String optionalFolderPath,@ToolParam(description = "任务名称") String jobName,@ToolParam(description = "开始位置(必须是整数)") String start) {Gson gson = new GsonBuilder().create();return gson.toJson(jenkinsTemplate.progressiveTextJob(optionalFolderPath, jobName, Integer.parseInt(start)));}
}
  • application.yml
spring:ai:mcp:server:stdio: truename: jenkins-apiversion: 0.0.1type: SYNCmain:web-application-type: nonebanner-mode: off
logging:level:root: INFO
jenkins:# jenkins的访问urlserver-uri: ${JENKINS_API_SERVER_URI}username: ${JENKINS_API_USERNAME}password: ${JENKINS_API_TOKEN}

使用配置

如果是用 Cursor 作为客户端,那么可以通过一下方式启动 MCP Server ,本地 MCP Server 服务请将{你的路径}替换成实际的 jar 包存放路径

  • command方式
java -Dspring.ai.mcp.server.transport=STDIO -Dspring.main.web-application-type=none -jar {你的路径}\mcp-jenkins-server-0.0.1-SNAPSHOT.jar
  • mcp.json配置
{"mcpServers": {"jenkins-mcp": {"command": "java","args": ["-Dspring.ai.mcp.server.stdio=true","-Dspring.main.web-application-type=none","-jar","{你的路径}\\mcp-jenkins-server-0.0.1-SNAPSHOT.jar"],"env": {"jenkins.server-uri": "jenkins-uri","jenkins.username": "username","jenkins.password": "password/token" }}}
}

最终演示效果

用户提问:请部署v1.2.3版本到测试环境

MCP Client解析后调用:

{"tool": "buildJobWithParams","params": {"optionalFolderPath": "","jobName": "qa-system","properties": {"version": ["v1.2.3"], "env": ["test"]}}
}

Jenkins MCP Server执行结果:

{"value": "12345","errors": []
}

总结

目前大模型的优势就是它能够一定程度地理解用户所说的内容,并转换成调用工具所需的请求参数,减少人工解析的工作量并且降低人工适配的成本。现在 MCP 还处于初期发展阶段,因此需要广大开发者的支持,才能支撑起庞大 AI 应用生态构建。

相关链接
MCP 介绍
Spring AI MCP
Jenkins 官网
jenkins-rest(Github 地址)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/75876.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vcpkg安装指定版本的库

一.vcpkg安装 使用git将vcpkg源码克隆到本地制定目录&#xff08;D:\vcpkg&#xff09;&#xff0c;并初始化 git clone https://github.com/microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh # Linux/macOS .\bootstrap-vcpkg.bat # Windows 如下图&#xff1a; 二.安…

WPF ContentPresenter详解2

ContentPresenter与ContentControl的区别 ContentControl 和 ContentPresenter 是 WPF 中两个相关的控件&#xff0c;但它们在用途和功能上有一些关键的区别。理解这两者的区别和联系有助于更好地设计和开发用户界面。 1. 类层次结构 ContentControl&#xff1a;位于 WPF 控件…

【HTML5游戏开发教程】零基础入门合成大西瓜游戏实战 | JS物理引擎+Canvas动画+完整源码详解

《从咖啡杯到财务自由&#xff1a;一个程序员的合成之旅——当代码遇上物理引擎的匠心之作》 &#x1f31f; 这是小游戏开发系列的第四篇送福利文章&#xff0c;感谢一路以来支持和关注这个项目的每一位朋友&#xff01; &#x1f4a1; 文章力求严谨&#xff0c;但难免有疏漏之…

RTMP推流+EasyDSS云服务+边缘AI分析的无人机监控系统设计

在现代科技不断发展的背景下&#xff0c;无人机技术已经广泛应用于各个领域&#xff0c;从航拍摄影到工业巡检&#xff0c;从农业监测到应急救援&#xff0c;无人机以其高效的工作能力&#xff0c;为人们的生活和工作带来了诸多便利与创新&#xff0c;而其视频传输与分析系统更…

HCIP(VLAN综合实验)

实验拓补图 实验分析 一、实验目的 掌握VLAN的创建和配置方法理解VLAN在局域网中的作用学习如何通过VLAN实现网络隔离和通信 二、实验环境 交换机&#xff08;SW1、SW2、SW3&#xff09;个人电脑&#xff08;PC1、PC2、PC3、PC4、PC5、PC6&#xff09;路由器&#xff08;R1…

第十二章——位运算

按位的与& 若x的第i位和y的第i位都是1&#xff0c;那么&#xff08;x&y&#xff09;1&#xff0c;否则&#xff08;x&y&#xff09; 0 应用&#xff1a;希望让某一位或某些位为0 。取一个数中的一段。 按位的或| 若x的第i位1或y的第i位1&#xff0c;那么&…

【Mysql:内置函数】

日期函数&#xff1a; 查看当前日期&#xff1a; select current_date();查看当前时间&#xff1a; select current_time(); 查看当前时间戳&#xff1a; select current_timestamp(); 计算两个日期的差值&#xff1a; select datediff(date1,date2); 当前的日期时间&a…

71. 我的第一个Linux驱动实验

一、字符设备驱动框架 字符设备驱动的编写主要就是驱动对应的open、close、read。。。其实就是 file_operations结构体的成员变量的实现。 其中关于 C 库以及如何通过系统调用“陷入” 到内核空间这个我们不用去管&#xff0c;我们重点关注的是应用程序和具体的驱动&#xff0…

jdk21使用Vosk实现语音文字转换,免费的语音识别

1.下载vosk的model vosk官网&#xff1a;https://alphacephei.com/vosk/models 我这里使用较小的vosk-model-small-cn-0.22 2.添加相关pom文件 <!-- 获取音频信息 --><dependency><groupId>org</groupId><artifactId>jaudiotagger</artifac…

C++修炼:string类的使用

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 欢迎点赞&#xff0c;关注&am…

【go微服务】如何快速掌握grpc开发

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【区块链 + 文化版权】基于 FISCO BCOS 的方言大数据语料库 | FISCO BCOS 应用案例

苏州喵自在区块链科技有限公司打造的基于FISCO BCOS 的粤语大数据语料库&#xff0c; 旨在利用区块链技术保护和发展粤语文化遗产。该项目利用区块链的不可篡改性、分布式存储、智能合约和激励机制等特性&#xff0c; 为保护非物质文化遗产&#xff0c; 加强粤语研究与教育和开…

亚马逊云科技提供完全托管的DeepSeek-R1模型

近日&#xff0c;亚马逊云科技宣布在Amazon Bedrock上线完全托管的DeepSeek-R1模型。DeepSeek是首个登陆Amazon Bedrock的国产大模型&#xff0c;自今年1月底推出以来&#xff0c;已有数千客户使用Amazon Bedrock的自定义模型导入功能部署了DeepSeek-R1模型。 DeepSeek在过去几…

vmwaretools解压失败|vmware tools distrib cannot mkdir read only file system|bug汇总

最简单的一条路线&#xff1a;你的解压命令用sudo了吗&#xff1f; 这个方法不能解决的话就看下面内容。本文提供给你全过程思路。 如需转载&#xff0c;标记出处 背景&#xff1a; 之前虚拟机和主机的复制黏贴还能用&#xff0c;今天突然用不了&#xff0c;重新下载安装包&am…

Spring MVC配置详解:从历史到实战

文章目录 一、Java Web的发展历程1.Model I与Model II开发模式&#xff08;1&#xff09; Model I开发模式&#xff08;2&#xff09;Model II开发模式 2.MVC设计模式Spring MVC本质MVC工作流程 二、Spring MVC快速入门实战1.环境搭建步骤&#xff08;1&#xff09;创建Maven W…

Docker应用部署之mysql篇(day5)

文章目录 前言一、问题描述二、解决方案1. 搜索 MySQL 镜像2. 拉取 MySQL 镜像3. 创建并运行 MySQL 容器参数说明&#xff1a; 4. 验证容器是否运行5. 进入 MySQL 容器 三、总结 前言 在日常开发和部署中&#xff0c;MySQL 是最常用的关系型数据库之一。借助 Docker&#xff0…

【Elasticsearch基础】基本核心概念介绍

Elasticsearch作为当前最流行的分布式搜索和分析引擎&#xff0c;其强大的功能背后是一套精心设计的核心概念体系。本文将深入解析Elasticsearch的五大核心概念&#xff0c;帮助开发者构建坚实的技术基础&#xff0c;并为高效使用ES提供理论支撑。 1 索引&#xff08;Index&…

MFC添加免费版大漠3.1233

先创建一个MFC工程&#xff0c; 添加dm.dll 方法一&#xff1a;通过类向导-添加类-类型库中的MFC类-文件&#xff0c;选择dm.dll&#xff0c;如果没有"添加类型库中的MFC类"选项就用方法二添加 方法二&#xff1a;添加-新建项-MFC-Active或TypeLib-实现接口位置选…

【Linux】应用层协议 HTTP

应用层协议 HTTP 一. HTTP 协议1. URL 地址2. urlencode 和 urldecode3. 请求与响应格式 二. HTTP 请求方法1. GET 和 POST (重点) 三. HTTP 状态码四. HTTP 常见报头五. 手写 HTTP 服务器 HTTP&#xff08;超文本传输协议&#xff09;是一种应用层协议&#xff0c;用于在万维网…

【活动回顾】StarRocks Singapore Meetup #2 @Shopee

3 月 13 日&#xff0c;StarRocks 社区在新加坡成功举办了第二场 Meetup 活动&#xff0c;主题为“Empowering Customer-Facing Analytics”。本次活动在 Shopee 新加坡办公室举行&#xff0c;吸引了来自 Shopee、Grab 和 Pinterest 的专家讲师以及 50 多位参会者。大家围绕电商…