You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 10:04:35