代码之家  ›  专栏  ›  技术社区  ›  David Victor

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

  •  5
  • David Victor  · 技术社区  · 12 年前

    我正在将一个web应用程序从Websphere 7(JEE5)迁移到JBoss EAP 6.2.0(JEE6)。它目前在Glassfish 3&是。

    web界面使用/生成JSON-所以我使用Jackson2和Spring3MVC 映射Jackson2HttpMessageConverter 涉及在一个简单的控制器类中处理(去)串行化。

    在JBoss中,我看到Jackson2注释 @JsonProperty公司 等在ejb模块中被忽略-(它们仅应用于JPA实体),但是 被应用于web模块中。因此,JBoss中的一些对象的响应会返回不同的字段名,这会导致用户界面中断。

    我已经尝试了 jboss-deployment-structure.xml 无效(见下文)。我知道JBoss附带Jackson 1.x作为内部模块。然而,这似乎不是问题所在,否则web模块注释也会被忽略?例如。: Jackson annotations ignored after deployment to JBOSS

    该应用程序由3个maven模块组成:war、ejb(jar)&耳容器。

    我将重构代码以从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>
    

    初始解决方案(现在恢复)

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

    所有这一切的关键在于,通过使用Jackson Mixin,串行化的定制范围被限制在web模块中,从而避免了由于 ejb震击器 子部署。不 jboss-deployment-structure.xml 正在使用。

    添加Mixin

    public interface MyMixin {
    
    
        @JsonIgnore
        String getUnwantedField();
    
        @JsonProperty(value = "newName")
        String getOldName();
    
    }
    

    然后在启动我的web控制器时,我将Mixin连接到Jackson ObjectMapper,它自动连接到控制器中,并在我的调度器servlet xml配置中定义。

     @Autowired
     private ObjectMapper objectMapper;
    
     @PostConstruct
        void configObjectMapper() {
            objectMapper.addMixInAnnotations(MyEjbJar.class, MyMixin.class);     
        }
    

    Dispatcher servlet:

    .
    .
        <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>
    
    1 回复  |  直到 9 年前
        1
  •  1
  •   Community Mohan Dere    9 年前

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

    所发生的情况是,注释的类因加载注释的类加载器而异。另请参见: similar issue on SO

    通过“不同”,我的意思是它们是相同的注释,来自相同的jar&版本,但根据equals合约,它们不被视为等价的,它们的散列码不同,因此 杰克森注释测试器 即使注释显示为针对JPA POJO类保存,也不会定位注释。

    变通办法

    我通过使ear ModuleLoader成为jackson 2的常见加载器来解决这个问题。我通过制作 com.fasterxml.jackson.core数据绑定 附属国 假如 战争中的范围;ejb-jar,并将其标记为ear POM中的正常编译范围依赖项。

    这种方法在这里得到了认可 JBoss AS classloading 尽管它使用 jboss部署结构 或者MANIFEST.MF来实现几乎相同的事情。