การแปลงวัตถุ Java เป็นอาร์เรย์ไบต์เป็นเรื่องธรรมดามากในสถานการณ์ที่ใช้การส่งผ่านโปรโตคอลการสื่อสารโดยใช้ netty ตัวอย่างเช่นโปรโตคอลมีส่วนหัวโปรโตคอลที่จัดตั้งขึ้น ClassIDS ข้อความและข้อมูลอื่น ๆ และเนื้อหาคีย์อื่นคือน้ำหนักบรรทุก เนื้อหาโปรโตคอลที่แตกต่างกันจะถูกวางไว้ในน้ำหนักบรรทุกและน้ำหนักบรรทุกนี้มักจะเป็นอาร์เรย์ไบต์
ดังนั้นวิธีการสร้างวัตถุ Java ให้เป็นอาร์เรย์ไบต์ได้อย่างสะดวก?
1 bytebuf เติม
ลองยกตัวอย่างของวัตถุต่อไปนี้:
ระดับสาธารณะ UGVDATA ใช้ serialisible {ส่วนตัวคงที่สุดท้าย Long SerialVersionUid = -219988432063763456L; // สถานะรหัสสถานะไบต์; // ลองจิจูดลองจิจูด GPS ปัจจุบัน // Latitude Latitude Latitude Float ปัจจุบัน; // หน่วยความเร็วในการขับขี่คือ m/s ด้วยความเร็วทศนิยมลอย // เปอร์เซ็นต์แบตเตอรี่ในปัจจุบันเปอร์เซ็นต์การแบตเตอรี่สั้น ๆ ; // หมายเลขงานยาวภารกิจ; ไบต์สาธารณะ [] 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 ()); return buf.array (); } // ละเว้นการตั้งค่า}จากนั้นคุณเพียงแค่ต้องออกวัตถุข้างต้นใหม่และเรียกใช้วิธี TobyTearray เพื่อแปลงวัตถุนี้เป็นอาร์เรย์ไบต์
2. ใช้ JSON อย่างชำนาญ
เราทุกคนรู้ว่าสตริงสามารถแปลงเป็นอาร์เรย์ไบต์ นอกจากนี้ยังง่ายต่อการแปลงวัตถุเป็นสตริง JSON เพียงใช้ FastJSON โดยตรง หากคุณมีปัญหาในการใช้ fastjson คุณสามารถตรวจสอบบล็อกอื่นของ Json.parseObject และ json.tojsonstring อินสแตนซ์ของฉัน
json.tojsonstring (ugvdata) .getBytes ()
3 วิธีการสะท้อนกลับ
ข้อเสียของวิธีแรกคือแต่ละคลาสจะต้องเขียนวิธี Tobytearray เช่นนี้ หากมีชั้นเรียนมากเกินไปมันเป็นปัญหามาก มีวิธีที่สะดวกหรือไม่? แน่นอนว่ามีหนึ่งซึ่งใช้การสะท้อน (มันจะสะท้อนให้เห็นในครั้งแรกเท่านั้นและแคชท้องถิ่นจะทำในภายหลังดังนั้นค่าใช้จ่ายประสิทธิภาพไม่ใหญ่) คุณต้องเพิ่มห้าคลาสต่อไปนี้ในโฟลเดอร์
1. ทำได้
นำเข้า com.fasterxml.jackson.annotation.jsonignore; นำเข้า com.google.common.collect.lists; นำเข้า lombok.data; นำเข้า java.lang.reflect.field; นำเข้า java.util.collections; รายการ <fieldWrapper> RENLEVEFILELDWRAPPERLIST (คลาส Clazz) {ฟิลด์ [] ฟิลด์ = clazz.getDeclaredFields (); รายการ <fieldWrapper> fieldWrapperList = lists.newarrayList (); สำหรับ (ฟิลด์ฟิลด์: ฟิลด์) {codeCPropretity codeCPropretity = field.getNanTation (codeCPropretity.class); if (codeCProprety == null) {ดำเนินการต่อ; } FieldWrapper fw = ใหม่ FieldWrapper (ฟิลด์, codecProprete); FieldWrapperlist.add (FW); } collections.sort (FieldWrapperList, ตัวเปรียบเทียบใหม่ <FieldWrapper> () {@Override Public Public Int Compare (FieldWrapper O1, FieldWrapper O2) {return o1.getCodecProprethety (). order () - o2.getCodecProprety (). ส่งคืน FieldWrapperList; } @jsonignore รายการนามธรรมสาธารณะ <FieldWrapper> getFieldWrapperList ();}2. ความน่าเชื่อถือ
นำเข้า java.lang.annotation.ElementType; นำเข้า java.lang.annotation.Retention; นำเข้า java.lang.annotation.retentionPolicy; นำเข้า java.lang.annotation.target; @retention (retentionpolicy.runtime) @target สั่งซื้อ * @return */ int order (); /*** ความยาวข้อมูล ใช้ในระหว่างการถอดรหัสมันใช้งานได้ยกเว้นประเภทข้อมูลอย่างง่าย (เช่นสตริง) * @return */ int length () ค่าเริ่มต้น 0;}
3. FieldWrapper
นำเข้า lombok.allargsconstructor; นำเข้า lombok.data; นำเข้า java.lang.reflect.field;@data@allargsconstructorpublic คลาส FieldWrapper { / *** ขึ้นและลงคุณลักษณะฟิลด์ฟิลด์ส่วนตัว; / *** คำอธิบายประกอบในการขึ้นและลงคุณลักษณะข้อมูล*/ codecpropretity private codeCpropretity;}4. payloaddecoder
นำเข้า io.netty.buffer.bytebuf; นำเข้า io.netty.buffer.unpooled; นำเข้า java.lang.reflect.field นำเข้า java.lang.reflect.method; นำเข้า java.nio.charset.charset; แก้ไข (ไบต์ [] src, คลาส <t> clazz) {t อินสแตนซ์ = null; ลอง {อินสแตนซ์ = clazz.newinstance (); } catch (exception e) {โยน runtimeException ใหม่ ("คลาสอินสแตนซ์ล้มเหลว", e); } รายการ <fieldWrapper> fieldWrapperList = instance.getFieldWrapperList (); bytebuf buffer = unpooled.buffer (). writebytes (src); สำหรับ (FieldWrapper FieldWrapper: FieldWrapperList) {FillData (FieldWrapper, อินสแตนซ์, บัฟเฟอร์); } return อินสแตนซ์; } โมฆะคงที่ส่วนตัว FillData (FieldWrapper FieldWrapper, อินสแตนซ์วัตถุ, บัฟเฟอร์ bytebuf) {ฟิลด์ฟิลด์ = fieldWrapper.getField (); field.setAccessible (จริง); สตริง typename = field.getType (). getName (); ลอง {switch (typename) {case "java.lang.boolean": case "boolean": boolean b = buffer.readboolean (); field.set (อินสแตนซ์, b); หยุดพัก; กรณี "java.lang.character": case "char": charsequence charsequence = buffer.readcharequence (fieldwrapper.getCodecPropretity (). length (), charset.forname ("UTF-8")); field.set (อินสแตนซ์, charsequence); หยุดพัก; กรณี "java.lang.byte": case "byte": byte ": byte b1 = buffer.readbyte (); field.set (อินสแตนซ์, b1); break; case" java.lang.short ": กรณี" สั้น ": readshort สั้น ๆ buffer.readint (); "java.lang.double": case "double": double readdouble = buffer.readdouble (); Field.set (อินสแตนซ์, readstring);5. PayloadenCoder
นำเข้า io.netty.buffer.bytebuf; นำเข้า io.netty.buffer.unpooled; นำเข้า java.lang.reflect.field นำเข้า java.lang.reflect.method; นำเข้า java.nio.charset.charset; getPayLoad (คำสั่ง t) {รายการ <fieldWrapper> fieldWrapperList = command.getFieldWrapperList (); bytebuf buffer = unpooled.buffer (); FieldWrapperList.foreach (FieldWrapper -> write2ByTebuf (FieldWrapper, คำสั่ง, บัฟเฟอร์)); return buffer.Array (); } / ** * ข้อมูลถูกเขียนไปยัง byteBuf * * @param fieldwrapper * @param อินสแตนซ์ * @param buffer * / โมฆะคงที่ private write2ByTebuf (FieldWrapper FieldWrapper, อินสแตนซ์ออบเจ็กต์, บัฟเฟอร์ byteBuf) สตริง typename = field.getType (). getName (); field.setAccessible (จริง); ค่าวัตถุ = null; ลอง {value = field.get (อินสแตนซ์); } catch (unglemalAccessException e) {ใหม่ runtimeException ("การสะท้อนกลับล้มเหลวในการรับค่ายื่น:" + field.getName (), e); } switch (typename) {case "java.lang.boolean": case "boolean": buffer.writeboolean ((บูลีน) ค่า); หยุดพัก; กรณี "java.lang.character": case "char": buffer.writecharequence ((charsequence) ค่า, charset.forname ("UTF-8")); หยุดพัก; กรณี "java.lang.byte": case "byte": buffer.writeByte ((ไบต์) ค่า); หยุดพัก; กรณี "java.lang.short": กรณี "สั้น": buffer.writeshort ((สั้น) ค่า); หยุดพัก; กรณี "java.lang.integer": กรณี "int": buffer.writeint ((int) ค่า); หยุดพัก; กรณี "java.lang.long": case "long": buffer.writelong ((ยาว) ค่า); หยุดพัก; กรณี "java.lang.float": case "float": buffer.writefloat ((ลอย) ค่า); หยุดพัก; กรณี "java.lang.double": case "double": buffer.writedouble ((สอง) ค่า); หยุดพัก; กรณี "java.lang.string": buffer.writecharequence ((charsequence) ค่า, charset.forname ("UTF-8")); หยุดพัก; ค่าเริ่มต้น: โยน runtimeException ใหม่ (typename + "ไม่รองรับ, บั๊ก"); -หลังจากเพิ่มคลาสห้าชั้นข้างต้นแล้วมันก็ใช้งานง่ายมาก คุณจะต้องแปลง DrivestartData เป็นอาร์เรย์ไบต์ดังที่แสดงด้านล่าง
payloadencoder.getPayload (drivestartData)
4 สรุป
บางคนอาจถามว่าสามประเภทข้างต้นเห็นได้ชัดว่าเป็นประเภทที่สองในการแปลง JSON นั้นง่ายที่สุดดังนั้นทำไมคุณต้องใช้อีกสองคน?
ในความเป็นจริงประเภทที่หนึ่งและสามสามารถแบ่งออกเป็นหมวดหมู่เดียวกันทั้งสองแปลงวัตถุโดยตรงเป็นอาร์เรย์ไบต์ หากเลเยอร์ถัดไปถูกแยกวิเคราะห์ก็สามารถใช้ทีละตัวได้
กรณีที่สองคือการแปลงสตริง JSON ของวัตถุเป็นอาร์เรย์ไบต์ ปัญหาคือจุดเริ่มต้นของสตริง JSON คือ "{" นั่นคือหลักแรกของอาร์เรย์ไบต์ที่แปลงคือ "{" สอดคล้องกับค่าของ "{"
ในการใช้งานควรขึ้นอยู่กับสถานการณ์ หากเลเยอร์ถัดไปวิเคราะห์องค์ประกอบโดยตรงให้ใช้สิ่งแรกหากมีวัตถุน้อยกว่า ใช้อันที่สามหากมีวัตถุมากมาย
หากเลเยอร์ถัดไปแยกวิเคราะห์รูปแบบของ JSON ให้ใช้รูปที่สอง
ทั้งหมดข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น