AI摘要

阿里大模型(通义千问)Java对接最简方案,适用于快速在Java本地/服务端调用通义千问系列模型进行对话生成。
适用场景:快速在 Java 本地/服务端调用通义千问系列模型进行对话生成。
适合人群:熟悉 Spring Boot/RestTemplate 的 Java 开发者或技术爱好者。
建议先看:实践三(RESTful API 设计原则)。
你将收获:最小可运行的文本对话/流式对话/图片生成调用,含代理与安全要点。

1. 准备工作

创建RestTemplate(安全与代理)

@Bean("aliAiHttpClient")
public RestTemplate aliRestTemplate(RestTemplateBuilder builder) {
    ClientHttpRequestInterceptor authInterceptor = (request, body, execution) -> {
        request.getHeaders().setBearerAuth(System.getenv("ALI_API_KEY"));
        return execution.execute(request, body);
    };
    RestTemplate restTemplate = builder
            .connectTimeout(Duration.ofSeconds(10))
            .readTimeout(Duration.ofSeconds(60))
            .additionalInterceptors(authInterceptor)
            .build();

    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    // 设置代理(以 http://127.0.0.1:7890 为例)
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
    factory.setProxy(proxy);
    restTemplate.setRequestFactory(factory);

    return restTemplate;
}

获取模型

public List getModel() {
    List<Map<String, String>> modelList = new ArrayList<>();

    Map<String, String> model = new HashMap<>();
    model.put("id", "qwen-plus");
    modelList.add(model);

    model = new HashMap<>();
    model.put("id", "qwen-image");
    modelList.add(model);

    return modelList;
}

文字聊天

public Map chat(String model, String message) throws JsonProcessingException {
    HttpHeaders headers = new HttpHeaders();
    Map param = new HashMap();
    param.put("model", model);
    Map messageMap = new HashMap();
    messageMap.put("role", "user");
    messageMap.put("content", message);
    param.put("messages", List.of(messageMap));
    HttpEntity<Map> entity = new HttpEntity<>(param, headers);
    ResponseEntity<String> exchange = restTemplate.exchange("https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
            HttpMethod.POST,
            entity,
            String.class);

    return objectMapper.readValue(exchange.getBody(), Map.class);
}

文字聊天 SSE

    public void chatStream(String model, String message, Consumer<String> onDelta) throws JsonProcessingException {
        String url = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions";

        Map<String, Object> body = new HashMap<>();
        body.put("model", model);
        body.put("stream", true);
        Map messageMap = new HashMap();
        messageMap.put("role", "user");
        messageMap.put("content", message);
        body.put("messages", List.of(messageMap));

        RequestCallback requestCallback = request -> {
            request.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            byte[] json = objectMapper.writeValueAsBytes(body);
            StreamUtils.copy(json, request.getBody());
        };

        ResponseExtractor<Void> responseExtractor = response -> {
            try (InputStream in = response.getBody();
                 BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    log.info("chatStream,{}", line);
                    if (!line.startsWith("data:")) {
                        continue; // 忽略注释或空行
                    }
                    try {
                        String data = line.substring("data:".length()).trim();
                        if ("[DONE]".equals(data)) {
                            break;
                        }
                        Map map = objectMapper.readValue(data, Map.class);
                        List choices = (List) map.get("choices");
                        if (choices != null && !choices.isEmpty()) {
                            for (Object choice : choices) {
                                Map choiceMap = (Map) choice;
                                Map delta = (Map) choiceMap.get("delta");
                                String content = delta.get("content").toString();
                                if (content != null && !content.isEmpty()) {
                                    onDelta.accept(content);
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }

                }
            }
            return null;
        };

        restTemplate.execute(url, HttpMethod.POST, requestCallback, responseExtractor);
    }

控制器

@PostMapping(value ="/chat/stream",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter chatStream(@RequestBody Map<String, String> param, HttpServletResponse response) throws JsonProcessingException {
    String model;
    if (param.get("model") != null) {
        model = param.get("model");
    } else {
        model = "";
    }
    String message;
    if (param.get("message") != null) {
        message = param.get("message");
    } else {
        message = "";
    }

    SseEmitter emitter = new SseEmitter(0L); // 0 表示不超时;可按需设置毫秒
    CompletableFuture.runAsync(() -> {
        try {
            aliAiService.chatStream(model, message, delta -> {
                try {
                    emitter.send(SseEmitter.event().name("delta").data(delta));
                } catch (IOException e) {
                    emitter.completeWithError(e);
                }
            });
            // 上游完成
            emitter.send(SseEmitter.event().name("done").data("[DONE]"));
            emitter.complete();
        } catch (Exception ex) {
            emitter.completeWithError(ex);
        }
    });
    return emitter;
}

生成图片

public Map generateImageUrl(String model, String prompt, String size) throws JsonProcessingException {
    HttpHeaders headers = new HttpHeaders();
    Map body = new HashMap();
    body.put("model", model);

    Map input = new HashMap();
    Map message = new HashMap();
    message.put("role", "user");
    message.put("content", List.of(Map.of("text", prompt)));
    input.put("messages", List.of(message));

    body.put("input", input);

    body.put("parameters", Map.of("negative_prompt", "", "prompt_extend", true, "watermark", true, "size", size));

    HttpEntity<Map> entity = new HttpEntity<>(body, headers);
    ResponseEntity<String> exchange = restTemplate.exchange("https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation",
            HttpMethod.POST,
            entity,
            String.class);

    return objectMapper.readValue(exchange.getBody(), Map.class);
}

控制器

@PostMapping("/image/url")
public Map imageUrl(@RequestBody Map<String, String> param) throws JsonProcessingException {
    String model = param.getOrDefault("model", "qwen-image");
    String prompt = param.getOrDefault("prompt", "");
    String size = param.getOrDefault("size", "1328*1328");
    return aliAiService.generateImageUrl(model, prompt, size);
}
最后修改:2025 年 09 月 18 日
如果觉得我的文章对你有用,请随意赞赏
END
本文作者:
文章标题:软件工程实践六:阿里大模型(通义千问)Java 对接最简方案
本文地址:https://blog.ybyq.wang/archives/1116.html
版权说明:若无注明,本文皆Xuan's blog原创,转载请保留文章出处。