Spring-ai-alibaba文生图
文章目录
- Spring AI Alibaba 图像模型实战(文生图)
- 版本
- 一、依赖引入
- 二、yml 配置
- 三、代码案例
- 1. 控制器:注入 ImageModel,三种接口
- 2.(可选)图片未完成时的重试
Spring AI Alibaba 图像模型实战(文生图)
用 Spring AI Alibaba 接入阿里云百炼 DashScope,完成「文字 → 图片」。
版本
- Spring Boot:
3.4.5 - spring-ai-alibaba-starter-dashscope:
1.0.0.4 - Java:
17
Spring-ai更新速度快,请以官方为准
可参考网址:
- Spring-ai官网
- Spring-ai阿里巴巴
- 阿里百炼模型广场
- 开发者指南(API/SDK)
一、依赖引入
<!-- Spring Web,提供 REST 接口 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring AI Alibaba:自动装配 DashScopeImageModel --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId><version>1.0.0.4</version></dependency><!-- 官方 DashScope SDK(部分场景会用到) --><dependency><groupId>com.alibaba</groupId><artifactId>dashscope-sdk-java</artifactId><version>2.22.18</version></dependency>二、yml 配置
# 复制为 application.yaml;密钥用环境变量,不要写死在仓库里spring:application:name:spring-image-demoai:dashscope:# IDEA Run Configuration → Environment:DASHSCOPE_API_KEY=sk-xxxapi-key:${DASHSCOPE_API_KEY}image:options:# DashScopeImageModel 兼容的万相文生图模型# 不要用 qwen-image-* 等多模态同步模型,会报 url error / 400model:wanx2.1-t2i-turbo启动前设置环境变量:
$env:DASHSCOPE_API_KEY="你的百炼API Key"三、代码案例
1. 控制器:注入 ImageModel,三种接口
@RestController@RequestMapping("/example")publicclassDashScopeImageController{/** 由 starter 自动配置注入(底层是 DashScopeImageModel) */privatefinalImageModelimageModel;privatestaticfinalStringDEFAULT_PROMPT="为人工智能生成一张富有科技感的图片!";publicDashScopeImageController(ImageModelimageModel){this.imageModel=imageModel;}/** * 最简文生图:用默认 prompt 生成一张图,把远端 URL 的字节写回浏览器。 * GET /example/image */@GetMapping("/image")publicvoidimage(HttpServletResponseresponse){// 1)构造 ImagePrompt(只有提示词,模型走 yml 默认配置)ImageResponseimageResponse=imageModel.call(newImagePrompt(DEFAULT_PROMPT));// 2)异步任务完成后,结果里一般是临时图片 URLStringimageUrl=imageResponse.getResult().getOutput().getUrl();try{// 3)服务端打开 URL,把 PNG 字节写给前端(浏览器直接显示图片)URLurl=URI.create(imageUrl).toURL();InputStreamin=url.openStream();response.setHeader("Content-Type",MediaType.IMAGE_PNG_VALUE);response.getOutputStream().write(in.readAllBytes());response.getOutputStream().flush();}catch(IOExceptione){response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);}}/** * 同一 prompt 生成多张图,返回 URL 集合。 * GET /example/image/multiPrompt?prompt=一只会编程的猫&count=2 */@GetMapping("/image/multiPrompt")publicResponseEntity<Collection<String>>generateImageWithMultiPrompt(@RequestParam(value="prompt",defaultValue="一只会编程的猫")Stringprompt,@RequestParam(defaultValue="2")intcount){// N:一次要几张图ImageOptionsoptions=ImageOptionsBuilder.builder().N(count).build();ImageResponseresponse=imageModel.call(newImagePrompt(prompt,options));// 每张结果取 URL,收集成 SetSet<String>imageSet=response.getResults().stream().map(result->result.getOutput().getUrl()).collect(Collectors.toSet());returnResponseEntity.ok(imageSet);}/** * 多条件拼 prompt + 宽高。 * GET /example/image/multipleConditions?subject=猫&environment=办公室&style=生动 */@GetMapping("/image/multipleConditions")publicResponseEntity<?>multipleConditions(@RequestParam(value="subject",defaultValue="一只会编程的猫")Stringsubject,@RequestParam(value="environment",defaultValue="办公室")Stringenvironment,@RequestParam(value="height",defaultValue="1024")Integerheight,@RequestParam(value="width",defaultValue="1024")Integerwidth,@RequestParam(value="style",defaultValue="生动")Stringstyle){// 把多个参数拼成一句完整提示词Stringprompt=String.format("一个%s,置身于%s的环境中,使用%s的艺术风格,高清4K画质,细节精致",subject,environment,style);ImageOptionsoptions=ImageOptionsBuilder.builder().height(height).width(width).build();try{ImageResponseresponse=imageModel.call(newImagePrompt(prompt,options));// 成功时直接返回图片 URL 字符串returnResponseEntity.ok(response.getResult().getOutput().getUrl());}catch(Exceptione){// 失败时返回 JSON 错误信息,避免空白 500returnResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("error","图像生成失败","message",e.getMessage(),"timestamp",LocalDateTime.now()));}}}2.(可选)图片未完成时的重试
万相文生图是异步任务。旧版在 pending 时可能抛RuntimeException,默认 Retry 可能不够。可提供自定义RetryTemplate:
@ConfigurationpublicclassImageRetryConfig{@Bean@PrimaryRetryTemplateimageRetryTemplate(){returnRetryTemplate.builder().maxAttempts(30)// 最多重试次数// 初始间隔 2s,倍率 1.5,上限 15s.exponentialBackoff(Duration.ofSeconds(2),1.5,Duration.ofSeconds(15)).retryOn(RuntimeException.class).build();}}注意:HTTP 401(Key 无效)、400(参数错误)属于不可恢复错误,靠加长重试解决不了。
