搜尋

搜尋結果

舊八佰伴的興衰 上編
環宇搜奇
幸村・2022-08-25

望著窗外的景色,外牆掛起了「歡迎老董事長回來」的垂幅,背後的辦公室擺設還是和四年前一模一樣。 八佰伴集團已經沒有了,四年前離開上海的時候還是董事長,現在回來的只是一個白髮蒼蒼的垂暮老人。 當這對老夫婦看到原來的辦公室的模樣,兩人相擁痛哭,隨行人員也陪著流淚。 從大阪坐新幹線去東京,中間會經過伊豆半島的熱海,除了盛產蜜瓜,同時也是八佰伴創辦的地方。 1930年和田加津太太(電視劇「阿信的故事」原型)和丈夫和田良平一起在熱海開了一間蔬果店,取名「八佰伴」,正式開始了艱辛的創業時代。 第二年,兒子和田一夫出生了,為了照顧小孩和兼顧店務,和田加津太太經常把兒子背在身上,推著小車四處收購水果。 日子雖然艱苦,但依然經營得有聲有色,可惜好景不常,一場大火把和田夫婦的多年的心血付諸一炬。 但大火沒有打倒和田夫婦,有句說話叫「人無事才能成為世界冠軍」,和田夫婦馬上重新振作,新店又在大火的灰燼中重生,同時兒子和田一夫剛從大學畢業,老父親就請求兒子回到熱海繼承家業。 名牌大學的經濟學出身和田一夫一改以往的經營方法,以前去果攤買菜還可以講價,但以後只允許明碼實價買賣,並正改名為「八佰伴食品百貨公司」,奠定了以後的企業化的經營理念。 1962年和田一夫到美國考察,發現了更先進的經營手法 -「超級市場」。 回國以後,和田一夫把八佰伴改成超級市場的構想告訴父親,父親是農民出身,對於兒子的計劃暗自佩服,聽後徹夜未眠,第二天就把八佰伴正式交由兒子管理,這一年,和田一夫才33歲。 經過五年的努力,八佰伴在熱海已經開設了七間分店。 下一步,就是跳出日本,在巴西聖保羅市開設第一間海外分店,第一天就湧入了一萬名顧客,大排長龍。 但最成功的分店,就是兩年後開將的新加坡分店,由於當地的商店習慣星期六日都休息,而恰恰八佰伴年中無休,掀起到全市周末逛百貨超市的風潮,更徹底改變了新加坡商店周末休息的模式。 令人意想不到的是,日本的傳統豆沙包(多啦A夢的最愛),居然大受新加坡人的歡迎,每天早上都有人大排長龍等待新鮮出爐,連總理的母親都是豆沙包的死忠粉絲。 一九八二年,八佰伴正式在日本上市。 八十年代是一個光輝燦爛的年代,全球經濟急速發展,天下熙熙皆為利來,天下攘攘皆為利往,日本經濟也從戰後恢復到巔峰,樓價直上天際,單東京房價已經可以買起全美國的房地產。 這一年,八佰伴在全球的的營業額達到一千億日元。 兩年後香港沙田開設分店,同時在香港上市。八佰伴最鼎盛時期全球有四百多家分店,年銷售額五千億日元。 1991年在上海浦東開業,單日就接待了107萬人次顧客,破了金氏世界紀錄,所以和田一夫顧盼自雄,對改革開放後的中國充滿信心,跟據巨大的人口市場和經濟規模估算,八佰伴最少可以開設多1000多間分店。 六年後九月的一個早晨,靜岡縣地方法院收到一份破產申請,金額高達1613億日元,八佰伴申請破產,龐大的超市帝國像一夜間轟然倒下。 和田一夫犯了一個致命的錯誤。 下週四待續

《曹操 VS 信長》完結篇 - 人間五十何所憾?
走遍世界
幸村・2022-06-23

