Spring AI MCP实战:调用高德API查询天气(2025年最新完整教程)
MCP 在 Spring AI 上下文中,通常指 Model-Controller-Pattern(模型-控制器-模式),这是 Spring Boot 应用的标准 MVC 架构(Model-View-Controller 的变体,View 部分可替换为 API 响应)。本教程将手把手教你从零构建一个 Spring AI 应用,使用 MCP 架构集成高德地图天气查询 API,并结合 Spring AI 的 AI 能力(如通义大模型)生成智能天气报告(例如,基于天气数据生成“今天出门建议”)。
为什么用 Spring AI?
Spring AI 是 Spring 官方 2023 年推出的框架(2025 年已达 1.0 GA),简化 AI 集成(如大模型调用)。这里我们用它调用阿里云通义模型(DashScope)生成天气解读,同时用 RestTemplate 调用高德 API。整个应用是 RESTful API,支持城市查询天气。
前提条件
- JDK 17+(Spring Boot 3.x 要求)
- Maven 3.6+ 或 Gradle
- 高德 API Key(免费申请,日限 30 万次)
- 阿里云 DashScope API Key(免费试用,集成 Spring AI Alibaba)
- IDE:IntelliJ IDEA 或 VS Code
预计时间:30-45 分钟。最终输出:一个可运行的 Spring Boot 应用,POST /weather?city=北京,返回 JSON 天气数据 + AI 生成的建议。
第一步:申请 API Key(5 分钟)
高德天气 API
- 访问 高德开放平台,注册/登录开发者账号。
- 点击“应用管理 > 创建新应用”,应用类型选“Web 服务”。
- 添加 Key(服务平台选“Web 服务”),复制 Key(例如:
your_amap_key)。
- API 文档:天气查询接口
- URL 示例:
https://restapi.amap.com/v3/weather/weatherInfo?key=your_amap_key&city=110000&extensions=allcity:城市编码(北京=110000,上海=310000;全国列表见文档)。extensions:base(实时)或 all(+预报)。- 返回:JSON,如
{ "status": "1", "lives": [{ "weather": "晴", "temperature": "22", ... }] }。
阿里云 DashScope(Spring AI 用)
- 访问 阿里云控制台,开通 DashScope 服务(免费额度 1000 元)。
- 创建 API Key(例如:
your_dashscope_key)。 - Spring AI Alibaba 集成:用此 Key 调用通义模型生成天气解读。
第二步:创建 Spring Boot 项目(5 分钟)
用 Spring Initializr(https://start.spring.io/)生成项目:
- Project: Maven
- Language: Java
- Spring Boot: 3.2.x(最新)
- Group: com.example
- Artifact: spring-ai-weather-mcp
- Dependencies:
- Spring Web(REST API)
- Spring AI Alibaba AutoConfiguration(AI 集成)
- Spring Boot Starter Test
下载 ZIP,解压到本地,用 IDE 打开。
pom.xml 关键依赖(自动添加 Spring AI Alibaba):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI Alibaba (通义大模型) -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
<version>1.0.0-M1</version> <!-- 2025 最新版 -->
</dependency>
</dependencies>
第三步:配置 application.yml(3 分钟)
在 src/main/resources/application.yml 添加:
spring:
ai:
alibaba:
dashscope:
api-key: ${DASHSCOPE_API_KEY:your_dashscope_key} # 环境变量或直接填
chat:
options:
model: qwen-max # 通义千问大模型
temperature: 0.7
amap:
key: ${AMAP_API_KEY:your_amap_key} # 高德 Key
server:
port: 8080
运行前设置环境变量:
- Windows:
set DASHSCOPE_API_KEY=your_key - Linux/Mac:
export DASHSCOPE_API_KEY=your_key
同理设置AMAP_API_KEY。
第四步:构建 MCP 架构(Model-Controller-Pattern,15 分钟)
Model(模型):天气数据 POJO
创建 src/main/java/com/example/model/WeatherResponse.java(高德 API 响应模型):
package com.example.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
public class WeatherResponse {
private String status;
private String info;
private Integer infocode;
private List<Live> lives; // 实时天气
private List<Forecast> forecasts; // 预报
// Getters/Setters
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
// ... 其他 getters/setters
public static class Live {
private String province;
private String city;
private String adcode;
private String reporttime;
private String weather;
private String temperature;
private String winddirection;
private String windpower;
private String humidity;
// Getters/Setters...
}
public static class Forecast {
// 类似 Live,省略...
}
}
创建 AiWeatherAdvice.java(AI 生成的建议模型):
package com.example.model;
public class AiWeatherAdvice {
private String punnyResponse; // AI 生成的双关语或建议
private String weatherConditions; // 天气解读
// Getters/Setters
public String getPunnyResponse() { return punnyResponse; }
public void setPunnyResponse(String punnyResponse) { this.punnyResponse = punnyResponse; }
public String getWeatherConditions() { return weatherConditions; }
public void setWeatherConditions(String weatherConditions) { this.weatherConditions = weatherConditions; }
}
Controller(控制器):REST API 入口
创建 src/main/java/com/example/controller/WeatherController.java:
package com.example.controller;
import com.example.model.WeatherResponse;
import com.example.model.AiWeatherAdvice;
import com.example.service.WeatherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WeatherController {
@Autowired
private WeatherService weatherService;
@Value("${amap.key}")
private String amapKey;
@GetMapping("/weather")
public WeatherResponse getWeather(@RequestParam String city) {
// 调用服务获取天气 + AI 建议
WeatherResponse weather = weatherService.getWeather(city, amapKey);
AiWeatherAdvice advice = weatherService.generateAdvice(weather);
// 这里可合并到响应中,或返回复合对象
System.out.println("AI 建议: " + advice.getPunnyResponse()); // 日志输出
return weather; // 实际项目中返回 WeatherResponse + advice
}
}
Pattern(服务层:集成 Spring AI + 高德 API)
在 Service 中实现核心逻辑。创建 src/main/java/com/example/service/WeatherService.java:
package com.example.service;
import com.alibaba.dashscope.aigc.chat.ChatClient;
import com.alibaba.dashscope.aigc.chat.options.ChatOptions;
import com.example.model.WeatherResponse;
import com.example.model.AiWeatherAdvice;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.ai.chat.model.ToolContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
@Service
public class WeatherService {
@Autowired
private RestTemplate restTemplate; // Spring Web 自带
@Autowired
private ChatClient chatClient; // Spring AI Alibaba 的 ChatClient
// 高德城市编码映射(简化,实际用数据库或缓存)
private final Map<String, String> cityCodes = Map.of(
"北京", "110000", "上海", "310000", "广州", "440100"
);
public WeatherResponse getWeather(String city, String key) {
String adcode = cityCodes.getOrDefault(city, "110000"); // 默认北京
String url = "https://restapi.amap.com/v3/weather/weatherInfo?key=" + key +
"&city=" + adcode + "&extensions=all&output=JSON";
String response = restTemplate.getForObject(url, String.class);
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(response, WeatherResponse.class);
} catch (Exception e) {
throw new RuntimeException("天气查询失败: " + e.getMessage());
}
}
// Spring AI 工具:天气解读生成器
public AiWeatherAdvice generateAdvice(WeatherResponse weather) {
WeatherResponse.Live live = weather.getLives().get(0);
String prompt = "基于天气: " + live.getWeather() + ", 温度: " + live.getTemperature() +
"°C, 风力: " + live.getWindpower() + "。生成一个有趣的出门建议(双关语风格)。";
// 用 Spring AI Alibaba 调用通义模型
ChatOptions options = ChatOptions.builder()
.withModel("qwen-max")
.withMessages(prompt)
.build();
String aiResponse = chatClient.call(options).getOutput().getContent(); // 简化调用
AiWeatherAdvice advice = new AiWeatherAdvice();
advice.setPunnyResponse(aiResponse);
advice.setWeatherConditions("今天" + live.getWeather() + ",适合户外活动!");
return advice;
}
}
说明:
getWeather:用 RestTemplate 调用高德 HTTP API。generateAdvice:用 Spring AI 的 ChatClient 调用通义模型生成智能建议(例如,“晴天如你心情,带把伞防惊喜!”)。- 工具集成:可扩展为 Spring AI Tool(如 WeatherForLocationTool),用
@ToolParam注解。
第五步:运行与测试(5 分钟)
- 运行主类
SpringAiWeatherMcpApplication.java:
@SpringBootApplication
public class SpringAiWeatherMcpApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAiWeatherMcpApplication.class, args);
}
}
- 测试 API:用 Postman 或 curl:
curl "http://localhost:8080/weather?city=北京"
返回示例:
{
"status": "1",
"lives": [{
"city": "北京市",
"weather": "晴",
"temperature": "15",
"windpower": "≤3",
"humidity": "40"
}],
// ... 预报数据
}
控制台日志:AI 建议(如“晴朗天气,钻石般闪耀,出门捡钱吧!”)。
- 扩展:添加异常处理、缓存(Redis)、安全(OAuth)。
常见问题与优化(2025 年实战Tips)
| 问题 | 解决方案 |
|---|---|
| Key 无效 | 检查高德控制台配额(日 30 万次),DashScope 额度。 |
| AI 响应慢 | 用 temperature=0.5 优化,或异步调用。 |
| 城市编码未知 | 集成高德“行政区查询 API”动态获取 adcode。 |
| 部署生产 | 用 Docker + Kubernetes,监控 AI 调用次数。 |
资源推荐(2025 最新):
- Spring AI 官方:spring.io/projects/spring-ai
- Spring AI Alibaba:java2ai.com(天气 Agent 示例)
- 高德文档:lbs.amap.com/api/webservice/guide/api/weatherinfo
这个 MCP 应用已完整可跑!如果需要 GitHub 源码、Docker 镜像,或扩展(如多城市批量查询),告诉我,我直接发你。玩转 Spring AI,未来 AI 开发就是这么简单!