You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Spring AI对接OpenRouter调用DALL-E 3生成图片时,出现HttpMessageConverter不匹配异常

使用Spring AI对接OpenRouter调用DALL-E 3生成图片时,出现HttpMessageConverter不匹配异常

看起来你遇到的问题是Spring AI在解析OpenRouter的响应时“水土不服”——它返回了text/html格式的内容,但Spring AI的OpenAI客户端默认只认application/json格式,导致找不到合适的转换器处理响应。我帮你梳理下问题根源和解决步骤:

问题根源分析

  1. API端点与格式不匹配:OpenRouter的API路径、响应规则和原生OpenAI有差异,你当前配置的base-url可能不对,且OpenRouter对请求头有额外要求(比如Referer),如果没满足会返回错误页面(也就是text/html格式的内容)。
  2. Spring AI默认转换器限制:原生的MappingJackson2HttpMessageConverter只处理application/json类型的响应,遇到text/html直接“罢工”。
  3. 模型名称可能有误:OpenRouter上调用DALL-E3需要带厂商前缀,不是单纯的dall-e-3。

一步步解决问题

1. 修正配置文件(application.properties)

调整Base URL并添加OpenRouter强制要求的请求头:

spring.application.name=ImageGenerator
spring.ai.openai.api-key=你的OpenRouter API密钥
# OpenRouter的正确v1版本Base URL
spring.ai.openai.base-url=https://openrouter.ai/api/v1
logging.level.org.springframework.ai=DEBUG
server.port=8081
# OpenRouter上的DALL-E3模型名称带前缀
spring.ai.openai.image.options.model=openai/dall-e-3
# OpenRouter要求的请求头,测试环境可以填本地地址
spring.ai.openai.image.options.headers[HTTP-Referer]=https://localhost:8081
spring.ai.openai.image.options.headers[X-Title]=ImageGeneratorDemo

2. 自定义RestTemplate处理text/html响应

创建配置类,让转换器能把text/html格式的响应当成JSON解析:

package com.image_generator.ImageGenerator;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class OpenRouterConfig {

    @Bean
    public RestTemplate openRouterRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        
        // 给JSON转换器添加text/html的支持
        List<MediaType> supportedTypes = new ArrayList<>(jsonConverter.getSupportedMediaTypes());
        supportedTypes.add(MediaType.TEXT_HTML);
        jsonConverter.setSupportedMediaTypes(supportedTypes);
        
        // 替换原有的转换器
        restTemplate.getMessageConverters().removeIf(c -> c instanceof MappingJackson2HttpMessageConverter);
        restTemplate.getMessageConverters().add(jsonConverter);
        return restTemplate;
    }
}

3. 配置适配OpenRouter的Image客户端

用更灵活的OpenAiImageClient替代OpenAiImageModel,注入自定义的RestTemplate:

package com.image_generator.ImageGenerator;

import org.springframework.ai.openai.OpenAiImageClient;
import org.springframework.ai.openai.OpenAiImageOptions;
import org.springframework.ai.openai.api.OpenAiImageApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class OpenAiImageConfig {

    @Value("${spring.ai.openai.api-key}")
    private String apiKey;

    @Value("${spring.ai.openai.base-url}")
    private String baseUrl;

    @Bean
    public OpenAiImageApi openAiImageApi(RestTemplate openRouterRestTemplate) {
        return new OpenAiImageApi(baseUrl, apiKey, openRouterRestTemplate);
    }

    @Bean
    public OpenAiImageClient openAiImageClient(OpenAiImageApi openAiImageApi) {
        return new OpenAiImageClient(openAiImageApi, OpenAiImageOptions.builder().build());
    }
}

4. 修改Controller适配新客户端

调整代码使用OpenAiImageClient,同时注意b64_json格式的返回值处理:

package com.image_generator.ImageGenerator;

import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.openai.OpenAiImageClient;
import org.springframework.ai.openai.OpenAiImageOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AIController {

    @Autowired
    private OpenAiImageClient openAiImageClient;

    @GetMapping("image/{prompt}")
    public String generateImage(@PathVariable String prompt) {
        System.out.println("prompt = " + prompt);
        try {
            ImageResponse imageResponse = openAiImageClient.call(
                    new ImagePrompt(prompt, OpenAiImageOptions.builder()
                            .responseFormat("b64_json")
                            .model("openai/dall-e-3")
                            .height(1024)
                            .quality("standard")
                            .width(1024)
                            .n(1)
                            .build())
            );
            // 注意:b64_json格式返回的是base64字符串,不是URL
            String result = imageResponse.getResult().getOutput().getB64Json();
            if (result == null) {
                result = imageResponse.getResult().getOutput().getUrl();
            }
            System.out.println("生成结果 =========== " + result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return "生成失败:" + e.getMessage();
        }
    }
}

5. 升级Spring AI版本(可选但推荐)

你的pom.xml里用的是1.0.0版本,建议升级到最新稳定版(比如1.1.4),对第三方API的兼容性更好:

<properties>
    <java.version>17</java.version>
    <spring-ai.version>1.1.4</spring-ai.version>
</properties>

最后检查点

  • 确认你的OpenRouter API密钥有效,且已经开通了DALL-E3的访问权限
  • 测试时如果还是返回text/html,大概率是请求头没设置对,重点检查HTTP-Referer

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 07:24:32