比亞迪將與東風揚子江合作生產新能源汽車

東風揚子江汽車與比亞迪共同合作,將組建新的製造企業,並打造中國一流的新能源汽車研發、生產基地。

武漢市長唐良智介紹了武漢的經濟社會發展情況,表示武漢汽車整車規劃目標是2015年達到年產300萬輛,將積極支持該專案落戶武漢並全力做好服務。

王傳福表示武漢近年發展亮點很多,令人振奮,尤其是招商引資勢頭很好,比亞迪願參與武漢的改革發展大潮。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

廣汽新能源概念車E-jet 廣州車展全球首發

廣汽集團此次攜旗下全品牌車型亮相廣州車展,全球首發傳祺A級四門轎跑概念車「E-jet」,不但依靠綠色科技降低油耗提高環保水準,更在造型方面體現綠色與時尚的完美結合。

廣汽A級新能源概念車E-Jet是一款針對都市年輕消費群開發的四門四座轎跑車,它基於廣汽自主開發的全新A級平臺,並搭載由廣汽自主研發的增程式純電驅動系統,具備「純電驅動」和「增程式驅動」兩種驅動模式,實現低能耗、零排放與多樣化出行需求的完美結合,是廣汽全球研發網最新成果。

E-Jet整體造型以「光影雕塑」為設計理念,前後兩段式的「佐羅線」彰顯了車身的修長和流暢,完美的實現了動感和力量兼具,性感與優雅並存,融合轎車的大方、氣派以及跑車的激情奔放,用現代造型語言塑造出年輕、感性、自信的設計魅力。並預示著明年即將量產的傳祺A級轎車的神韻。中網格柵、輪轂、大燈等細節設計精緻、新穎、獨特,凸顯廣汽自主品牌的「設計魅力」。

廣汽A級新能源概念車E-Jet無論從觀賞性和實用性方面均能滿足都市年輕消費者的口味,先進可靠的增程式新能源技術應用拉近了新能源技術與普通消費者的距離。「綠色也時尚」的E-Jet,不但創造了自主品牌新能源汽車的設計新高度,更將引領A級車市場都市時尚新趨勢。

如果說E-Jet的外觀設計激昂澎湃,充滿動感,它的內飾設計則呈現一種如高山流水般優雅、寧靜、宜人的氛圍。整個內飾以「水流」為主題。通過流暢的線條、豐富的層次,營造出瀑布般,或跌宕,或蜿蜒的意境空間。局部的功能部件,如儀錶盤區域、換擋部分、門拉手等依勢成型,好似水面突出的礁石。這種氛圍讓人在進入車內時,能將現代都市的喧囂和煩惱關在門外,平復心緒,享受這怡人的自然之美。內飾色調優雅高貴。門板處精心設計的圖案,將傳統山水畫與最新的「圖元化」手法結合,創造出既有中國意境又引領時尚的形式感。

E-Jet還擁有一個特別的集智慧手機、資訊顯示等多功能於一身的I-KEY專用鑰匙,嵌入方向盤實現與車連接。車內即時聯網,應用廣汽自主研發的「Telematics」智慧化資訊作業系統,資訊介面實現人性化多屏互動,體現了汽車駕駛與現代化生活方式的無縫連接,實現了汽車的資訊化、智慧化、情感化和生活化。

E-jet以現代的設計手法、最新的科技手段將傳統的東方文化情懷重新演繹,於「動」「靜」之間抒寫新派中國設計的精彩篇章,並引領了資訊化汽車設計的新趨勢。

11月21日,廣汽集團國家認定企業技術中心正式掛牌,廣汽研究院坐落於番禺化龍的新基地啟用,這艘承載廣汽自主研發創新重任的科技航母,正式啟航。

今年4月,廣汽集團在北京車展上發佈廣汽全球研發網,以廣汽研究院為依託,整合全球資源搭建而成的汽車技術開發戰略平臺。現已在純電技術、增程技術、混合動力等多種新能源車型研發中取得顯著成果。

此前,廣汽已有「E-linker 」小型純電多功能概念車、傳祺增程式純電動、油電混合動力、插電式四驅混合動力等多款新能源車型問世。近期,將在廣州投入200-400台插電式混動傳祺試運行。廣汽順應未來汽車行業發展趨勢,聚焦新能源車戰略已有實質性進展。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

菲亞特無意在歐洲市場推出500e電動車

菲亞特全球品牌CEO奧爾維爾·弗朗索瓦(Olivier Francois)日前表示,菲亞特無意在歐洲市場推出500e

500e是菲亞特500微型車的電動版本,預期售價為3.5萬美元,續航里程約為100英里(約合160公里),菲亞特計畫於2013年第二季度首先在美國加利福尼亞州推出該車型。

菲亞特-克萊斯勒集團CEO瑪律喬內曾表示,該公司每售出一輛500e電動車將損失8,000至10,000美元。菲亞特向美國推出500e車型,是為了滿足美國部分州份關於推動零排放汽車銷量的要求。

電動汽車並未受到美國消費者的青睞,據R.L.POLK公司提供的資料,美國市場今年前9個月汽車銷量總計為1,190萬輛,而電動車的銷量僅為2.6萬輛,其中加利福尼亞州電動車的銷量為2,618輛,占美國電動車銷售總量的10%。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

雪佛蘭Spark電動版將亮相 預計起售價低於2.5萬美元

雪佛蘭Spark電動版將於11月底在洛杉磯國際車展上亮相,並在加利福尼亞州和俄勒岡州率先登陸,預計這款車的起售價將低於2.5萬美元。

這款車搭載了一台最大輸出功率為96千瓦的電機和鋰離子電池組。通用公司介紹,這款電池組讓Spark電動版有最佳里程表現,但通用方面並未對這款車的其他性能做具體說明。

同時,通用汽車公司北美總裁Mark Reuss表示,如果基於先進科技打造純電動小車,而這款車的百公里加速不超過8秒,那麼消費者就不會拒絕。沃藍達和Spark電動版的問世表明,雪佛蘭不僅對電動車有深入瞭解,也能幫助消費者獲得最佳的電動車駕駛體驗。

另外,雖然通用方面尚未透露雪佛蘭Spark電動版的上市時間,但據媒體分析,這款車有可能於2013年在全球市場選擇性銷售。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

上海國際汽配件展期間舉行之思想領袖會議

首屆中國高新汽車國際峰會由中國國家發展和改革委員會國際合作中心(簡稱「發改委國際合作中心」)和法蘭克福展覽公司聯合主辦,來自中國和海外的汽車業高層將匯聚一堂。
不容錯過:彼此互動,交流理念,推廣嶄新戰略,探索行業的最佳實踐、尖端技術、卓越服務與完善應用的方法:

中國嘉賓
國內汽車行業政策與規劃:

‧ 中國國家發展和改革委員會(發改委):主題演講
‧ 中國國務院發展研究中心(DRC)副主任侯雲春先生
‧ 中國國家科技部(MOST)國家863計劃節能與新能源汽車項目辦公室副主任甄子健博士
‧ 中國上海新能源汽車推進辦公室主任劉建華先生

科技創新、產業化、品牌與質量:

‧ 中國汽車技術研究中心(CATARC)清潔能源汽車生產力促進中心主任王成先生
‧ 中國上汽集團汽車公司下屬上海國際汽車工程師學會(SAE-S)秘書長梁元聰先生
‧ 中國北京理工大學(BIT)電動車輛國家工程實驗室(NELEV)副主任及教授林程博士
‧ 中華全國工商業聯合會副主席孫曉華先生
‧ 中國北京理工大學管理與經濟學院、國務院顧問、中國質量協會執行董事、中國標準化協會執行董事郎志正教授

國際嘉賓
各國近況、戰略與行業轉變:

‧ 德國電動車協會(BEM EV)行政總裁及市場部主管Christian Heep先生
‧ 瑞典ElBil2020項目副主席及項目經理Allan Larsson先生
‧ 中國麥肯錫上海公司項目經理李鐵錚博士
‧ 馬來西亞汽車研究所(MAI)行政總裁M. Madani Sahari先生
‧ 中國Synergistics公司總裁兼首席執行官及博斯中國公司高級顧問Bill Russo先生

電力交通與個人出行工具:

‧ 德國英飛凌公司高級企業副總裁Anton Mueller先生
‧ 中國普華永道PRTM管理咨詢公司合夥人許剛博士
‧ 馬來西亞Proton公司高級研究與合作研究部負責人Md Ridzuan Bin Md Yusof先生

商用車與車隊:

‧ 美國高效傳動系統公司首席技術官Andrew Frank博士
‧ 中國斯堪尼亞中心高級顧問Christian Kunkel博士
‧ 美國加利福尼亞州聖安娜市清潔能源汽車生產力促進中心執行董事Rick D. Longobart先生

聯網車輛與車輛遠程管理系統:

‧ 英國GSMA互聯生活計劃mAutomotive項目總監Francesca Forestieri女士
‧ 中國上海益普索(Ipsos)汽車研究全球負責人Klaus Paur先生
‧ 美國Sprint公司國際批發與業務發展部副總裁何逸靜女士
‧ 台灣工業技術研究院(ITRI),信息與通信研究實驗室,遠程信息處理與車載控制系統小組,聯網汽車通信部門經理李夏新先生
‧ 瑞典WirelessCar公司董事總經理Martin Rosell先生

充電與基礎設施:

‧ 英國高通歐洲公司業務發展和市場營銷部副總裁Anthony Thomson博士
‧ 德國多特蒙德基礎設施及電網電動車輛競爭力中心執行主任Jan Fritz Rettberg博士
‧ 日本東京電力公司(TEPCO)研發中心移動技術組高級經理青木浩行博士

能源儲存與電池創新:

‧ 美國Lux Research分析員張卓先生
‧ 以色列Shmuel De-Leon能源公司首席執行官Shmuel De-Leon先生

安全、測試、認證與認可:

‧ 德國機動車監督協會/德凱達管理咨詢(上海)公司張鷹先生
‧ 荷蘭TNO-Homologations公司業務發展經理Rob van der Aar先生

相關訊息請參訪:
 

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

2013中國新能源汽車及電動車展覽會

展會名稱:2013中國新能源汽車及電動車展覽會

展會時間:2013年3月19日-23日

展會地點:中國|北京展覽館

日程: 2013年3月21日-2013年3月23日 展期

主辦單位:中國低碳產業協會 、北京市電動車行業協會、北京市交通委員會、聯合國工業發展組織、國際太陽能技術轉讓中心、中國可再生能源行業協會、北京旺旅展覽展示有限公司

三、 費用明細Details of charges

標準展台(9平米): 7800元

豪華展位(18平米): 18000元

室內光地(36平米起):1000元/平米

室外光地(36平米起):500元/平米

技術交流及產品推介會——讓市場瞭解企業技術及產品的最佳途徑

收費標準:5000元/30分鐘;主辦單位提供場地(150-200人)。

注意:請參展企業於參展前一個月提供產品的相關信息,以供組委會參考並邀請相關專業嘉賓。

四、 參展範圍Exhibition Scope

綠色低碳交通車輛展區:

各類電動自行車、電動三輪車、燃油助力車及殘疾人專用電動車、電動滑板車等特種電動車、各類自行車、摺疊車、童車等

新能源車輛展區:

整 車:電動(混合動力)客車、電動(混合動力)公交車、電動(混合動力)轎車、電動旅遊觀光車、電動高爾夫車,電動吉普車、太陽能電動車、電動客貨車、電動清潔車、電動叉車、電動升降車;氫能源、天然氣等各種新能源、清潔燃料、混合動力車輛;各種低排放、環保節能型汽車

配套電池、配件、零部件和相關技術資料展區

1. 電動車電池及電池維護、電機、充電器、控制器、輪胎、塑殼及其它零配件和維修工具與設備,電動車及自行車用防盜鎖具、報警設備等;

2. 各種動力電池與管理系統:蓄電池,燃料電池及其他能源儲備系統;各種電池生產,檢測,維護設備等;各類廢舊電池回收及三廢處理設備、回收處理技術等;

3. 充電裝置;電機電控系統;儲能裝置等;能源管理系統;充(換)電站設備;充換電池及電池等能源管理系統;加油站擴建充(換)電站、新能源汽車充電技術項目解決方案、智能電網、太陽能、風能互補新能源汽車充電站技術產品;停車場充電設施;充電站(器)電源設備和基礎設施;

4. 電池修復儀等配套輔助產品、各種機械加工、流水線、檢測儀器製造設備和工具等配套設備;

5. 零部件:低排放節能型發動機、混合動力發動機及清潔燃料發動機;整車總線與控制系統;電機電控系統;電力電容器、飛輪、逆變器、電熱泵、電動助力轉向、電動空調、功率模塊、相關檢測、計量、模具設備等。

6. 相關行業媒體軟件出版、培訓、諮詢、施工技術及其他相關材料、工藝、技術等;

特種車輛展區:清障車、環保車輛、改裝車輛等。

五、 組委會聯繫方式/Contact Information

聯繫地址:北京市德外大街西三旗東路金燕龍辦公樓東樓309室

聯繫電話:010-56105081,13366745071

聯繫人:李菲菲,李主任 13341032258

聯繫傳真:010-52214567-7

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

Elasticsearch系列—生產集群的索引管理

概要

索引是我們使用Elasticsearch里最頻繁的部分日常的操作都與索引有關,本篇從運維人員的視角,來玩一玩Elasticsearch的索引操作。

基本操作

在運維童鞋的視角里,索引的日常操作除了CRUD,還是打開關閉、壓縮、alias重置,我們來了解一下。

創建索引

[esuser@elasticsearch02 ~]$curl -XPUT 'http://elasticsearch02:9200/music?pretty' -H 'Content-Type: application/json' -d '
{
    "settings" : {
        "index" : {
            "number_of_shards" : 3, 
            "number_of_replicas" : 2 
        }
    },
    "mappings" : {
        "type1" : {
            "properties" : {
                "name" : { "type" : "text" }
            }
        }
    }
}'

{
    "acknowledged": true,
    "shards_acknowledged": true
}

默認情況下,索引創建命令會在每個primary shard的replica shard 開始進行複製后,或者是請求超時之後,返迴響應消息,如上。

acknowledged表示這個索引是否創建成功,shards_acknowledged表明了每個primary shard有沒有足夠數量的replica開始進行複製。

可能這兩個參數會為false,但是索引依然可以創建成功。因為這些參數僅僅是表明在請求超時之前,這兩個操作有沒有成功,也有可能請求超時了,在超時前都沒成功,但是實際上Elasticsearch Server端接收到了消息,並且都執行了,只是響應前還沒來得及執行,所以響應的是false。

刪除索引

curl -XDELETE 'http://elasticsearch02:9200/music?pretty'

查詢索引設置信息

curl -XGET 'http://elasticsearch02:9200/music?pretty'

打開/關閉索引

curl -XPOST 'http://elasticsearch02:9200/music/_close?pretty'
curl -XPOST 'http://elasticsearch02:9200/music/_open?pretty'

如果一個索引關閉了,那麼這個索引就沒有任何的性能開銷了,只要保留這個索引的元數據即可,然後對這個索引的讀寫操作都不會成功。一個關閉的索引可以接着再打開,打開以後會進行shard recovery過程。

如果集群數據定時有備份,在執行恢復的操作之前,必須將待恢復的索引關閉,否則恢復會報失敗。

壓縮索引

我們知道索引的primary shard數量在創建時一旦指定,後期就不能修改了,但是有一個這樣的情況:預估的shard數量在實際生產之後,發現估算得有點高,比如原來設置number_of_shards為8,結果生產上線后發現數據量沒那麼大,我想把這個索引的primary shard壓縮一下,該如何操作呢?

shrink命令的作用就是對索引進行壓縮的,不過有個限制:壓縮后的shard數量必須可以被原來的shard數量整除。如我們的8個primary shard的index可以只能被壓縮成4個,2個,或者1個primary shard的index。

shrink命令的工作流程:
  1. 創建一個跟source index的定義一樣的target index,但是唯一的變化就是primary shard變成了指定的數量。
  2. 將source index的segment file直接用hard-link的方式連接到target index的segment file,如果操作系統不支持hard-link,那麼就會將source index的segment file都拷貝到target index的data dir中,會很耗時。如果用hard-link會很快。
  3. target index進行shard recovery恢復。