了解歷史人物,特別是影響後世深遠的關鍵人物,不能不認識一點佛學。 佛學不是那種非常艱深、玄乎其玄的佛教Terms,其實佛學可以很淺白,與很多現代社會學觀念相通。 比如「業力」,就是大部份人的行為習慣,或某個位高權重的上為者,影響了社會乃至歷史的走向。 秦始皇就是一例,雖然「秦」國祚短,但統一了六國,之後「漢」繼承了秦的大一統皇朝,為中華民族埋下了「天下分久必合」的思想烙印。 曹操和信長都是皇朝的奠基者,在亂世軍閥混戰的時代,殺戮雖然不能避免,但兩者的嗜殺和殘酷明顯超過了必要的界限。 信長火燒比叡山,殺光山上的村落及寺廟勢力; 曹操徐州屠城,對百姓大肆殺戮,官渡之戰後,又把八萬名袁軍俘虜全數活埋。 上有所好 下必甚焉,繼承者豐臣秀吉也在萬曆朝鮮戰爭殺人無數;曹丕和司馬懿亦以殘酷見稱。 所有人都要面對這種高壓的殘酷現實,天下的老百姓都沒有選擇,因為沒有能夠阻止信長和曹操,這種象徵「惡」的嚴酷業力,最後怎樣影響整個社會? 先說曹魏,曹丕死後,司馬懿篡奪了曹魏的江山社稷,幾乎殺盡曹家;後來司馬氏後人被人篡奪王位的時候更令人慘不忍睹。 司馬氏建立的西晉王朝,一共只出過四個皇帝。第二任的惠帝是出了名的昏庸皇帝,在位期間和叔伯兄弟鬩牆搞出內戰「八皇之亂」,惠帝亦被堂兄殺死; 後來西晉陷入了「五胡亂華」,之後兩個皇帝都是被匈奴俘虜後殺死。 整個漢族文明陷入了數百年黑暗無邊的日子,接近土崩瓦解。 土崩和瓦解其實是兩個不同的概念,漢朝有個人叫徐樂曾經說過「天下之患,在於土崩,不在瓦解,古今一也。」-《漢書。徐樂傳》 瓦解只是缸瓦掉在地上碎了,還能夠拼湊在一起,像改朝換代,雖然老百姓也要過苦日子,但過一段時間就恢復了,歷史上常有。 但土崩不一樣,像土渣一樣粉碎了,拼湊不起來,文明就崩潰了。 後來人們痛定思痛,打著宋明理學的旗幟撥亂反正,才使華夏文明免於毀滅。 至於日本戰國,國運比曹魏好太多了。 信長死後,經過豐臣秀吉的攻打朝鮮的折騰,所幸江山落在明君德川家康手上。 很多人說德川家康和司馬懿很相似,大家都是靠著驚人的忍耐力獲取天下,其實兩者有著本質上的差異。 大阪之陣後,家康不僅限制了各地藩主的勢力,頒佈了「武家諸法度」、「禁中並公家諸度法度」,連天皇都要遵守家康立下的規則,成功建立了二百六十年安居樂業的德川幕府時代。 逝者如斯,在漫漫歷史長河中,唯一不變的是人性,在比較曹操和信長的時候,要記得他們都曾經真實存在以及活生生的人,和你我一樣有過頑皮的童年、經歷過迷惘的青年、奮戰拼搏的壯年。 他們善惡糾纏交錯,雖然有說太陽底下無新事,我們每天看過、遇過的難題,未來還會不斷迴圈,但我們可以選擇不一樣的道路。

挾天子的藝術 - 信長與義昭的相愛相殺
走遍世界
幸村・2022-04-12

