6

在尝试使用 Eclipse Moxy 将类编组为 JSON 时,我遇到了一个非常烦人的错误。

我的一个域类中有一个具有以下值的属性:"the City’s original city site"其中包含代码点 u+2019 (')

当 Jaxb 尝试编组这个值时,我莫名其妙地得到了一个奇怪的控制:"Citys original city site"

这会导致无效的 JSON 在解码时返回空值。我用杰克逊试过这个,并收到一个 ascii 转义字符,这仍然是错误的,但它至少使 JSON 有效!

Moxy 应该能够正确输出,因为 ' 是一个有效的 unicode 字符并且在 JSON 中有效。有什么办法可以正确输出 ' (和任何其他 unicode 字符),最好将这个不必要的字符转换为常规撇号。

这是我的提供者类:

@Provider
@Component("customMOXyJsonProvider")    
public class CustomMOXyJsonProvider extends MOXyJsonProvider {

    @Override
    protected void preWriteTo(Object object, Class<?> type, Type genericType,
                              Annotation[] annotations, MediaType mediaType,
                              MultivaluedMap<String, Object> httpHeaders, Marshaller marshaller)
            throws JAXBException {
        marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, true);
        marshaller.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");
    }

}

我正在使用 2.5.1 版的 Moxy。

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.moxy</artifactId>
        <version>2.5.1</version>
    </dependency>

我的系统中有几个组件理论上可能会破坏值(postgres、jdbc、hibernate、cxf 和 tomcat),但我通过测试确定该值正确存储在我的域类中 - 然后损坏,如 Elliot Spitzer在编组步骤上拜访妓女。

4

1 回答 1

4

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。

更新#3

该问题现已在 EclipseLink 2.5.2 和 2.6.0 流中得到修复。从 2013 年 10 月 10 日起,您将能够从以下位置下载每晚构建:

或者来自 Maven

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>org.eclipse.persistence.moxy</artifactId>
    <version>2.5.2-SNAPSHOT</version>
</dependency>

<repository>
    <id>oss.sonatype.org</id>
    <name>OSS Sonatype Staging</name>
    <url>https://oss.sonatype.org/content/groups/staging</url>
</repository>

更新#2

以下错误可用于跟踪我们在此问题上的进展:


更新#1

您的用例适用于 EclipseLink 2.5.0。我们在 EclipseLink 2.5.1 中进行的性能修复引入了失败:


原始答案

我们的编组中似乎存在一个错误,而我们的 JSONOutputStream编组中不存在该错误Writer(XML 可以正常工作)。以下是我的快速调查发现的内容。一旦我有更多信息,我会更新我的答案。

Java 模型

public class Foo {

    private String bar;

    public String getBar() {
        return bar;
    }

    public void setBar(String bar) {
        this.bar = bar;
    }

}

演示代码

import java.io.OutputStreamWriter;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.bind.Marshaller;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Foo.class}, properties);

        Foo foo = new Foo();
        foo.setBar("the City’s original city site");


        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        // Broken
        marshaller.marshal(foo, System.out);

        // Works
        marshaller.marshal(foo, new OutputStreamWriter(System.out));
    }

}

输出

{
   "bar" : "the Citys original city site"
}{
   "bar" : "the City’s original city site"
}
于 2013-10-09T15:41:47.630 回答