JAXB應用實例

来源:https://www.cnblogs.com/chenbenbuyi/archive/2018/01/20/8283657.html
-Advertisement-
Play Games

過往的項目中數據存儲都離不開資料庫,不過最近做的一個項目的某些數據(比如人員信息、菜單、許可權等等)卻完全沒有涉及任何資料庫操作,直接XML搞定。這裡無意比較優劣,因為資料庫存儲和XML存儲本就有不同的適用場景,盲目比較毫無意義,只是因為業務需要,僅此而已。先來概念一下——XML,可擴展標記語言,設計 ...


  過往的項目中數據存儲都離不開資料庫,不過最近做的一個項目的某些數據(比如人員信息、菜單、許可權等等)卻完全沒有涉及任何資料庫操作,直接XML搞定。這裡無意比較優劣,因為資料庫存儲和XML存儲本就有不同的適用場景,盲目比較毫無意義,只是因為業務需要,僅此而已。先來概念一下——XML,可擴展標記語言,設計宗旨是用來傳輸數據而非顯示數據,其遵循W3C標準,是一種通用的數據交換格式,具有很強的跨平臺性,並且數據無需轉換,所以,如果你要將數據做跨平臺傳輸,那麼把數據保存在 XML 文件中是有好處的。當然,這裡要說明,由於XML僅僅是作為一種文檔模式的結構化存儲,所以並不適用於大數據量的存儲。現在的Java中有很多類庫比如DOM、SAX、JDOM和DOM4J等等都可以操作XML,但如果僅僅是想做JavaBean和XML節點元素的互相轉換,而不涉及動態XML的處理,那麼JAXB絕對是一個不錯的選擇。在比較新的jdk版本中,JAXB都是jdk的擴展包javax中自帶的類庫,不需要你引入第三方jar包。下麵,博主正式給看客上菜,詳細介紹一下JAXB的實際用法——

 一 JavaBean和XML相互轉換初體驗

  1 package model;
  2 
  3 import javax.xml.bind.annotation.*;
  4 import java.io.Serializable;
  5 
  6 //JavaBean代碼
  7 
  8 @XmlType(propOrder = {})
  9 @XmlRootElement(name = "user")
 10 @XmlAccessorType(XmlAccessType.PROPERTY)
 11 @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
 12 public class User implements Serializable {
 13 
 14     private String userName;
 15     private int age;
 16     private String role;
 17     private String bibi;
 18 
 19     public User() {
 20     }
 21 
 22     public User(String userName, int age, String role, String bibi) {
 23         this.userName = userName;
 24         this.age = age;
 25         this.role = role;
 26         this.bibi = bibi;
 27     }
 28 
 29     public String getUserName() {
 30         return userName;
 31     }
 32 
 33     public void setUserName(String userName) {
 34         this.userName = userName;
 35     }
 36 
 37     @XmlAttribute
 38     public int getAge() {
 39         return age;
 40     }
 41 
 42     public void setAge(int age) {
 43         this.age = age;
 44     }
 45 
 46     @XmlElement
 47     public String getRole() {
 48         return role;
 49     }
 50 
 51     public void setRole(String role) {
 52         this.role = role;
 53     }
 54 
 55     @XmlTransient
 56     public String getBibi() {
 57         return bibi;
 58     }
 59 
 60     public void setBibi(String bibi) {
 61         this.bibi = bibi;
 62     }
 63 
 64     @Override
 65     public String toString() {
 66         return "User{" +
 67                 "userName='" + userName + '\'' +
 68                 ", age=" + age +
 69                 ", role='" + role + '\'' +
 70                 ", bibi='" + bibi + '\'' +
 71                 '}';
 72     }
 73 }
 74 
 75 //測試
 76 public class test {
 77     @Test
 78     public void saveXmlTest() {
 79         User user = new User("陳本布衣", 2018, "超級管理員","瞎嗶嗶");
 80         File file = new File("E://user.xml");
 81         try {
 82             JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
 83             Marshaller marshaller = jaxbContext.createMarshaller();
 84             //格式化輸出,即按標簽自動換行,否則就是一行輸出
 85             marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
 86             //設置編碼(預設編碼就是utf-8)
 87             marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
 88             //是否省略xml頭信息,預設不省略(false)
 89             marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);
 90             marshaller.marshal(user, file);
 91         } catch (JAXBException e) {
 92             e.printStackTrace();
 93         }
 94     }
 95 
 96     @Test
 97     public void getUserTest() {
 98         File file = new File("E://user.xml");
 99         try {
100             JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
101             Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
102             User user = (User) unmarshaller.unmarshal(file);
103             System.out.println(user.toString());
104         } catch (JAXBException e) {
105             e.printStackTrace();
106         }
107     }
108 }
View Code