桶狹間戰役後,信長花了七年,攻下了齋藤家的稻葉山城,成功兌換了老岳父齋藤道三的空頭支票。 老岳父也是個狠角色,人稱「美濃的蝮蛇」,堪稱戰國時代「下克上文化」的代表人物,『信長公記』就有記載齋藤道三因為小罪就處人車裂之刑、烹刑時也親自點火,自己動手親力親為。 俗說有話「人必自侮而人侮之」,後來兒子齋藤義龍起兵造反,道三臨死前豪言壯語把美濃送給女婿信長,已經「輸到甩褲」了,強弩之末還故作大方地送給女婿,信長得悉後也不知道好氣還是好笑。 每個人都死亡,所以每個人都註定消逝;每個人出生,但不是每個人都算活過。 永祿十年,信長終於給老岳父報了仇,把稻葉山城改名「岐阜城」,信長站在岐阜城的天守顧昐自雄,站穩陣腳後,修改印鑑為「天下布武」,劍指天下。 上兩講講到幕府大將軍足利義輝被奸臣所害,而弟弟足利義昭跳出來宣稱自己才是室町幕府的合法繼承人,雖然幕府的威信一瀉千里,但信長看出足利義昭的價值,率軍護送義昭上洛,成為名正言順的第十五代大將軍。 在別人眼裏一文不值的足利義昭,為什麼信長眼裏是奇貨可居?事實上,信長能橫掃天下,最後幾乎統一日本,足利義昭可謂功不可沒。 信長看中的是幕府號令天下的「合法性」,而「合法性」有四個層次。 第一個層次是「天命所歸」。 例如天降祥瑞呀,斬白蛇起義,發現一棵禾苗生出九個稻穗呀,都是古代的Marketing策略,都是一種對民眾宣揚我就是真命天子,都是天命所歸的表現成式。 第二個層次是技術活,是仁政王道的合法性。 你有天命,我也有天命。我家的小公狗昨天也生了一窩小貓,誰不會偽造天命?口講無憑,古代人也不是好忽悠的,所以你就需要品行端正,愛民如子,老百姓對你百般擁戴,獲得高度認可度才有德行的合法性,劉備走難時百姓也願意跟隨就是一個典型的例子。 第三是掌握權柄的器物。 例如日本傳統的三神器,八咫鏡、天叢雲劍、八尺瓊勾玉,又或者三國時代的傳國玉璽,本身就象徵著天命和權力,落在你手,你就有相應的合法性。器物由王家代代相傳,本身就被賦予了神聖性。孫權得到了傳國玉璽,後來建立了吳國,玉璽就發揮了穩定人心的作用。 第四就是就是最重要的,程序的合法性。 每個組織或政權都有一套既定的程序規範,例如選總統,又要提名又要參選,只要按照這個程序,你就具備了合法性,否則你就是僭越非法,天下人人得而誅之。 挾天子的好處是,在古代傳統社會之中,大將軍的身份就有集齊了四項要素,他就是最高的權力象徵。 信長出錢出力扶助足利義昭入京登位,兩個人如膠似漆,但好景不長,兩年後兩人的關係就跌落谷底。 到底發生了什麼事?

[翻書倒櫃] 關於紅茶我們該知道的二三事 - 《紅茶之書》
文化創意
君尋・2021-02-18

