2013-03-26 12 views
5

Jestem niesamowicie nowy w Jackson i mam problem ze zrozumieniem, w jaki sposób mogę coś osiągnąć.Jackson Custom Mapper do konwersji Byte Array na String

Mam niektóre dane typu byte[] (dane należą do klas generowanych z JAXB). Zanim dane zostaną przesłane do przeglądarki, Jackson (jak sądzę) zamieni je w JSON, aby strona mogła je pochłonąć. Przynajmniej do tej pory to moje niedorzeczne zrozumienie.

Dane JSON pokazują moje byte [] jako ciągi, które nie pasują do ekranu, który chcemy. Na przykład rzeczywiste dane mogą być CAFEDEAD, ale ciąg JSON wygląda na 3q2+78r+. Chciałbym, żeby JSON zawierał ciąg znaków CAFEDEAD

Moje pytanie brzmi, czy mogę napisać coś niestandardowego dla Jacksona, że ​​zanim utworzy on ostateczny JSON, zmieni dane byte[] w czytelny ciąg szesnastkowy? A jeśli nie, jakie inne opcje mam?

Mam dostęp do javascript, więc jeśli istnieje sposób, aby z powrotem przywrócić ciąg JSON, ja też mam na to ochotę.

+1

Dlaczego to ważne, w jaki sposób JSON propaguje dane binarne? To brzmi jak prawdopodobnie Base64 - więc odkoduj base64, aby odzyskać oryginalne dane binarne, a następnie możesz je wyświetlić w dowolny sposób. –

+0

Dasz temu pomysłowi szansę, dziękuję Jon! – Robb

+0

Pokaż nam kod – Jason

Odpowiedz

-1

Można używać adnotacji @JsonSerialize i @JsonDeSerialize nad dowolną właściwością. javadoc jest

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

bym osobiście użyć techniki serializacji/deserializacji zamiast konwersji na stronie klienta jak zapewne skończy się to robi w wielu miejscach.

0

Bez żadnego kodu, musiałem odgadnąć, co robisz zgodnie z twoim pytaniem. Ten poradnik JSON parse to/from using Jackson pokazuje jak przerobić ObjectMapper do Stringfiyed reprezentacji JSON na przykład

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

Potem, gdy klient JavaScript odbiera ten ciąg, będziesz mieć do analizowania tego stosując albo wbudowana funkcja parse JSON lub jQuery warunkiem jeden. Jak

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

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

Powodem próby analizowania go przy użyciu parse() pierwsza jest uniknięcie jQuery podczas gdy jest już wbudowany w funkcji dla tego dostarczane przez przeglądarkę. Jeśli jednak ta funkcja nie zostanie wykryta, przeanalizuje ją za pomocą jQuery.

Mam nadzieję, że to pomoże

za zainteresowanie

Twój przykład dane wydaje się być pewnego rodzaju danych binarnych i próbujesz wysłać go w sieciach. Może to spowodować, że routery będą filtrować te dane. Jeśli jesteś zainteresowany, możesz rzucić okiem na kodowanie tych danych w Base64 przed przesłaniem ich strumieniowo do klienta. Jest to bardzo łatwe, ponieważ istnieje już wiele bibliotek.

Some resources regarding to this topic.

Więc to będzie jak

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

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

Czy możesz wyjaśnić mi, dlaczego otrzymałem skargę? – Jason

1

Uwaga: Jestem EclipseLink JAXB (MOXy) ołowiu i członkiem grupy JAXB (JSR-222) ekspertów.

Poniżej przedstawiono sposób obsługi tego przypadku użycia z MOXy jako dostawcą wiążącym JSON.

Java model

Domyślnie implementacja JAXB będzie konwertować byte[] do base64Binary. Możesz użyć HexBinaryAdapter, aby był reprezentowany jako 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; 

} 

Demo

W kodzie demo poniżej czytamy JSON do obiektów, a następnie zapisać go z powrotem do 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

Aby określić Moxy jako dostawcę JAXB musisz dołączyć plik o nazwie jaxb.properties w tym samym opakowaniu jak model domeny (patrz: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html).

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

input.json/Output

W foo i bar właściwości reprezentują te same dane. foo jest reprezentowany jako base64Binary i bar jest reprezentowany jako hexBinary.

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

Aby uzyskać więcej informacji

3

Jackson zamieni bajt [] na base64 kodowanych danych binarnych. Jest to bezpieczny sposób przekazywania treści binarnych. W przeciwnym razie nie ma sposobu, aby wiedzieć, które kodowanie znaków może być używane przez zawarte w nim dane, więc próba zbudowania z niego łańcucha byłaby ryzykowna i podatna na błędy.

Tak więc najprostszym sposobem byłoby, aby odbiornik base64 dekodować zawartość z powrotem do danych binarnych.

Można alternatywnie dodać niestandardowy serializator, aby przekształcić go w inne reprezentacje (hex, base85), ale to naprawdę zależy od tego, jaki jest cel.