生成的XML:

二 JAXB使用基礎介紹

  ① 常用API

  • JAXBContext類,是應用的入口,通過該類創建序列化和反序列化對象,也即編組對象和解組對象
  • Marshaller 編組介面,將Java對象序列化為XML數據;
  • Unmarshaller 解組介面,將XML數據反序列化為Java對象。

  ② 常用註解

  • @XmlRootElement,將Java類或枚舉映射成XML元素根節點,是唯一一個必須註解,name屬性指定根節點名稱,不指定預設為類名的小寫;
  • @XmlElement,將Java類的一個屬性映射為XML節點元素,name屬性可自定義元素名;
  • @XmlAttribute,將Java類的一個屬性映射為XML節點元素的屬性,name屬性可自定義屬性名
  • @XmlType,將Java類或枚舉類型映射到XML模式類型,常與@XmlRootElement、@XmlAccessorType共用,propOrder屬性定義欄位生成的XML節點順序;
  • @XmlAccessorType,控制欄位或屬性的序列化。屬性XmlAccessType有4個常量值:FIELD表示JAXB將自動綁定Java類中的每個非靜態的(static)、非瞬態的(由@XmlTransient標註)欄位到XML;PROPERTY表示java對象中所有通過getter/setter方式綁定成屬性到XML;PUBLIC_MEMBER表示Java對象中所有的public訪問許可權的成員變數和通過getter/setter方式訪問的成員變數,該值為預設值;NONE表示Java對象的所有屬性都不映射為XML的元素;
  • @XmlAccessorOrder,控制JAXB 綁定類中屬性和欄位的排序,有兩個屬性,AccessorOrder.ALPHABETICAL——對生成的XML元素按字母書序排序,XmlAccessOrder.UNDEFINED——不排序,預設為該值;
  • @XmlJavaTypeAdapter,自定義適配器(即擴展抽象類XmlAdapter並覆蓋marshal()和unmarshal()方法),解決日期(Date),數字(Number)格式化問題;
  • @XmlElementWrapper ,對於數組或集合(即包含多個元素的成員變數),生成一個包裝該數組或集合的XML元素(稱為包裝器),該註解只能用在集合上;
  • @XmlTransient ,用於標示在由Java對象映射XML時,忽略此屬性,在生成的XML文件中將不出現此元素。

  ③ 實際應用中註意的問題

  ① 如果JavaBean中定義了有參的構造器,那麼必須同時定義無參構造器,否則轉XML會拋無預設構造函數的異常;

  ② 成員變數值為NULL時,將不會映射成對應的XML元素——由於基本數據類型預設值不為空,所以基本數據類型不設值也會映射成XML元素,值為預設值;

  ③ @XmlAccessorType 註解中如果屬性值為XmlAccessType.FIELD,則表示通過成員變數來映射,set/get方法上的映射註解就是多餘的,所以如果此時set/get方法上再標註元素或者屬性映射註解,將拋屬性重覆性異常;屬性值為XmlAccessType.NONE不映射為XML元素的前提是Java欄位或set/get方法上都沒有映射註解;

  ④ @XmlType propOrder屬性能夠自定義欄位的排序,該屬性如果設置,要麼寫成{}的形式,否則在就必須將所有@XmlElement標註或者沒有@XmlElement標註的但實際上會被映射為XML節點的欄位添加到排序列表,不然會拋異常;如果propOrder屬性設置有值,@XmlAccessorOrder註解的元素排序規則將失效;

 三 應用實際

  先準備好測試用的工具方法:

 1 package util;
 2 
 3 
 4 import model.User;
 5 
 6 import javax.xml.bind.JAXBContext;
 7 import javax.xml.bind.JAXBException;
 8 import javax.xml.bind.Marshaller;
 9 import javax.xml.bind.Unmarshaller;
