如何将Spring中@ExceptionMapper返回的PojoA转换为PojoB以输出不同格式的响应
如何将Spring中@ExceptionMapper返回的PojoA转换为PojoB以输出不同格式的响应
嘿,这个需求我之前也碰到过,给你几个实用的思路,你可以根据项目的实际情况来选:
方案一:直接在@ExceptionMapper里转换(最直观)
如果你的@ExceptionMapper数量不多,直接在每个Mapper里完成转换是最省心的。先写个通用的转换工具类(比如用MapStruct、ModelMapper,或者自己写简单的get/set映射),然后在原来返回PojoA的地方,先转成PojoB再返回。
示例代码:
@Provider public class CustomExceptionMapper implements ExceptionMapper<CustomException> { @Override public Response toResponse(CustomException exception) { // 原来生成PojoA的逻辑 PojoA pojoA = buildErrorResponse(exception); // 转换为PojoB PojoB pojoB = PojoConverter.convertAtoB(pojoA); return Response.status(Response.Status.BAD_REQUEST) .entity(pojoB) .build(); } }
方案二:用MessageBodyWriter统一处理序列化逻辑
要是不想逐个修改@ExceptionMapper,可以自定义一个MessageBodyWriter,当系统要序列化PojoA为JSON时,自动把它转换成PojoB再输出。这样所有返回PojoA的场景(包括异常映射)都会被统一处理。
示例代码:
@Provider @Produces(MediaType.APPLICATION_JSON) public class PojoAtoBWriter implements MessageBodyWriter<PojoA> { @Override public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return PojoA.class.isAssignableFrom(type); } @Override public void writeTo(PojoA pojoA, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException { // 转换PojoA到PojoB PojoB pojoB = PojoConverter.convertAtoB(pojoA); // 用Jackson序列化PojoB到输出流 new ObjectMapper().writeValue(entityStream, pojoB); } }
方案三:用响应拦截器统一替换实体
还可以通过ContainerResponseFilter在响应发送给客户端之前,拦截并替换响应里的实体。只要检测到实体是PojoA,就换成PojoB,同样能实现全局统一处理。
示例代码:
@Provider public class PojoAResponseFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { Object entity = responseContext.getEntity(); if (entity instanceof PojoA) { PojoA pojoA = (PojoA) entity; PojoB pojoB = PojoConverter.convertAtoB(pojoA); responseContext.setEntity(pojoB); } } }
小提示
- 转换工具类可以用MapStruct这类框架自动生成,避免手动写大量get/set代码,减少出错概率;
- 不管用哪种方案,要确保自定义的Provider类被Spring扫描到,或者手动注册到JAX-RS的配置中。
备注:内容来源于stack exchange,提问作者szymon_prz
相关产品推荐
相关产品推荐

