从 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文件