10 import java.io.File;
11 
12 public class JaxbUtil {
13 
14     public static void convertToXml(Object obj, File file) {
15         try {
16             JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
17             Marshaller marshaller = jaxbContext.createMarshaller();
18             //格式化輸出,即按標簽自動換行,否則就是一行輸出
19             marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
20             //設置編碼(預設編碼就是utf-8)
21             marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
22             //是否省略xml頭信息,預設不省略(false)
23             marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);
24             marshaller.marshal(obj, file);
25             //控制台輸出
26             marshaller.marshal(obj,System.out);
27         } catch (JAXBException e) {
28             e.printStackTrace();
29         }
30     }
31 
32     public static <T> T convertToJavaBean(Class<T> clz, File file) {
33         try {
34             JAXBContext jaxbContext = JAXBContext.newInstance(clz);
35             Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
36             T t = (T) unmarshaller.unmarshal(file);
37             return t;
38         } catch (JAXBException e) {
39             e.printStackTrace();
40         }
41         return null;
42     }
43 }

  ① 簡單對象處理

  簡單對象處理起來比較簡單,譬如人員對象User中包含菜單Menu,只需將定義的普通Menu對象也按照JAXB的註解進行標註,在User對象中當成普通欄位一樣的定義即可——

@XmlType(propOrder = {"userName","role","menu"})
@XmlRootElement(name = "user")
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
public class User implements Serializable {

    private String userName;
    private int age;
    private String role;
    private String bibi;
    private Menu menu;
    public User() {
    }

    public User(String userName, int age, String role, String bibi) {
        this.userName = userName;
        this.role = role;
        this.age = age;
        this.bibi = bibi;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @XmlAttribute
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @XmlElement(nillable=true)
    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    @XmlTransient
    public String getBibi() {
        return bibi;
    }

    public void setBibi(String bibi) {
        this.bibi = bibi;
    }

    @XmlElement
    public Menu getMenu() {
        return menu;
    }

    public void setMenu(Menu menu) {
        this.menu = menu;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                ", role='" + role + '\'' +
                ", menu=" + menu +
                '}';
    }
}


//菜單對象

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Menu {
    private String name;
    private String id;

    public Menu() {
    }

    public Menu(String name, String id) {
        this.name = name;
        this.id = id;
    }

    @Override
    public String toString() {
        return "Menu{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                '}';
    }
}
View Code

 

  ② 集合處理

  實際應用場景中集合應用要更常見一些,比如上面的用戶菜單,一個用戶肯定會有多個不同的菜單,所以,我們來將上面的菜單改用集合處理——

