如何不修改OpenAPI Generator生成代码 覆写JAX-RS ContextResolver Provider
多个同类型JAX-RS Provider的加载规则
当存在多个实现了相同接口的Provider时,JAX-RS的选择逻辑遵循以下优先级:
- 第一优先级:
@Priority注解的数值,数值越小优先级越高。未显式指定注解的Provider默认优先级为Priorities.USER(常量值为5000) - 第二优先级:媒体类型匹配,若Provider声明了
@Produces/@Consumes注解,会优先匹配和当前请求/响应媒体类型相符的Provider - 兜底规则:如果前两个条件都完全一致,Provider的选择取决于JAX-RS实现的类扫描顺序,该逻辑没有统一标准,不可靠。
覆盖自动生成Provider的方法
你完全可以不用修改生成的代码,只需要给自定义的Provider加上更高优先级的@Priority注解即可,调整后的代码如下:
package xxx.service.util; import javax.annotation.Priority; import javax.ws.rs.Priorities; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @Provider @Priority(Priorities.USER - 100) // 优先级高于默认的5000,会优先被选择 public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> { private final ObjectMapper mapper; public ObjectMapperContextResolver() { this.mapper = createObjectMapper(); } @Override public ObjectMapper getContext(Class<?> type) { return mapper; } private ObjectMapper createObjectMapper() { ObjectMapper mapper = new ObjectMapper(); // 可选:如果需要保留生成代码中的时间处理规则,保留下方两行配置,注意导入对应RFC3339DateFormat包 // mapper.registerModule(new JavaTimeModule()); // mapper.setDateFormat(new RFC3339DateFormat()); // 你的自定义配置 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); return mapper; } }
异常排查
如果调整优先级后还是不生效,请检查:
- 自定义Provider所在的
xxx.service.util包已经被纳入JAX-RS的组件扫描范围,或者你已经在Application/ResourceConfig中显式注册了该类 - 项目中没有其他优先级更高的
ContextResolver<ObjectMapper>实现被注册
内容的提问来源于stack exchange,提问作者Ziqi Liu
相关产品推荐
相关产品推荐

