从 JSON 输出球衣 moxy 中删除“类型”

Posted

技术标签:

【中文标题】从 JSON 输出球衣 moxy 中删除“类型”【英文标题】:Remove "type" from JSON output jersey moxy 【发布时间】:2014-02-01 04:37:47 【问题描述】:

如何从我拥有的 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。我该如何配置?

【问题讨论】:

【参考方案1】:

当我扩展一个类并生成 JSON 时,我得到了同样的错误——但仅限于***(根)类。作为一种解决方法,我用@XmlType(name="") 注释我的子类,这样可以防止生成的type 属性出现在我的JSON 中。

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

【讨论】:

使用 name 属性,您可能会覆盖 type 属性中写入的内容。由于您将其定义为空,因此 Jersey 会完全跳过该属性。【参考方案2】:

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。 我最近遇到了这个问题。为什么只有在编组为 JSON 而不是 XML 时才会发生这种情况?【参考方案3】:

您可以构建自定义消息正文编写器。

@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"));
    

【讨论】:

这似乎有点矫枉过正? @RobAu 检查我的更新,剩下的就是编写writeTo 方法。 嗨,Alex,感谢您的详细说明。我仍然认为这个问题似乎“工作量太大”,表明解决方案可以工作,但更难维护等。我的替代方案是重写 FactoryPattern 并删除子类 bean。我希望有一个更简单的基于注释/配置的解决方案。【参考方案4】:

使用它来生成 JSON 就不会出现这个问题:

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

【讨论】:

他要moxy【参考方案5】:

我在稍微不同的情况下使用了特定于 Jersey 的 Jackson 包,它起作用了。详细配置见Jersy document。就我而言,我在 @XmlRootElement 类中使用了泛型类型字段。 MOXy 在 JSON 输出中添加了一个类型。我明白为什么 MOXy 会这样做。如果 JSON 输出需要解组回 Java 对象,MOXy 需要知道类型以创建正确的对象。但是,就我而言,JSON 输出中的类型不美观。

【讨论】:

以上是关于从 JSON 输出球衣 moxy 中删除“类型”的主要内容,如果未能解决你的问题,请参考以下文章

java 使用java EclipseLink / MOXy提供程序(glassfish 4.0.1和JUnit4)解组json字符串和json文件

Jersey 2.2:输出 xml 正常,但在 json 上失败

数据结构(删除多余元素)

如何从 JSON 数组数据输出中删除大括号 []?

使用 Jolt 从 JSON 输出中删除空值

从 ASP.Net Web 服务 json 输出中删除“d”对象