首页 > 代码库 > 剖析固定長度欄位的訊息字串
剖析固定長度欄位的訊息字串
在進行系統整合時,系統間不管是透過網路、檔案傳送訊息資料,常會遇到訊息字串的各個欄位是固定長度的,這種情況下程式怎麼寫會比較簡潔易懂? 這裡是我提供的一個方法,使用 annotation 將訊息字串欄位的設定值直接寫在程式上,而不是寫在設定檔裡,這樣應該會比較直覺。
假設有個程式,要顯示中華民國總統的任期和歷史評價,其訊息格式如下:
首先,我們定義一個 annotation,可以設定欄位的開始位置和長度,如下:
1 package idv.steven; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 @Retention(RetentionPolicy.RUNTIME) 9 @Target(ElementType.FIELD)10 public @interface MsgField {11 public int start();12 public int length();13 }
接著定義一個 POJO,並且於類別裡的各個欄位上設定開始位置、長度,因為訊息有四個欄位,當然這個類別也有相對應的四個欄位。
1 package idv.steven.pojo; 2 3 import idv.steven.MsgField; 4 5 public class Message { 6 @MsgField(start=0,length=4) 7 private String startYear; 8 @MsgField(start=4,length=4) 9 private String endYear;10 @MsgField(start=8,length=10)11 private String name;12 @MsgField(start=18,length=30)13 private String evaluate;14 15 /**16 * @return 任期開始的年份17 */18 public String getStartYear() {19 return startYear;20 }21 public void setStartYear(String startYear) {22 this.startYear = startYear;23 }24 25 /**26 * @return 任期結束的年份27 */28 public String getEndYear() {29 return endYear;30 }31 public void setEndYear(String endYear) {32 this.endYear = endYear;33 }34 35 /**36 * @return 姓名37 */38 public String getName() {39 return name;40 }41 public void setName(String name) {42 this.name = name;43 }44 45 /**46 * @return 評價47 */48 public String getEvaluate() {49 return evaluate;50 }51 public void setEvaluate(String evaluate) {52 this.evaluate = evaluate;53 }54 }
下面就是剖析訊息的程式了…
1 package idv.steven; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 import java.util.Arrays; 7 8 import idv.steven.pojo.Message; 9 10 /**11 * 剖析固定欄位長度的訊息12 * @author Steven13 */14 public class Parser {15 private Message parsing(byte[] msg) 16 throws IllegalArgumentException, IllegalAccessException, 17 NoSuchMethodException, SecurityException, 18 InvocationTargetException, ClassNotFoundException {19 20 Message message = new Message();21 22 Class<?> aClass = Class.forName(Message.class.getName());23 Field[] fields = aClass.getDeclaredFields();24 for(Field field:fields) {25 MsgField msgField = field.getAnnotation(MsgField.class);26 if (msgField != null) {27 byte[] subMsg = Arrays.copyOfRange(msg, msgField.start(), msgField.start() + msgField.length());28 29 Method method = aClass.getMethod(getSetterName(field.getName()), String.class);30 method.invoke(message, new String(subMsg));31 //field.set(message, new String(subMsg));32 }33 }34 35 return message;36 }37 38 private String getSetterName(String fieldName) {39 return String.format("set%s%s", fieldName.substring(0, 1).toUpperCase(), fieldName.substring(1));40 }41 42 public void run(byte[] msg) {43 try {44 Message message = parsing(msg);45 46 System.out.println("任期: " + message.getStartYear() + " ~ " + message.getEndYear());47 System.out.println("總統姓名: " + message.getName());48 System.out.println("歷史評價: " + message.getEvaluate());49 } catch (Exception e) {50 e.printStackTrace();51 } 52 }53 54 public static void main(String[] args) {55 56 new Parser().run("20082016馬英九 一個自私的笨蛋、禍國殃民! ".getBytes());57 }58 }
執行結果如下:
任期: 2008 ~ 2016總統姓名: 馬英九 歷史評價: 一個自私的笨蛋、禍國殃民!
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。