使用 Java EE 7 / Glassfish 4.1 编组/解组 JSON 导致空对象

Marshaling / Demarshaling JSON with Java EE 7 / Glassfish 4.1 results in null object

我从 Java EE 6 升级到 Java EE 7,我的一些 REST 服务停止工作。缩小范围,似乎这种变化似乎是在 Java EE 7 中 Jersey 从 Jackson 切换到 MOXy 时发生的。

我的服务是这样的:

@Stateless
@Path("access")
public class AccessFacadeREST extends AbstractFacade<Access> {
    @PersistenceContext(unitName = "AccessServerPU")
    private EntityManager em;

    public AccessFacadeREST() {
        super(Access.class);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Produces({"application/xml", "application/json"})
    public ObjectResponse create(@Context HttpServletRequest requestContext,
                                 @Context SecurityContext context,
                                 ObjectRequest<Access> req) {
        req.setHostname(requestContext.getRemoteAddr());
        return AccessValidation.create(em, req);
    }
}

此处 req 为空,因此在使用 JSON 呈现时生成 NullPointerException。当显示为 XML 时,它工作正常。 ObjectRequest 是一个通用的 class 我用它来为几种不同类型的请求包装带有身份验证内容标准的请求。

我测试了与 return 一个充满垃圾数据的 ObjectRequest<Access> 实例类似的 @GET 服务。它在使用 XML 时再次运行良好,但是当我尝试 return JSON 时 returns null(无一例外)。

我发现 Java EE7 REST server no longer returning List as JSON 对理解潜在问题很有用,但我不知道如何让它在我的情况下起作用。我的 ApplicationConfig class 看起来像:

@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {

    @Override
    public Set<Object> getSingletons() {
        Set<Object> set = new HashSet<>();
        log.info("Enabling custom Jackson JSON provider");
        set.add(new JacksonJsonProvider());
        return set;
    }

    @Override
    public Map<String, Object> getProperties() {
        Map<String, Object> map = new HashMap<>();
        log.info("Disabling MOXy JSON provider");
        map.put("jersey.config.disableMoxyJson.server", true);
        return map;
    }

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet<>();
        addRestResourceClasses(resources);
        return resources;
    }

    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(AccessFacadeREST.class);
    }
}

我想我需要配置 ApplicationConfig class 才能使用 Jackson,但我不知道如何概括我找到的解决方案来涵盖我的情况。所以,真的有两个问题:

  1. 我是否正确地将潜在问题描述为某种 MOXy 缺陷?
  2. 我如何使用 MOXy 或 Jackson 解决此问题(我没有偏好,只要它有效)?

设置:

编辑 以回应以下问题...

项目 pom.xml 具有以下条目:

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.4.4</version>
</dependency>

您应该可以通过禁用 MOXy(在 getClasses() 中注册下面的 class)并摆脱您的 set.add(new JacksonJsonProvider()); 单例来解决这个问题。我将它用于我所有的 GF4 项目以强制 Jersey 使用 Jackson。

/**
 * Feature to disable Moxy and Enable Jackson processing
 */
private static class Jackson2Feature implements Feature {

    @Override
    public boolean configure(FeatureContext context) {
        final String disableMoxy = PropertiesHelper.getPropertyNameForRuntime(
                CommonProperties.MOXY_JSON_FEATURE_DISABLE,
                context.getConfiguration().getRuntimeType());
        context.property(disableMoxy, true);

        // add the default Jackson exception mappers and allow jaxb annotations
        context.register(JsonParseExceptionMapper.class);
        context.register(JacksonJaxbJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class);
        return true;
    }
}