JAXB JSON 强制数组上的括号

发布于 2024-09-27 20:26:58 字数 775 浏览 1 评论 0原文


我试图在仅包含一个元素的列表上强制加上括号。

我想要这样的东西:
{"id":"0","industries":[{"id":"0","name":"Technologies"}],"name":"Google Inc."}

但我得到:
{"id":"0","industries":{"id":"0","name":"Technologies"},"name":"Google Inc."}

这是我的实体:

@Entity
@XmlRootElement
public class Company {
 private int id;

 private String name;
 private String description;

 @XMLElement(name="industries")
 private List<Industry> industryList;

    [...]

最后,我的JAXB 上下文解析器:

public JAXBContextResolver() throws Exception {

MappedBuilder builder = JSONConfiguration.mapped(); builder.arrays(“行业”); builder.rootUnwrapping(true);

this.context = new JSONJAXBContext(builder.build(), Company.class); }

I'm trying to force brackets on lists that contain only one element.

I want something like this:
{"id":"0","industries":[{"id":"0","name":"Technologies"}],"name":"Google Inc."}

But I get:
{"id":"0","industries":{"id":"0","name":"Technologies"},"name":"Google Inc."}

Here is my Entity:

@Entity
@XmlRootElement
public class Company {
 private int id;

 private String name;
 private String description;

 @XMLElement(name="industries")
 private List<Industry> industryList;

    [...]

And finally, my JAXB Context Resolver:

public JAXBContextResolver() throws Exception {

MappedBuilder builder = JSONConfiguration.mapped();
builder.arrays("industries");
builder.rootUnwrapping(true);

this.context = new JSONJAXBContext(builder.build(), Company.class);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

鸵鸟症 2024-10-04 20:26:58

感谢您的帮助,但我找到了答案。您实际上需要指定一个 JAXBContextResolver 来指定自然的 JSON 配置。您需要提供需要转换为 JSON 的每个容器的类型列表。在此示例中,您可以看到我指定了作为 Company 容器的 GetCompanyResponse。

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
    private JAXBContext context;
    private Class[] types = { GetCompanyResponse.class };

    public JAXBContextResolver() throws Exception {
        this.context = new JSONJAXBContext(JSONConfiguration.natural().build(), types);
    }

    public JAXBContext getContext(Class<?> objectType) {
        for (Class clazz : types) {
            if (clazz.equals(objectType)) {
                return context;
            }
        }

        return null;
    }
}

thanks for your help, but I found the answer. You actually need to specify a JAXBContextResolver which specify natural JSON configuration. You need to provide a type list of every container that need to be transform to JSON. In this example, you can see that I specified the GetCompanyResponse that is a container of Company.

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
    private JAXBContext context;
    private Class[] types = { GetCompanyResponse.class };

    public JAXBContextResolver() throws Exception {
        this.context = new JSONJAXBContext(JSONConfiguration.natural().build(), types);
    }

    public JAXBContext getContext(Class<?> objectType) {
        for (Class clazz : types) {
            if (clazz.equals(objectType)) {
                return context;
            }
        }

        return null;
    }
}
我恋#小黄人 2024-10-04 20:26:58

注意:我是EclipseLink JAXB (MOXy) 的领导者和 JAXB 2 (JSR-222 )专家组。

EclipseLink JAXB (MOXy) 提供本机 JSON 绑定支持。它将正确编组包装为 JSON 数组的大小为 1 的集合。下面是一个完整的例子。

公司

package forum3946102;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Company {
    private int id;

    private String name;

    private String description;

    @XmlElement(name = "industries")
    private List<Industry> industryList;
}

行业

package forum3946102;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Industry {
    private int id;

    private String name;
}

jaxb.properties

为了将 MOXy 指定为您的 JAXB 提供商,您需要添加一个名为 jaxb.properties 的文件code> 与您的域类位于同一包中,并包含以下条目:

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

演示

package forum3946102;

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(Company.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty("eclipselink.media-type", "application/json");
        unmarshaller.setProperty("eclipselink.json.include-root", false);
        String jsonString = "{\"id\":\"0\",\"industries\":[{\"id\":\"0\",\"name\":\"Technologies\"}],\"name\":\"Google Inc.\"}";
        StreamSource jsonSource = new StreamSource(new StringReader(jsonString));
        Company company = unmarshaller.unmarshal(jsonSource, Company.class).getValue();

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

}

输出

以下是运行演示代码的输出:

{"id" : 0, "name" : "Google Inc.", "industries" : [{"id" : 0, "name" : "Technologies"}]}

了解更多信息

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.

EclipseLink JAXB (MOXy) provides native JSON-binding support. It will correctly marshal collections of size 1 wrapped as a JSON array. Below is a complete example.

Company

package forum3946102;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Company {
    private int id;

    private String name;

    private String description;

    @XmlElement(name = "industries")
    private List<Industry> industryList;
}

Industry

package forum3946102;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Industry {
    private int id;

    private String name;
}

jaxb.properties

In order to specify MOXy as your JAXB provider you need to add a file called jaxb.properties in the same package as your domain classes with the following entry:

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

Demo

package forum3946102;

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(Company.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty("eclipselink.media-type", "application/json");
        unmarshaller.setProperty("eclipselink.json.include-root", false);
        String jsonString = "{\"id\":\"0\",\"industries\":[{\"id\":\"0\",\"name\":\"Technologies\"}],\"name\":\"Google Inc.\"}";
        StreamSource jsonSource = new StreamSource(new StringReader(jsonString));
        Company company = unmarshaller.unmarshal(jsonSource, Company.class).getValue();

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

}

Output

Below is the output from running the demo code:

{"id" : 0, "name" : "Google Inc.", "industries" : [{"id" : 0, "name" : "Technologies"}]}

For More Information

迟月 2024-10-04 20:26:58

我对此不太确定,但尝试删除 industryList@XMLElement 注释

我已经做了相反的事情:使用 jaxb 从 xsd 模式生成 java 类文件。我查看了带有集合字段的生成的类,它们没有任何特定的注释。

另外你可能想尝试 JSON Lib: http://json-lib.sourceforge.net/

你可以执行以下操作:

jsonString = JSONObject.fromObject(pojoObject)

这将生成 json 字符串,该字符串将包含例如复杂类型的集合。

然后,您可以使用 HttpServletResponse 等发送 jsonString。

我建议序列化 DTO 对象,而不是序列化实体对象。

I'm not too sure about this, but try removing the @XMLElement annotation for industryList

I have done stuff the other way around: using jaxb to generate java classes from xsd schema files. I've looked at the generated classes with collection fields, and they don't have any specific annotations on them.

Also you may wanna try JSON Lib: http://json-lib.sourceforge.net/

you could do things like:

jsonString = JSONObject.fromObject(pojoObject)

which will generate json string that will incorporate e.g. collections of complex types.

You could then send the jsonString using e.g. HttpServletResponse.

I would recommend serializing DTO objects rather than serialize your entity objects.

热血少△年 2024-10-04 20:26:58

深入 JSONObject 并换出需要为 JSONArray 的区域。创建后,json putOpt 将用新的引用对象替换旧的引用对象。

之前
"投资": {"子账户": {
"id": "SubAccountId_2_CORP",
"分配百分比": "100.0",
“产品代码”:“PC01”,
"ProductFullName": "产品全名"
}}

之后
"投资": {"子账户": [{
"id": "SubAccountId_2_CORP",
"分配百分比": "100.0",
“产品代码”:“PC01”,
"ProductFullName": "产品全名"
}]}

