Javaオブジェクトをバイト配列に変換することは、Nettyを使用して通信プロトコル伝送を使用するシナリオでは非常に一般的です。たとえば、プロトコルにはいくつかの確立されたプロトコルヘッダー、ClassID、MessageIDS、その他の情報があり、別の重要なコンテンツはペイロードです。さまざまなプロトコルの内容がペイロードに配置され、このペイロードは多くの場合バイト配列です。
では、Javaオブジェクトをバイト配列に便利に構築するにはどうすればよいですか?
1 bytebuf fill
次のオブジェクトの例を示しましょう。
パブリッククラスのugvdataは、serialisible {private static final long serialversionuid = -21998432063763456l; //ステータスコードバイトステータス。 //現在のGPS経度フロート経度; //現在のGPS Latitude Float Latitude; //駆動速度ユニットはM/sで、小数点のフロート速度があります。 //現在のバッテリーの割合短いバッテリーの割合。 //タスク番号ロングクエスト; public byte [] tobytearray(){bytebuf buf = unpooled.buffer(32); buf.writebyte(this.getStatus()); buf.writefloat(getLongitude()); buf.writefloat(getLatitude()); buf.writefloat(getSpeed()); buf.writeshort(getbatterypercentage()); buf.writelong(getQuest()); buf.array(); } // omit get set}次に、上記のオブジェクトのいずれかを新しいものにして、Tobytearrayメソッドを呼び出して、このオブジェクトをバイト配列に変換する必要があります。
2。JSONを巧みに使用します
私たちは皆、文字列をバイト配列に変換できることを知っています。また、オブジェクトをJSON文字列に変換することも簡単です。FastJSONを直接使用するだけです。 Fastjsonの使用に問題がある場合は、json.parseObjectとjson.tojsonstringインスタンスの別のブログをご覧ください。
json.tojsonstring(ugvdata).getBytes()
3反射法
最初の方法の欠点は、各クラスがこのようなTobytearrayメソッドを記述する必要があることです。クラスが多すぎると、非常に厄介です。便利な方法はありますか?もちろん、リフレクションを使用するものがあります(初めて反射するだけで、ローカルキャッシュは後で実行されるため、パフォーマンスオーバーヘッドは大きくありません)。フォルダーに次の5つのクラスを追加する必要があります
1.CODECABLE
com.fasterxml.jackson.annotation.jsonignore;インポートcom.google.common.collect.lists; import lombok.data; Import java.lang.reflect.field; Import java.util.collection; import java.util.comparator; Import java.util.util.util.list.list.list.list.list.list.list.list.list.list.list.list.list.list.list.list.list.list.list. List <FieldWrapper> ResolveFileLdWrapperList(class clazz){field [] fields = clazz.getDeclaredfields(); List <FieldWrapper> fieldWrapperList = lists.newArrayList(); for(フィールドフィールド:フィールド){codecproprety codecproprety = field.getannotation(codecproprety.class); if(codecproprety == null){継続; } fieldwrapper fw = new fieldwrapper(field、codecproprety); fieldwrapperlist.add(fw); } collections.sort(fieldwrapperlist、new Comparator <FieldWrapper>(){@Override public compare(fieldwrapper o1、fieldwrapper o2){return o1.getCodecProprety()。 Return FieldWrapperList; } @jsonignoreパブリックアブストラクトリスト<FieldWrapper> getFieldWrapperList();}2.CodecProprety
java.lang.annotation.elementType; Import java.lang.annotation.retention; import java.lang.annotation.retentionPolicy; Import java.lang.annotation.target; @retention(retentionpolicy.runtime)@target({elementpe.field.pilded})public @Interface codecececpredececprety @return */ int Order(); /***データの長さ。デコード中に使用すると、単純なデータ型(文字列など)を除いてのみ機能します。 * @return */ int length()default 0;}3。フィールドライッパー
Import Lombok.AllargSconstructor; Import Lombok.Data; Import Java.lang.Reflect.field;@data@allargSconstructOrpublic FieldWrapper { / *** Up and Down Data属性* /プライベートフィールドフィールド。 / ***上下のデータ属性に関する注釈*/ private codecproprety codecproprety;}4。PayloadDecoder
io.netty.buffer.bytebuf; import io.netty.buffer.unpooled; import java.lang.reflect.field; Import java.lang.reflect.method; Import Java.nio.Charset.Charset; Import Java.util.List; Resolve(byte [] src、class <t> clazz){t instance = null; try {instance = clazz.newinstance(); } catch(Exception e){新しいruntimeException( "インスタンス化クラスが失敗した"、e)をスローします。 } list <fieldwrapper> fieldwrapperlist = instance.getFieldWrapperList(); bytebuf buffer = unpooled.buffer()。writebytes(src); for(fieldwrapper fieldwrapper:fieldwrapperlist){filldata(fieldwrapper、instance、buffer); } returnインスタンス; } private static void filldata(fieldwrapper fieldwrapper、object instance、bytebuf buffer){field field = fieldwrapper.getfield(); field.setAccessible(true); string typename = field.getType()。getName(); try {switch(typename){case "java.lang.boolean":case "boolean":boolean b = buffer.readboolean(); field.set(instance、b);壊す; case "Java.lang.Character":case "char":charquence charsequence = buffer.readcharescence(fieldwrapper.getcodecproprety()。length()、charset.forname( "utf-8")); field.set(instance、charsequence);壊す;ケース "Java.lang.byte":case "byte":byte ":byte b1 = buffer.read.set(); field.set(instance、b1); break; case" java.lang.short ":case" short ":short readshort = buffer.readshort(); field.set(intance、intsance); case" java "Java buffer.set(readint); 「java.lang.double」:double double = buffer.read.set(instance、readdouble); field.set(readstring);5。PayloadEncoder
io.netty.buffer.bytebuf; import io.netty.buffer.unpooled; import java.lang.reflect.field; Import java.lang.reflect.method; Import java.nio.Charset.Charset; Import Java.util.List; Public PayLoadEncoder {Public LoadEncoder <texecable getPayload(t command){list <fieldwrapper> fieldwrapperlist = commad.getFieldWrapperList(); bytebuf buffer = unpooled.buffer(); fieldwrapperlist.foreach(fieldwrapper-> write2bytebuf(fieldwrapper、command、buffer)); return buffer.array(); } / ** *データはbytebufに書き込まれます * * @param fieldwrapper * @param instance * @param buffer * / private static void write2bytebuf(fieldwrapper fieldwrapper、object instance、bytebuf buffer){field field = fieldwrapper.getfield(); string typename = field.getType()。getName(); field.setAccessible(true);オブジェクト値= null; try {value = field.get(instance); } catch(Illegalaccessexception e){new runtimeException( "反射は価値を得ることができなかった、filed:" + field.getName()、e); } switch(typename){case "java.lang.boolean":case "boolean":buffer.writeboolean((boolean)value);壊す;ケース "Java.lang.Character":case "char":buffer.writechar seaveence((charsequence)value、charset.forname( "utf-8"));壊す;ケース "Java.lang.byte":case "byte":buffer.writebyte((byte)value);壊す;ケース "Java.lang.short":case "short":buffer.writeshort((short)value);壊す; case "Java.lang.integer":case "int":buffer.writeint((int)value);壊す;ケース "Java.lang.Long":case "long":buffer.writelong((long)value);壊す;ケース "Java.lang.float":case "float":buffer.writefloat((float)value);壊す;ケース "Java.lang.double":case "double":buffer.writedouble((double)value);壊す;ケース "java.lang.string":buffer.writechar sequence((charsequence)value、charset.forname( "utf-8"));壊す;デフォルト:新しいruntimeexception(typename + "not supported、bug")をスローします。 }}}上記の5つのクラスを追加した後、非常に使いやすいです。以下に示すように、DrivestartDataをバイト配列に変換するだけです。
PayloadEncoder.getPayload(drivestartData)
4つの要約
一部の人々は、上記の3つのタイプは明らかにJSONを変換する2番目のタイプであることが最も単純なので、なぜ他の2つを使用する必要があるのですか?
実際、最初と3番目のタイプは同じカテゴリに分類でき、両方ともオブジェクトを直接バイト配列に変換します。次のレイヤーが解析されている場合、1つずつ取ることができます。
2番目のケースは、オブジェクトのJSON文字列をバイト配列に変換することです。問題は、JSON文字列の始まりは「{」、つまり、変換されたバイト配列の最初の数字は「{」の値に対応することです。
使用中は、状況に基づいている必要があります。次のレイヤーが要素を直接分析する場合は、オブジェクトが少ない場合は最初の要素を使用します。多くのオブジェクトがある場合は、3番目のものを使用します。
次のレイヤーがJSONのいくつかの形式を解析する場合は、2番目のレイヤーを使用します。
上記はすべて、この記事のコンテンツ全体です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。