2015-02-24 48 views
2

我需要將一些任意的JSON內容包裝到POJO中,然後使用MOXy/JAXB將其序列化爲JSON,但無法弄清楚如何將JsonObject與JAXB綁定。我只需要編組JsonObject,解組並不是必需的。如何爲JAXB MOXy編寫JsonStructure(JSR-353)XmlAdaptor?

即具有POJO:

@XmlRootElement 
public class MsgPOJO { 
    public String type; 
    public Object content; 
} 

如何把一個任意JSON內容在 'MsgPOJO.content',並對其進行序列化:

String jsonDoc = "{\"prop\":\"value\"}"; 
MsgPOJO msg = new MsgPOJO(); 
msg.type = "whatever"; 
msg.content = jsonDoc; 

所以,這將是輸出:

{ 
    "type": "whatever", 
    "content": { 
    "prop": "value" 
    } 
} 

我在考慮用@XmlJavaTypeAdapter註釋MsgPOJO.content,但這似乎並不能讓我獲得任何地方,因爲JSON內容可能是任意的。

這將是很好,如果能MOXY元帥JsonObjectJsonStructure,所以我可以這樣定義的POJO:

@XmlRootElement 
public class MsgPOJO { 
    public String type; 
    public JsonObject content; 
} 

有沒有一種方法,使這項工作?或者它是MOXy/JAXB的限制嗎?

+0

有一點要考慮的是GSON http://google-gson.googlecode.com/svn-history/trunk/gson/docs/javadocs/com/google/gson/Gson .html它是一個將任何類轉換成Json字符串並重新返回的庫。你可以使用它而不是自己做,它一直爲我工作。 – REGAL 2015-02-24 18:06:33

回答

0

默認情況下,MOXy不支持JSON-P結構的編組/解組,您需要實現XmlJavaTypeAdapter。以下是JsonObject適配器的示例。

MsgPOJO.java

package org.eclipse.persistence.testing.jsonp; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlRootElement; 

/** 
* Created by mvojtek on 24/02/15. 
*/ 
@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class MsgPOJO { 

    public String type; 

    public JsonObjectWrapper content; 

    public String getType() { 
     return type; 
    } 

    public void setType(String type) { 
     this.type = type; 
    } 

    public JsonObjectWrapper getContent() { 
     return content; 
    } 

    public void setContent(JsonObjectWrapper content) { 
     this.content = content; 
    } 

    @Override 
    public String toString() { 
     return "MsgPOJO{" + 
       "type='" + type + '\'' + 
       ", content=" + content + 
       '}'; 
    } 
} 

JsonObjectWrapper.java

package org.eclipse.persistence.testing.jsonp; 

import javax.json.JsonObject; 
import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

/** 
* Created by mvojtek on 24/02/15. 
*/ 
@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class JsonObjectWrapper { 

    @XmlJavaTypeAdapter(JsonObjectAdapter.class) 
    private JsonObject jsonObject; 

    public JsonObject getJsonObject() { 
     return jsonObject; 
    } 

    public void setJsonObject(JsonObject jsonObject) { 
     this.jsonObject = jsonObject; 
    } 

    @Override 
    public String toString() { 
     return "JsonObjectWrapper{" + 
       "jsonObject=" + jsonObject + 
       '}'; 
    } 
} 

JsonObjectAdapter.java

package org.eclipse.persistence.testing.jsonp; 

import javax.json.Json; 
import javax.json.JsonObject; 
import javax.json.JsonReader; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 
import java.io.StringReader; 

/** 
* Created by mvojtek on 24/02/15. 
*/ 
public final class JsonObjectAdapter extends XmlAdapter<String,JsonObject> { 
    @Override 
    public String marshal(JsonObject v) throws Exception { 
     if (null == v) { 
      return null; 
     } 
     return v.toString(); 
    } 

    @Override 
    public JsonObject unmarshal(String v) throws Exception { 
     if (null == v) { 
      return null; 
     } 
     JsonReader jsonReader = Json.createReader(new StringReader(v)); 
     return jsonReader.readObject(); 
    } 
} 

Test.java

package org.eclipse.persistence.testing.jsonp; 

import org.eclipse.persistence.jaxb.JAXBContextFactory; 
import org.eclipse.persistence.jaxb.JAXBContextProperties; 
import org.eclipse.persistence.oxm.MediaType; 

import javax.json.Json; 
import javax.json.JsonReader; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 
import java.io.StringReader; 
import java.io.StringWriter; 

public class Test { 

    public static void main(String[] args) throws Exception { 

     //marshal 
     JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[]{MsgPOJO.class}, null); 

     Marshaller marshaller = jaxbContext.createMarshaller(); 
     marshaller.setProperty(JAXBContextProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON); 

     MsgPOJO msgPOJO = new MsgPOJO(); 
     msgPOJO.setType("myType"); 

     JsonReader jsonReader = Json.createReader(new StringReader("{\"prop\":\"value\"}")); 

     JsonObjectWrapper wrapper = new JsonObjectWrapper(); 
     wrapper.setJsonObject(jsonReader.readObject()); 

     msgPOJO.setContent(wrapper); 

     StringWriter marshallerOutput = new StringWriter(); 

     marshaller.marshal(msgPOJO, marshallerOutput); 

     String result = marshallerOutput.toString(); 
     System.out.println("marshal result = "+result); 

     //unmarshal 
     Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
     unmarshaller.setProperty(JAXBContextProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON); 
     unmarshaller.setProperty(JAXBContextProperties.JSON_INCLUDE_ROOT, true); 

     MsgPOJO msgPOJO2 = (MsgPOJO)unmarshaller.unmarshal(new StringReader(result)); 

     System.out.println("msgPOJO2="+msgPOJO2); 
    } 
} 

如果你不想要字符串,你可以在MyList和MyMap結構的幫助下編寫一般結構。之後,您可以編寫XmlJavaTypeAdapter,將JsonObject編組爲此新類型。結果將是json,不是與輸入的字符串表示相同,而是合法的json。

https://github.com/eclipse/eclipselink.runtime/blob/master/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/rs/model/MyList.java

https://github.com/eclipse/eclipselink.runtime/blob/master/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/rs/model/MyMap.java

+0

@mvojtek:謝謝你的回答,這與我正在嘗試的類似 - 問題不在於它被編組爲:'{「msgPOJO」:{「type」:「myType」,「content」:{「jsonObject 「:」{「prop \」:\「value \」}「}}}'而不是:'{」msgPOJO「:{」type「:」myType「,」content「:{」jsonObject「:{ 「prop」:「value」}}}}',即'XmlAdapter'只是調用'JsonObject.toString()',所以'content.jsonObject'被序列化爲一個String而不是JSON對象/映射。 – siddhadev 2015-02-25 09:54:03

+0

我已經更新了我的答案,提供了一些關於無字符串結果的適配器的提示。 – 2015-02-25 17:00:13

+0

如果您擁有地圖列表或地圖地圖,它仍然不起作用,即它只適用於簡單字符串到字符串對象或字符串數​​組。我需要的是一種在JAXB/MOXy POJO中傳遞泛型JSON對象的方法。 – siddhadev 2015-02-26 10:47:20