【问题标题】:Marshaling / Demarshaling JSON with Java EE 7 / Glassfish 4.1 results in null object使用 Java EE 7/Glassfish 4.1 编组/解组 JSON 会导致空对象
【发布时间】:2015-01-07 06:40:57
【问题描述】:

我从 Java EE 6 升级到 Java EE 7,我的一些 REST 服务停止工作。缩小范围来看,这种变化似乎是在 Jersey 从 Jackson 切换到 Java EE 7 中的 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 是一个通用类,我用它来包装请求,其中包含针对几种不同类型请求的身份验证内容标准。

我测试了一个类似的@GET 服务以返回一个充满垃圾数据的ObjectRequest&lt;Access&gt; 实例。它在使用 XML 时再次运行良好,但在我尝试返回 JSON 时返回null(没有引发异常)。

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

@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 类以使用 Jackson,但我不知道如何概括我找到的解决方案来涵盖我的情况。所以,真的有两个问题:

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

设置:

  • Netbeans 8.0.2
  • Glassfish 4.1
  • JDK 8 / JRE 8U25(64 位)

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

项目pom.xml 有以下条目:

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

【问题讨论】:

  • 您是否使用&lt;groupId&gt;com.fasterxml.jackson.jaxrs&lt;/groupId&gt; 组下的fasterxml jackson json 提供程序?我记得当我在 Jersey 版本之间迁移时遇到过类似的问题,但那是很久以前的事了。细节让我无法理解。
  • @DeepakBala 请参见上面的编辑,但简而言之,是的,我在项目的 pom.xml 文件中有该条目。

标签: java json jackson moxy java-ee-7


【解决方案1】:

你应该可以通过禁用 MOXy 来解决这个问题(在getClasses() 中注册下面的类)并摆脱你的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;
    }
}

【讨论】:

  • 或者您可以只使用jersey-media-json-jackson(Glassfish 也随附)和register(JacksonFeature.class)。一个班轮。 Moxy 会自动禁用。见Note
猜你喜欢
  • 2016-07-06
  • 2021-01-05
  • 2014-11-14
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
  • 1970-01-01
相关资源
最近更新 更多