使用Jersey REST Webtarget API POST JSON对象列表报MessageBodyWriter错误如何解决?
报错原因
- 核心触发原因是Java泛型的类型擦除机制:运行时Jersey无法从直接传入的
List<User>实例中获取到泛型实参User的类型信息,只能识别到原始类型java.util.ArrayList,已注册的JSON序列化MessageBodyWriter无法匹配到对应泛型集合的序列化规则,因此抛出该异常。
解决方案
提供两种可落地的方案:
方案1:使用GenericEntity包装泛型集合(推荐,无需调整后端接口)
Jersey自带的GenericEntity可以保留运行时泛型类型信息,是处理泛型参数序列化的标准方案,代码示例如下:
// 构造GenericEntity时通过匿名子类保留List<User>的泛型类型信息 GenericEntity<List<User>> userListEntity = new GenericEntity<List<User>>(users) {}; Entity<GenericEntity<List<User>>> body = Entity.json(userListEntity); Response response = webTarget .path("/multipleusers") .request(MediaType.APPLICATION_JSON) .post(body);
注意:构造GenericEntity时必须追加尾部的{}生成匿名子类,否则依然会丢失泛型类型信息。
方案2:自定义包装类封装列表
如果不方便使用GenericEntity,可以新增一个简单的POJO包装类包裹列表,明确类型信息避免擦除问题:
- 定义包装类:
public class UserBatchRequest { private List<User> userList; // 必须保留无参构造方法 public UserBatchRequest() {} public UserBatchRequest(List<User> userList) { this.userList = userList; } // getter、setter方法省略 }
- 调整请求代码:
Entity<UserBatchRequest> body = Entity.json(new UserBatchRequest(users)); Response response = webTarget .path("/multipleusers") .request(MediaType.APPLICATION_JSON) .post(body);
注意:使用该方案需要同步调整后端接口的参数接收结构,对应接收UserBatchRequest类型的参数。
内容的提问来源于stack exchange,提问作者dezenstigar
相关产品推荐
相关产品推荐

