يعد تحويل كائنات Java إلى صفائف بايت أمرًا شائعًا جدًا في السيناريوهات حيث يتم استخدام نقل بروتوكول الاتصال باستخدام NetTy. على سبيل المثال ، يحتوي البروتوكول على بعض رؤوس البروتوكول المعمول بها ، والفئران ، والرسائل وغيرها من المعلومات ، ومحتوى رئيسي آخر هو حمولة. سيتم وضع محتويات البروتوكول المختلفة في الحمولة ، وغالبًا ما تكون هذه الحمولة الصافية عبارة عن مجموعة بايت.
لذلك ، كيف تبني كائن جافا بشكل مريح في صفيف بايت؟
1 BYTEBUF ملء
دعونا نعطي مثالا على الكائن التالي:
الطبقة العامة ugvdata تنفذ serialisible {private static final long serialversionuid = -219988432063763456l ؛ // Code Code Byte Status ؛ // خط الطول الحالي GPS الطول. // خط عرض خط العرض GPS الحالي ؛ // وحدة سرعة القيادة هي m/s ، مع سرعة تعويم النقطة العشرية ؛ // النسبة المئوية للبطارية الحالية BatteryPercentage ؛ // رقم المهمة السعي الطويل ؛ البايت العام [] tobytearray () {bytebuf buf = unpooled.buffer (32) ؛ buf.writeByte (this.getStatus ()) ؛ buf.writefloat (getLongitude ()) ؛ buf.writefloat (getLatitude ()) ؛ buf.writefloat (getSpeed ()) ؛ buf.writeShort (getBatteryperCenge ()) ؛ buf.writelong (getQuest ()) ؛ إرجاع buf.array () ؛ } // حذف التعيين}ثم تحتاج فقط إلى تحديد الكائن أعلاه والاتصال بأسلوب TOBYTEARRAY لتحويل هذا الكائن إلى صفيف بايت.
2. استخدم JSON بمهارة
نعلم جميعًا أنه يمكن تحويل السلاسل إلى صفائف بايت. من السهل أيضًا تحويل كائن إلى سلسلة JSON ، فقط استخدم FastJson مباشرة. إذا كانت لديك مشاكل في استخدام FastJson ، فيمكنك التحقق من مدونة أخرى من مثيل Json.ParseObject و JSON.TOJSORNING
json.tojsonstring (ugvdata) .getbytes ()
3 طريقة الانعكاس
عيب الطريقة الأولى هو أن كل فصل يجب أن يكتب طريقة TobyTearray مثل هذا. إذا كان هناك الكثير من الفصول ، فهي مزعجة للغاية. هل هناك أي طريقة مريحة؟ بالطبع ، هناك واحد ، يستخدم الانعكاس (سيعكس فقط المرة الأولى ، وسيتم إجراء ذاكرة التخزين المؤقت المحلية لاحقًا ، وبالتالي فإن النفقات العامة للأداء ليست كبيرة). تحتاج إلى إضافة الفئات الخمسة التالية في مجلد
1.CODECADE
استيراد com.fasterxml.jackson.annotation.jsonignore ؛ استيراد com.google.common.collect.lists ؛ استيراد lombok.data ؛ استيراد java.lang.reflect.field solvefileldwrapperlist (class clazz) {field [] fields = clazz.getDeclaredFields () ؛ قائمة <FieldWrapper> fieldWrapperList = lists.newarrayList () ؛ لـ (حقل الحقل: الحقول) {codecproprety codecproprety = field.getAnnotation (codecproprety.class) ؛ if (codecproprety == null) {contern ؛ } fieldwrapper fw = new fieldwrapper (الحقل ، codecproprety) ؛ FieldWrapperList.add (FW) ؛ } collections.sort (fieldWrapperList ، New Cookator <FieldWrapper> () {Override public int compare (fieldWrapper O1 ، fieldWrapper O2) {return o1.getCodecpropRety (). order () - O2.getCodecPropRety (). order () ؛}}) ؛ إرجاع FieldWrapperList ؛ } @jsonignore قائمة الملخصات العامة <FieldWrapper> getFieldWrapperList () ؛}2.CODECPROPRETY
استيراد java.lang.annotation.elementtype ؛ import java.lang.annotation.retention ؛ import java.lang.annotation.retion regurn */ int order () ؛ /*** طول البيانات. يستخدم أثناء فك التشفير ، فهو يعمل فقط باستثناء نوع بيانات بسيط (مثل السلسلة). * return */ int length () الافتراضي 0 ؛}
3. FieldWrapper
استيراد lombok.allargsconstructor ؛ استيراد lombok.data ؛ استيراد java.lang.reflect.field ؛@data@allargsconstructorpublic class fieldwrapper { / *** Up and Down Data Sentributes* / حقل الحقل الخاص ؛ / *** التعليقات التوضيحية على سمات البيانات لأعلى ولأسفل*/ codecproprety private codecproprety ؛}4. PayloadDecoder
استيراد io.netty.buffer.bytebuf ؛ استيراد io.netty.buffer.unpooled ؛ استيراد java.lang.reflect.field ؛ استيراد java.lang.reflect.method ؛ استيراد java.nio.charset.charset src ، class <t> clazz) {t evalue = null ؛ حاول {مثيل = clazz.newinstance () ؛ } catch (استثناء e) {رمي new runTimeException ("فشل فئة التثبيت" ، e) ؛ } list <FieldWrapper> fieldWrapperList = evalue.getFieldWrapperList () ؛ bytebuf buffer = unpooled.buffer (). WriteBytes (SRC) ؛ لـ (fieldwrapper fieldwrapper: fieldWrapperList) {fillData (fieldwrapper ، مثيل ، عازلة) ؛ } مثيل الإرجاع ؛ } private static void filldata (fieldwrapper fieldwrapper ، مثيل الكائن ، bytebuf buffer) {field field = fieldwrapper.getfield () ؛ Field.SetAccessible (صحيح) ؛ string typename = field.gettype (). getName () ؛ حاول {switch (typename) {case "java.lang.boolean": case "boolean": boolean b = buffer.readboolean () ؛ field.set (مثيل ، ب) ؛ استراحة؛ Case "Java.lang.Character": Case "char": charquence charquence = buffer.ReadCharsence (fieldwrapper.getCodecProprety (). length () ، charset.forname ("UTF-8")) ؛ field.set (مثيل ، charsequence) ؛ استراحة؛ حالة "java.lang.byte": case "byte": byte ": byte b1 = buffer.readbyte () ؛ field.set (مثيل ، b1) = readint "java.lang.double": Case "Double": Double readDouble = charset.forname ("utf-8").5. Payloadencoder
استيراد io.netty.buffer.bytebuf ؛ استيراد io.netty.buffer.unpooled ؛ استيراد java.lang.reflect.field ؛ استيراد java.lang.reflect.method command) {list <FieldWrapper> fieldWrapperList = command.getFieldWrapperList () ؛ bytebuf buffer = unpooled.buffer () ؛ FieldWrapperList.foreach (fieldwrapper -> write2bytebuf (fieldwrapper ، command ، buffer)) ؛ إرجاع buffer.array () ؛ } / ** * تتم كتابة البيانات إلى bytebuf * * param fieldWrapper * @param مثيل * param buffer * / private static void write2bytebuf (fieldwrapper fieldwrapper ، outure exture ، bytebuf buffer) {field field = fieldwrapper.getfield () ؛ string typename = field.gettype (). getName () ؛ Field.SetAccessible (صحيح) ؛ قيمة الكائن = فارغة ؛ حاول {value = field.get (مثيل) ؛ } catch (alfictalaccessexception e) {new runTimeException ( } switch (typename) {case "java.lang.boolean": case "boolean": buffer.writeboolean ((boolean) value) ؛ استراحة؛ حالة "java.lang.character": Case "char": buffer.WriteCharsequence ((charsequence) value ، charset.forname ("utf-8")) ؛ استراحة؛ حالة "java.lang.byte": case "byte": buffer.writeByte ((byte) value) ؛ استراحة؛ Case "Java.lang.short": Case "Short": Buffer.WriteShort ((Short) value) ؛ استراحة؛ حالة "java.lang.integer": case "int": buffer.writeint ((int) value) ؛ استراحة؛ Case "Java.lang.long": Case "Long": Buffer.Writelong ((Long) value) ؛ استراحة؛ حالة "java.lang.float": Case "Float": Buffer.WriteFloat ((float) value) ؛ استراحة؛ Case "Java.lang.double": Case "Double": Buffer.Writedouble ((double) value) ؛ استراحة؛ Case "Java.lang.String": Buffer.WriteCharsequence ((charsequence) value ، charset.forname ("UTF-8")) ؛ استراحة؛ الافتراضي: رمي new RunTimeException (typename + "غير مدعوم ، خطأ") ؛ }}}بعد إضافة الفئات الخمسة أعلاه ، من السهل جدًا استخدامها. تحتاج فقط إلى تحويل DrivestartData إلى صفيف بايت كما هو موضح أدناه.
payloadencoder.getPayload (DrivestartData)
4 ملخص
قد يسأل بعض الأشخاص ، من الواضح أن الأنواع الثلاثة المذكورة أعلاه هي النوع الثاني لتحويل JSON هو أبسط ، فلماذا تحتاج إلى استخدام الآخرين؟
في الواقع ، يمكن تصنيف الأنواع الأولى والثالثة في نفس الفئة ، وكلاهما تحويل الكائن مباشرة إلى صفيف بايت. إذا تم تحليل الطبقة التالية ، فيمكن أن تؤخذ واحدة تلو الأخرى ؛
الحالة الثانية هي تحويل سلسلة JSON للكائن إلى صفيف بايت. المشكلة هي أن بداية سلسلة JSON هي "{" ، أي الرقم الأول من صفيف البايت الذي تم تحويله هو "{" يتوافق مع قيمة "{"
قيد الاستخدام ، يجب أن يعتمد على الموقف. إذا كانت الطبقة التالية تحلل العناصر مباشرةً ، فاستخدم الأول إذا كان هناك عدد أقل من الكائنات ؛ استخدم الثالث إذا كان هناك العديد من الكائنات ؛
إذا قامت الطبقة التالية بتحليل بعض أشكال JSON ، فاستخدمها الثانية.
كل ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.