从JSON输出中删除"type"(类型)- Jersey Moxy

11

如何从我的JSON输出中删除type。我有一个包含REST服务输出的类/bean。我正在使用jersey-media-moxy进行转换。

该服务

@Resource
public interface MyBeanResource
{
    @GET
    @Path("/example")
    @Produces( MediaType.APPLICATION_JSON )
    public Bean getBean();
}

豆子

@XmlRootElement
class Bean
{
   String a;
}  

我想添加一些功能(用于使用构造函数初始化bean)

class BeanImpl extends Bean
{
    BeanImpl(OtherClass c)
    {
        a = c.toString()
    }
}

输出的JSON为:

{type:"beanImpl", a:"somevalue"}

我不想在我的JSON中包含type。我该如何配置?

5个回答

17

当我继承一个类并生成JSON时,只有顶级(根)类会出现相同的错误。为解决此问题,我使用@XmlType(name="")注释我的子类,这可以防止生成的type属性在我的JSON中出现。

Blaise,我不确定为什么这样能行。有什么想法吗?


2
使用name属性,您可能会覆盖类型属性中的内容。由于您将其定义为空,因此Jersey完全跳过了该属性。 - kazanaki

3

MOXy将添加类型标识符以区分不同的子类型。但是,只有在MOXy知道子类型时(默认情况下不知道),才会发生这种情况。

演示代码

演示

以下是Jersey将调用MOXy的等效代码。

import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

public class Demo {

    public static void main(String[] args) throws Exception {
        MOXyJsonProvider mjp = new MOXyJsonProvider();

        BeanImpl beanImpl = new BeanImpl(new OtherClass());
        mjp.writeTo(beanImpl, Bean.class, Bean.class, null, null, null, System.out);

    }

}

输出

{}

可能的问题?

你的真实Bean类上是否有@XmlSeeAlso注解?

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlSeeAlso(BeanImpl.class)
class Bean
{
   String a;
}  

假设 BeanImpl 也有一个无参构造函数,则输出将为:
{"type":"beanImpl"}

没有,我没有@XmlSeeAlso。 - Rob Audenaerde
我最近遇到了这个问题。为什么只有在编组为JSON而不是XML时才会出现这种情况? - umphy

1
你可以构建一个自定义的消息正文编写器。
@Provider
@Produces({
   MediaType.APPLICATION_JSON
})
public class BeanBodyWriter implements MessageBodyWriter<Bean> {

    @Override
    public long getSize(Bean t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        // Called before isWriteable by Jersey. Return -1 if you don't the size yet. 
        return -1;
    }

    @Override
    public boolean isWriteable(Class<?> clazz, Type genericType, Annotation[] annotations, MediaType mediaType) {
        // Check that the passed class by Jersey can be handled by our message body writer
        return Bean.class.isAssignableFrom(clazz);
    }

    @Override
    public void writeTo(Bean t, Class<?> clazz, Type genericType, Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders, OutputStream out) throws IOException, WebApplicationException {

        // Call your favorite JSON library to generate the JSON code and remove the unwanted fields...
        String json = "...";

        out.write(json.getBytes("UTF-8"));
    }
}

1
那似乎有些过头了? - Rob Audenaerde
@RobAu,请检查我的更新,所剩的是编写“writeTo”方法。 - Stephan
嗨,Alex,感谢你的详细解释。我仍然认为这对于问题来说似乎是“太多工作”,表明解决方案可以工作,但更难以维护等。我的替代方案是重写为FactoryPattern并删除子类化的bean。我希望有一个更简单的基于注释/配置的解决方案。 - Rob Audenaerde

0
使用此方法生成JSON,您就不会遇到那个问题了:
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.3.3</version>
</dependency>

他正在要求更多的勇气。 - Jack

0

我在一个稍微不同的情况下使用了Jersey特定的Jackson包,它起作用了。详细的配置在Jersy文档中有描述。在我的情况下,我在@XmlRootElement类中使用了一个通用类型字段。MOXy在JSON输出中添加了一个类型。我可以理解为什么MOXy这样做。如果JSON输出需要反序列化回Java对象,MOXy需要知道类型以创建正确的对象。然而,在我的情况下,类型在JSON输出中是不美观的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接