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

在進行系統整合時,系統間不管是透過網路、檔案傳送訊息資料,常會遇到訊息字串的各個欄位是固定長度的,這種情況下程式怎麼寫會比較簡潔易懂? 這裡是我提供的一個方法,使用 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 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
總統姓名: 馬英九
歷史評價: 一個自私的笨蛋、禍國殃民!    

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

时间: 2024-10-11 10:04:16

剖析固定長度欄位的訊息字串的相关文章

九度1535 重叠的最长字串 字符串哈希

题目描述: 给定两个字符串,求它们前后重叠的最长子串的长度,比如"abcde"和"cdefg"是"cde",长度为3. 输入: 输入可能包含多个测试案例. 对于每个测试案例只有一行, 包含两个字符串.字符串长度不超过1000000,仅包含字符'a'-'z'. 输出: 对应每个测试案例,输出它们前后重叠的最长子串的长度. 样例输入: abcde cdefg 样例输出: 3 #include <iostream> #include <

[ SQLServer ] 數字類型的欄位細節 - 轉載

[MSSQL] 欄位開立(2) - decimal, numeric, float, real, money 的抉擇 https://dotblogs.com.tw/henryli/2015/06/13/151557 資料庫黑洞部落格 https://dotblogs.com.tw/henryli/1

Oracle Long 類型欄位處理

Long 數據類型的特點 1.LONG 数据类型中存储的是可变长字符串,最大长度限制是2GB. 2.对于超出一定长度的文本,基本只能用LONG类型来存储,数据字典中很多对象的定义就是用LONG来存储的.1.LONG 数据类型中存储的是可变长字符串,最大长度限制是2GB. 2.对于超出一定长度的文本,基本只能用LONG类型来存储,数据字典中很多对象的定义就是用LONG来存储的. 3.LONG类型主要用于不需要作字符串搜索的长串数据,如果要进行字符搜索就要用varchar2类型. 4.很多工具,包括

单词错误纠正功能 编辑距离 最大公共字串 两个字符串的相似度 差异度

莱文氏距离 i指向a字符串中的字符j指向b字符串中的字符s[][]存储第a中第i个字符和b中第j个字符相比较后,最小的莱文氏距离值 状态的转移对应2种,其中字符不相等时有3种情况1.a[i]==b[j] ,那么 i++ j++ ,距离值保持上一状态的2.a[i]!=b[j] ,需要增加距离值,那么需要考虑是下面3种情况的哪一种(能得到最小的距离值增量,所以需要做穷举组合处理) 2.1. i++ (表示a中当前字母当删除处理,或者在b中虚拟添加一个和a[i]一样的字符,处理后,距离值+1,然后i自

怎么使float保留两位小数或多位小数*如何将整数 int 转换成字串 String

5.怎么使float保留两位小数或多位小数* 两种方法: import java.math.*; -- 方法1: float f = 34.232323; BigDecimal b = new BigDecimal(f); float f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue(); // b.setScale(2, BigDecimal.ROUND_HALF_UP) 表明四舍五入,保留两位小数 方法2: float scale

搜索里的相似度计算-最长公共字串

相似度计算的任务是根据两段输入文本的相似度返回从0到1之间的相似度值:完全不相似,则返回0,:完全相同,返回1.衡量两端文字距离的常用方法有:海明距离(Hamming distance),编辑距离,欧氏距离,文档向量的夹角余弦距离,最长公共字串. 1. 余弦相似度 把两篇文档看作是词的向量,如果x,y为两篇文档的向量,则:Cos(x, y) = (x * y) / (||x|| * ||y||) 使用Hashmap可以很方便的把这个计算出来 2. 最长公共字串(Longest Common Su

正位瑜伽垫如“田”字格,助练习者养成良好的瑜伽习惯!

最近有些教练认为练习瑜伽不需要正确,更不需要精准,对此我作保留意见,也为此明白为什么有那么多人因为练习瑜伽而受伤了. 今日看了一篇关于小学生如何学习写好字的文章,标题是<孩子为什么"写字"难看?原因是不知道田字格里写字的标准!>,其中各种好处我就不用多说,给我印象最深刻的一个是:有助于孩子形成好的学习习惯,相信每一位生为人母(父)都希望自己的孩子从小养成一个好的学习习惯.但为什么对于自己学习新的事物时可以那么任性,可以不学习标准就随意挥洒,凭感觉行事.难道是觉得自己在这方面

以相同的條件,把多行記錄的某些欄位串在一起

Select Distinct     pppo_cName As 員工姓名,    IsNull(        Stuff((Select '/' + IsNull(Rtrim(calculateChief.pppo_cName),'') + calculateChief.pppo_cJobNumber        From PPWWorkGroup_ppwg calculateChiefGroup        Inner Join PPWPerson_pppo calculateChi

什么是位、字节、字、KB、MB

位:"位(bit)"是电子计算机中最小的数据单位.每一位的状态只能是0或1. 字节:8个二进制位构成1个"字节(Byte)",它是存储空间的基本计量单位.1个字节可以储存1个英文字母或者半个汉字,换句话说,1个汉字占据2个字节的存储空间. 字:"字"由若干个字节构成,字的位数叫做字长,不同档次的机器有不同的字长.例如一台8位机,它的1个字就等于1个字节,字长为8位.如果是一台16位机,那么,它的1个字就由2个字节构成,字长为16位.字是计算机进行