紅茶與我們的生活可謂密不可分,不管是早上在茶餐廳點的奶茶或檸茶,還是在休閒假日的午後到大酒店享受下午茶餐,這些我們習以為常的生活都離不開紅茶文化。源自英殖時期達官貴人的英式下午茶文化,慢慢演變成平民化的冰室、茶餐廳,由上而下、在地化的方式把紅茶文化傳承到今天,成為港澳地區常見的奶茶、檸茶。然而當我們歸根咎底時,便會發覺這股紅茶文化淵遠流長並深藏意義。源自東方的紅茶,經歷漫長的旅程傳到西方,並由英國把紅茶的美味推廣到全世界,整趟旅程可謂是歐洲向外擴張的貿易史中的一種寫照。紅茶亦是推動歷史發展的重要角色,在東方紅茶是導致鴉片戰爭的背後原因之一,而在西方則是為美國獨立定下基礎的波士頓傾茶事件中最為重要的主角。 該澄清的是本書並非只關於紅茶的歷史,而是能讓讀者概括了解紅茶知識的一本工具書。書中詳細介紹英國傳統喝茶時會用到的器具、紅茶的品種、產地和茶廠、下午茶文化和伯爵茶的由來。但本書最重要的目的,作者開宗明義地說是要推廣紅茶文化,務求讓初學者或者專家,都能在閱讀本書後,對喝紅茶這件事有更深的了解。因此書中首章以極為科學,以及圖文並茂的方式介紹「正確」的泡紅茶方式。水溫、水質、壺的形狀,以及至關重要的紅茶品種,都是影響茶葉在沖泡過程中能否發生「跳躍」現像的重要因素。茶葉的「跳躍」現像能使茶中的含氧量、兒茶素和咖啡因保持絕佳的比例,便可讓紅茶的三大要素,味道、香氣和茶色完美展現。 至於喝紅茶時應該要加奶還是檸檬?則關乎於用來沖泡的水是屬於軟水還是硬水。排除水的本質外,常用來配搭紅茶的檸檬,若在茶中放太久反而影響味道,因其表面釋放的物質會令茶的澀味更濃烈。牛奶也是一門大哉問,多年來人們曾為先倒紅茶還是先倒奶而爭吵不休,直到英國皇家化學學會以科學方式分析,判斷應先倒牛奶在杯中,後再加紅茶的順序,更有利保留牛奶和紅茶各自的優點。當我們得知上述的基礎知識後,便會明白到為何英國人喝紅茶喜歡加奶,而東方人則習慣直接喝紅茶,原來全都與所在地的水質,以及當地人首次接觸紅茶的歷史有關。下次當到大酒店花幾百元享用下午茶或其他美膳時,亦不妨利用這些難得的機會,了解食物和飲品背後的文化和歷史,把用餐體驗由現場的五官感受上升到知性的層次。 以下是書中介紹正確泡出紅茶,並同時保有完美三大要素(味道、香氣、茶色)的方法  使用新鮮的水。 一定要燒至少一公升以的水,以確保水中的氧氣不會被燒光。 以大火快速燒水,觀察熱水的沸騰狀態,在水中氧氣尚未燒光前熄火。即把熱水溫度在95至98度之間,當水面產生大氣泡、水花四濺時馬上熄火。 如室溫太底或熱水壺冷掉,必須先以熱水溫壺。 倒入熱水時要一口氣往茶葉沖下去。 成功的話,浮在水面的茶葉會隨氧氣消失而沉底,其後藉熱對流往水上浮,即所謂「跳躍」現象。 此外,水質不同亦會影響茶的品質。以硬水沖茶,茶色雖然濃,但味道卻清淡,不會殘留澀味,但亦會降低茶的特色。適合加牛奶品嚐,亦是英國人為何喜歡加奶的原因。相反,軟水則特能保留紅茶本來的特色,茶色雖淡,但味道和香氣強烈,同樣地澀味亦更為突出。 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 關於今回 [翻書倒櫃] 的推介書本: 書名: 紅茶之書:一趟穿越東方與西方的紅茶品味之旅 作者: 磯淵猛 出版社: 時報出版 出版日期:2016/04/19

[議劇論映] 同異戶的偵探故事 -《天才少女福爾摩斯》
娛樂殿堂
君尋・2020-09-28

