spring-ai-alibaba第六章阿里dashscope集成mcp百度翻译tools

1、百度翻译mcp服务端 pom文件

    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-mcp-server-webflux-spring-boot-starter</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
    </dependencies>

2、百度翻译mcp服务端yml配置文件

#
# Copyright 2025-2026 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# spring.main.web-application-type=none

# NOTE: You must disable the banner and the console logging 
# to allow the STDIO transport to work !!!
spring:
  main:
    banner-mode: off
  ai:
    mcp:
      server:
        name: my-translate-server
        version: 0.0.1

    alibaba:
      toolcalling:
        baidutranslate:
          enabled: true
          app-id: xxxxxxxx
          secret-key: oooooooo

server:
  port: 38080
# logging.pattern.console=

3、百度翻译mcp服务端 百度appid合key配置文件类

package org.springframework.ai.mcp.sample.server.conf;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@ConfigurationProperties(prefix = "spring.ai.alibaba.toolcalling.baidutranslate")
@Configuration
public class BaidutranslateProperties {

    private String appId;

    private String secretKey;

    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

}

4、百度翻译 mcp 服务端 百度翻译service类

package org.springframework.ai.mcp.sample.server;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.mcp.sample.server.conf.BaidutranslateProperties;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @author yingzi
 * @date 2025/3/27:11:13
 */
@Service
public class BaidutranslateService {

    private static final Logger logger = LoggerFactory.getLogger(BaidutranslateService.class);

    private static final String TRANSLATE_HOST_URL = "https://fanyi-api.baidu.com/api/trans/vip/translate";

    private static final Random random = new Random();
    private final WebClient webClient;
    private final String appId;
    private final String secretKey;

    public BaidutranslateService(BaidutranslateProperties properties) {
        assert StringUtils.hasText(properties.getAppId());
        this.appId = properties.getAppId();
        assert StringUtils.hasText(properties.getSecretKey());
        this.secretKey = properties.getSecretKey();

        this.webClient = WebClient.builder()
                .defaultHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded")
                .build();
    }

    @Tool(description = "Baidu translation function for general text translation")
    public Map<String, String> baiduTranslateMethod(@ToolParam(description = "Content that needs to be translated") String q,
                                                    @ToolParam(description = "Source language that needs to be translated") String from,
                                                    @ToolParam(description = "Target language to translate into") String to) {
        if (!StringUtils.hasText(q) || !StringUtils.hasText(from)
                || !StringUtils.hasText(to)) {
            return null;
        }
        String salt = String.valueOf(random.nextInt(100000));
        String sign = DigestUtils.md5DigestAsHex((appId + q + salt + secretKey).getBytes());
        String url = UriComponentsBuilder.fromHttpUrl(TRANSLATE_HOST_URL).toUriString();
        try {
            MultiValueMap<String, String> body = constructRequestBody(q, from, to, salt, sign);
            Mono<String> responseMono = webClient.post().uri(url).bodyValue(body).retrieve().bodyToMono(String.class);

            String responseData = responseMono.block();
            assert responseData != null;
            logger.info("Translation request: {}, response: {}", q, responseData);

            return parseResponse(responseData);

        }
        catch (Exception e) {
            logger.error("Failed to invoke translate API due to: {}", e.getMessage());
            return null;
        }
    }

    private MultiValueMap<String, String> constructRequestBody(String q, String from, String to, String salt, String sign) {
        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        body.add("q", q);
        body.add("from", from);
        body.add("to", to);
        body.add("appid", appId);
        body.add("salt", salt);
        body.add("sign", sign);
        return body;
    }

    private Map<String, String> parseResponse(String responseData) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            Map<String, String> translations = new HashMap<>();
            TranslationResponse responseList = mapper.readValue(responseData, TranslationResponse.class);
            String to = responseList.to;
            List<TranslationResult> translationsList = responseList.trans_result;
            if (translationsList != null) {
                for (TranslationResult translation : translationsList) {
                    String translatedText = translation.dst;
                    translations.put(to, translatedText);
                    logger.info("Translated text to {}: {}", to, translatedText);
                }
            }
            return translations;
        }
        catch (Exception e) {
            try {
                Map<String, String> responseList = mapper.readValue(responseData,
                        mapper.getTypeFactory().constructMapType(Map.class, String.class, String.class));
                logger.info(
                        "Translation exception, please inquire Baidu translation api documentation to info error_code:{}",
                        responseList);
                return responseList;
            }
            catch (Exception ex) {
                logger.error("Failed to parse json due to: {}", ex.getMessage());
                return null;
            }
        }
    }

    public record TranslationResult(String src, String dst) {
    }

    public record TranslationResponse(String from, String to, List<TranslationResult> trans_result) {
    }
}

5、百度翻译 mcp服务端启动类

/*
 * Copyright 2025-2026 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author brianxiadong
 */

package org.springframework.ai.mcp.sample.server;


import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class McpBaiduServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(McpBaiduServerApplication.class, args);
    }


    @Bean
    public ToolCallbackProvider baiduTranslateFunction(BaidutranslateService baidutranslateService) {
        return MethodToolCallbackProvider.builder().toolObjects(baidutranslateService).build();
    }


}

 

6、spring-ai 大模型应用程序 mcp客户端, 集成了mcp天气查询工具和 mcp百度翻译工具

