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
相关产品推荐
相关产品推荐