 import org.json.JSONArray;
 import org.json.JSONObject;
 import org.json.XML;
 private static int PRETTY_PRINT_INDENT_FACTOR = 4;




            try {
            org.json.JSONObject xmlJSONObj = XML.toJSONObject(inBatchTrans.getINPUT_MESSAGE()); 

            try {
                JSONArray subAcctArray = xmlJSONObj.getJSONObject("TXLife").getJSONObject("TXLifeRequest").getJSONObject("OLifE").getJSONObject("Holding").getJSONObject("Investment").getJSONArray("SubAccount");
                // Already JsonArray do nothing
            } catch (Exception e) {
                // convert to Array
                JSONObject subAcctObj = xmlJSONObj.getJSONObject("TXLife").getJSONObject("TXLifeRequest").getJSONObject("OLifE").getJSONObject("Holding").getJSONObject("Investment").getJSONObject("SubAccount");
                JSONArray keys = subAcctObj.names();
                JSONArray values = subAcctObj.toJSONArray(keys);

                JSONObject subAccount = new JSONObject();
                JSONArray  subAccountList = new JSONArray();
                int key = keys.length();
                for (int i = 0; i < key; i++) {
                    subAccount.put(keys.get(i).toString(), values.get(i));
                }
                subAccountList.put(0, subAccount);
                xmlJSONObj.getJSONObject("TXLife").getJSONObject("TXLifeRequest").getJSONObject("OLifE").getJSONObject("Holding").getJSONObject("Investment").putOpt("SubAccount", subAccountList);
            }

            String jsonPrettyPrintString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR);
            System.out.println(jsonPrettyPrintString);
        } catch (org.json.JSONException je) {
            System.out.println(je.toString());
        }

Drill down JSONObject and swap out an area that needs to be JSONArray. Once created, json putOpt will replace old reference object with new.

Before
"Investment": {"SubAccount": {
"id": "SubAccountId_2_CORP",
"AllocPercent": "100.0",
"ProductCode": "PC01",
"ProductFullName": "Product Full Name"
}}

After
"Investment": {"SubAccount": [{
"id": "SubAccountId_2_CORP",
"AllocPercent": "100.0",
"ProductCode": "PC01",
"ProductFullName": "Product Full Name"
}]}

 import org.json.JSONArray;
 import org.json.JSONObject;
 import org.json.XML;
 private static int PRETTY_PRINT_INDENT_FACTOR = 4;

.
.
.
.

            try {
            org.json.JSONObject xmlJSONObj = XML.toJSONObject(inBatchTrans.getINPUT_MESSAGE()); 

            try {
                JSONArray subAcctArray = xmlJSONObj.getJSONObject("TXLife").getJSONObject("TXLifeRequest").getJSONObject("OLifE").getJSONObject("Holding").getJSONObject("Investment").getJSONArray("SubAccount");
                // Already JsonArray do nothing
            } catch (Exception e) {
                // convert to Array
                JSONObject subAcctObj = xmlJSONObj.getJSONObject("TXLife").getJSONObject("TXLifeRequest").getJSONObject("OLifE").getJSONObject("Holding").getJSONObject("Investment").getJSONObject("SubAccount");
                JSONArray keys = subAcctObj.names();
                JSONArray values = subAcctObj.toJSONArray(keys);

                JSONObject subAccount = new JSONObject();
                JSONArray  subAccountList = new JSONArray();
                int key = keys.length();
                for (int i = 0; i < key; i++) {
                    subAccount.put(keys.get(i).toString(), values.get(i));
                }
                subAccountList.put(0, subAccount);
                xmlJSONObj.getJSONObject("TXLife").getJSONObject("TXLifeRequest").getJSONObject("OLifE").getJSONObject("Holding").getJSONObject("Investment").putOpt("SubAccount", subAccountList);
            }

            String jsonPrettyPrintString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR);
            System.out.println(jsonPrettyPrintString);
        } catch (org.json.JSONException je) {
            System.out.println(je.toString());
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文