码迷,mamicode.com
首页 > 其他好文 > 详细

剖析固定長度欄位的訊息字串

时间:2014-08-09 18:22:18      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   java   使用   os   io   

在進行系統整合時,系統間不管是透過網路、檔案傳送訊息資料,常會遇到訊息字串的各個欄位是固定長度的,這種情況下程式怎麼寫會比較簡潔易懂? 這裡是我提供的一個方法,使用 annotation 將訊息字串欄位的設定值直接寫在程式上,而不是寫在設定檔裡,這樣應該會比較直覺。

假設有個程式,要顯示中華民國總統的任期和歷史評價,其訊息格式如下:

bubuko.com,布布扣

首先,我們定義一個 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 Steven
13  */
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
總統姓名: 馬英九    
歷史評價: 一個自私的笨蛋、禍國殃民!    

 

剖析固定長度欄位的訊息字串,布布扣,bubuko.com

剖析固定長度欄位的訊息字串

标签:style   blog   http   color   java   使用   os   io   

原文地址:http://www.cnblogs.com/stevwn/p/3901236.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!