JAX-RS 2.0服务嵌套未知类型列表序列化问题求助
解决JAX-RS返回未知类型对象列表的序列化问题
这个问题我之前也碰到过!核心原因是JAX-RS的序列化器没办法自动识别你列表里的具体对象类型,只能把它们当成Object处理,所以才输出了对象toString()的结果。下面给你两种通用的解决方案,都不依赖特定应用服务器:
前提:改造Wrapper为泛型类
首先需要把你的WrapperClass改成泛型类,这样才能在运行时保留列表元素的类型信息:
public class WrapperClass<T> { private List<T> objects; // Getter和Setter public List<T> getObjects() { return objects; } public void setObjects(List<T> objects) { this.objects = objects; } }
方案一:用GenericEntity结合动态参数化类型
这个方案完全基于JAX-RS标准API,通过手动构建参数化类型,让序列化器识别列表元素的具体类型:
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.Response; @GET @Path("{entity}") public Response find(@PathParam("entity") String entity) { Class<?> clazz = someMethod(entity); List<?> list = someMethod(clazz); // 创建泛型Wrapper实例 WrapperClass<?> wrapper = new WrapperClass<>(); wrapper.setObjects(list); // 手动构建ParameterizedType,明确Wrapper的泛型参数为当前clazz ParameterizedType wrapperType = new ParameterizedType() { @Override public Type[] getActualTypeArguments() { return new Type[]{clazz}; } @Override public Type getRawType() { return WrapperClass.class; } @Override public Type getOwnerType() { return null; } }; // 用GenericEntity包装Wrapper,传递类型信息给序列化器 GenericEntity<?> genericEntity = new GenericEntity<>(wrapper, wrapperType); return Response.ok().entity(genericEntity).build(); }
方案二:手动用Jackson ObjectMapper序列化
如果你的项目已经依赖Jackson(Glassfish 4.1默认自带Jackson作为JSON序列化器),这种方式更直观,直接告诉序列化器要处理的对象类型:
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @GET @Path("{entity}") public Response find(@PathParam("entity") String entity) { Class<?> clazz = someMethod(entity); List<?> list = someMethod(clazz); WrapperClass<?> wrapper = new WrapperClass<>(); wrapper.setObjects(list); ObjectMapper mapper = new ObjectMapper(); // 构建Wrapper的泛型类型,指定列表元素为clazz Type wrapperType = TypeFactory.defaultInstance() .constructParametricType(WrapperClass.class, clazz); try { String json = mapper.writerFor(wrapperType).writeValueAsString(wrapper); return Response.ok(json, MediaType.APPLICATION_JSON).build(); } catch (JsonProcessingException e) { // 处理序列化异常,返回错误响应 return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("序列化失败:" + e.getMessage()) .build(); } }
两种方案都能实现你想要的输出格式:
{ "objects": [ {"name":"goofy"}, {"name":"mickey"} ] }
内容的提问来源于stack exchange,提问作者luca.vercelli
相关产品推荐
相关产品推荐

