Spring API接收/返回JSONObject问题求助(org.json库约束)
解决Spring API中使用org.json库的两个核心问题
我来帮你搞定这两个和org.json库相关的Spring API问题,咱们一步步拆解:
问题1:直接接收JSONObject得到空对象的原因及解决
Spring MVC默认用Jackson处理JSON的序列化/反序列化,但org.json.JSONObject并没有被Jackson原生支持——Jackson不知道如何把请求体的JSON字符串转换成org.json.JSONObject实例,所以你直接用@RequestBody JSONObject data时会得到空对象。
解决方案:自定义Jackson反序列化器
我们需要给Jackson写一个专门的反序列化器,让它能正确将请求体转成org.json.JSONObject:
- 创建反序列化器类
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import org.json.JSONObject; import java.io.IOException; public class JSONObjectDeserializer extends JsonDeserializer<JSONObject> { @Override public JSONObject deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { // 先把请求体转成JSON字符串,再实例化org.json.JSONObject String jsonString = jsonParser.readValueAsTree().toString(); return new JSONObject(jsonString); } }
- 配置Jackson加载这个反序列化器
创建一个Spring配置类,把反序列化器注册到Jackson的ObjectMapper中:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import org.json.JSONObject; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); // 注册JSONObject的反序列化器 module.addDeserializer(JSONObject.class, new JSONObjectDeserializer()); objectMapper.registerModule(module); return objectMapper; } }
配置完成后,你Controller里的/test、/testjson等接口就能直接接收JSONObject且不会为空了。
问题2:返回JSONObject的正确方式
同样,Jackson默认无法正确序列化org.json.JSONObject为响应JSON,我们需要再加一个自定义序列化器:
- 创建序列化器类
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import org.json.JSONObject; import java.io.IOException; public class JSONObjectSerializer extends JsonSerializer<JSONObject> { @Override public void serialize(JSONObject jsonObject, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { // 直接输出JSONObject的字符串形式,保证响应格式正确 jsonGenerator.writeRawValue(jsonObject.toString()); } }
- 把序列化器也注册到Jackson配置中
修改刚才的JacksonConfig,添加序列化器:
@Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(JSONObject.class, new JSONObjectDeserializer()); // 新增:注册JSONObject的序列化器 module.addSerializer(JSONObject.class, new JSONObjectSerializer()); objectMapper.registerModule(module); return objectMapper; }
现在你的Controller方法直接返回JSONObject就能输出正确的JSON响应了。
优化你的业务代码
调整DataService的processData方法,直接接收JSONObject:
public JSONObject processData(JSONObject jsonObject) { ObjectMapper mapper = new ObjectMapper(); mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); Data data = null; try { data = mapper.readValue(jsonObject.toString(), Data.class); } catch (IOException e) { e.printStackTrace(); } // 原有的数据处理逻辑不变... try { Response response = call.execute(); String result = response.body().string(); System.out.println(result); JSONObject json = new JSONObject(result); System.out.println(json); return json; } catch (IOException | JSONException e) { e.printStackTrace(); } return null; }
对应的Controller接口也可以改成直接接收JSONObject:
@RequestMapping(method = RequestMethod.POST, value = "/timeseries") public JSONObject proccessAtosData(@RequestBody JSONObject data) { return dataservice.processData(data); }
最后确认依赖
确保你项目中引入了正确的org.json依赖(以Maven为例):
<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20240303</version> <!-- 使用最新稳定版 --> </dependency>
内容的提问来源于stack exchange,提问作者ahmed benhmouda
相关产品推荐
相关产品推荐

