【问题标题】:JAXB null instead empty string during marshaling在封送处理期间 JAXB null 而不是空字符串
【发布时间】:2012-07-04 09:44:47
【问题描述】:

在编组字符串时如何将“null”打印为字段值?

示例:error 和 error_code 是字符串,我想使用“null”作为值,表示服务器端没有发生值/错误。

{
   "error_code": null,
   "error": null
}

今天,我不得不使用 EMPTY 值,所以“error_code”或“error”这些字段一般都属于 json,如果没有显式初始化为 this.errorCode = StringUtils.EMPTY; 所以今天,我有下一个json:

{
   "error_code": "",
   "error": ""
}

这是代码中的样子:

@XmlRootElement()
@XmlAccessorType(XmlAccessType.FIELD)
public class Response
{
        @SuppressWarnings("unused")
        private static final Logger log = LoggerFactory.getLogger(Response.class);

        public static final String ERROR_FIELD_NAME = "error";
        public static final String ERROR_CODE_FIELD_NAME = "error_code";

        // @XmlJavaTypeAdapter(CafsResponse.EmptyStringAdapter.class)
        @XmlElement(name = Response.ERROR_CODE_FIELD_NAME)
        private String errorCode;

        // @XmlJavaTypeAdapter(CafsResponse.EmptyStringAdapter.class)
        @XmlElement(name = Response.ERROR_FIELD_NAME)
        private String errorMessage;

    // Empty Constructor
    public Response()
    {
            this.errorCode = StringUtils.EMPTY; // explicit initialization, otherwise error_code will not appear as part of json, how to fix this this ?
            this.errorMessage = StringUtils.EMPTY;
    }

等等……

// Empty Constructor
public Response()
{
        this.errorCode = null; // this variant dosn't work either, and error_code again didn't get to json 
        this.errorMessage = null;
}

看,@XmlJavaTypeAdapter,我认为这可能对我有帮助 - 但没有:)

我将“null”作为字符串而不是 null 值。

if (StringUtils.isEmpty(str))
{
   return null;
}
return str;

{
   "error_code": "null", // this is not whta i wanted to get.
   "error": "null"
}

对此有任何帮助吗? - 有什么不清楚的地方问我。

完整列表:

/**
 * Empty string Adapter specifying how we want to represent empty strings
 * (if string is empty - treat it as null during marhsaling)
 * 
 */
@SuppressWarnings("unused")
private static class EmptyStringAdapter extends XmlAdapter<String, String>
{

        @Override
        public String unmarshal(String str) throws Exception
        {
                return str;
        }


        @Override
        public String marshal(String str) throws Exception
        {
                if (StringUtils.isEmpty(str))
                {
                        return null;
                }
                return str;
        }

}

【问题讨论】:

  • 以下内容应该有所帮助:blog.bdoughan.com/2012/04/…
  • @BlaiseDoughan 基本上我有一些用@XmlElement 元素定义的POJO 字段,如下所示: @XmlElement(nillable = true) private String error_code;现在,当我将输出显示为 application/xml - 我得到正确的值:w3.org/2001/XMLSchema-instance"> 但是当我使用 application/json 作为输出时,我得到:` "status" : { "@nil" : "true" } ` 这似乎不正确。根据 JSON 规范,它更像是:"error_code" : null 如何解决这个问题?
  • 我添加了一个答案,展示了如何使用 MOXy 作为 JSON 提供程序来实现您的用例。
  • OK :) 现在我明白了,所以这是一个由 EclipseLink JAXB (MOXy) 成功处理的 JAXB 问题。我一定会试一试的!谢谢你。我会将这个问题标记为已解决。

标签: java jaxb jersey


【解决方案1】:

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

您可以使用 MOXy 作为您的 JSON 提供程序来支持此用例。下面是一个例子:

回应

MOXy 会将标有@XmlElement(nillable=true) 的属性编组为您正在寻找的表示形式 (见:http://blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html)。

package forum11319741;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Response {

        public static final String ERROR_FIELD_NAME = "error";
        public static final String ERROR_CODE_FIELD_NAME = "error_code";

        @XmlElement(name = Response.ERROR_CODE_FIELD_NAME, nillable = true)
        private String errorCode;

        @XmlElement(name = Response.ERROR_FIELD_NAME, nillable = true)
        private String errorMessage;

}

jaxb.properties

要将 MOXy 用作您的 JAXB 提供程序,您需要在与域模型相同的包中包含一个名为 jaxb.properties 的文件,其中包含以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):

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

演示

package forum11319741;

import javax.xml.bind.*;

public class Demo {

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

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty("eclipselink.media-type", "application/json");
        marshaller.setProperty("eclipselink.json.include-root", false);

        Response response = new Response();
        marshaller.marshal(response, System.out);
    }

}

输出

{
   "error_code" : null,
   "error" : null
}

MOXy 和 JAX-RS

您可以使用 MOXyJsonProvider 类在 JAX-RS 应用程序中启用 MOXy 作为 JSON 提供程序(请参阅:http://blog.bdoughan.com/2012/05/moxy-as-your-jax-rs-json-provider.html)。

package org.example;

import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

public class CustomerApplication  extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<Class<?>>(2);
        set.add(MOXyJsonProvider.class);
        set.add(CustomerService.class);
        return set;
    }

}

更多信息

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 2012-07-18
    相关资源
    最近更新 更多