由飾演《怪奇物語》女主角而成名的年輕女星Millie Bobby Brown獨挑大樑主演的《天才少女福爾摩斯》在9 月23日正式登上Netflix。電影改編自Nancy Springer於2006年所出版的同名小說系列中的《侯爵失蹤案》,而此系列是根據《福爾摩斯》原著而生的二次創作作品。故事講述大名鼎鼎的神探夏洛克福爾摩斯的16歲妹妹艾諾拉有著不比哥哥遜色的聰明才智,她不但獨自尋找突然消失的母親的下落,同時還要擺脫哥哥們的追捕,而在旅途當中遇上離家出走的侯爵,反而被捲入另一事件當中。 - 左右兩邊分別為哥哥邁克羅夫特及夏洛克 比起廣大影迷熟知的《福爾摩斯》電影和影集,《天才少女福爾摩斯》只保留極為微弱的推理元素以及近乎沒有的懸疑氣氛,取而代之的是輕快節奏的少女冒險故事。電影前段是最讓人期待的地方,艾諾拉運用演繹推理以及最為擅長的密文破解,找出母親留給她的線索,不但讓觀眾感到艾諾拉的智慧,也使得觀眾更期待她在故事後段面對更大迷團的表現。然而,離家出走後的艾諾拉迎來的卻是一連串的冒險,其中也不乏緊張的動作場面但亦只是點到即止。一直維持的輕快節奏卻因侯爵失蹤事件而被打斷,變為稍有冗長的文戲。到後期兩條原是平衡的故事線合而為一,但編劇卻處理得不好。看不出兩者間微小關連的觀眾更有可能認為電影是以副線當主線來演,只給人一種電影要收尾,所以草草了事之感。最終結局也像時間夠了,要來個happy ending。 - 與侯爵間的故事並沒有太多火花 雖然劇本上與期待有落差,不過《天才少女福爾摩斯》所表達的意義,還是可以透過電影的演出和道具、背景等設定,傳達給予觀眾。不論是人物的服裝打扮還是佈景設置,電影成功呈現出栩栩如生的19世紀末的英國社會,尤其是不同階層的人物穿著,以及女性的服裝打扮。電影以艾諾拉的角度,一個16年以來只在母親獨力裁培下、被貫輸有別於主流社會的異端知識,並從未入世的少女,和觀眾一起體現社會風氣依然守舊的英國中經歷到的人、事、物。其中,哥哥之一的邁克羅夫特呈現的就是極為傳統的父權代表。他是艾諾拉在母親失蹤後的唯一監護人,並要求艾諾拉按照「淑女」的標準打扮,亦即要穿上封建時代遺物的束身衣和裙撐,就有如中國的纏足一樣。甚至乎把艾諾拉送到寄宿學校,並必須學習「淑女」的行為舉止,如何喝湯,以及如何展現笑的感情,也有一套規範。另一方面,艾諾拉的母親代表的就是提升女性地位和權力的一種自由主義,她從沒有將上述的迂腐思想和規範教育給她,反而不斷提醒艾諾拉,要找到屬於自己的自由、目標以及願景,不要被社會制度的枷鎖所束縛。而中立的夏洛克就是代表著沈默的大多數,明白及理解當前的現況,卻不會主動作出任何行動。艾諾拉則是堅持自己的信念而行動,碰到困難敢於面對,遇到值得的亦勇於嘗試,她強烈的個人主義帶領她突破社會的框架,主動爭取和掌握自己的未來,亦是最終她能勝過夏洛克的原因。 - 被教育中的艾諾拉 電影中艾諾拉曾說:「福爾摩斯家的人,必須走出自己的路」。不但只是艾諾拉,《天才少女福爾摩斯》這套電影本身亦確實走出屬於自己的風格,以至無法與電影《神探福爾摩斯(Sherlock Holmes)》、《福爾摩斯的最後奇案(Mr. Holmes)》及影集的《新世紀福爾摩斯(Sherlock)》、《福爾摩斯新傳(Elementary)》作出相比。這部電影沒有過於沈重和錯綜複雜的迷團,反而是一部描述年輕活潑、絕頂聰明之餘又有點衝動不成熟的福爾摩斯的故事。如同電影的主旨一樣,《天才少女福爾摩斯》不會被過去對「福爾摩斯電影」的既定印象所規範,因此亦不難理解為什麼電影中會經常出現「打破第四面牆」的演出。關於艾諾拉福爾摩斯這位自由自在的偵探,必定能在新時代中展現出有別於傳統的偵探故事,就讓我們一起期待下去。 - 不少打破第四面牆的畫面,亦即角色直接與觀眾對話 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 關於[議劇論映] 本欄目將會分享日本及歐美的影集和電影。除最新上映及流行的作品外,亦會推薦值得回味的滄海遺珠。

架設 Squid proxy,作為國産 Linux RPM 安裝包更新的 RPM proxy
科技新知
MacauYeah・2026-02-26