 1 package model;
 2 
 3 import javax.xml.bind.annotation.*;
 4 import java.io.Serializable;
 5 import java.util.Date;
 6 import java.util.List;
 7 
 8 @XmlType(propOrder = {"userName", "role", "menus"})
 9 @XmlRootElement(name = "user")
10 @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
11 public class User implements Serializable {
12 
13     private String userName;
14     private int age;
15     private String role;
16     private String bibi;
17     private List<Menu> menus;
18 
19     public User() {
20     }
21 
22     public User(String userName, int age, String role, String bibi) {
23         this.userName = userName;
24         this.role = role;
25         this.age = age;
26         this.bibi = bibi;
27     }
28 
29     public String getUserName() {
30         return userName;
31     }
32 
33     public void setUserName(String userName) {
34         this.userName = userName;
35     }
36 
37     @XmlAttribute
38     public int getAge() {
39         return age;
40     }
41 
42     public void setAge(int age) {
43         this.age = age;
44     }
45 
46     @XmlElement
47     public String getRole() {
48         return role;
49     }
50 
51     public void setRole(String role) {
52         this.role = role;
53     }
54 
55     @XmlTransient
56     public String getBibi() {
57         return bibi;
58     }
59 
60     public void setBibi(String bibi) {
61         this.bibi = bibi;
62     }
63 
64     @XmlElement
65     public List<Menu> getMenus() {
66         return menus;
67     }
68 
69     public void setMenus(List<Menu> menus) {
70         this.menus = menus;
71     }
72 
73     @Override
74     public String toString() {
75         return "User{" +
76                 "userName='" + userName + '\'' +
77                 ", age=" + age +
78                 ", role='" + role + '\'' +
79                 ", menus=" + menus +
80                 '}';
81     }
82 }
View Code
 1 package model;
 2 
 3 import javax.xml.bind.annotation.XmlAttribute;
 4 import javax.xml.bind.annotation.XmlRootElement;
 5 import java.util.List;
 6 
 7 @XmlRootElement
 8 public class Menu {
 9     private String name;
10     private String id;
11     private List<Menu> child;
12 
13     public Menu() {
14     }
15 
16     public Menu(String name, String id) {
17         this.name = name;
18         this.id = id;
19     }
20     @XmlAttribute
21     public String getName() {
22         return name;
23     }
24 
25     public void setName(String name) {
26         this.name = name;
27     }
28     @XmlAttribute
29     public String getId() {
30         return id;
31     }
32 
33     public void setId(String id) {
34         this.id = id;
35     }
36 
37     public List<Menu> getChild() {
38         return child;
39     }
40 
41     public void setChild(List<Menu> child) {
42         this.child = child;
43     }
44 
45     @Override
46     public String toString() {
47         return "Menu{" +
48                 "name='" + name + '\'' +
49                 ", id='" + id + '\'' +
50                 '}';
51     }
52 }
View Code
 1 package test;
 2 
 3 
 4 import model.Menu;
 5 import model.User;
 6 import org.junit.Test;
 7 import util.JaxbUtil;
 8 import java.io.File;
 9 import java.util.ArrayList;
10 import java.util.List;
11 
12 public class test {
13     @Test
14     public void saveXmlTest() {
15         User user = new User("陳本布衣", 2018, "超級管理員","瞎嗶嗶");
16         List<Menu> list1 = new ArrayList<>();
17         Menu menu1 = new Menu("系統管理","9527");
18         Menu child1 = new Menu("許可權管理","9999");
19         Menu child2 = new Menu("用戶管理","2322");
20         list1.add(child1);
21         list1.add(child2);
22         menu1.setChild(list1);
23         List<Menu> list2 = new ArrayList<>();
24         Menu menu2 = new Menu("參數配置","2222");
25         Menu child3 = new Menu("許可權管理","3333");
26         Menu child4 = new Menu("用戶管理","4444");
27         list2.add(child3);
28         list2.add(child4);
29         menu2.setChild(list2);
30         List<Menu> menus = new ArrayList<>();
31         menus.add(menu1);
32         menus.add(menu2);
33         user.setMenus(menus);
34         File file = new File("E://user.xml");
35         JaxbUtil.convertToXml(user,file);
36     }
37 
38     @Test
39     public void getUserTest() {
40         File file = new File("E://user.xml");
41         User user = JaxbUtil.convertToJavaBean(User.class, file);
42         System.out.println(user);
43     }
44 }
View Code

 

  上面的菜單中似乎少了點層次關係,這個時候可以使用集合包裝器註解@XmlElementWrapper自定義一個包裝節點,這樣產生的XML文檔才更有層次:

1     @XmlElementWrapper(name = "menu")
2     @XmlElement
3     public List<Menu> getMenus() {
4         return menus;
5     }

  最終產生的XML文檔就是這樣的:

 

  ③ 格式化處理

   業務數據中日期、數值通常是必不可少的,在數據存儲的時候,這些數據通常都需要做格式化處理,比如將日期格式化,貨幣型數值處理等等。JAXB中格式化處理需要繼承適配器抽象類XmlAdapter,並覆寫其序列化和反序列化的方法,這裡僅用常用的日期格式化為例:

 1 package adapter;
 2 
 3 import javax.xml.bind.annotation.adapters.XmlAdapter;
 4 import java.text.DateFormat;
 5 import java.text.SimpleDateFormat;
 6 import java.util.Date;
 7 
 8 public class DateAdapter extends XmlAdapter<String, Date> {
 9     private static final DateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
10 
11     @Override
12     public Date unmarshal(String date) throws Exception {
13         return SDF.parse(date);
14     }
15 
16     @Override
17     public String marshal(Date date) throws Exception {
18         return SDF.format(date);
19     }
20 }

  將該適配器通過註解應用到User類表時間的date欄位上:

1     @XmlJavaTypeAdapter(DateAdapter.class)
2     public Date getDate() {
3         return date;
4     }
5 
6     public void setDate(Date date) {
7         this.date = date;
8     }

