Jackson枚举反序列化异常:无法将字符串"E"转为ForecastType
问题分析与解决方案
从报错信息看,Jackson在反序列化时仍在尝试用枚举的名称(如SPECIAL_EVENT)匹配输入值"E",而非你自定义的映射关系。本地测试正常但部署到WebLogic后失效,核心原因大概率是WebLogic 12c自带的Jackson版本与项目打包的Jackson 2.14.1冲突,WebLogic优先加载了自带的旧版本Jackson,导致你添加的@JsonCreator、@JsonProperty注解不生效。
以下是针对性的解决步骤:
1. 强制WebLogic优先加载项目中的Jackson包
WebLogic默认会优先使用自身内置的类库,你需要在项目的weblogic.xml中配置类加载优先级,让项目的Jackson包先被加载:
<wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.7/weblogic-web-app.xsd"> <wls:container-descriptor> <wls:prefer-application-packages> <!-- 指定所有Jackson相关包优先使用项目中的版本 --> <wls:package-name>com.fasterxml.jackson.*</wls:package-name> </wls:prefer-application-packages> </wls:container-descriptor> </wls:weblogic-web-app>
将这个配置文件放在项目的WEB-INF目录下,重新打包部署。
2. 确认项目打包包含完整的Jackson 2.14.1依赖
替换jackson-all-1.9.10.jar后,需要确保项目中包含Jackson 2.x的三个核心包:
jackson-core-2.14.1.jarjackson-databind-2.14.1.jarjackson-annotations-2.14.1.jar
检查Ant构建脚本,确认这三个包都被正确打包到WEB-INF/lib中,且版本一致,没有混入旧版本的Jackson包。
3. 显式配置Spring的ObjectMapper
确保Spring使用你自定义配置的ObjectMapper,避免被WebLogic或Spring默认的ObjectMapper覆盖。可以在Spring配置类中添加如下Bean:
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.ba.schema.revman.dmdfcstrestservicev01.nsdandfopv01.ForecastType; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; @Primary @Bean public ObjectMapper customObjectMapper() { ObjectMapper mapper = new ObjectMapper(); // 关闭默认的枚举按名称反序列化行为 mapper.disable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); // 注册自定义的ForecastType反序列化器 SimpleModule module = new SimpleModule(); module.addDeserializer(ForecastType.class, (parser, context) -> { String inputValue = parser.getText(); return java.util.Arrays.stream(ForecastType.values()) .filter(type -> type.getValue().equals(inputValue)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("无效的forecastType值: " + inputValue)); }); mapper.registerModule(module); return mapper; }
@Primary注解确保这个ObjectMapper被Spring优先使用。
4. 验证SOAP请求的正确性
最后确认SOAP请求中的forecastType字段值确实是纯字符串"E",没有多余的空格、转义字符或大小写错误(比如小写"e")。
内容的提问来源于stack exchange,提问作者Mounika
相关产品推荐
相关产品推荐