pom文件

	<dependencies>

		<dependency>
			<groupId>org.springframework.ai</groupId>
			<artifactId>spring-ai-mcp-client-webflux-spring-boot-starter</artifactId>
			<version>${spring-ai.version}</version>
		</dependency>

		<dependency>
			<groupId>com.alibaba.cloud.ai</groupId>
			<artifactId>spring-ai-alibaba-starter</artifactId>
			<version>${spring-ai-alibaba.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>


	</dependencies>

yml配置文件

 

server:
  port: 58888
  servlet:
    encoding:
      charset: UTF-8
      enabled: true
      force: true

spring:
  application:
    name: mcp
  ai:
    dashscope:
      api-key: sk-xoxoxoxoxoxox
    mcp:
      client:
        sse:
          connections:
            server1:
              url: http://localhost:58080
            server2:
              url: http://localhost:38080
  mandatory-file-encoding: UTF-8

# 调试日志
logging:
  level:
    io:
      modelcontextprotocol:
        client: DEBUG
        spec: DEBUG

 

百度翻译controller

package org.springframework.ai.mcp.samples.client.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/translate")
public class McpTranslateController {

    private final ChatClient dashScopeChatClient;
    private final ToolCallbackProvider tools;


    public McpTranslateController(ChatClient.Builder chatClientBuilder, ToolCallbackProvider tools) {
        this.tools = tools;
        this.dashScopeChatClient = chatClientBuilder
                .build();
    }


    /**
     * 无工具版
     */
    @GetMapping("/chat")
    public String simpleChat(@RequestParam(value = "query", defaultValue = "帮我把以下内容翻译成英文:寻寻觅觅") String query) {
        return dashScopeChatClient.prompt(query).call().content();
    }

    /**
     * 调用工具版 - function
     */
    @GetMapping("/chat-mcp")
    public String chatTranslateFunction(@RequestParam(value = "query", defaultValue = "帮我把以下内容翻译成英文:寻寻觅觅") String query) {
        return dashScopeChatClient.prompt(query).tools(tools).call().content();
    }


}

 

天气查询 controller

package org.springframework.ai.mcp.samples.client.controller;



import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/weather")
public class McpWeatherController {

    private final ChatClient dashScopeChatClient;
    private final ToolCallbackProvider tools;

    public McpWeatherController(ChatClient.Builder chatClientBuilder, ToolCallbackProvider tools) {
//        使用方式只需注入ToolCallbackProvider和ChatClient.Builder
        this.tools = tools;
        this.dashScopeChatClient = chatClientBuilder
                .build();
    }


    /**
     * 调用工具版 - function
     */
    @GetMapping("/chat-mcp")
    public String chatMcp(@RequestParam(value = "query", defaultValue = "请告诉我北京1天以后的天气",required = false) String query) {
        System.out.println("\n>>> QUESTION: " + query);
        String msg = dashScopeChatClient.prompt(query).tools(tools).call().content();
        System.out.println("\n>>> ASSISTANT: " + msg);
        return msg;
    }

    @GetMapping("/chat")
    public String chat(@RequestParam(value = "query", defaultValue = "请告诉我北京1天以后的天气",required = false) String query) {
        System.out.println("\n>>> QUESTION: " + query);
        String msg = dashScopeChatClient.prompt(query).call().content();
        System.out.println("\n>>> ASSISTANT: " + msg);
        return msg;
    }


}

 

启动类

/*
 * Copyright 2025-2026 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author brianxiadong
 */
package org.springframework.ai.mcp.samples.client;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication(exclude = {
        org.springframework.ai.autoconfigure.mcp.client.SseHttpClientTransportAutoConfiguration.class
})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }


}

 

 

### Spring阿里MCPAI应用程序中的集成 Spring框架及其生态系统提供了丰富的工具集来构建分布式微服务架构,而阿里MCP(Microservice Control Plane)则专注于为企业提供全面的服务治理能力。两者结合可以显著提升AI应用开发效率和服务质量。 #### 使用Spring Boot简化AI应用开发 通过Spring Boot自动配置特性,开发者能够快速搭建起基于Java的应用程序骨架结构[^1]。对于机器学习模型部署而言,这意味着更少的手动设置工作量以及更高的灵活性: ```java @SpringBootApplication public class AiApplication { public static void main(String[] args) { SpringApplication.run(AiApplication.class, args); } } ``` #### 利用Alibaba Cloud MCP实现高效服务管理 针对大规模生产环境下的复杂需求场景,借助于阿里MCP所提供的流量控制、熔断降级等功能模块,可有效保障线上业务稳定运行的同时支持弹性伸缩机制[^2]。具体到AI领域,则体现在以下几个方面: - **灰度发布**:允许新版本逐步替换旧版API接口,在不影响现有用户体验的前提下完成迭代升级; - **限流策略**:防止突发请求洪峰冲击导致系统崩溃,特别适用于预测类高并发调用场合; - **链路追踪**:配合Jaeger/Zipkin等开源组件记录每一次跨服务交互过程,便于定位性能瓶颈并优化整体响应时间; #### 实现端到端的安全性和可观测性 为了确保整个系统的安全性及透明度,建议采用如下措施加强防护力度: - 集成OAuth2.0认证授权协议保护敏感数据访问权限; - 开启日志审计功能跟踪异常行为模式变化趋势; - 结合Prometheus+Grafana监控平台实时展示各项指标状态图表。 综上所述,利用Spring生态体系搭配阿里MCP不仅能满足现代企业对智能化转型过程中提出的多样化诉求,而且有助于打造更加健壮可靠的云端基础设施底座。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非ban必选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值