Java后端接收Angular请求时JSONObject映射UnrecognizedPropertyException如何解决
你的判断是对的,问题核心是Jackson默认不支持org.json.JSONObject类型的序列化/反序列化:当前端发送的JSON请求到达后端时,Jersey用Jackson把请求体映射成Watchlist对象,遇到JSONObject类型的watchlist字段时,Jackson会尝试把JSON里的键值对映射为JSONObject类的JavaBean属性,但JSONObject本身没有对应的getter/setter,也没有配置Jackson的映射规则,所以直接抛出无法识别字段的异常。
方案1:改用
Map<String, Object>(最便捷,推荐新手使用)
直接把后端Watchlist类的watchlist字段类型替换为Map<String, Object>,Jackson天生支持Map类型的序列化和反序列化,完全满足你用isin作为键存储投资的需求。修改后的代码如下:public class Watchlist { private int id; private int userid; private Map<String, Object> watchlist; // 补充对应getter、setter }存数据库的时候直接把Map转成JSON字符串即可,比如用Jackson的ObjectMapper:
// 类中初始化ObjectMapper private ObjectMapper objectMapper = new ObjectMapper(); @PUT @Path("updateWatchlist") @Consumes({MediaType.APPLICATION_JSON}) public void updateWatchlist(Watchlist watchlist){ try { String sql = "UPDATE watchlistdb set watchlist=? where id=?"; PreparedStatement ps = DatabaseHelper.connectDatabase().prepareStatement(sql); // 把Map转成JSON字符串存入数据库 ps.setString(1, objectMapper.writeValueAsString(watchlist.getWatchlist())); ps.setInt(2,watchlist.getId()); ps.execute(); } catch (Exception e){ e.printStackTrace(); } }前端代码不需要做任何修改。
方案2:保留JSONObject,添加Jackson适配模块
如果你一定要用org.json.JSONObject,可以引入Jackson对org.json类型的支持模块,Maven依赖示例如下:<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-json-org</artifactId> <version>和你项目的Jackson核心版本保持一致即可</version> </dependency>然后把
JsonOrgModule注册到项目的ObjectMapper全局配置中,Jackson就可以正常序列化和反序列化JSONObject,不需要修改其他业务代码。方案3:强类型实体优化(更规范,适合长期维护)
直接定义投资对应的Java实体类Investment,把watchlist字段的类型改为Map<String, Investment>,相比Map<String, Object>和JSONObject的弱类型写法,类型更安全,后续业务逻辑修改也更容易排查问题。
内容的提问来源于stack exchange,提问作者JSar

