2013-03-26 81 views
5

傑克遜令人難以置信的新穎,我對理解我如何完成某件事情有困難。傑克遜自定義映射器將字節數組轉換爲字符串

我有一些類型爲byte[]的數據(數據在JAXB生成的類中)。在將數據發送到瀏覽器之前,傑克遜(我相信)將它變成JSON,以便網頁可以使用它。至少這是我迄今爲止的粗糙理解。

JSON數據顯示我的byte []爲字符串,與我們想要的顯示不匹配。例如,實際數據可能是CAFEDEAD,但JSON字符串看起來像3q2+78r+。我想讓JSON包含字符串CAFEDEAD

我的問題是,我可以爲Jackson創建一個自定義的東西,在它創建最終的JSON之前,將byte[]數據轉換爲可讀的十六進制字符串?或者,如果沒有,我還有什麼其他選擇?

我有權訪問JavaScript,因此如果有方法可以將JSON字符串恢復回來,那麼我也可以。

+1

爲什麼JSON如何傳播二進制數據很重要?這聽起來像可能是Base64 - 因此解碼base64以獲取原始二進制數據,然後您可以根據需要顯示它。 – 2013-03-26 17:37:06

+0

會給這個想法一個鏡頭,謝謝喬恩! – Robb 2013-03-26 17:38:46

+0

請告訴我們一些代碼 – Jason 2013-03-27 05:35:50

回答

-1

您可以對任何屬性使用@JsonSerialize和@JsonDeSerialize註釋。 javadoc的是

http://jackson.codehaus.org/1.2.1/javadoc/org/codehaus/jackson/map/annotate/JsonSerialize.html 

我個人使用的序列化/反序列化技術,而不是轉換在客戶身邊,你可能最終在多個地方做。

0

沒有任何代碼,我不得不根據你的問題猜測你在做什麼。本教程JSON parse to/from using Jackson告訴您如何ObjectMapper轉換成JSON的Stringfiyed表示例如當JavaScript客戶端收到此字符串

"{"age":29,"messages":["msg 1","msg 2","msg 3"],"name":"mkyong"}" 

然後,你將不得不解析這個使用可內置JSON解析功能或jQuery的提供一。像

... 
    var myJson = JSONString.parse() | jQuery.parseJSON(JSONString); 
    .. 

    myJson.age; //29 
    myJson.name; //"mkyong" 

原因嘗試使用解析解析它()首先是避免使用jQuery,而已經有一個內置的功能,這個由瀏覽器提供。但是,如果沒有檢測到這個函數,它將通過jQuery解析它。

我希望這有助於

爲了您的利益

您的數據例子似乎是某種形式的二進制數據,你正試圖通過網絡發送。這可能會導致路由器過濾這些數據。如果您有興趣,您可以在將數據流式傳輸到客戶端之前將其編碼到Base64中。這很容易,因爲已經有很多圖書館了。

Some resources regarding to this topic.

所以它會像

SERVER 
    1) Jackson creates JSON String 
    2) Server encodes into Base64 
    3) Send 

CLIENT 
    1) Receive 
    2) Decode base64 
    3) parse JSON String 
+0

你能解釋我爲什麼收到downvote嗎? – Jason 2013-04-24 11:37:38

1

注:我是EclipseLink JAXB (MOXy)鉛和JAXB (JSR-222)專家小組的成員。

以下是您如何使用MOXy作爲JSON綁定提供程序來支持此用例。

Java模型

默認情況下,一個JAXB實現將一個byte[]轉換爲base64Binary的。您可以使用HexBinaryAdapter將其表示爲hexBinary。

package forum15643723; 

import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 

    private byte[] foo; 

    @XmlJavaTypeAdapter(HexBinaryAdapter.class) 
    private byte[] bar; 

} 

演示

在演示代碼下面我們將讀取到的JSON對象,然後寫回JSON。

package forum15643723; 

import java.util.*; 
import javax.xml.bind.*; 
import javax.xml.transform.stream.StreamSource; 
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[] {Root.class}, properties); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     StreamSource json = new StreamSource("src/forum15643723/input.json"); 
     Root root = (Root) unmarshaller.unmarshal(json, Root.class).getValue(); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(root, System.out); 
    } 

} 

jaxb.properties

要指定莫西爲您的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 

input.json /輸出

foo的和bar屬性表示相同的數據。 foo表示爲base64Binary,bar表示爲hexBinary。

{ 
    "foo" : "3q2+78r+", 
    "bar" : "DEADBEEFCAFE" 
} 

更多信息

3

傑克遜將字節[]轉換成Base64編碼的二進制數據。這是傳遞二進制內容的安全方式。否則,無法知道包含的數據可能使用哪種字符編碼,因此嘗試從中創建一個字符串將是有風險和容易出錯的。

所以最簡單的方法是將接收器base64解碼內容重新轉換爲二進制數據。

您也可以添加自定義序列化程序以轉換爲其他表示(hex,base85),但這取決於目標是什麼。