【问题标题】:Remove "type" from JSON output jersey moxy从 JSON 输出球衣 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。我该如何配置?

【问题讨论】:

    标签: java json jersey marshalling moxy


    【解决方案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 输出中的类型不美观。

    【讨论】:

      猜你喜欢
      • 2015-06-10
      • 2017-07-29
      • 1970-01-01
      • 2021-03-18
      • 2014-02-12
      • 2016-10-21
      • 1970-01-01
      • 2021-12-20
      • 2014-05-04
      相关资源
      最近更新 更多