前編我們介紹了 Qemu 運行國産OS做快速測試。應該基本使用大家都可以實驗到。 在投産環境上,我們通常還要控制它的kernel或lib版本更新,但這麼多的不同OS版本,想一次過做rpm mirror,並不太實際。 若以監管為目標,那些不同種類的OS,限制互聯網存取,統一經過某個http proxy的取得RPM更新,應該是一個最低成本的做法。 本文就來介紹一下,使用Ubuntu 24建設 Squid http proxy,達到rpm proxy的結果。 ubuntu 24.04 squid settings apt-get update && apt-get install squid vim /etc/squid/squid.conf 約在1404行,指定一個新的acl(access control list)名字,fixip, 它的允許來源IP是你的rpm base OS # around line 1404, add acl fixip src xxx.xxx.xxx.xxx 約在1627行, 放行新的acl # around line 1627, add http_access allow fixip rpm os settings 在rpm base的OS上,通常在 /etc/yum.repos.d/ 低下就找到它們的 rpm 包來源為置,在每個來源上加上 proxy 設定,就可以了。 Anolis OS 8 因為rpm來源眾多,我們只想讓其中兩個經proxy更新,例如 /etc/yum.repos.d/AnolisOS-AppStream.repo, /etc/yum.repos.d/AnolisOS-BaseOS.repo, 最在後加入 proxy=http://yyy.yyy.yyy.yyy:3128。 yyy.yyy.yyy.yyy 就是設了 Squid的機器 [AppStream] name=AnolisOS-$releasever - AppStream baseurl=http://mirrors.openanolis.cn/anolis/$releasever/AppStream/$basearch/os enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ANOLIS gpgcheck=1 proxy=http://yyy.yyy.yyy.yyy:3128 [BaseOS] name=AnolisOS-$releasever - BaseOS baseurl=http://mirrors.openanolis.cn/anolis/$releasever/BaseOS/$basearch/os enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ANOLIS gpgcheck=1 proxy=http://yyy.yyy.yyy.yyy:3128 OpenEuler 22 來源檔只有一個,/etc/yum.repos.d/openEuler.repo, 但內存多個section, 需要在每個section的尾段,加入 proxy=http://yyy.yyy.yyy.yyy:3128 [OS] name=OS baseurl=http://repo.openeuler.org/openEuler-22.03-LTS-SP4/OS/$basearch/ metalink=https://mirrors.openeuler.org/metalink?repo=$releasever/OS&arch=$basearch metadata_expire=1h enabled=1 gpgcheck=1 gpgkey=http://repo.openeuler.org/openEuler-22.03-LTS-SP4/OS/$basearch/RPM-GPG-KEY-openEuler proxy=http://yyy.yyy.yyy.yyy:3128 [everything] name=everything baseurl=http://repo.openeuler.org/openEuler-22.03-LTS-SP4/everything/$basearch/ metalink=https://mirrors.openeuler.org/metalink?repo=$releasever/everything&arch=$basearch metadata_expire=1h enabled=1 gpgcheck=1 gpgkey=http://repo.openeuler.org/openEuler-22.03-LTS-SP4/everything/$basearch/RPM-GPG-KEY-openEuler proxy=http://yyy.yyy.yyy.yyy:3128 ... ... [update] name=update baseurl=http://repo.openeuler.org/openEuler-22.03-LTS-SP4/update/$basearch/ metalink=https://mirrors.openeuler.org/metalink?repo=$releasever/update&arch=$basearch metadata_expire=1h enabled=1 gpgcheck=1 gpgkey=http://repo.openeuler.org/openEuler-22.03-LTS-SP4/OS/$basearch/RPM-GPG-KEY-openEuler proxy=http://yyy.yyy.yyy.yyy:3128 ... ... 指令 我們可以先用curl,來測試一下最基本的連線。請確保指令是在最初定義的xxx.xxx.xxx.xxx範圍內。 curl -v -x http://yyy.yyy.yyy.yyy:3128 http://mirrors.openanolis.cn/anolis/8.10/ 部份更新指令 由於我們前述 rpm 包並不是所有都加了proxy,我們只限定某些進行更新,所以我們使用--disablerepo --enablerepo來限制指定的更新來源。 # anolis dnf install --disablerepo='*' --enablerepo='BaseOS' 'tmux' dnf upgrade --disablerepo='*' --enablerepo='kernel-5.10' 'kernel*' # openeuler dnf install --disablerepo='*' --enablerepo='everything' tmux dnf upgrade --disablerepo='*' --enablerepo='update' 'kernel*' 參考連結 squid tutorial https://www.digitalocean.com/community/tutorials/how-to-set-up-squid-proxy-on-ubuntu-20-04 yum proxy tutorial https://www.baeldung.com/linux/yum-dnf-repositories-set-proxy

