JBoss 的 EJB Jar 中忽略了 Jackson 2 注释(6.2.0 GA)

Dav*_*tor 5 java jboss spring jackson

我正在将一个 Web 应用程序从 Websphere 7 (JEE5) 迁移到 JBoss EAP 6.2.0 (JEE6)。目前它在 Glassfish 3 和 WAS 中运行良好。

Web 界面使用/生成 JSON - 因此我使用 Jackson2 和 Spring 3 MVC MappingJackson2HttpMessageConverter来处理简单控制器类中的序列化(反序列化)。

在 JBoss 中,我看到 Jackson2 注释@JsonProperty等在 ejb 模块中被忽略 - (它们仅应用于 JPA 实体),但在 Web 模块中应用因此,JBoss 中某些对象的响应会带有不同的字段名称,这会导致我们的用户界面出错。

我已经尝试了所有排列均jboss-deployment-structure.xml无济于事(见下文)。我知道 JBoss 附带 Jackson 1.x 作为内部模块。然而,这似乎不是问题,否则网络模块注释也会被忽略?例如:部署到 JBOSS 后忽略 Jackson 注释

该应用程序的结构为 3 个 Maven 模块 - war、ejb (jar) 和 Ear 容器。

我将重构代码以从 JPA 实体中删除注释,但实际上最好找到一个一致的解决方案,因为还有其他几个应用程序需要迁移。

我在下面尝试过 JBoss 描述符,没有什么区别。

<jboss-deployment-structure>
    <ear-subdeployments-isolated>false</ear-subdeployments-isolated>
    <deployment>
        <exclusions>
            <module name="org.codehaus.jackson.jackson-core-asl"/>
            <module name="org.codehaus.jackson.jackson-mapper-asl"/>
        </exclusions>
    </deployment>
    <sub-deployment name="my-war.war">
        <exclusions>
            <module name="org.codehaus.jackson.jackson-core-asl"/>
            <module name="org.codehaus.jackson.jackson-mapper-asl"/>
        </exclusions>
    </sub-deployment>
    <sub-deployment name="my-ejbs.jar">
        <exclusions>
            <module name="org.codehaus.jackson.jackson-core-asl"/>
            <module name="org.codehaus.jackson.jackson-mapper-asl"/>
        </exclusions>
    </sub-deployment>
</jboss-deployment-structure>
Run Code Online (Sandbox Code Playgroud)

初始解决方法(现已恢复)

虽然它没有解决最初的问题是由什么引起的,但我已经通过在 Web 模块中添加 Jackson Mixin 来重命名/抑制相关字段来解决这个问题。我已经测试过这个并且效果很好。

所有这一切的要点是,通过使用 Jackson Mixin,序列化的定制范围被限制在 Web 模块内,从而避免了由于ejb-jar子部署而可能出现的类加载问题。没有使用jboss-deployment-struct.xml 。

添加一个混音

public interface MyMixin {


    @JsonIgnore
    String getUnwantedField();

    @JsonProperty(value = "newName")
    String getOldName();

}
Run Code Online (Sandbox Code Playgroud)

然后,在我的 Web 控制器启动时,我将 Mixin 连接到 Jackson ObjectMapper,该对象自动连接到控制器中并在我的调度程序 servlet xml 配置中定义。

 @Autowired
 private ObjectMapper objectMapper;

 @PostConstruct
    void configObjectMapper() {
        objectMapper.addMixInAnnotations(MyEjbJar.class, MyMixin.class);     
    }
Run Code Online (Sandbox Code Playgroud)

调度程序 servlet:

.
.
    <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>
Run Code Online (Sandbox Code Playgroud)

Dav*_*tor 1

我已经(通过 IDE 调试器和添加日志记录)跟踪了用于 war 模块和 ejb jar 模块的不同类加载器。根据文档,这是 JBoss AS 7 的预期默认行为。war使用war ModuleLoader,ejb jar使用ear ModuleLoader。

所发生的情况是,注释的类根据加载注释的类加载器而有所不同。另请参阅: SO 上的类似问题

我所说的“不同”是指它们是相同的注释,源自相同的 jar 和版本,但根据 equals 合约,它们不被视为等效,它们的哈希码不同,因此 JacksonAnnotationIntrospector不会定位注释,即使它们显示为持有反对 JPA POJO 类。

解决方法

我通过使ear ModuleLoader成为jackson 2的通用加载器来解决这个问题。我通过使com.fasterxml.jackson.core数据绑定依赖项在war和ejb jar中提供范围,并将其标记为正常编译范围来解决这个问题耳朵中的 POM 依赖性。

这种方法在JBoss AS 类加载中得到了认可,尽管它使用jboss-deployment-struct或 MANIFEST.MF 来实现几乎相同的功能。