5

私はジャクソンにとても慣れていないので、何かを達成する方法を理解するのに問題があります.

タイプbyte[]のデータがあります (データは JAXB から生成されたクラス内にあります)。データがブラウザーに送信される前に、Jackson はデータを JSON に変換して (私は信じています)、Web ページがそれを使用できるようにします。少なくとも、これまでのところ、それは私の大雑把な理解です。

JSON データは mybyte []を文字列として示していますが、これは必要な表示と一致しません。たとえば、実際のデータは かもしれませんCAFEDEADが、JSON 文字列は のようになり3q2+78r+ます。JSON に文字列を含めたいCAFEDEAD

私の質問は、Jackson が最終的な JSON を作成する前にbyte[]データを読み取り可能な 16 進文字列に変換するカスタムを作成できるかどうかです。または、そうでない場合、他にどのようなオプションがありますか?

私は JavaScript にアクセスできるので、JSON 文字列を元に戻す方法があれば、私もそれに賛成です。

4

4 に答える 4

3

Jackson は byte[] を Base64 でエンコードされたバイナリ データに変換します。これは、バイナリ コンテンツを安全に渡す方法です。そうしないと、含まれるデータでどの文字エンコーディングが使用されているかを知る方法がないため、そこから文字列を構築しようとすると危険でエラーが発生しやすくなります。

したがって、最も簡単な方法は、レシーバーの base64 でコンテンツをデコードしてバイナリ データに戻すことです。

別の方法として、カスタム シリアライザーを追加して他の表現 (16 進数、base85) に変換することもできますが、実際には目的が何であるかによって異なります。

于 2013-03-27T16:59:16.193 に答える
1

注: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。

以下は、JSON バインディング プロバイダーとして MOXy を使用してこのユース ケースをサポートする方法です。

Java モデル

デフォルトでは、JAXB 実装は abyte[]を 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

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

input.json/出力

fooプロパティとプロパティはbar同じデータを表します。 foobase64Binary としてbar表され、hexBinary として表されます。

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

詳細については

于 2013-03-27T10:59:23.397 に答える
-1

@JsonSerialize および @JsonDeSerialize アノテーションは、任意のプロパティに対して使用できます。javadoc は

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

おそらく複数の場所で行うことになるため、クライアント側での変換ではなく、シリアル化/逆シリアル化の手法を個人的に使用します。

于 2013-03-26T17:41:31.803 に答える
-1

コードがなければ、質問に従って何をしているのかを推測する必要がありました。このチュートリアルJSON parse to / from using Jacksonでは、ObjectMapper を JSON の Stringfiyed 表現に変換する方法を示します。

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

次に、Javascript クライアントがこの文字列を受け取ると、組み込みの JSON 解析関数または jQuery が提供する関数を使用してこれを解析する必要があります。お気に入り

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

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

最初に parse() を使用して解析を試みる理由は、ブラウザーによって提供される組み込み関数が既に存在する場合に jQuery の使用を避けるためです。ただし、この関数が検出されない場合は、jQuery を介して解析されます。

これが役立つことを願っています

あなたの興味のために

あなたのデータの例は、ある種のバイナリ データのように見え、ネットワーク経由で送信しようとしています。これにより、ルーターがこれらのデータをフィルタリングする可能性があります。興味がある場合は、クライアントにストリーミングする前に、このデータを Base64 にエンコードする方法を確認できます。すでに多くのライブラリが存在するため、非常に簡単に実行できます。

このトピックに関するいくつかのリソース。

だからそれは次のようになります

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

CLIENT
  1) Receive
  2) Decode base64
  3) parse JSON String
于 2013-03-27T05:44:35.467 に答える