Spring boot 10 - openapi 生成器 - spring boot java client
科技新知
MacauYeah・2025-08-19

之前我們在介紹Spring Boot Web 調試工具 ,就試安裝 openapi 相關的元件。其實 openapi 並不單是為了提供 swagger 測試介面,它主要是提供一個描述的方式,讓我們針對一個特定 openapi 文件,生成對應的 api server 或 api client 接口。也就是,如果 server 方有提供該文件,道理上可以經 openapi 的工具,生成一個可以直接訪問 server 的 client library。本節,可以沿用之前的 spring boot web api doc ,為它產生一個client library 作為實驗。 在生成 client library 之前,我們還需要一個工具 openapi-generator-cli 。最簡單的取得方式,就是經過 npm , 在你需要生成 client library 的專案中,安裝你需要的 openapi-generator-cli 版本。 npm install @openapitools/openapi-generator-cli 那怕你不是使用 nodejs 作為開發,也可以經過這個方法安裝。它只提供使用 cmd 指令的捷徑。 生成 Java Client Library 我們先把 backend server 起好 cd somewhere && mvn spring-boot:run,然後使用 openapi-generator-cli 去生成以 java spring boot 3 為底的 client library 。 npx openapi-generator-cli generate \ -i http://localhost:8080/v3/api-docs \ --api-package io.github.macauyeah.springboot.tutorial.openapiclient.api \ --model-package io.github.macauyeah.springboot.tutorial.openapiclient.model \ --invoker-package io.github.macauyeah.springboot.tutorial.openapiclient.invoker \ --group-id io.github.macauyeah.springboot.tutorial \ --artifact-id spring-boot-web-api-open-api-client \ --artifact-version 0.0.1-SNAPSHOT \ -g java \ -p useJakartaEe=true \ -p useSpringBoot3=true \ --library webclient \ -o spring-boot-web-api-open-api-client 生成的 source code 就像是 spring-boot-web-api-open-api-client ,具體的使用方式,可以看看測試用例 ApiControllerApiTest.java private final ApiControllerApi api = new ApiControllerApi(); @Test public void postDateQueryTest() { // default call ApiDateRequest apiDateRequest = new ApiDateRequest(); apiDateRequest.setInputDate(OffsetDateTime.now()); LOG.debug("default web client postDateQuery:{}", api.postDateQuery(apiDateRequest).block()); // replace webClient in ApiClient if you have special auth config on // webClient, you can also change basePath during new obj creation ObjectMapper mapper = new ObjectMapper(); mapper.setDateFormat(new SimpleDateFormat()); mapper.registerModule(new JavaTimeModule()); WebClient webClient = WebClient.builder() .codecs(configurer -> { configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper)); configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper)); }) .build(); ApiControllerApi api2 = new ApiControllerApi( new ApiClient(webClient) .setBasePath("http://localhost:8080/")); LOG.debug("create api2 by local web client postDateQuery:{}", api2.postDateQuery(apiDateRequest).block()); // use webClient directly String response = webClient.post().uri("http://localhost:8080/api/record").bodyValue(apiDateRequest).retrieve() .bodyToMono(String.class).block(); LOG.debug("request by local web client postDateQuery:{}", response); } 上述例子中,如果大家沒有任何特殊要求,其實經過 api.postDateQuery(apiDateRequest).block() 就完成了。有需要改 api endpoint 的,只要生成新的 ApiClient 並設定 basePath new ApiClient().setBasePath("XXXXXX") 就好。真的要加入更多權限設定,就需要生成新的 ApiClient 並設定 webClient new ApiClient(webClient) 這個生成的 Java Client Library 道理上還是要經過 maven 等打包,變成 jar 檔,才能被其他 Java 專案所引用。筆者就建議大家直接把成生的視為獨立的 module (sub module) 存放,其他專案就以 maven dependency 的方式引用。想要混合現有專案,動態生成專案內某些 java package,暫時不太可行。因為它也有大量的 dependency ,交由 openapi-generator-cli 自己管理會比較好,它們升級時,你也可以完整升級。 openapi-generator-cli https://github.com/OpenAPITools/openapi-generator-cli spring-boot-web-api-open-api-client