案例演示
  1. 我們創建一個number_of_shards為8的索引,名稱為music8
curl -XPUT 'http://elasticsearch02:9200/music8?pretty' -H 'Content-Type: application/json' -d '
{
    "settings" : {
        "index" : {
            "number_of_shards" : 8, 
            "number_of_replicas" : 2 
        }
    },
    "mappings" : {
        "children" : {
            "properties" : {
                "name" : { "type" : "text" }
            }
        }
    }
}'
  1. 在索引內灌點數據進去
  2. 將索引的shard都移到一個node上去,如node1
curl -XPUT 'http://elasticsearch02:9200/music8/_settings?pretty' -H 'Content-Type: application/json' -d '
{
  "settings": {
    "index.routing.allocation.require._name": "node-1", 
    "index.blocks.write": true 
  }
}'

這個過程叫shard copy relocate,使用

`curl -XGET ‘http://elasticsearch02:9200/_cat/recovery?v’

可以查看該過程的進度。

  1. 執行shrink命令,新的索引名稱為music9
curl -XPOST 'http://elasticsearch02:9200/music8/_shrink/music9?pretty' -H 'Content-Type: application/json' -d '
{
  "settings": {
	"index.number_of_shards": 2, 
    "index.number_of_replicas": 1,
    "index.codec": "best_compression" 
  }
}'

執行完成后,可以看到music9的shard數據變化了,並且擁有music8所有的數據。

  1. 將別名指向新的music9索引,客戶端訪問無感知。

rollover索引

我們最常見的日誌索引,需要每天創建一個新的帶日期的索引,但客戶端又使用同一個alias進行寫入,此時可以用rollover命令將alias重置到這個新的索引上。

假設log_write別名已經存在,示例命令:

curl -XPOST 'http://elasticsearch02:9200/log_write/_rollover/log-20120122
-H 'Content-Type: application/json' -d '
{
  "conditions": {
    "max_age":   "1d"
  }
}'

用crontab定時每天執行一次,並且將日期部分用shell腳本進行參數化,這樣每天都創建一個帶日期的索引名字,而客戶端那邊一直使用log_write別名作寫入操作,對日誌系統非常實用。

索引mapping管理

索引的mapping管理是非常基礎的操作,我們可以在創建索引時定義mapping信息,也可以在索引創建成功后執行增加字段操作。

列舉以下幾個常用示例:

查看索引的mapping信息

curl -XGET 'http://elasticsearch02:9200/music/_mapping/children?pretty'

查看索引指定field的mapping信息

curl -XGET 'http://elasticsearch02:9200/music/_mapping/children/field/content?pretty'

創建索引時帶上mapping信息

# 節省篇幅,省略大部分字段
curl -XPUT 'http://elasticsearch02:9200/music?pretty' -H 'Content-Type: application/json' -d ' 
{
  "mappings": {
    "children": {
      "properties": {
        "content": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
		}
      }
    }
  }
}'

為索引增加一個字段name,類型為text

curl -XPUT 'http://elasticsearch02:9200/music/_mapping/children?pretty' -H 'Content-Type: application/json' -d ' 
{
  "properties": {
    "name": {
      "type": "text"
    }
  }
}'

索引別名

客戶端訪問Elasticsearch的索引時,規範化操作都不會直接使用索引名稱,而是使用索引別名,索引別名能夠起到封裝Elasticsearch真實索引的作用,像上面的rollover操作,索引重建操作,別名起到了非常關鍵的作用。

我們來簡單看一下索引的基本操作:

# 創建索引別名
curl -XPOST 'http://elasticsearch02:9200/_aliases?pretty' -H 'Content-Type: application/json' -d '
{
    "actions" : [
        { "add" : { "index" : "music", "alias" : "music_prd" } }
    ]
}'
# 刪除索引別名
curl -XPOST 'http://elasticsearch02:9200/_aliases?pretty' -H 'Content-Type: application/json' -d '
{
    "actions" : [
        { "remove" : { "index" : "music", "alias" : "music_prd" } }
    ]
}'
# 重命名別名:先刪掉后添加
curl -XPOST 'http://elasticsearch02:9200/_aliases?pretty' -H 'Content-Type: application/json' -d '
{
    "actions" : [
        { "remove" : { "index" : "music", "alias" : "music_prd" } },
        { "add" : { "index" : "music2", "alias" : "music_prd" } }
    ]
}'
# 多個索引綁定一個別名
curl -XPOST 'http://elasticsearch02:9200/_aliases?pretty' -H 'Content-Type: application/json' -d '
{
    "actions" : [
        { "add" : { "indices" : ["music1", "music2"], "alias" : "music_prd" } }
    ]
}'

索引setting修改

查看索引setting信息:

curl -XGET 'http://elasticsearch02:9200/music/_settings?pretty'

修改setting信息:

curl -XPUT 'http://elasticsearch02:9200/music/_settings?pretty' -H 'Content-Type: application/json' -d '
{
    "index" : {
        "number_of_replicas" : 1
    }
}'

setting最常見的修改項就是replicas的數量,其他的參數修改的場景不是特別多。

索引template

假設我們正在設計日誌系統的索引結構,日誌數據量較大,可能每天創建一個新的索引,索引名稱按日期標記,但別名是同一個,這種場景就比較適合使用index template。

我們舉個示例,先創建一個索引模板:

curl -XPUT 'http://elasticsearch02:9200/_template/template_access_log?pretty' -H 'Content-Type: application/json' -d '
{
  "template": "access-log-*",
  "settings": {
    "number_of_shards": 2
  },
  "mappings": {
    "log": {
      "_source": {
        "enabled": false
      },
      "properties": {
        "host_name": {
          "type": "keyword"
        },
		"thread_name": {
          "type": "keyword"
        },
        "created_at": {
          "type": "date",
          "format": "YYYY-MM-dd HH:mm:ss"
        }
      }
    }
  },
  "aliases" : {
      "access-log" : {}
  }
}'

索引名稱符合”access-log-*”將使用該模板,我們創建一個索引:

curl -XPUT 'http://elasticsearch02:9200/access-log-01?pretty'

查看該索引:

curl -XGET 'http://elasticsearch02:9200/access-log-01?pretty'

可以看到如下結構:

[esuser@elasticsearch02 bin]$ curl -XGET 'http://elasticsearch02:9200/access-log-01?pretty'
{
  "access-log-01" : {
    "aliases" : {
      "access-log" : { }
    },
    "mappings" : {
      "log" : {
        "_source" : {
          "enabled" : false
        },
        "properties" : {
          "created_at" : {
            "type" : "date",
            "format" : "YYYY-MM-dd HH:mm:ss"
          },
          "host_name" : {
            "type" : "keyword"
          },
          "thread_name" : {
            "type" : "keyword"
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1581373546223",
        "number_of_shards" : "2",
        "number_of_replicas" : "1",
        "uuid" : "N8AHh3wITg-Zh4T6umCS2Q",
        "version" : {
          "created" : "6030199"
        },
        "provided_name" : "access-log-01"
      }
    }
  }
}

說明使用了模板的內容。

當然也有命令可以查看和刪除template:

curl -XGET 'http://elasticsearch02:9200/_template/template_access_log?pretty'

curl -XDELETE 'http://elasticsearch02:9200/_template/template_access_log?pretty'

索引常用查詢

索引操作統計查詢

發生在索引上的所有CRUD操作,Elasticsearch都是會做統計的,而且統計的內容非常翔實,我們可以使用這條命令:

curl -XGET 'http://elasticsearch02:9200/music/_stats?pretty'

內容非常詳細,有好幾百行,從doc的數據和佔用的磁盤字節數,到get、search、merge、translog等底層數據應有盡有。

segment信息查詢

索引下的segment信息,可以使用這條命令進行查詢:

curl -XGET 'http://elasticsearch02:9200/music/_segments?pretty'

內容也同樣挺多,我們摘抄出關鍵的部分做個示例:

"segments" : {
  "_1" : {
    "generation" : 1,
    "num_docs" : 1,
    "deleted_docs" : 0,
    "size_in_bytes" : 7013,
    "memory_in_bytes" : 3823,
    "committed" : true,
    "search" : true,
    "version" : "7.3.1",
    "compound" : true,
    "attributes" : {
      "Lucene50StoredFieldsFormat.mode" : "BEST_SPEED"
    }
  }
}

這個片段表示名稱為_1的segment的信息。詳細如下:

  • _1:segment的名稱
  • generation:segment的自增長ID
  • num_docs:segment中沒有被刪除的document的數量
  • deleted_docs:segment中被刪除的document數量
  • size_in_bytes:segment佔用的磁盤空間
  • memory_in_bytes:segment會將一些數據緩存在內存中,這個數值就是segment佔用的內存的空間大小
  • committed:segment是否被sync到磁盤上去了
  • search:segment是否可被搜索,如果這個segment已經被sync到磁盤上,但是還沒有進行refresh,值為false
  • version:lucene的版本號
  • compound:true表示lucene已將這個segment所有的文件都merge成了一個文件
shard存儲信息

查看索引下shard的存儲情況,分佈在哪個node上,這條命令還是挺有用處的:

curl -XGET 'http://elasticsearch02:9200/music/_shard_stores?status=green&pretty'

摘抄了一個片段,3表示shard的id:

"3" : {
  "stores" : [
    {
      "A1s1uus7TpuDSiT4xFLOoQ" : {
        "name" : "node-2",
        "ephemeral_id" : "Q3uoxLeJRnWQrw3E2nOq-Q",
        "transport_address" : "192.168.17.137:9300",
        "attributes" : {
          "ml.machine_memory" : "3954196480",
          "rack" : "r1",
          "xpack.installed" : "true",
          "ml.max_open_jobs" : "20",
          "ml.enabled" : "true"
        }
      },
      "allocation_id" : "o-t-AwGZRrWTflYLP030jA",
      "allocation" : "primary"
    },
    {
      "RGw1IXzZR4CeZh9FUrGHDw" : {
        "name" : "node-1",
        "ephemeral_id" : "B1pv6c4TRuu1vQNvL40iPg",
        "transport_address" : "192.168.17.138:9300",
        "attributes" : {
          "ml.machine_memory" : "3954184192",
          "rack" : "r1",
          "ml.max_open_jobs" : "20",
          "xpack.installed" : "true",
          "ml.enabled" : "true"
        }
      },
      "allocation_id" : "SaXqL8igRUmLAoBBQyQNqw",
      "allocation" : "replica"
    }
  ]
},
補充幾個操作
  1. 清空索引緩存

curl -XPOST 'http://elasticsearch02:9200/music/_cache/clear?pretty'

  1. 強制flush

強行將os cache里的數據強制fsync到磁盤上去,同時還會清理掉translog中的日誌

curl -XPOST 'http://elasticsearch02:9200/music/_flush?pretty'

  1. refresh操作

顯式地刷新索引,讓在自動refresh前的所有操作變成可見

curl -XPOST 'http://elasticsearch02:9200/music/_flush?pretty'

  1. force merge

強制合併segment file,可以減小segment的數量
curl -XPOST 'http://elasticsearch02:9200/music/_forcemerge?pretty'

以上4個操作,一般是由Elasticsearch自動去執行,非特殊情況下不需要人工干預。

小結

本篇從運維角度簡單介紹了一下索引的一些日常操作與管理,能夠熟練應用的話,可以提升操縱索引的效率。

專註Java高併發、分佈式架構,更多技術乾貨分享與心得,請關注公眾號:Java架構社區
可以掃左邊二維碼添加好友,邀請你加入Java架構社區微信群共同探討技術

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

一個非侵入的Go事務管理庫——工作原理

在上一篇文章“一個非侵入的Go事務管理庫——如何使用”中,我講述了如何使用事務庫。有些讀者可能讀過”清晰架構(Clean Architecture)的Go微服務: 事物管理” ,其中描述了事務管理系統的舊版本。那篇文章和本文之間會有一些重疊。因為大多數人可能還沒有讀過那篇文章或者即使讀了也忘記了它的內容。因此為了照顧多數讀者,本文還是從頭開始(假設你沒有讀過前文)。如果你讀過,那你可以直接跳過熟悉的部分。

好的事務庫對於使用它的應用程序是透明的。在Go的“sql”庫中,有兩種類型的數據庫鏈接,“sql.DB”和“sql.Tx”。當你不需要事務支持時,使用“sql.DB”;否則使用“sql.Tx”。為了讓這兩種不同場景共享相同的持久層代碼,我們需要對數據庫鏈接進行一個封裝來同時支持這兩種場景。我從”db transaction in golang” 里得到了這個想法。

數據庫層的接口

數據庫層是事務管理庫中處理數據庫訪問的最低層。應用程序不需要修改該層,只有事務管理庫需要這樣做。

數據庫訪問封裝

下面是可同時支持事務和非事務操作的共享數據庫訪問接口, 它在“gdbc.go”中定義。

// SqlGdbc (SQL Go database connection) is a wrapper for SQL database handler ( can be *sql.DB or *sql.Tx)
// It should be able to work with all SQL data that follows SQL standard.
type SqlGdbc interface {
	Exec(query string, args ...interface{}) (sql.Result, error)
	Prepare(query string) (*sql.Stmt, error)
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	// If need transaction support, add this interface
	Transactioner
}

// Transactioner is the transaction interface for database handler
// It should only be applicable to SQL database
type Transactioner interface {
	// Rollback a transaction
	Rollback() error
	// Commit a transaction
	Commit() error
	// TxEnd commits a transaction if no errors, otherwise rollback
	// txFunc is the operations wrapped in a transaction
	TxEnd(txFunc func() error) error

}

它有兩部分。一個是數據庫接口,它包含了常規的數據庫操作,如查詢表、更新表記錄。另一個事務接口,它包含里支持事務所需要的函數,如“提交”和“回滾”。“SqlGdbc”接口是兩者的結合。該接口將用於連接數據庫。

數據庫訪問接口的實現

下面是數據庫訪問接口的代碼實現。它在“sqlConnWrapper.go”文件中。它定義了兩個結構體,“SqlDBTx”是對“sql.DB”的封裝,將被非事務函數使用。“SqlConnTx”是對“sql.Tx”的封裝,將被事務函數使用。

// SqlDBTx is the concrete implementation of sqlGdbc by using *sql.DB
type SqlDBTx struct {
	DB *sql.DB
}

// SqlConnTx is the concrete implementation of sqlGdbc by using *sql.Tx
type SqlConnTx struct {
	DB *sql.Tx
}

func (sdt *SqlDBTx) Exec(query string, args ...interface{}) (sql.Result, error) {
	return sdt.DB.Exec(query, args...)
}

func (sdt *SqlDBTx) Prepare(query string) (*sql.Stmt, error) {
	return sdt.DB.Prepare(query)
}

func (sdt *SqlDBTx) Query(query string, args ...interface{}) (*sql.Rows, error) {
	return sdt.DB.Query(query, args...)
}

func (sdt *SqlDBTx) QueryRow(query string, args ...interface{}) *sql.Row {
	return sdt.DB.QueryRow(query, args...)
}

func (sdb *SqlConnTx) Exec(query string, args ...interface{}) (sql.Result, error) {
	return sdb.DB.Exec(query, args...)
}

func (sdb *SqlConnTx) Prepare(query string) (*sql.Stmt, error) {
	return sdb.DB.Prepare(query)
}

func (sdb *SqlConnTx) Query(query string, args ...interface{}) (*sql.Rows, error) {
	return sdb.DB.Query(query, args...)
}

func (sdb *SqlConnTx) QueryRow(query string, args ...interface{}) *sql.Row {
	return sdb.DB.QueryRow(query, args...)
}

事務接口的實現

下面是“Transactioner”接口的代碼實現,它在文件 “txConn.go”中。我從”database/sql Tx — detecting Commit or Rollback”中得到這個想法。

因為“SqlDBTx”不支持事務,所以它的所有函數都返回“nil”。

// DB doesn't rollback, do nothing here
func (cdt *SqlDBTx) Rollback() error {
	return nil
}

//DB doesnt commit, do nothing here
func (cdt *SqlDBTx) Commit() error {
	return nil
}

// DB doesnt rollback, do nothing here
func (cdt *SqlDBTx) TxEnd(txFunc func() error) error {
	return nil
}

func (sct *SqlConnTx) TxEnd(txFunc func() error) error {
	var err error
	tx := sct.DB

	defer func() {
		if p := recover(); p != nil {
			log.Println("found p and rollback:", p)
			tx.Rollback()
			panic(p) // re-throw panic after Rollback
		} else if err != nil {
			log.Println("found error and rollback:", err)
			tx.Rollback() // err is non-nil; don't change it
		} else {
			log.Println("commit:")
			err = tx.Commit() // if Commit returns error update err with commit err
		}
	}()
	err = txFunc()
	return err
}

func (sct *SqlConnTx) Rollback() error {
	return sct.DB.Rollback()
}

func (sct *SqlConnTx) Commit() error {
	return sct.DB.Commit()
}

持久層的接口

在數據庫層之上是持久層,應用程序使用持久層來訪問數據庫表中的記錄。你需要定義一個函數在本層中實現對事務的支持。下面是持久層的事務接口,它位於“txDataService.go”文件中。

// TxDataInterface represents operations needed for transaction support.
type TxDataInterface interface {
	// EnableTx is called at the end of a transaction and based on whether there is an error, it commits or rollback the
	// transaction.
	// txFunc is the business function wrapped in a transaction
	EnableTx(txFunc func() error) error
}

以下是它的實現代碼。它只是調用下層數據庫中的函數“TxEnd()”,該函數已在數據庫層實現。下面的代碼不是事務庫的代碼(它是本文中惟一的不是事務庫中的代碼),你需要在應用程序中實現它。

func (uds *UserDataSql) EnableTx(txFunc func() error) error {
	return uds.DB.TxEnd(txFunc)
}

獲取數據庫鏈接的代碼

除了我們上面描述的調用接口之外,在應用程序中你還需要先獲得數據庫鏈接。事務庫中有兩個函數可以完成這個任務。

返回”SqlGdbc”接口的函數

函數”Build()”(在”factory.go”中)將返回”SqlGdbc”接口。根據傳入的參數,它講返回滿足”SqlGdbc”接口的結構,如果需要事務支持就是“SqlConnTx”,不需要就是“SqlDBTx”。如果你不需要在應用程序中直接使用數據庫鏈接,那麼調用它是最好的。

// Build returns the SqlGdbc interface. This is the interface that you can use directly in your persistence layer
// If you don't need to cache sql.DB connection, you can call this function because you won't be able to get the sql.DB
// in SqlGdbc interface (if you need to do it, call BuildSqlDB()
func Build(dsc *config.DatabaseConfig) (gdbc.SqlGdbc, error) {
	db, err := sql.Open(dsc.DriverName, dsc.DataSourceName)
	if err != nil {
		return nil, errors.Wrap(err, "")
	}
	// check the connection
	err = db.Ping()
	if err != nil {
		return nil, errors.Wrap(err, "")
	}
	dt, err := buildGdbc(db, dsc)
	if err != nil {
		return nil, err
	}
	return dt, nil
}

func buildGdbc(sdb *sql.DB,dsc *config.DatabaseConfig) (gdbc.SqlGdbc, error){
	var sdt gdbc.SqlGdbc
	if dsc.Tx {
		tx, err := sdb.Begin()
		if err != nil {
			return nil, err
		}
		sdt = &gdbc.SqlConnTx{DB: tx}
		log.Println("buildGdbc(), create TX:")
	} else {
		sdt = &gdbc.SqlDBTx{sdb}
		log.Println("buildGdbc(), create DB:")
	}
	return sdt, nil
}

返回數據庫鏈接的函數

函數”BuildSqlDB()”(在”factory.go”中)將返回”sql.DB”。它會忽略傳入的事務標識參數。應用程序在調用這個函數獲得數據庫鏈接后,還需要根據事務標識自己生成“SqlConnTx”或“SqlDBTx”。如果你需要在應用程序里緩存”sql.DB”,那麼你必須調用這個函數。

// BuildSqlDB returns the sql.DB. The calling function need to generate corresponding gdbc.SqlGdbc struct based on
// sql.DB in order to use it in your persistence layer
// If you need to cache sql.DB connection, you need to call this function
func BuildSqlDB(dsc *config.DatabaseConfig) (*sql.DB, error) {
	db, err := sql.Open(dsc.DriverName, dsc.DataSourceName)
	if err != nil {
		return nil, errors.Wrap(err, "")
	}
	// check the connection
	err = db.Ping()
	if err != nil {
		return nil, errors.Wrap(err, "")
	}
	return db, nil

}

局限性

首先,它只支持SQL數據庫的事務。如果你有一個NoSql數據庫,那麼它不支持(大多數NoSql數據庫不支持事務)。

其次,如果你的事務跨越數據庫(例如在不同的微服務之間),那麼它將無法工作。常用的做法是使用“Saga Pattern”。你可以為事務中的每個操作編寫一個補償操作,並在回滾階段逐個執行補償操作。在應用程序中添加“Saga”解決方案並不困難。你可能會問,為什麼不把“Saga”加到事務庫中呢? 這是一個有趣的問題。我覺得還是單獨為“Saga”建一個庫比較合適。

第三,它不支持嵌套事務(Nested Transaction),因此你需要手動確保在代碼中沒有嵌套事務。如果代碼庫不是太複雜,這很容易做到。如果你有一個非常複雜的代碼庫,其中有很多事務和非事務代碼混在一起,那麼你需要一個支持嵌套事務的解決方案。我沒有花時間研究如何添加嵌套事務,但它應該有一定的工作量。如果你對此感興趣,可以從”database/sql: nested transaction or save point support”開始。到目前為止,對於大多數場景,當前的解決方案可能是在代價不大的情況下的最佳方案。

如何擴展庫的功能

“SqlGdbc”接口沒有列出“sql”包中的所有函數,只列出我的應用程序中需要的函數。你可以輕鬆地擴展該接口以包含其他函數。

例如,如果需要將全鏈路跟蹤(詳情請見”Go微服務全鏈路跟蹤詳解”)擴展到數據庫中,則可能需要在上下文中傳遞到數據庫函數中。“sql”庫已經支持具有上下文的數據庫函數。你只需要找到它們並將它們添加到”SqlGdbc”接口中,然後在”sqlConnWrapper “中實現它們。然後在持久層中,需要使用上下文作為參數調用函數。

源碼:

完整源碼: “jfeng45/gtransaction”

索引:

1 “一個非侵入的Go事務管理庫——如何使用”

2 “清晰架構(Clean Architecture)的Go微服務: 事物管理”

3 “db transaction in golang”

4 “database/sql Tx — detecting Commit or Rollback”

5 “Applying the Saga Pattern – GOTO Conference”

6 “database/sql: nested transaction or save point support”

7 “Go微服務全鏈路跟蹤詳解”

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

HTML躬行記(1)——SVG

  <svg>是矢量圖的根元素,通過xmlns屬性聲明命名空間,從而告訴用戶代理標記名稱屬於哪個XML方言。在下面的示例中,為<svg>元素聲明了寬度和高度(默認以像素為單位),其子元素<title>可作為提示,在<desc>中可聲明一段描述性純文本,這兩個元素都不會在頁面中呈現。而<rect>是一個矩形,將被繪製到頁面中。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100">
  <title>SVG example</title>
  <desc>SVG contains a rectangle</desc>
  <rect width="50" height="50" fill="#F60" />
</svg>

  SVG作為一種圖像格式,可以包含在<img>元素內(如下所示)或CSS樣式中(例如background-image屬性)。

<img src="demo.svg" />

一、坐標系統

1)視口

  在SVG中,有一張無限大的畫布,而畫布區域被稱為視口(viewport)。通過<svg>元素的width和height兩個屬性可定義視口的尺寸,視口的原點在其左上角。

  而在視口中,還包含一個坐標系統,由viewBox屬性控制。它能包含四個數值(以逗號或空格分隔),分別是用戶坐標系統的最小橫坐標(x軸)和縱坐標(y軸),以及寬和高。

  下面的兩個<svg>元素,第一個採用了默認的坐標系統,第二個聲明了新的坐標系統,並且寬高比相同,如圖1所示,第二個矩形縮小了。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>

圖 1

  接下來修改兩個最小坐標(如圖2所示),第一個<svg>元素聲明的最小坐標為(20,20),雖然矩形的坐標是(0,0),但是比最小坐標要小,所以就會往左上角偏移;第二個<svg>元素聲明了負數坐標,與前一個正好相反;在第三個<svg>元素中,修改了矩形的坐標,正好在左上角。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="20 20 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="-20 -20 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="20 20 300 200">
  <rect width="50" height="50" fill="#F60" x="20" y="20" />
</svg>

圖 2

2)preserveAspectRatio屬性

  當viewBox屬性中聲明的尺寸與視圖的寬高比不一致時,可以使用preserveAspectRatio屬性指定圖形的縮放比例和對齊方式,語法如下,默認值是“xMidYMid meet”。

preserveAspectRatio: <align> [<meetOrSlice>]

  其中<align>的屬性值由兩個軸(x和y)以及三個位置(min、mid和max)組合而成,如表1所列。

表 1

說明
xMin viewport與viewBox的左側對齊
xMid viewport與viewBox的x軸中點對齊
xMax viewport與viewBox的右側對齊
YMin viewport與viewBox的頂部對齊
YMid viewport與viewBox的y軸中點對齊
YMax viewport與viewBox的底部對齊

  在下面的示例中,由於三個<svg>元素寬高比是3:2,而viewBox的寬高比是3:1,因此矩形會等比縮小。對它們分別應用xMinYMin、xMidYMid和xMinYMax,效果如圖3所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMin">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMidYMid">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMax">
  <rect width="50" height="50" fill="#F60" />
</svg>

圖 3

  注意,因為寬度正好適配,所以對於x軸的對齊方式,效果都是相同的。

  <meetOrSlice>可控製圖形的適配或裁剪,可選的值如表2所列。

表 2

說明
meet 保留圖形的寬高比,並且縮放viewBox以適應viewport
slice 保留圖形的寬高比,並且放大viewBox以覆蓋viewport

  在下面的示例中,兩個矩形的高度比視口要大,對它們分別應用meet和slice,效果如圖4所示,第二個矩形將整個視口給填滿了。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMin meet">
  <rect width="150" height="150" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMin slice">
  <rect width="150" height="150" fill="#F60" />
</svg>

圖 4

二、形狀

  SVG的基本形狀包括線段(line)、矩形(rect)、圓形(circle)、橢圓(ellipse)、多邊形(polygon)和折線(polyline)。

1)<line>

  線段元素需要指定起止點的坐標,如下所示,效果如圖5所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <line x1="20" y1="100"  x2="100" y2="20" stroke="black" stroke-width="2"/>
</svg>

圖 5

  其中stroke和stroke-width是筆畫屬性,可指定筆畫的顏色和寬度,相關屬性如表3所列,部分屬性的效果如圖6所示。

表 3

說明
stroke 筆畫顏色
stroke-dasharray 筆畫的外觀(實線、點線或虛線),由一系列逗號分隔的数字組成,表示長度和空隙長度
stroke-dashoffset 相對繪圖起點的偏移值
stroke-linecap 描邊的展現形狀
stroke-linejoin 路徑轉角處的形狀
stroke-miterlimit 斜接長度與線寬的最大比例
stroke-opacity 筆畫不透明度,取值範圍0~1,其中0表示透明
stroke-width 筆畫寬度

圖 6

2)<rect>

  除了直角矩形之外,還可以聲明圓角矩形,如下所示,效果如圖7所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect x="10" y="10" width="100" height="100" rx="15" ry="15" fill="#F60"/>
</svg>

圖 7

3)<circle>和<ellipse>

  利用圓形,可非常便捷的畫出圓環,效果如圖8所示。將<circle>元素的stroke-dasharray聲明為圓的周長(2πR),例如半徑為50,周長就是314。如果為stroke-dashoffset屬性定義一個值,就能得到圓環缺失一段的效果,從而就能模擬出圓環型的進度條了。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <circle cx="100" cy="100" r="50" stroke="black" stroke-width="2" 
    stroke-dasharray="314" stroke-dashoffset="40" fill="transparent" />
</svg>

圖 8

  橢圓和圓形類似,只是需要聲明兩個方向的半徑,如圖9所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <ellipse cx="100" cy="100" rx="100" ry="50" />
</svg>

圖 9

4)<polygon>

  <polygon>可畫出任意形狀的封閉圖形,例如平行四邊形、梯形等。在points屬性中,可聲明各個點的坐標,每組坐標用逗號隔開,下面繪製了一個五角星,如圖10所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <polygon points="100,0 160,180 10,60 190,60 40,180" fill="#F60"/>
</svg>

圖 10

5)<polyline>

  折線不需要閉合,與<polygon>元素類似,也是由points屬性繪製,如下所示,得到的折線如圖11所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <polyline points="20,100 40,60 70,80 100,20" fill="none" stroke="black" />
</svg>

圖 11

6)<path>

  上述基本形狀都可以由<path>元素來繪製,並且通過<path>元素還可繪製出不規則的圖形,例如心形,如下所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <path d="M 10,30
           A 20,20 0,0,1 50,30
           A 20,20 0,0,1 90,30
           Q 90,60 50,90
           Q 10,60 10,30 z" />
</svg>

  其中d屬性可聲明一系列路徑,包含多個指令,如表4所列。

表 4

指令 效果
M、m 移動到指定的坐標
L、l 繪製一條直線
H、h 繪製一條水平線
V、v 繪製一條垂直線
Z、z 關閉路徑
Q、q 繪製一條二次貝塞爾曲線
T、t 繪製一條平滑的二次貝塞爾曲線
C、c 繪製一條三次貝塞爾曲線
S、s 繪製一條平滑的三次貝塞爾曲線
A、a 繪製弧形曲線

三、文檔結構

1)內部樣式

  SVG允許在其內部嵌入<style>元素,如下所示,其中CDATA區段中的文本會被解析器忽略,但不影響渲染。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <style>
    <![CDATA[
    line {
      stroke: black;
      stroke-width: 2;
    }
    ]]>
  </style>
  <line x1="20" y1="100" x2="100" y2="20" />
</svg>

2)<g>

  <g>元素相當於一個容器,能將其所有的子元素組合在一起。應用於<g>元素中的屬性會被其子元素所繼承,如下所示,兩個圓的筆畫顏色都是綠色,而寬度都是10,如圖12所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <g id="ring" fill="white" stroke="green" stroke-width="10">
    <circle cx="80" cy="80" r="50" />
    <circle cx="120" cy="120" r="50" />
  </g>
</svg>

圖 12

3)<use>

  <use>元素可引用其它圖形,以及<g>元素,類似於複製黏貼的功能。在下面的示例中,通過<use>元素的xlink:href屬性引用了id為ring的<g>元素,並且將<use>元素上聲明的屬性傳給了<circle>元素。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <g id="ring">
    <circle cx="80" cy="80" r="50" />
    <circle cx="120" cy="120" r="50" />
  </g>
  <use x="100" y="0" fill="white" stroke="green" stroke-width="10" xlink:href="#ring" />
</svg>

  注意,當給<use>元素定義坐標后,<circle>元素會與其相加計算出最終的坐標,如圖13所示。

圖 13

4)<defs>

  可將需要復用的圖形抽象到<defs>元素中,在其內部定義的圖形不會直接呈現到頁面中。在上面那個示例的基礎上,將<g>元素整個放置到<defs>中,效果如圖14所示,沒有渲染<g>元素中的圓。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <defs>
    <g id="ring">
      <circle cx="80" cy="80" r="50" />
      <circle cx="120" cy="120" r="50" />
    </g>
  </defs>
  <use x="100" y="0" fill="white" stroke="green" stroke-width="10" xlink:href="#ring" />
</svg>

圖 14

5)<symbol>

  <symbol>提供了另一種組合圖形的方式,但與<g>元素不同,它的圖形不會呈現,並且它可以聲明viewBox和preserveAspectRatio兩個屬性,如下所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100">
  <symbol id="ring" viewBox="0 0 300 200">
    <circle cx="80" cy="80" r="50" />
    <circle cx="120" cy="120" r="50" />
  </symbol>
  <use fill="white" stroke="green" stroke-width="10" xlink:href="#ring" />
</svg>

6)<image>

  <use>元素可以引用SVG文件的某個部分,而<image>元素可以引用整個SVG文件或柵格圖像(如下所示),並且能控制引用文件的尺寸和preserveAspectRatio屬性,效果如圖15所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <image xlink:href="img/avatar.png" width="150" />
</svg>

圖 15

四、變形、圖案和漸變

1)變形

  transform屬性定義了一系列圖形元素變形的規則,包括位移(translate)、縮放(scale)、旋轉(rotate)和傾斜(skew)。注意,與CSS3中的transform屬性不同,SVG中的transform屬性作用的對象是坐標系統,而不是元素本身。

  translate()函數會接收兩個參數,沿x軸和y軸位移坐標系統,如圖16所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="translate(50, 30)" />
</svg>

圖 16

  scale()函數也會接收兩個參數(這點與CSS3中的scale()不同),沿x軸和y軸縮放坐標系統,如圖17所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="scale(2, 3)" />
</svg>

圖 17

  rotate()函數可接收三個參數,第一個是旋轉角度,另外兩個是原點坐標,也就是坐標系統按照該原點旋轉,如圖18所示,第三個矩形指定了原點。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="rotate(30)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="rotate(30, 50, 30)" />
</svg>

圖 18

  傾斜分為兩個函數:skewX()和skewY(),分別會沿着x軸和y軸傾斜,如圖19所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="skewX(30)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="skewY(30)" />
</svg>

圖 19

2)圖案

  要創建一個圖案,就得使用<pattern>元素包裹圖形元素,再利用patternUnits屬性確定平鋪圖案的方式。它有兩個關鍵字可選,默認的objectBoundingBox會讓<pattern>元素的尺寸以百分數或0~1之間的小數表示,參照對象分別是引用<pattern>的圖形元素的寬和高。

  以下面的圖案為例,它的寬和高都是10%,參照的圓形的寬高都是200,計算出的實際值就都是20,效果如圖20所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <pattern id="star1" width="10%" height="10%" patternUnits="objectBoundingBox">
      <circle cx="10" cy="10" r="10" />
    </pattern>
  </defs>
  <circle cx="100" cy="100" r="100" fill="url(#star1)" />
</svg>

圖 20

  另一個userSpaceOnUse會讓<pattern>元素的尺寸以絕對值表示,如下所示,因為<pattern>元素的寬高都為25,所以圖案會有空白間隙,得到的效果如圖21所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <pattern id="star2" width="25" height="25" patternUnits="userSpaceOnUse">
      <circle cx="10" cy="10" r="10" />
    </pattern>
  </defs>
  <circle cx="100" cy="100" r="100" fill="url(#star2)" />
</svg>

圖 21

  <pattern>元素還包含另一個patternContentUnits屬性,用於處理圖案內部的排列方式,它的兩個關鍵字也是objectBoundingBox和userSpaceOnUse,後者是該屬性的默認值。

  objectBoundingBox會讓<pattern>中的圖形元素以小數定義,如下所示。三個屬性值都是0.1(不能用百分數),參照的仍然是引用<pattern>的圖形元素,計算得到的實際值都是20,效果如圖22所示,每個圖案只显示四分之一個圓。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <pattern id="star3" width="10%" height="10%" patternContentUnits="objectBoundingBox">
      <circle cx=".1" cy=".1" r=".1" />
    </pattern>
  </defs>
  <circle cx="100" cy="100" r="100" fill="url(#star3)" />
</svg>

圖 22

3)漸變

  <linearGradient>元素用於繪製線性漸變,其子元素<stop>可指定某處的色標(即漸變點),如下所示,在起點、中點和止點處聲明了三種顏色,其中stop-opacity用於聲明不透明度(取值範圍0~1),1表示完全不透明,得到的效果如圖23所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <linearGradient id="gradient">
      <stop offset="0" stop-color="#F60" />
      <stop offset="50%" stop-color="#CCC" stop-opacity=".5"/>
      <stop offset="100%" stop-color="#FC0" />
    </linearGradient>
  </defs>
  <rect width="200" height="100" fill="url(#gradient)" />
</svg>

圖 23

  如果要改變線性漸變的方向,可通過修改起點和終點的坐標實現,例如沿垂直線漸變,代碼如下,得到的效果如圖24所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <linearGradient id="gradientVertical" x1="0" y1="0" x2="0" y2="100%">
      <stop offset="0" stop-color="#F60" />
      <stop offset="50%" stop-color="#CCC" stop-opacity=".5" />
      <stop offset="100%" stop-color="#FC0" />
    </linearGradient>
  </defs>
  <rect width="200" height="100" fill="url(#gradientVertical)" />
</svg>

圖 24

  <linearGradient>元素還有一個spreadMethod屬性,可指定在漸變範圍之外的填充方式,它有三個值可選,如下所列。

  (1)pad:默認值,用起點和終點的顏色填充。

  (2)reflect:按終點到起點,起點到終點的方式重複填充。

  (3)repeat:按起點到終點的方式重複填充。

  下面用一個示例來演示spreadMethod屬性,如圖25所示,從左往右,spreadMethod屬性的值依次是pad、reflect和repeat。

<svg xmlns="http://www.w3.org/2000/svg" width="800" height="200">
  <defs>
    <linearGradient id="spreadMethod" x1="20%" y1="30%" x2="60%" y2="70%">
      <stop offset="0" stop-color="#F60" />
      <stop offset="40%" stop-color="#CCC" />
      <stop offset="80%" stop-color="#FC0" />
    </linearGradient>
    <linearGradient id="gradientPad" href="#spreadMethod" spreadMethod="pad" />
    <linearGradient id="gradientReflect" href="#spreadMethod" spreadMethod="reflect" />
    <linearGradient id="gradientRepeat" href="#spreadMethod" spreadMethod="repeat" />
  </defs>
  <rect width="200" height="100" fill="url(#gradientPad)" />
  <rect width="200" height="100" fill="url(#gradientReflect)" x="210" />
  <rect width="200" height="100" fill="url(#gradientRepeat)" x="420" />
</svg>

圖 25

  另外一種徑向漸變由<radialGradient>元素控制,具體可參考官方文檔。

五、文本

1)<text>

  <text>元素用於處理SVG文件中的文本,在該元素中可修改字體樣式,包括字體名稱、大小、顏色、外觀等。在下面的示例中,聲明了四個<text>元素,併為它們添加了各自的樣式,效果如圖26所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="100">
  <style>
    .small {
      font: italic 13px sans-serif;
    }
    .heavy {
      font: bold 30px sans-serif;
    }
    .Rrrrr {
      font: italic 40px serif;
      fill: red;
    }
  </style>
  <text x="20" y="35" class="small">My</text>
  <text x="40" y="35" class="heavy">name</text>
  <text x="55" y="55" class="small">is</text>
  <text x="65" y="55" class="Rrrrr">Strick!</text>
</svg>

圖 26

2)對齊

  在<text>元素中對齊文本得用text-anchor屬性,它的對齊方式為起點(start)、居中(middle)和終點(end)。在下面的示例中,為了便於觀察這三個關鍵字的行為,畫了一條參考線,如圖27所示。

<svg xmlns="http://www.w3.org/2000/svg" width="120" height="150">
  <path d="M60,15 L60,110 M30,40 L90,40 M30,75 L90,75 M30,110 L90,110" stroke="grey" />
  <text text-anchor="start" x="60" y="40">Start</text>
  <text text-anchor="middle" x="60" y="75">Middle</text>
  <text text-anchor="end" x="60" y="110">End</text>
</svg>

圖 27

  SVG中的文本對齊與CSS中的略有不同,當起點對齊時,第一個字符會貼着參考線;當居中對齊時,文本的中間位置會被參考線貫穿;當終點對齊時,文本的最後一個字符會貼着參考線。

3)<tspan>

  在<text>元素中,通過其子元素<tspan>可調整文本屬性,從而實現一段文本呈現不同的效果,如下所示,這段文本為斜體,而<tspan>元素中的文本被加粗並且賦予了紅色(如圖28所示)。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <style>
    text {
      font: italic 18px serif;
    }
    tspan {
      font: bold 20px sans-serif;
      fill: red;
    }
  </style>
  <text x="10" y="30" class="small">
    My name is
    <tspan>Strick</tspan>!
  </text>
</svg>

圖 28

4)長度
  textLength屬性用於定義文本的長度,lengthAdjust屬性用於設置字符間距和字形,如下所示,默認值spacing只會控制字符間距,而spacingAndGlyphs還能控制字形,如圖29所示。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="60">
  <text y="20" textLength="90%" lengthAdjust="spacing">Big text length</text>
  <text y="40" textLength="90%" lengthAdjust="spacingAndGlyphs">Big text length</text>
</svg>

圖 29

5)文本路徑

  將文本放置在<textPath>元素中,就可讓文本按任意的路徑排列,而不是以往的水平或垂直排列。在下面的示例中,文本按一條螺旋曲線排列,如圖30所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="120">
  <defs>
    <path id="curve" d="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50" />
  </defs>
  <text>
    <textPath href="#curve">
      My name is Strick! What is your name?
    </textPath>
  </text>
</svg>

圖 30

六、動畫

1)<animate>

  <animate>是一個動畫元素,它可以包含在圖形元素中,多個<animate>元素可以實現多重動畫。例如將矩形先沿着水平方向,再沿着垂直方向位移,最後在位移結束后切換背景色的動畫,代碼如下所示,效果如圖31。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <rect id="move" width="50" height="50" fill="#F60">
    <animate attributeType="XML" dur="1s" repeatCount="1" attributeName="x"
        from="0" to="50" fill="freeze" begin="1s" id="line" />
    <animate attributeType="XML" dur="1s" repeatCount="1" attributeName="y"
        from="0" to="30" fill="freeze" begin="2s" />
    <animate attributeType="XML" dur="3s" repeatCount="indefinite" attributeName="fill"
        values="#F60;#FC0;#CCC" begin="line.end" />
  </rect>
</svg>

圖 31

  <animate>元素包含多個動畫屬性,此處只使用了其中的幾個,具體說明如下,其中fill=”freeze”是指動畫結束后保持最後的動作。

  (1)attributeName:執行動畫的屬性。

  (2)attributeType:屬性類型,可選值包括XML和CSS。

  (3)from:屬性的起始值。

  (4)to:屬性的結束值。

  (5)dur:動畫持續時間。

  (6)repeatCount:動畫執行次數,可以是有限次的整數,也可以是無限次的indefinite。

  (7)begin:動畫開始時機,可以是秒數,也可以是某個動作,例如上面第一個動畫結束后執行顏色的切換。

  <set>元素是對<animate>元素的補充,可為那些不能過渡的屬性提供動畫,例如在某個時刻显示文本,如下所示,點擊矩形可显示“change color”。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <!--省略矩形代碼-->
  <text x="100" y="20" text-anchor="middle" style="display:none">
    <set attributeName="display" attributeType="CSS" to="block" begin="move.click" dur="1s" fill="freeze" />
    change color
  </text>
</svg>

2)<animateTransform>

  對於transform屬性的動畫,得用<animateTransform>元素完成。下面的示例演示了旋轉矩形(如圖32所示),其中type屬性用於指定變形的動作,可選的值有translate、scale、rotate、skewX和skewY。

<svg xmlns="http://www.w3.org/2000/svg" width="180" height="160">
  <rect id="move" width="50" height="50" fill="#F60" x="80" y="80">
    <animateTransform attributeName="transform" attributeType="XML" type="rotate"
        from="0 80 80" to="360 80 80" dur="5s" repeatCount="indefinite" />
  </rect>
</svg>

圖 32

3)<animateMotion>

  <animateMotion>元素可讓圖形沿着任意路徑運動,無論是直線還是曲線,都能實現。在下面的示例中,橙色矩形會沿着S型曲線來回運動,如圖33所示。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <path fill="none" stroke="#000"
        d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
  <rect width="20" height="10" fill="#F60">
    <animateMotion dur="10s" repeatCount="indefinite"
        path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
  </rect>
</svg>

圖 33

  如果要讓矩形始終沿着平行於曲線的方向運動,那麼可以將rotate屬性設為auto,如圖34所示。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <path fill="none" stroke="#000"
        d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
  <rect width="20" height="10" fill="#F60">
    <animateMotion dur="10s" repeatCount="indefinite" rotate="auto"
        path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
  </rect>
</svg>

圖 34

 

【參考資料】
SVG元素參考

[技術分享] 理解 SVG 中的 Viewport 和 ViewBox-拖曳與縮放功能實做(上)

理解SVG viewport,viewBox,preserveAspectRatio縮放

SVG圖像的viewport和viewBox用於設置圖像可見區域的大小

SVG:理解stroke-dasharray和stroke-dashoffset屬性

SVG 研究之路 (16) – Stroke-miterlimit

如何使用SVG圖案

SVG 研究之路 (26) – 有趣的 Patterns

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

JSON類庫Jackson優雅序列化Java枚舉類

1. 前言

Java開發中我們為了避免過多的魔法值,使用枚舉類來封裝一些靜態的狀態代碼。但是在將這些枚舉的意思正確而全面的返回給前端卻並不是那麼順利,我們通常會使用Jackson類庫序列化對象為JSON,今天就來講一個關於使用Jackson序列化枚舉的通用性技巧。

2. 通用枚舉範式

為了便於統一處理和規範統一的風格,建議指定一個統一的抽象接口,例如:

/**
 * The interface Enumerator.
 */
public interface Enumerator {
    /**
     * Code integer.
     *
     * @return the integer
     */
    Integer code();

    /**
     * Description string.
     *
     * @return the string
     */
    String description();
}

我們來寫一個實現來標識性別:

public enum GenderEnum implements Enumerator {
   
    UNKNOWN(0, "未知"),

    MALE(1, "男"),

    FEMALE(2, "女");


    private final Integer code;
    private final String description;

    GenderEnum(Integer code, String description) {
        this.code = code;
        this.description = description;
    }


    @Override
    public Integer code() {
        return code;
    }

    @Override
    public String description() {
        return description;
    }
}

3. 序列化枚舉

如果我們直接使用Jackson對枚舉進行序列化,將只能簡單的輸出枚舉的String名稱:

    @Resource
    private ObjectMapper objectMapper;

    @Test
    void enumTest() {
        try {
            String s = objectMapper.writeValueAsString(GenderEnum.MALE);
            // 輸出字符串 MALE
            System.out.println(s);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

我們期望將GenderEnum.MALE 序列化為 {"code":1,"description":"男"} 。我們可以向ObjectMapper定製化一個Module來實現這種個性化需求:

         // 聲明一個簡單Module 對象
         SimpleModule module = new SimpleModule();
           // 給Module 添加一個序列化器
            module.addSerializer(Enumerator.class, new JsonSerializer<Enumerator>() {
                @Override
                public void serialize(Enumerator value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                   // 開始寫入對象
                    gen.writeStartObject();
                    // 分別指定 k v   code   description 
                    gen.writeNumberField("code",value.code());
                    gen.writeStringField("description",value.description());
                    // 顯式結束操作
                    gen.writeEndObject();
                }
            });

        // 註冊 Module
        objectMapper.registerModule(module);

然後再次執行就會獲取我們期望的結果。然而這並不算合理。

4. Spring Boot 中自動全局配置

Spring Boot應用中我們希望能全局配置。Spring Boot的自動配置為我們提供了一個個性化定製ObjectMapper的可能性,你只需要聲明一個Jackson2ObjectMapperBuilderCustomizer並注入Spring IoC:

@Bean
public Jackson2ObjectMapperBuilderCustomizer enumCustomizer(){
    return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.serializerByType(Enumerator.class, new JsonSerializer<Enumerator>() {
        @Override
        public void serialize(Enumerator value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                    gen.writeStartObject();
                    gen.writeNumberField("code",value.code());
                    gen.writeStringField("description",value.description());
                    gen.writeEndObject();


        }
    });
}

這樣就實現了全局配置。

5. 總結

這裏我們介紹了如何定製Jackson庫以達到對枚舉進行更加友好的序列化的目的。其實不單單枚舉,你也可以實現其它序列化,反序列化,時間輸出格式的定製。這些特性留給你自己挖掘。多多關注:碼農小胖哥 獲取更多開發技巧。

關注公眾號:Felordcn 獲取更多資訊

個人博客:https://felord.cn

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準