   最後的時間就是按照格式化輸出——

  

四 問題補充

  上述博文中描述的工具方法僅僅是出於學習中追根問本的目的寫得稍微冗餘了些,實際上,我所知道的是最遲從jdk1.7開始,JAXB就對解組和編組的方法進行了更簡單的封裝,所以,實際項目中除非自己要進行個性化設置,否則大可不用自己再創建JAXBContext實例,直接通過JAXB靜態調用相應的工具方法就行了,有興趣的看官稍微跟蹤一下源碼就能瞭然,於是上面的工具方法可以寫得更簡單——

 1 package util;
 2 
 3 
 4 import javax.xml.bind.JAXB;
 5 import java.io.File;
 6 
 7 public class JaxbUtil {
 8 
 9     public static void convertToXml(Object obj, File file) {
10         JAXB.marshal(obj,file);
11     }
12 
13     public static <T> T convertToJavaBean(Class<T> clz, File file) {
14         return JAXB.unmarshal(file, clz);
15     }
16 }

  OK,對於JAXB的知識分享就差不多這麼些了。對於這種比較單一技能點的學習,就是根據API多寫點代碼練習測試,從測試的結果對錯中總結出自己的深層理解,併在實際項目學以致用,不變應萬變,望看官讀畢都有所收穫!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 因為是開發階段,我需要在本地調試,而微信開發需要配置功能變數名稱,這樣natapp.cn就有了用武之地,應該說natapp就是為此而生的。 natapp.cn是什麼 這是一個內網映射的網站,支持微信公眾號、小程式本地開發調試,具體詳情請到官網去瞭解:https://natapp.cn/ 雖然官網已經有配置教 ...
  • C/S又稱Client/Server或客戶/伺服器模式。伺服器通常採用高性能的PC、工作站或小型機,並採用大型資料庫系統,如Oracle、Sybase、Informix或 SQL Server。客戶端需要安裝專用的客戶端軟體。 B/S是Brower/Server的縮寫,客戶機上只要安裝一個瀏覽器(B ...
  • Django中模型(二) 三、定義模型 1、模型、屬性、表、欄位間的關係: 一個模型類在資料庫中對應一張表;在模型類中定義的屬性,對應該模型對照表中的欄位。 2、定義屬性 A、概述 ·django根據屬性的類型確定以下信息 ·當前選擇的資料庫支持欄位的類型 ·渲染管理表單時使用的預設html控制項 · ...
  • B站是目前本人看到的最好的免費學習Python的網站 黑馬程式員- https://space.bilibili.com/37974444?spm_id_from=333.338.viewbox_report.6#/ B站上找老男孩Linux 教育視頻 關註黑馬程式員官方微信可下載近70G的Pyth ...
  • #for 和 while #for用來迭代處理,什麼叫迭代?你就當沒看到這個詞,for是把一堆玩意做一個一個加工用的,比如吃一袋花生,得一個一個剝吧,就是這意思 a = 'abcde' #每個字母當做一個花生,a是一袋子 for i in a: #從袋子裡面一個一個拿花生,拿出的每一個花生都起名叫小 ...
  • 1.會話技術簡介 http協議是無狀態的,因此對於服務端來說,當它接收到客戶端的http請求時,無法識別這個請求來源於哪個客戶端。無狀態的協議有優點也有缺點,但對於需要識別客戶端甚至是需要記住客戶端的業務來說,應當要讓http協議"有狀態"。 需要記住客戶端的業務種類非常多。例如登陸系統,在一個頁面 ...
  • 本篇我們開始進入Java的學習,首先在學習如何編寫Java語言前要先瞭解Java程式的基本結構。 一、Java程式的基本結構 一個Java程式的基本結構大體可以分為包、類、main()主方法、標識符、關鍵字、語句和註釋等,如下: 我們來逐一分析一下每一條語句,過多的概念我就不詳述了,只說最基本的。 ...
  • 記得我在以前找工作的經歷中,遇到過一個面試官問過我一個很基礎的問題。問題是:有一個List中有10個元素,我現在想從中刪除3個元素,請問怎麼做?我當時也沒想,就直接說,List的有自帶的remove方法,可以直接使用,他說請詳細的說明一下,我說寫一個for迴圈,迴圈的次數是List的長度,然後在迴圈 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...