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

Spring Boot REST接口返回JSONObject报错:No converter found

解决Spring Boot返回org.json.JSONObject时的转换器错误

嘿,我来帮你搞定这个问题!你碰到的No converter found for return value of type: class org.json.JSONObject错误,核心原因很简单:Spring MVC默认的消息转换器不支持把org.json.JSONObject序列化成HTTP响应体。Spring Boot默认用Jackson处理JSON序列化,但Jackson只对自己的JsonNode、标准POJO、Map这些类型友好,org.json.JSONObject不在它的默认支持列表里。

下面给你几个实用的解决方案,按推荐程度排序:

方案1:直接返回Product POJO(最推荐)

这是最规范简洁的方式,Spring Boot能自动把POJO转成JSON,完全不用手动折腾JSONObject。

修改你的方法返回类型为Product,直接返回实例就行:

@GetMapping("/products/{id}") // 假设这是你的Controller方法注解
public Product getProductById(@PathVariable String id){
    // 省略Elasticsearch查询的前置逻辑...
    Product product = null;
    SearchHit[] searchHits = searchResponse.getHits().getHits();
    for (SearchHit hit : searchHits) {
        Map<String, Object> sourceAsMap = hit.getSourceAsMap();
        product = new Product();
        product.setName(sourceAsMap.get("name").toString());
        // 记得补充其他字段的赋值哦
    }
    return product; // 直接返回POJO,Spring会自动帮你转成JSON
}

方案2:返回Map<String, Object>

如果暂时不想用POJO,直接返回从Elasticsearch拿到的sourceAsMap也可以,Spring同样能自动把它序列化成JSON:

public Map<String, Object> getProductById(String id){
    // 查询逻辑...
    for (SearchHit hit : searchHits) {
        return hit.getSourceAsMap(); // 直接返回原始的字段映射
    }
    return Collections.emptyMap(); // 处理没有找到产品的情况
}

方案3:配置支持org.json.JSONObject的消息转换器

如果你非要用org.json.JSONObject,那可以自定义一个消息转换器,让Spring认识它:

创建一个配置类:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new JSONObjectHttpMessageConverter());
    }

    static class JSONObjectHttpMessageConverter extends AbstractHttpMessageConverter<JSONObject> {
        public JSONObjectHttpMessageConverter() {
            super(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8);
        }

        @Override
        protected boolean supports(Class<?> clazz) {
            return JSONObject.class.isAssignableFrom(clazz);
        }

        @Override
        protected JSONObject readInternal(Class<? extends JSONObject> clazz, HttpInputMessage inputMessage) throws IOException {
            String json = StreamUtils.copyToString(inputMessage.getBody(), StandardCharsets.UTF_8);
            return new JSONObject(json);
        }

        @Override
        protected void writeInternal(JSONObject jsonObject, HttpOutputMessage outputMessage) throws IOException {
            outputMessage.getBody().write(jsonObject.toString().getBytes(StandardCharsets.UTF_8));
        }
    }
}

顺便给你的代码提几个小优化

另外,我注意到你代码里有冗余的GetRequest逻辑(已经用SearchRequest根据_id查询了),可以删掉这部分;还有异常处理别只调用e.getLocalizedMessage(),最好把完整的异常栈打出来,方便排查问题:

// 优化后的异常处理
try {
    searchResponse = restHighLevelClient.search(searchRequest);
    logger.info("response ---->"+searchResponse);
} catch (IOException e) {
    logger.error("Failed to search product by id: {}", id, e); // 记录完整异常信息
    throw new RuntimeException("Failed to fetch product", e); // 抛出异常让Spring统一处理
}

内容的提问来源于stack exchange,提问作者Karthikeyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:50:34