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

JDK8+WebLogic14c迁移后自定义JacksonContextResolver失效求助

解决WebLogic14c中自定义JacksonContextResolver失效问题

问题背景

将Web应用从JDK1.7+WebLogic12c迁移至JDK1.8+WebLogic14c后,原自定义的JacksonContextResolver(用于配置JSON映射)完全失效,JSON返回的日期格式变为yyyy-MM-ddTHH:mm:ss.SSSZ [UTC],导致REST服务调用出现类型不匹配错误。此前在WebLogic12c环境中,依赖包打包在应用内,Resolver可正常工作;现在将JAX-RS/Jersey依赖设为provided后,推测应用使用了服务器默认的ObjectMapper。


解决方案

1. 修复自定义JacksonContextResolver代码缺陷

原代码中getContext方法直接返回null,这是导致Resolver失效的核心问题——JAX-RS要求ContextResolver必须返回配置好的ObjectMapper实例。同时优化日期时区配置逻辑:

package eu.sia.mdp.backoffice.common;

import java.text.SimpleDateFormat;
import java.util.TimeZone;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonContextResolver implements ContextResolver<ObjectMapper> {
    private final ObjectMapper objectMapper;
    
    private static final Logger log = LoggerFactory.getLogger(JacksonContextResolver.class);
    
    public JacksonContextResolver() {
        this.objectMapper = new ObjectMapper()
                .setSerializationInclusion(Include.NON_NULL)
                .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
                // 直接设置时区,替代原间接获取配置的方式
                .setTimeZone(TimeZone.getTimeZone("CET"));
        
        // 如需指定固定日期格式,取消注释并使用正确的格式字符串(注意yyyy/dd的大小写)
        // SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
        // df.setTimeZone(TimeZone.getTimeZone("CET"));
        // this.objectMapper.setDateFormat(df);
    }

    @Override
    public ObjectMapper getContext(Class<?> objectType) {
        // 返回配置好的ObjectMapper实例,而非null
        return this.objectMapper;
    }
}

2. 调整weblogic.xml配置,优先加载应用自带依赖

修改weblogic.xml的prefer-application-packages和prefer-application-resources配置,确保应用的Jersey、Jackson类优先于服务器自带类加载,同时移除服务器JAX-RS库的强制引用:

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app">

   <container-descriptor>
      <prefer-application-packages>
         <package-name>org.slf4j.*</package-name>
         <package-name>org.apache.commons.logging.*</package-name>
         <!-- 取消注释,让应用优先加载Jersey相关类 -->
         <package-name>org.glassfish.jersey.*</package-name>
         <package-name>org.glassfish.hk2.*</package-name>
         <package-name>org.jvnet.hk2.*</package-name>
         <package-name>org.objectweb.asm.*</package-name>
         <package-name>com.sun.ws.rs.ext.*</package-name>
         <!-- 添加Jackson包,确保自定义配置优先 -->
         <package-name>com.fasterxml.jackson.*</package-name>
         <package-name>javax.ws.rs.*</package-name>
         <package-name>javax.validation.*</package-name>
         <package-name>org.hibernate.validator.*</package-name>
      </prefer-application-packages>

      <prefer-application-resources>
         <resource-name>org/slf4j/impl/StaticLoggerBinder.class</resource-name>
         <resource-name>org.hibernate.validator.*</resource-name>
         <resource-name>javax.validation.*</resource-name>
         <!-- 添加Jackson资源文件 -->
         <resource-name>com/fasterxml/jackson/**</resource-name>
      </prefer-application-resources>
   </container-descriptor>

   <context-root>mdp-portale-bo</context-root>

   <!-- 移除服务器JAX-RS库引用,避免强制使用服务器默认实现 -->
   <!--
   <library-ref>
      <library-name>jax-rs</library-name>
      <specification-version>2.0</specification-version>
      <exact-match>false</exact-match>
   </library-ref>
   -->

    <resource-description>
        <res-ref-name>jdbc/MDPDB</res-ref-name>
        <jndi-name>jdbc/MDPDB</jndi-name>
    </resource-description>

</weblogic-web-app>

3. 调整web.xml配置,确保Resolver被扫描加载

如果包扫描未自动识别自定义Resolver,可直接在provider.classnames中添加其全类名,确保Jersey能加载到:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
    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"
    metadata-complete="false">

    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>eu.sia.mdp.backoffice</param-value>
        </init-param>
        <init-param>
            <param-name>jersey.config.server.provider.classnames</param-name>
            <param-value>
                com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider,
                eu.sia.mdp.backoffice.common.JacksonContextResolver
            </param-value>
        </init-param>
       <init-param>
            <param-name>jersey.config.server.tracing</param-name>
            <param-value>ALL</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    <mime-mapping>
        <extension>json</extension>
        <mime-type>application/json</mime-type>
    </mime-mapping>

    <resource-ref>
        <description>Database MP</description>
        <res-ref-name>jdbc/MPDB</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
</web-app>

4. 可选:将JAX-RS/Jersey依赖打包到应用中

若希望完全脱离WebLogic自带的JAX-RS库,可将pom.xml中相关依赖的scope从provided改为compile,让依赖打包到应用WAR包中:

<!-- JAX-RS -->
<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0.1</version>
    <scope>compile</scope>
</dependency>

<!-- Jersey相关依赖同理修改scope -->
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>${jersey.version}</version>
    <scope>compile</scope>
</dependency>

内容的提问来源于stack exchange,提问作者pietro laforgia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:20:15