Java JSON对象扁平化

5
我正在寻找一个Java库,将我的领域对象转换为扁平化的JSON格式。
例如:
public class Person {
   String name
   Address homeAddress
}

public class Address {
  String street
  String zip
}

JSON: {name:'John', homeAddress_street: '123 Street', homeAddress_zip: 'xxxxx'}

我已经研究了XStream、Eclipse MOXy、FlexJSON、JSON-lib和gson。

我的目标是摆脱我的json包装类并尽量减少代码。我希望有一个通用服务,可以获取任何域模型类的json表示,而无需编写xml描述符或任何自定义转换器来处理每种类型的模型。对于我的模型来说,1个级别深度就足够了。我没有找到使用注释或上述库中的内置功能的简单通用解决方案,但我可能已经忽略了它们。是否有一种非侵入式的库可以做到这一点?或者可能在我列出的其中一个库中?我正在使用Hibernate,所以该库必须能够处理CGLib代理。


你会如何将一个数组展平? - pingw33n
2个回答

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

以下是使用MOXy的@XmlPath扩展来完成此操作的示例。

人员信息

package forum7652387;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlAccessorType(XmlAccessType.FIELD)
public class Person {
    String name;

    @XmlPath(".")
    Address homeAddress;
}

地址

package forum7652387;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Address {
    @XmlElement(name="homeAddress_street")
    String street;

    @XmlElement(name="homeAddress_zip")
    String zip;
}

jaxb.properties

为了将MOXy作为您的JAXB提供程序,您需要在与域类相同的包中添加一个名为jaxb.properties的文件,并添加以下条目:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

演示

package forum7652387;

import java.io.StringReader;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Person.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty("eclipselink.media-type", "application/json");
        unmarshaller.setProperty("eclipselink.json.include-root", false);
        String jsonString = "{\"name\":\"John\", \"homeAddress_street\":\"123 Street\", \"homeAddress_zip\":\"xxxxx\"}";
        StreamSource jsonSource = new StreamSource(new StringReader(jsonString));
        Person person = unmarshaller.unmarshal(jsonSource, Person.class).getValue();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty("eclipselink.media-type", "application/json");
        marshaller.setProperty("eclipselink.json.include-root", false);
        marshaller.marshal(person, System.out);
    }

}

输出

 {"name" : "John", "homeAddress_street" : "123 Street", "homeAddress_zip" : "xxxxx"}

了解更多信息


如果一个“人”既有“家庭地址”又有“工作地址”,该怎么办? - Tom Anderson
@TomAnderson - 我已经提交了一个增强请求来支持这个用例。请随意添加更多细节:http://bugs.eclipse.org/376632 - bdoughan
我认为你已经说了所有需要说的关于它的事情! - Tom Anderson
能否在不对每个类中的每个字段进行注释的情况下,使用反射与Moxy来实现这一点? - user979051

-1

我曾经简单地使用过GSON,我认为它可以做到你需要的。在调查它时,我编写了以下非常简单的示例来确认它就是我需要的;首先,一个POJO:

import java.util.List;

public class Member {

    private String name;
    private int age;
    private List<String> stuff;

    public Member() {
    }

    public String getName() {
        return name;
    }

    public void setName( String name ) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge( int age ) {
        this.age = age;
    }

    public List<String> getStuff() {
        return stuff;
    }

    public void setStuff( List<String> stuff ) {
        this.stuff = stuff;
    }

}

接下来是工作类:

import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {

    public static void main( String[] args ) {
        Main m = new Main();
        m.execute( args );
    }

    private void execute( String[] args ) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        Member member = new Member();

        List<String> stuff = new ArrayList<String>();
        stuff.add( "shoes" );
        stuff.add( "hat" );
        member.setStuff( stuff );
        member.setName( "Bert" );
        member.setAge( 21 );

        String output = gson.toJson( member, Member.class );
        log( output );

        Member member2 = gson.fromJson( output, Member.class );
        log(member2.getName());
    }

    private void log( String text ) {
        System.out.println( text );
    }

}

不需要XML描述符或自定义转换器。这是你想要的吗?


2
它是如何将模型平坦化的呢?你的示例模型中不包含任何其他领域对象。 - user979051

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