走進JavaWeb技術世界1:Web後端與J2EE的由來

 

轉自:微信公衆號 碼農翻身javascript

 

這個問題來自於QQ網友,一句兩句說不清楚,索性寫個文章。css

 

我剛開始作Web開發的時候,根本沒有前端,後端之說。html

 

緣由很簡單,那個時候服務器端的代碼就是一切:接受瀏覽器的請求,實現業務邏輯,訪問數據庫,用JSP生成HTML,而後發送給瀏覽器。前端

 

即便後來Javascript在瀏覽器中添加了一些AJAX的效果,那也是錦上添花,絕對不敢造次。由於頁面的HTML主要仍是用所謂「套模板」的方式生成:美工生成HTML模板,程序員用JSP,Veloctiy,FreeMaker等技術把動態的內容添加上去,僅此而已。java

 

那個時候最流行的圖是這個樣子:mysql

 

在最初的J2EE體系中,這個表示層可不只僅是瀏覽器中運行的頁面,還包括Java寫的桌面端,只是Java在桌面端太不爭氣, 沒有發展起來。nginx

 

每一個程序員都是所謂「全棧」工程師,不只要搞定HTML, JavaScript, CSS,還要實現業務邏輯,編寫訪問數據庫的代碼。等到部署的時候,就把全部的代碼打成一個WAR包,往Tomcat指定的目錄一扔,測試一下沒問題,收工回家!程序員

 

不差錢的公司會把程序部署到Weblogic,Websphere這樣的應用服務器中,還會用上高大上的EJB。web

 

雖然看起來生活「簡單」又「愜意」,但實際上也須要實現那些多變的、不講邏輯的業務需求,苦逼的本質並無改變。面試

 

1先後端的分離

隨着你們對瀏覽器頁面的視覺和交互要求愈來愈高,「套模板」的方式漸漸沒法知足要求,這個所謂的表示層慢慢地遷移到瀏覽器當中去了,一大批像Angular, ReactJS之類的框架崛起,先後端分離了!

 

後端的工程師只負責提供接口和數據,專一於業務邏輯的實現,前端取到數據後在瀏覽器中展現,各司其職。

 

像Java這樣的語言很適合去實現複雜的業務邏輯,尤爲是一些MIS系統,行業軟件如稅務、電力、菸草、金融,通訊等等。  因此剝離表示層,只作後端挺合適的。 

 

可是若是僅僅是實現業務邏輯,那後端也不會須要這麼多技術了,搞定SSH/SSM就好了。 

 

2後端技術

互聯網,尤爲是移動互聯網開始興起之後,海量的用戶呼嘯而來,一個單機部署的小小War包確定是撐不住了,必須得作分佈式。 

 

原來的單個Tomcat得變成Tomcat的集羣,前邊弄個Web服務器作請求的負載均衡,不只如此,還得考慮狀態問題,session的一致性。

 

(老劉注:參見文章《小白科普:分佈式和集羣》)

 

業務愈來愈複雜,咱們不得不把某些業務放到一個機器(或集羣)上,把另一部分業務放到另一個機器(或集羣)上,雖然系統的計算能力,處理能力大大加強,可是這些系統之間的通訊就變成了頭疼的問題,消息隊列(MQ),RPC框架(如Dubbo)應運而生,爲了提升通訊效率,各類序列化的工具(如Protobuf)也爭先空後地問世。

 

單個數據庫也撐不住了,那就作數據庫的讀寫分離,若是還不行,就作分庫和分表,把原有的數據庫垂直地切一切,或者水平地切一切, 但無論怎麼切,都會讓應用程序的訪問很是麻煩,由於數據要跨庫作Join/排序,還須要事務,爲了解決這個問題,又有各類各樣「數據訪問中間件」的工具和產品誕生。

 

爲了最大程度地提升性能,緩存確定少不了,能夠在本機作緩存(如Ehcache),也能夠作分佈式緩存(如Redis),如何搞數據分片,數據遷移,失效轉移,這又是一個超級大的主題了。

 

互聯網用戶喜歡上傳圖片和文件,還得搞一個分佈式的文件系統(如FastDFS),要求高可用,高可靠。

 

數據量大了,搜索的需求就天然而然地浮出水面,你得弄一個支持全文索引的搜索引擎(如Elasticsearch ,Solr)出來。

 

林子大了,什麼鳥都有,必須得考慮安全,數據的加密/解密,簽名、證書,防止SQL注入,XSS/CSRF等各類攻擊。

 

3「大後端」

前面提到了這麼多的系統,還都是分佈式的,每次上線,運維的同窗說:把這麼多系統協調好,把老子都累死了。

 

得把持續集成作好,能自動化地部署,自動化測試(其實前端也是如此),後來出現了一個革命化的技術docker, 可以讓開發、測試、生成環境保持一致,系統原來只是在環境(如Ngnix, JVM,Tomcat,MySQL等)上部署代碼,如今把代碼和環境一併打包, 運維的工做一會兒就簡化了。

 

公司本身購買服務器比較貴,維護也很麻煩,又難於彈性地增加,那就搞點虛擬的服務器吧,硬盤、內存均可以動態擴展(反正是虛擬的), 訪問量大的時候多用點,沒啥訪問量了就釋放一點,按需分配,很方便,這就是雲計算的一個場景。

 

隨着時間的推移,各個公司和系統收集的數據愈來愈多,都堆成一座大山了,難道就放在那裏白白地浪費硬盤空間嗎?

 

有人就驚奇地發現,咦,咱們利用這些數據搞點事情啊, 好比把數據好好分析一下,預測一下這個用戶的購買/閱讀/瀏覽習慣,給他推薦一點東西嘛。

 

但是這麼多數據,用傳統的方式計算好幾天甚至好幾個月才能出個結果,到時候黃花菜都涼了,因此也得利用分佈式的技術,想辦法把計算分到各個計算機去,而後再把計算結果收回來, 時勢造英雄,Hadoop及其生態系統就應運而生了。

 

以前據說過一個大前端的概念,把移動端和網頁端都歸結爲「前端」,我這裏造個詞「大後端」,把那些用戶直接接觸不到的、發生在服務器端的都歸結進來。

 

4怎麼學?

如今不管是前端仍是後端,技術領域多如牛毛,都嚴重地細分了,因此我認爲真正的全棧工程師根本不存在,由於一我的精力有限,不可能搞定這麼多技術領域,太難了。

 

培訓機構所說的「全棧」,我認爲就是先後端還在拉拉扯扯,藕斷絲連,沒有完全分離的時候的「全棧」工程師。

 

那麼問題來了, 後端這麼多東西,我該怎麼學?

 

以前寫過一篇文章叫作《上天仍是入地》,說了學習的廣度和深度,在這裏也是相通的。

 

往深度挖掘,能夠成爲某個技術領域的專家,如搜索方面的專家、安全方面的專家,分佈式文件的專家等等,無論是哪一個領域,重點都不是學會使用某個工具和框架, 而是保證你能夠本身的知識和技術去搞定這個領域的頂尖問題。

 

往廣度發展,各個技術領域都要了解,對於某種需求,可以選取合適的軟件和技術架構來實現它,把需求轉化成合適的技術組件,讓這些組件以合適的方式鏈接、部署、運行,這也須要持續地學習和不斷的經驗積累。

 

最後,以一張漫畫來結束吧!

 

(完)

 

 

我爲何對後端編程情有獨鍾?

轉自: 老劉 碼農翻身 2017-05-10

這幾年前端很熱鬧,發展也很快, Angular, React, Vue ... 等各類各樣的新技術層出不窮, 而且不斷地搶後端的飯碗。 好比說著名的Model - View -Controller , 原來前端只負責View層,展現數據,如今先後端分離, 前端把控制層Controller 也給搶走了, 可憐的後端程序猿只剩下RESTful服務提供的數據了, 再加上Node.js攻其不備,入侵服務器端, 有木有危機感?

 

但我仍是對後端編程情有獨鍾, 緣由很簡單, 相比GUI編程,  我更喜歡API編程,  有點費解? 聽我慢慢道來。

 

1  單機時代的GUI

 

最先的時候我其實也是挺喜歡GUI編程的, 誰願意只在命令行下折騰呢?

 

做爲「初戀」的C語言,雖然功能強大、效率高, 可是隻能在命令行窗口寫點小程序, 很無趣。

 

後來遇到VB, 不禁的眼前一亮: 哇塞, 還能這麼寫程序!  建立一個窗體,把各類各樣的控件拖動上去, 擺好位置, 設好屬性,而後雙擊,在onClick方法中寫下代碼就ok了。

 

號稱VB殺手的Delphi 也相似, 都是所謂的RAD(Rapid Application Development) 。

 

當時的控件多如牛毛,上了年紀的程序員應該還記得CSDN出的《程序員大本營》, 裏邊有張光盤,全是程序猿們開發的VB控件, 你想發送郵件, 拖動一個不可見的SMTP控件過來, 設定郵箱服務器和端口, 直接就能夠發信, 很是簡單。  你想用一個定時器功能, 沒問題,那裏有個定時器控件,能夠直接使用 , 這纔是真正的組件化開發。

 

因爲開發出來的應用只能在PC上, 在Windows上運行, 不會出現現在手機端各類各樣的適配問題,壟斷在某些時候也是好處啊。

 

雖然這些桌面應用程序不像Web頁面那樣美輪美奐, 但對於我這個缺少藝術細胞的人來講,   這是GUI編程的黃金時代。

 

2 Web GUI

 

好景不長, 技術變遷很快, Web時代來臨了。

 

因而開始學HTML, CSS, Javascript, 忙着折騰我的主頁,  作了沒多久就意識到, 用HTML產生頁面佈局怎麼這麼麻煩,當時CSS還不普及 , 頁面佈局全靠一個表格套一個表格來作,   若是沒有Dreamweaver, Frontpage 這樣的軟件幫忙, 這些<tr><td>標籤絕對會把人淹死。

 

光有佈局還不行,還得弄圖片, 調顏色, 我在大學還學了photoshop , 想着本身設計。後來看到一本書上的例子, 在photoshop中不使用任何外界圖片, 從零開始作出一個可口可樂易拉罐出來, 那光影效果當時就把我震撼了,  馬上意識到本身不是搞藝術的這塊料, 仍是老老實實的回去寫程序去吧。

 

我的主頁怎麼辦?  我就Copy了一個別人的網站, 改了改,變成了這個樣子(圖片沒有顯示):

 

 

忘了Copy誰的網站了, 向原做者表示歉意,當時是學生,知識產權意識不夠,擱如今確定得掏錢去買。 

 

如今通常的開發團隊都配有美工, 能夠設計界面,設計完還能「切圖」,造成漂亮的html+css的靜態頁面, 接下來的問題就是怎麼把靜態的網頁變成動態的網頁, 這就八仙過海,各顯神通了。  

 

傳統的方式就是在服務器端完成, 利用各類各樣的模板技術, 在靜態頁面中加上動態內容, 直接生成HTML UI元素。

 

最近流行的就是讓瀏覽器來負責, 經過js 調用後端API,把數據變成HTML UI元素後展現出來。

 

無論是那種方式, CSS都是不可或缺的。由於它控制了頁面的佈局結構, 又是佈局,快逃!

 

3 Java GUI

 

上了Java的賊船之後, 也作了一些GUI的工做, 相比於VB/Delphi拖放控件的便捷, 用Java寫界面簡直就是地獄! 

 

雖然也有圖形化的界面編輯器, 也能夠拖放控件, 可是自動生成的代碼那叫一個慘不忍睹。 更悲催的是,稍微手工改動一下, 那個界面編輯器就可能不認了。   絕大多數狀況下仍是直接寫代碼來生成界面。 (再次大聲疾呼:不要再Swing和AWT上浪費精力,用的極少。 )

 

這裏必須說一下Java和VB在界面編程的區別,  Java 的界面全是用代碼來生成的,就是說你須要寫代碼建立一個按鈕, 寫代碼把這個按鈕放到什麼地方去, 因此即便是GUI程序, 最終的表現形式也只是Java 文件而已。

 

VB則不一樣,它專門有個.frm文件, 裏邊存儲全部界面控件和佈局的信息, 最終也須要把.frm打包發佈。 因此在編輯界面這一點, VB和Dephi 是很是方便的。

 

程序員們這麼痛苦, 那些大牛確定會來解救咱們的, 比方說能不能用XML來描述界面啊, 在XML中把各個控件及其佈局關係都給描述好, 由系統讀取,建立界面,就像原來的.frm文件同樣。 Android 不就是這麼幹的嗎?

 

可是XML文件讀起來也夠痛苦的, 爲了靈活性, 這個XML文件還不能隱藏起來,有時候還要手工去改, 改完還不容易看到真正的效果, 唉,想一想就頭大。

 

更不用說Android的適配問題了, 不一樣屏幕尺寸,不一樣的分辨率, 不一樣的像素密度給程序員帶來了極大的工做量。

(每一個矩形表明一種設備)

4  後端編程

 

囉嗦了這麼多, 其實就想表達一箇中心思想: 我是有點懼怕GUI編程。 而Web 前端和App前端都是在和GUI打交道。

 

我甚至想,這可能和內向的性格有關係, 擅長和機器打交道, 不擅長和人打交道。 前端須要琢磨用戶的心理、使用習慣、用戶體驗, 這不是個人優點。

 

在軟件編程領域, 與其費力不討好的補上短板, 不如把本身的長處發揮到極致。

 

既然如此,那就呆在後端編程吧, 這裏沒有GUI, 只有API。  悄悄地躲在電腦的背後,  給Web前端和App前端提供服務, 讓他們調用。

 

有人會說: 前端把Controller和View都拿走了, 後端就是個API的提供者,能折騰啥啊。

 

別小看後端編程,後端是很是有技術含量的,像什麼高併發、緩存、負載均衡、分佈式、消息隊列、安全、搜索、數據複製.... 每一個方向都值得靜下心來去深挖。

 

無論前端技術怎麼變化, 做爲提供服務的後端老是要存在的,這是一大優點。

 

後端編程還有一個優點就是相對穩定, 比起大爆炸的前端,後端技術的變化要緩慢一些, 心思不會那麼浮躁, 有不少知識能夠慢慢的沉澱。

 

對於那些不喜歡作GUI的同窗,不妨考慮下後端編程。

 

 

J2EE究竟是何方神聖

 

1、J2EE歷史

 

前言:

昨天下午有同窗問我Java EE是幹什麼用的,能開發什麼系統, 我在QQ中敲了不少字,掰扯了半天,終於給他整明白了。

我忽然意識在其實不少初學者對Java EE的前因後果並去清楚, 你們並不知道爲何會出現這個技術, 要解決什麼問題。 因此就寫了這篇文章介紹下Java EE的歷史。

-----------------------------------------------------------------------

先把時間扯的遠一點, 94年我上高中的時候, 見過親戚家有過電腦, 很好奇, 雖然上面都是一些單機桌面程序, 根本上不了網, 可是一個小小的掃雷程序就足以吸引不少眼球了。

 

後來上了大學, 接觸電腦愈來愈多, 局域網已經普及, 互聯網開始擡頭,這時候C/S (Client-Server )結構的程序開始出現了,例如QQ, 棋牌類遊戲, 還有著名的PowerBuilder 開發的MIS(管理信息系統), 都是典型的客戶端-服務器結構, 程序運行在我的的電腦上,和服務器通訊。

 

C/S 軟件界面能夠整的很漂亮, 用戶體驗很好, 可是缺點也很明顯, 就是用戶必需要安裝客戶端, 而且須要升級客戶端來用新功能, 這樣就帶來兩個問題

(1) 服務器端發生變化, 必定要能兼容不少客戶端版本,要否則有的客戶端軟件就運行不了了, 由於客戶不必定升級。

(2) 可能會出現DLL 地獄問題 -- 本身百度下啥是DLL 地獄。

 

再後來Web大發展, 速度快了, 帶寬也夠了, 你們發現, Web頁面也能作的很漂亮了, 把程序放到服務器端, 用瀏覽器訪問多好, 用戶也不用安裝,全部功能都是即時更新。

可是html只是靜態的,怎麼才能變成動態的, 可交互的呢?

CGI 技術出現了, CGI 容許web服務器調用外部的程序, 並把結果輸出到Web瀏覽器, 這樣就能根據用戶的操做生產不一樣的動態頁面了。

在我讀大學的年代, CGI 最多見的就是實現一個計數器, 看着本身的主頁訪問量慢慢的增加,那種感受是很爽的。

固然,使用CGI 最苦逼的就是須要用程序輸出html , 那但是整個網頁的html , 不是其中的一個片斷 !

換句話說, 程序員只能在代碼裏寫html, 而不能在html裏寫代碼 。 你能夠想象一下用C 語言或者Perl 寫CGI腳本的程序員那種咬牙切齒的感受。

 

舉個例子, 經過瀏覽器提交了用戶名/ 密碼, cgi 會這麼作:

if (name=="liuxin" and password == "xxxx" ) {

println ("<html>");

println ("<head>");

println ("<title>歡迎</title>");

println ("</title>");

println("<body>")

println("<table>")

println("<tr><td>") ..... 我實在是寫不下去了,太崩潰了, 這是僞碼, 不要和我較勁...............

println("</td></tr>")

println("</table>")

println("</body>")

print("</html>")

}

 

 

 

這個時候咱們賴以餬口的Java 在幹嗎?

Java是Sun 發明的, 固然Sun 如今已經被Oracle 收購了。

Java 實際上是依靠Applet ,依靠互聯網才起家發達的, 你們在簡陋的頁面上忽然看到當時極爲炫目的Applet 小動畫, 馬上就震驚了。

但悲劇的是你們發現Applet 除了用來演示之外, 彷佛沒有找到真正的用武之地。

 

 

瀏覽器還必須得裝個java 插件, 後來微軟爲了阻止Java 還在本身瀏覽器IE中使壞 :-) , 這個插件運行一直不太穩定。

 

Java 看到CGI 技術發展的不錯, 本身也搞一個相似的吧, 這就是Servlet , 因爲提供了一個request, response, session等支持, 用起來比CGI方便多了。

可是輸出html這一塊沒有任何改進, 還得程序員一句一句的輸出html.

06年我進IBM的時候發現有個項目是在用servlet 輸出頁面html ,徹底沒用jsp, 我也就見怪不怪了, 這確定是個90年代的遺留應用。

 

最後你們都受不了這種極爲痛苦的輸出方式, 因而Sun 就弄了個JSP , 微軟也不甘示弱, 出了個ASP。

這下子Web開發出現了躍進,由於無論是JSP仍是ASP, 都是所謂的 Server Page , 也就是說程序員終於能夠把邏輯代碼和html混在一塊兒了! 在也不用一行一行的輸出純html了。

固然如今老師教導你, jsp中不要有邏輯代碼, 但在當時,這但是了不得的突破 。

咱們能夠先讓美工把頁面設計好, 而後把程序嵌入進去就好了。

 

再後來出現了Struts, 使用MVC解決了職責劃分問題, Web 應用邁向了新的臺階, 開始飛速發展, 對於這種應用,咱們稱爲 B/S 結構, 即Browser(瀏覽器)-Server (服務器) 。

C/S結構的程序固然不會消亡, 由於像聊天,視頻,遊戲等對性能, 界面,用戶體驗要求很高, 自然適合桌面程序實現。

 

爲了支持更大,更復雜的應用開發, 微軟爲ASP 添加了實現業務邏輯的COM, COM+ ,訪問數據庫的ADO 等技術。

而Sun和Java 社區有更大的野心,他們提出了一套更大的, 不一樣於傳統應用開發的架構,專門用於知足企業級開發的需求。

這些需求包括數據庫, 郵件, 消息,事務處理, Java 對這些通用的需求作了抽象,造成了一些規範和標準,除了Servelt 和 JSP ,還有EJB, JMS , JDBC 等等。

這些東西,Sun 把他們稱爲J2EE 。

爲啥不是Java EE ? 那個2是怎麼回事?

這徹底是一種市場策略, 原來Java 的版本是1.1 , 從1.2開始, Sun 稱之爲爲Java 2 平臺 , 以便告訴你們,這是一個突破性的技術平臺。 實際上也確實有所突破, Java 被分紅了 J2SE (標準版) , J2EE(企業版) 和J2ME(移動版) , 固然移動版在手機上一直沒有發展起來, 直到Android的出現--這是後話了。

到了2005年, Sun 又取消了那個 「2」 , 因而就變成了 Java SE, Java EE, Java ME 了。

 

J2EE須要運行在一個叫應用服務器的東西里, 這就是Weblogic, websphere , jboss, 也稱爲應用中間件。

 

J2EE發展的很是迅猛, 迅速統治了Web應用開發市場, 微軟的ASP只能偏居一隅了, 後來推出.NET 纔算扳回一城。

 

咱們走了漫長的路, 終於來到你的面前, 如今你知道Java EE 是幹啥的了吧 :-)

 

在後來的故事估計不少人都聽過了,Java EE遠遠沒有宣傳的那麼美好, EJB, 尤爲是Entity Bean 極爲難用, 對業務代碼侵入性極強, 在你們想拋棄而又沒有替代品的時候, 有一位大牛Rod Johnson如約而至,他說咱們不要這種臃腫,低效,脫離現實的J2EE, 咱們要靈活,輕便,輕量級的框架, 這就是Spring, 咱們就有了依賴注入,AOP....

有位叫Gavin King的澳大利亞小夥子也是在忍受不了EJB的O/R Mapping , 本身整了一個Hibernate 。

再加上更早出現的Struts, 咱們Java 程序員終於過起了幸福的SSH生活。

 

 

2、J2EE入門指南

 

 

前言

這是寫給零基礎小白的一系列文章。

爲啥叫生存指南呢, 由於Java發展了20年, 如今已經不只僅是一個單純的語言了, 而是一套完整的生態系統, 其中的術語像 HTML, XML, CSS, Javascript , AJAX, JQuery,Prototype, HTTP, Tomcat, JBoss, Nginx , Memecached , Redis, MVC ,Servlet, JSP, Struts, Hibernate, myBatis , Spring, JFinal, MySql, JDBC, EJB, JMS, Swing , AWT, Reflection, OSGi... 鋪面而來, 搞的你頭暈腦脹, 無所適從,很容易就Lost了。

因此寫這個文章的目的就是幫助小白能在Java 的汪洋大海里生存, 時不時的能冒出水面喘口氣, 看看空中的生存指南, 把握本身的方向繼續向前。

-------------------------------------------------------------

 

先回答一個問題? 爲何要學習Java ?

我想緣由無非有這麼幾點

1. 我周圍的人都在學, 因此我也學

2. Java 好找工做啊, 確實是,在中國,軟件行業還處於模仿、學習美國鬼子的階段, 作系統級編程的不是沒有, 像BAT就會用到。 不過絕大部分公司還都是搞應用級程序的開發, 因此Java, 尤爲是Java EE 工做機會是很是多的。

3. Java 看起來挺簡單的。

 

Java 語言自己看起來確實挺簡單的, 不像C語言, 一個指針就把你搞迷糊了;

也不像C++, 語法複雜而詭異, new 了一個對象之後還得記住 釋放內存,確實是挺悲催的;

Java 即便加上了面向對象(封裝,繼承,多態), 也是簡單的使人髮指, 不用上大學,高中生,甚至初中生都能看明白。

但是你會發現學了基本的Java 之後, 除了能寫個水仙花數, 九九乘法表,仍是啥也幹不了,更別說月薪過萬了。

人家公司至少要求精通SSH,AJAX,JQuery ,CSS,mysql , 這條路走起來就不那麼容易了。

 

再看第二個問題: Java 到底能幹什麼?

一句話, Java 最擅長的就是Web 應用開發(通俗的講就是網站開發),不善長桌面應用開發。

你想一想你開發一個Java 桌面應用, 還得讓用戶下載一個Java 虛擬機, 甚至要設置環境變量, 通常人是搞不定的。 此外Java 內置的Swing ,AWT確實不怎麼樣, 開發出來的界面距離操做系統原生界面差了很遠, 因此除了特殊狀況, 奉勸那些還在孜孜不倦的研究Java 界面編程(Swing, AWT)的同窗仍是不要浪費精力了, 不要硬逼着Java幹他不擅長也不不肯意作的事情。

 

因此我們就聊聊Java Web 開發中用到的那些技術和術語。

先來講說HTML, 我們想象一個場景, 互聯網尚未出現, 你是個球迷+程序員, 電腦裏有不少的記錄足球的文件例如 足球.txt, 巴塞羅那.txt , 曼聯.txt .....

其中足球.txt 中有一個詞"巴薩羅那" , 爲了方便, 你想點這4個字就打開另一個文件「巴賽羅那.txt」 馬上就能看看球隊的介紹 ,這該怎麼辦?

你左思右想,終於頓悟了, 能夠這麼幹: 定義一個協議 <a href ="巴塞羅那.txt">巴塞羅那 </a>  , 而後開發一個軟件, 把全部的文本都管理起來, 遇到像<a href ...>這樣的東西, 軟件就認爲這是一個連接, 點擊後就打開另一個文件 !

這的確是個好主意,其實在1989年, 萬維網的發明人蒂姆·伯納斯·李也是這麼幹的, 你看你要是早出生20年,估計也是WWW的發明人了。

加了連接之後, 文本就不是不一樣的文本了, 而升級爲超文本 (Hypertext)了 !

 

可是若是你的「足球.txt」還有「廣州恆大」幾個字, 可是廣州恆大的介紹是在你哥們的電腦上, 而他也想把他的文本能連接到你的電腦文件上,這怎麼辦?

一個單機運行的軟件就不行的, 必須得有網絡 , 有網絡還不夠,你得解決通訊的問題。

你就想:既然上面的文本是超文本,而且須要把你好哥們的文本傳輸到你的電腦上才能看, 那通訊方法就叫作超文本傳輸協議吧 HyperText Transfer Protocol , 簡稱Http。

 

因而你又擴展上一個程序, 不但把你的文本文件都管理起來,還容許經過網絡訪問, 別人要想經過網絡看你的文件, 得發個這樣的命令給你的軟件:

http://192.168.0.10/football/巴薩羅那.txt 。 你的程序就會找到football 目錄下的 巴薩羅那.txt , 讀出內容, 發給對方, 而且給他說: 200 成功

若是找不到, 軟件就告訴他: 404 對不起,找不到 。

若是你的軟件在處理過程當中出了錯 , 軟件就說: 500  唉, 服務器出錯了。

這個軟件功能強大,專門在網絡上別人服務,就叫網絡服務器吧,能夠起個名字叫Apache 。

 

但是隻看文字太不爽了, 你還想看錶格,列表,圖片,甚至視頻。 乾脆本身定義一個描述界面的語言吧, 像這樣:

<table> ---表示表格

<li> --- 表示列表

<image> -- 表示圖片。

這些都稱爲標記(markup) , 因此如今你的超文本就更加豐富了, 這個語言就叫作 Hyper Text Markup Language , 簡稱爲 HTML。

 

原來的軟件只能顯示文本和處理連接, 如今還須要能處理這些標籤, 遇到不一樣的標籤, 就顯示相應的內容 。

如今你把你的文本所有用html改寫了一遍, 放到了Apache 服務器中, 你的哥們也把他的html放到了他的Apache服務器上, 固然大家的html之間還保持着連接 。 而後大家就能夠用新的軟件對這些html進行瀏覽了, 對了,能夠把這個軟件稱爲瀏覽器。

 

因爲方便,快捷,能發佈圖文並茂的信息, 更關鍵的是能夠把散佈在全世界各個角落中的計算機鏈接在一塊兒, HTML , HTTP, 網絡服務器,瀏覽器 迅速普及, 人們上網在也不用使用那些難用的telnet , ftp 了。 網絡就變成了這樣:

 

下面的文字來源於百度百科:

由於在互聯網技術上的傑出貢獻,伯納斯·李被業界公認爲「互聯網之父」。他的發明改變了全球信息化的傳統模式,帶來了一個信息交流的全新時代。然而比他的發明更偉大的是,伯納斯·李並無像其餘人那樣爲「WWW」申請專利或限制它的使用,而是無償的向全世界開放。伯納斯·李原本能夠在金錢上與蓋茨一比高低,但他的這一舉措卻爲互聯網的全球化普及翻開了里程碑式的篇章,讓全部人都有機會接觸到互聯網,也圓了那些。com公司建立者們的富翁夢。即使如此,伯納斯·李仍然十分謙虛,老是以一種平靜的口氣迴應:「我想,我沒有發明互聯網,我只是找到了一種更好的方法。」

互聯網之父 伯納斯·李

 

 

 

接上篇《給小白的Java EE生存指南》 , 你能夠經過公共號的消息歷史中查看。 今天繼續聊Web的事情。

 

上次說到你發明了html , http, 瀏覽器, web服務器, 這下子把整個世界的信息都連接成了一個了一個大網: world wide web

但是你注意到一個問題沒有, 這些html都是靜態的 , 也就是說你除了瀏覽你的網站和別人的網站以外,什麼都作不成。 用你發明的HTTP術語來說, 就是如今的互聯網, 只支持 「GET」

好比說, 你看了哥們的網站,知道廣州恆大奪得了2015亞冠冠軍, 想給他留個言表示一下興奮之情,這就作不到了。

這是不能令你滿意的, 對互聯網作擴展吧

先擴展HTML ,加上一堆新標籤 像<form>了, <input>了 什麼type=text, radio, textarea,checkbox 。。。 這樣你就能夠在html中支持輸入各式各樣的信息了。

你還得擴展HTTP協議, 引入一個「POST」這樣能夠把數據發到Web服務器。

Web 服務器固然也得擴展, 接收到POST過來的留言數據之後, 確定得想辦法處理啊 ,怎麼處理? 

無非就是新生成一個html , 除了把原有的數據保留之外,還要把新的留言相關的數據「動態」的加上去, 這就是所謂的動態頁面。

必須得有程序來辦這件事情, 你立刻就面臨兩個問題:

(1) 用什麼語言來寫, 畢竟有那麼多語言像C, Perl , Python, 甚至Java 都在虎視眈眈呢

(2) 這個程序怎麼和 Web 服務器交互

 

解決方法也很簡單, 你弄了了一個叫作 Common Gateway Interface (簡稱CGI) 的東西, 定義了標準的輸入(STDIN)和輸出(STDOUT), 全部的程序均可以從STDIN 讀入數據,處理後造成html, 而後向STDOUT 輸出 。

這下子任何語言均可以寫cgi程序了, 網頁也變成了「可交互式」的, 整個互聯網又向前推動了一大步, 各類各樣的商業網站如雨後春筍通常發展起來。

 

( ps : 如今CGI 技術已通過時了, ASP, JSP, PHP等技術是主流。

在Java的世界裏, 把Apache ,Ngnix 這樣的服務器稱爲靜態內容服務器, 主要處理像圖片/文件件這樣不變的,只讀的靜態資源,性能很是好; 把Tomcat, JBoss ,Websphere, Weblogic等稱爲動態內容服務器, 主要產生動態內容。

通常的設計會把Apache/Ngnix 放的前邊,接收全部的Http 請求,若是是靜態資源,就直接處理掉, 若是是動態資源,就轉發到Tomcat/Jboss 去處理。 )

 

等等,還有個小問題, 個人留言我能看到, 別人的留言我也想看到改怎麼辦? 很明顯, 每一個人經過瀏覽器提交的留言都須要保存起來, 在生成頁面的時候動態的讀取他們,造成html 。

 

能夠把全部的用戶留言都存放到一個文件當中,讀取文件造成html沒有任何壓力, 可是你要很是當心處理同步的問題:你提交留言的時候,別人也在提交, 可不能相互覆蓋啊 !

這也是爲何Web程序都有一個數據庫的緣由, 數據庫幫咱們解決了這些亂七八糟的同步問題, 咱們只須要向數據庫發出 Select, Insert, Upate ,Delete 就行了。數據庫的歷史要比WWW久遠的多, 早在大機時代就出現了, 如今已經發展的很是成熟 , 直接拿過來用就能夠了。

 

解決了用戶留言的問題, 你接下來要寫一個網上售票的應用, 讓你們在網上買球票, 買票的時候須要一個購物車, 你們能夠把票暫時放到購物車裏。

開發購物車的時候發現了你設計的HTTP一個很是嚴重的缺陷 : 沒有狀態 , 由於用戶往購物車裏加了一個球票, 一刷新頁面購物車就空了,裏邊的全部東西都丟失了。

假設用戶A在操做, 用戶B也在操做, 你的Apache服務器實際上根本區分不出來誰是用戶A, 誰是用戶B, 只是看到了一個個毫無關聯的GET和POST 。 根本記錄不下來同一個用戶在過去一段時間內作了什麼事情。

你想改一下HTTP協議, 但是悲催的是數以億計的網站已經在用了, 你想改都改不了了。

因而你想了個辦法, HTTP 協議不是有個header嗎, 在裏邊作作手腳 :

瀏覽器A第一次給服務器發送請求時, 服務器經過header告訴它一個編號number_a,瀏覽器A須要記住這個編號, 而後下次請求的時候(以及後續全部請求的時候)也經過header 把number_a 發給服務器。 這樣服務器一看, 奧,原來你是瀏覽器A 啊, 就能夠把瀏覽器A相關的購物車數據從內存中取出來, 造成html 發回瀏覽器A了。

瀏覽器A和服務器的這個經過這個編號來交互, 這個過程就稱爲 : session

用了這一個小伎倆, 這樣服務器就把各個瀏覽器(各個用戶)給區分開了。

 

到目前爲止,構建一個Web系統最基礎的工做能夠說已經完成了, 我想起來高中時物理老師說的一句話: 牛頓三定律出來之後 ,經典物理學的大廈已經創建起來了, 後人的工做無非是刷刷牆, 裝飾裝飾而已。

對於互聯網也是: HTTP + HTML + Web服務器 + 數據庫 就是WWW的基石, 後續的工做都是爲了提升生產率作的包裝和裝飾。

 

最後簡單作一個總結: 其實發明創造並無那麼難, 馬雲說過, 哪裏有抱怨,哪裏就有機會, 因此找一找如今你感受最不爽的地方, 也許能發明下一代互聯網呢。

 

 

 

前兩篇文章 《給小白的Java EE生存指南(1)》 和《給小白的Java EE生存指南(2)》 (注:回覆關鍵字「小白」便可查看)基本上把Web編程所依賴的基礎技術(HTTP,HTML, WEB服務器,瀏覽器)的前因後果介紹完了, 從這篇開始 ,正式開始進入應用程序的開發領域。

 

其實Web應用程序開發也有個極爲常見的技術: XML . 不少小白在問,爲何有XML, 要XML幹嗎?不是有HTML了嗎 ? 暈倒

對一項技術個人風格是喜歡刨根問底, 不但要知道how, 還要知道why , 瞭解了一個技術的成因, 才能真正掌握。

 

假設你用Java 寫了一個很棒的Web應用, 這個程序能夠在線購書, 在互聯網剛起步的時代這個應用火的一塌糊塗 , 後來有個出版社看到了機遇, 就想和你搞合做: 我這兒也有個Web應用,能夠給你提供不少書籍的資源, 你能不能開發個程序把這些書的信息讀出來,放到你的網站上?

 

這沒啥難的, 首先得定義一下你的應用和出版社的應用中間怎麼進行數據交換, 你要定義一個格式,像這樣:

[isbn|書名|做者|簡介|價格]

例如: [978-7-229-03093-3|三體|劉慈欣|中國最牛的科幻書|38.00]

 

數據雖然緊湊, 可是每一個字段是什麼含義,很差理解, 你想起了HTML的標籤好像不錯,不如學習HTML改進一下:

<book>

<isbn>978-7-229-03093-3</isbn>

<name>三體</name>

<author>做者</author>

<introduction>中國最牛的科幻書</introduction>

<price>38.00</price>

</book>

因爲HTML的標籤<head>,<title>,<tr><td>...... 是有限的,而你的標籤確實能夠隨意擴展的,想寫什麼寫什麼 因此你就把它稱爲 Extensible Markup Language, 簡稱XML

 

如今每一個字段的含義很明確, 人讀起來也很爽了, 可是畢竟是程序在處理出版社發過來的數據, 萬一他們的數據裏少了一些重要字段該怎麼辦, 能不能自動的檢測出來?

 

因此你須要設計一套校驗規則, 能讓程序自動校驗一段xml 文本是否是你指望的, 這個規則能夠像這樣:

<!ELEMENT book (isbn, name, author, introduction, price)>

<!ELEMENT price (#PCDATA)>

<!ELEMENT name (#PCDATA)>

<!ELEMENT isbn (#PCDATA)>

<!ELEMENT introduction (#PCDATA)>

<!ELEMENT author (#PCDATA)>

 

其中第一行的意思是 xml 須要有個 book 標籤(元素), 它包含了幾個子標籤 , 而且這幾個標籤必須都得有,而且按次序出現。

其餘行表示每一個標籤都是文本就能夠了。

你把這個東西起名爲文檔類型定義 Document Type Definition, 簡稱DTD 。

 

這樣就不怕出版社使壞了, 對他們發過來的數據, 在真正的處理以前, 你寫了個程序, 調用用DTD一驗證就知道是否是合法的, 少了個字段什麼的一會兒就能查出來,巨爽。

後來又有人發明了DTD的改進版XML Schema ,那就是後話了。

 

慢慢的你就發現,XML極爲靈活,描述一個東西很是方便, 除了應用之間交互數據以外,用來描述你的系統的配置信息也大有永無之地。

 

原來你爲了讓代碼有可移植性(說白了就是在別人的機器上安裝時不用費那麼大勁),把數據庫的ip , 用戶名, 密碼 都寫在了一個文本文件中, 這樣就能夠只改配置而不用改動代碼了

ip=192.168.0.1

name=test

user=liuxin

password=liuxin

 

可是碰到複雜的,尤爲是層次化的配置用文本文件就捉襟見肘了,例如:

form1.name=login

form1.class=com.test.login

form1.property1.name=ok

form1.property1.type=java.lang.String

form1.property2.name=failure

form1.property2.type=java.lang.String

 

form2.name=logout

form2.class=com.test.logout

form2.property1.name=ok

form2.property1.type=java.lang.String

form2.property2.name=failure

form2.property2.type=java.lang.String

是否是看的頭大?

改爲xml 描述看看, 是否是就容易理解多了:

<form name="login" class="com.test.login">

<property name="ok" type="java.lang.String" />

<property name="failure" type="java.lang.String" />

</form>

<form name="logout" class="com.test.logout">

<property name="ok" type="java.lang.String" />

<property name="failure" type="java.lang.String" />

</form>

 

其實不光是你, 如今絕大多數Java 應用程序的配置文件都是xml , 已經成爲事實的標準了。

總結:XML主要用於程序之間的數據交換, 以及描述程序的配置信息。

 

歷史知識:

早在1969年,IBM公司就開發了一種文檔描述語言GML用來解決不一樣系統中文檔格式不一樣的問題,這個語言在1986年演變成一個國際標準(ISO8879),並被稱爲SGML,SGML是不少大型組織,好比飛機、汽車公司和軍隊的文檔標準,它是語言無關的、結構化的、可擴展的語言,這些特色使它在不少公司受到歡迎,被用來建立、處理和發佈大量的文本信息。

 

在1989年,在CERN歐洲粒子物理研究中心的研究人員開發了基於SGML的超文本版本,被稱爲HTML。HTML繼承了SGML的許多重要的特色,好比結構化、實現獨立和可描述性,可是同時它也存在不少缺陷:好比它只能使用固定的有限的標記,並且它只側重於對內容的顯示。

同時隨着Web上數據的增多,這些HTML存在的缺點就變的不可被忽略。W3C提供了HTML的幾個擴展用來解決這些問題,最後,它決定開發一個新的SGML的子集,稱爲XML。

 

 

 

本文是給小白的Java EE生存指南的第4篇, 講一下幾乎100%Java 開發人員都要用的 Tomcat。

爲何有Tomcat ? 其實須要從Servlet 提及。

記得《給小白的Java EE生存指南(2)》 (回覆「小白」查看) 提到的動態網頁嗎? 常見的實現動態網頁的技術就是CGI。

可是做爲Java 的發明人, Sun確定要搞一個超越CGI的技術出來, 以前Sun 經過Applet出了一個超級大風頭, 讓整個世界一會兒認識了Java , 不過很快發現悲催的Applet其實用途不大, 眼看着互聯網開始起勢, 必定要搭上百年不遇的快車啊。

 

因而Servlet 就應運而生了, Servlet 其實就是Sun爲了讓Java 能實現動態的可交互的網頁, 從而進入Web編程的領域而定義的一套標準。

 

這套標準說了:

你想用Java 開發動態網頁,能夠定義一個本身的"Servlet"(名字很怪,不知道怎麼翻譯) , 但必定要是實現個人HttpServlet接口, 而後重載doGet(), doPost()等方法。

用戶從瀏覽器GET的時候, 調用doGet()方法, 從瀏覽器向服務器發送表單數據的時候, 調用doPost()方法。

(參見 《給小白的Java EE生存指南(1)》,回覆「小白」查看) 。

 

若是你想訪問用戶從瀏覽器傳遞過來的參數, 沒問題, 用HttpServletRequest 對象就行了, 裏邊有getParameter() ,getQueryString()方法。

若是你處理完了, 想向瀏覽器返回數據, 用HttpServletResponse 調用getPrintWriter() 就能夠輸出數據了。

若是你想實現一個購物車, 須要session, 很簡單, 從HttpServletRequest 調用getSession() 就行了。

 

你寫了一個"Servlet",接下來要運行, 你就發現無法經過java 直接運行了, 你須要一個可以運行Servlet的容器 , 這個容器Sun 最先實現了一個,叫Java Web Server, 1999年捐給了Apache Software foundation , 就更名叫Tomcat 。

 

因此Tomcat 就是一個Servlet容器, 能接收用戶從瀏覽器發來的請求, 而後轉發給Servlet處理, 把處理完的響應數據發回瀏覽器。

 

可是Servlet 輸出html ,仍是採用了老的CGI 方式,是一句一句輸出,因此,編寫和修改 HTML 很是不方便。

因而 Java Server Pages(JSP) 就來救急了,JSP 並無增長任何本質上不能用 Servlet 實現的功能。

實際上JSP在運行以前,須要先編譯成servlet , 而後才執行的。

可是,在 JSP 中編寫靜態HTML 更加方便,沒必要再用 println語 句來輸出每一行 HTML 代碼。更重要的是,藉助內容和外觀的分離,頁面製做中不一樣性質的任務能夠方便地分開:好比,由頁面設計者進行 HTML設計,同時留出供 Java 程序員插入動態內容的空間。

Tomcat 能運行Servlet, 固然運行JSP確定也是易如反掌。

 

既然是Web 服務器, Tomcat除了能運行Servlet和JSP以外, 也能像Apache/nginx 那樣,支持靜態html, 圖片,文檔的訪問, 只是性能要差一些, 在實際的應用中, 通常是這麼使用他們的:

Nginx 做爲負載均衡服務器 和靜態資源服務器放在最前端, 後面是tomcat組成的集羣。

若是用戶請求的是靜態資源, Nginx直接搞定, 不用麻煩後面的tomcat了。

若是是動態資源(如xxx.jsp) , Nginix 就會按照必定的算法轉發到某個Tomcat上, 達到負載均衡的目的。

 

 

本文是給小白的Java EE生存指南的第5篇, 講一下前端工程師必備的AJAX的前因後果。

 

回到2001年, 當時的老劉仍是小劉, 在計算所跟着老闆和四川的一個公司合做,作一個相似於OA(辦公自動化)的項目。

當時小劉剛畢業,寫過一些asp的程序,在小劉的意識當中, 仍是以爲只要你經過瀏覽器向服務器發出請求, 服務器處理之後, 須要刷新整個網頁才能看到服務器處理的結果。

可是有一天我忽然看到項目中大牛寫的一個頁面,這個頁面上面是菜單,中間是一個樹形結構,表明了一個公司的各個部門。

點擊了菜單之後, 整個頁面沒有刷新, 神奇的是那個部門的樹形機構居然發生了變化! 也就是說整個頁面沒有刷新, 只是頁面的局部發生了刷新。

太難以想象了 ! 我趕忙打開那個普通的asp程序, 看看究竟是什麼狀況。

原來點了菜單之後, 執行了一段javascript, 其中建立了一個叫XMLHttpRequest的東西;

var xhr;

if (window.XMLHttpRequest){

xhr=new XMLHttpRequest(); //非IE瀏覽器

}else{

xhr=new ActiveXObject("Microsoft.XMLHTTP"); //IE 瀏覽器

}

 

//放置一個回調函數: state_change, 當http的狀態發生變化時會調用

xhr.onreadystatechange=state_change

 

xhr.open("GET","http://xxxxxx.xxx/xxx.asp",true); // true 表示異步調用

xhr.send(); //這是一個耗時的操做

//具體的回調函數定義

function state_change()

{

if (xmlhttp.readyState==4 && xmlhttp.status==200){

//獲取到服務器返回的xml

xmlRes = xhr.responseXML;

//對xml進行處理,更新部門的樹形結構, 代碼略

document.getElementById('deptTree').innerHTML = xxxxxxx

}

 

}

 

//其餘代碼, 略

 

你能夠想象我第一次看到這樣的處理時那種震驚的表情。 原來頁面能夠這麼寫, javascript 能夠這麼用!

其實這裏體現的思想有兩點:

1. 異步調用

異步的意思是說, 調用一個耗時的函數(上例中的xhr.send()) 之後, 不等到它返回,就直接執行後續的代碼了。

固然在調用它以前會放置一個回調的函數callback(上例中的state_change),等到這個耗時的函數完成之後,再來調用callback 。

爲何要這麼作呢? 主要是網絡操做太耗時了, 你在瀏覽器中的一個點擊可能訪問是地球那一邊的服務器, 若是是同步操做, 即等待網絡操做完成之後再進行下一步, 就可能阻塞當前線程, 甚至會致使瀏覽器卡死的狀況。

 

異步調用在編程中是個很是經常使用的手段, 後來服務器端的javascript Node.js 幾乎全是基於事件的異步調用。

 

2. 用XML作瀏覽器端和服務器端的數據交換

這點毋庸解釋, 參見《給小白的Java EE指南(3): XML》 ,看看xml 的做用。

 

3. 局部刷新

Javascript 取到從服務器端返回的XML之後, 解析該XML, 而後經過DOM對象只更新整個頁面html的一部分,例如更新一個table, 一個div ....

document.getElementById('deptTree').innerHTML = xxxxxxx

 

異步的JavaScript和XML(Asynchronous Javascript And XML) 就簡稱AJAX, 你看這些縮寫其實沒什麼神祕的。

 

AJAX這個詞2005纔出現,以前已經出現了大量的「AJAX」Web應用, 我認爲其中最著名的就是Google Maps 它使用XMLHttpRequest異步調用服務器端來獲取數據,並將數據應用在客戶端,實現了無刷新的效果,極好的用戶體驗讓Google Maps獲取了巨大的成功。

 

 

【XML VS JSON】

可是在javascript中使用XML有兩個問題:

1. XML 要求有開始標籤和結束標籤, 如<name>liuxin</name> ,name出現了兩次, 這在網絡傳輸中實際上是一種冗餘浪費。

2. javascript 須要解析xml , 而後展現到瀏覽器中。

第二點尤爲不爽, 因此就有人發展了一個叫JSON(JavaScript Object Notation) 的一個輕量級的數據格式。 JSON其實就是javascript 語法的子集, 就是javascript中的對象和數組。

對象在js中表示爲「{}」括起來的內容,數據結構爲 {key:value,key:value,...}的鍵值對的結構。

數組在js中是中括號「[]」括起來的內容,數據結構爲 ["java","javascript","vb",...]。

這兩種結構雖然很簡單, 可是遞歸組合起來能表達任意的數據結構, 這就是簡單的力量, 下面就是一個例子:

{

"programmers":

[{

"firstName": "Brett",

"lastName": "McLaughlin",

"email": "aaaa"

}, {

"firstName": "Jason",

"lastName": "Hunter",

"email": "bbbb"

}],

"authors":

[{

"firstName": "Isaac",

"lastName": "Asimov",

"genre": "sciencefiction"

}, {

"firstName": "Tad",

"lastName": "Williams",

"genre": "fantasy"

}],

"musicians":

[{

"firstName": "Eric",

"lastName": "Clapton",

"instrument": "guitar"

}, {

"firstName": "Sergei",

"lastName": "Rachmaninoff",

"instrument": "piano"

}]

}

 

因爲JSON自己就是Javascript 語法的一部分, javascipt代碼能夠直接把他們當成對象來處理, 根本不用解析XML了。

再加上JSON結構很緊湊, 很快就流行開來了, 如今AJAX 基本上都是在用JSON來傳遞數據了。

 

題外話:第一次看到AJAX這個詞的時候, 做爲球迷的我腦海裏第一反應是荷蘭的阿賈克斯足球俱樂部, 在90年代, 阿賈克斯足球號稱青年近衛軍, 一幫小孩在歐冠決賽中把如日中天的AC米蘭都搞定了, 後來因爲《博斯曼法案》的實施,球員能夠自由轉會, 阿賈克斯就沒落了。

 

 

本文是給小白的Java EE生存指南的第6篇, 講點稍微有深度的:反射。 

這裏不定義什麼叫反射,先來看個例子,假設我給你一個Java 類: 

package com.example;

public class HelloWorld {

    public HelloWorld(){

    }

    public void sayHello(){

        System.out.println("hello world!");

    }

}

如今要求: 

(1) 你不能使用 HelloWorld hw = new HelloWorld() , 可是要構建一個HelloWorld的實例來. 

(2) 調用sayHello() 方法, 可是不能直接用 HelloWorld實例的 hw.sayHello()方法  , 提及來怪拗口的 :-)

 

用Java的反射功能, 能夠很輕鬆的完成上面的要求:

//第一步, 先把HelloWorld的類裝載進來

Class cls = Class.forName("com.example.HelloWorld");

//第二步, 建立一個HelloWorld的實例, 注意, 這裏並無用強制轉型把obj轉成HelloWorld

Object obj = cls.newInstance();

//第三步, 獲得這個類的方法, 注意, 一個類的方法也是對象啊

Method m = cls.getDeclaredMethod("sayHello"); 

//第四部, 方法調用, 輸出"hello world"

m.invoke(obj);    

可能有人要問了, 爲何不直接new 出來呢?  經過反射來建立對象,調用方法多費勁啊 ?

這是個好問題,關鍵點就是: 不少時候咱們並不能事先知道要new 什麼對象,  相反,咱們可能只知道一個類的名稱和方法名, 不少時候這些名稱都是寫在XML配置當中的。 
 

爲了更好的說明問題, 來看看幾個SSH的例子:

【Struts的例子】

1. 在XML配置文件中定義Action

<action name="HelloWorld" class="example.HelloWorld">        

        <result>/hello.jsp</result>  

</action> 

2. 定義Java 類

public class HelloWorld extends ExampleSupport {  

    public String execute() throws Exception {    

        ......

        return SUCCESS;                           

    }  

    .......

}

Struts 框架的做者事先確定不知道你會配置一個HelloWorld的Action 。

不過他能夠這麼作, Struts 在啓動之後,解析你配置XML配置文件, 發現名稱爲HelloWorld的Action, 找到相對於的類名example.HelloWorld, 而後就能夠經過反射去實例化這個類。 等到有人調用這個action 的時候, 能夠經過反射來調用HelloWorld的execute() 方法。 

【Hibernate的例子】

1.  定義Java類和表之間映射, 類名叫Event, 對應的表名是EVENTS 。

<hibernate-mapping package="org.hibernate.tutorial.hbm">

    <class name="Event" table="EVENTS">

        <id name="id" column="EVENT_ID">

            <generator class="increment"/>

        </id>

        <property name="date" type="timestamp" column="EVENT_DATE"/>

        <property name="title"/>

    </class>

</hibernate-mapping>

2. 定義Event 類,以下所示:

public class Event {

    private Long id;

    private String title;

    private Date date;

    ...... 爲了節省篇幅, 每一個屬性的getter /setter 方法略...

}

3. 查詢, 你能夠用Hibernate 這麼查詢表中的數據了:

List result = session.createQuery( "from Event" ).list();

        for ( Event event : (List<Event>) result ) {

            System.out.println( "Event (" + event.getDate() + ") : " + event.getTitle() );

}

Struts 的做者事先也不知道你會配置一個叫Event的類。 

不過他會這麼處理: 類名(Event)-> 數據庫表名(EVENTS) -> 發出SELECT查詢表數據 -> 經過反射建立Event的實例 -> 經過反射調用實例的setter方法把數據庫的值設置進去

 

【Spring的例子】

1. 配置一個Bean

<beanid="helloWorld"class="example.HelloWorld">

    <propertyname="message"value="Hello World!"/>

</bean>

 

2. 寫一個Java 文件

public  class   HelloWorld

{

    private String message;

    public void setMessage(String message){

        this.message  = message;

    }

    public void getMessage(){

        System.out.println("My Message : "+ message);

    }

}

3. 調用

 

ApplicationContext context =newClassPathXmlApplicationContext("Beans.xml");

HelloWorld hw=(HelloWorld) context.getBean("helloWorld");

hw.getMessage();

我都懶得解釋了, 無非是根據類的名稱經過反射建立一個類HelloWorld的實例, 而後再經過反射調用setMessage方法, 這樣當你getMessage就有值了。 

因此反射是很重要的, 在Java EE世界裏, 反射最大的用途就是支持以聲明式的方法(在XML中)來描述應用的行爲,   是Struts, Hibernate , Spring 的最核心的技術之一。   

簡單的來說, 反射能讓你在運行時而不是編程時作下面的事情:

(1) 獲取一個類的內部結構信息(或者成爲元數據), 包括包名,類名, 類全部的方法, 

(2) 運行時對一個Java對象進行操做, 包括建立這個類的實例, 設置一個屬性的值, 調用這個類的方法等等。 

這篇文章只是介紹了反射的一點皮毛和用途, 具體的細節仍是等待你本身去發掘吧。 

 

 

3、J2EE要死了?

 

最近有人問我說: 欣哥, 咱們如今都用Spring, Hibernate, SpringMVC了,這Java EE是否是已經死掉了?

 

這個問題讓我啼笑皆非,由於他彷佛尚未搞清楚Java EE究竟是怎麼回事,就給Java EE判了死刑。

 

Java EE是什麼呢? 

 

簡單來說Java EE 就是一個技術規範的集合,一些核心的技術規範包括:JDBC, Servlet, JSP, JNDI, EJB, RMI, XML , JMS , JTA, JPA,JavaMail 等等。  這些規範的目標很美好, 就是幫助程序員開發大規模的、分佈式的、高可用的「企業級」應用, 只是實際的效果可能就沒那麼美好了。

 

咱們先來看一看這些核心的技術規範都是幹嗎的,而後再來評判Java EE是否是快要死掉了。

 

JDBC : Java程序訪問數據庫的核心技術,無論是使用Hibernate , MyBatis, EJB, 仍是本身寫類庫, 只要你訪問數據庫, JDBC是繞不過去的, 我還沒見過在Java 中用其餘技術讀取數據庫的案例。

(參見文章:《JDBC的誕生》)

 

Servlet :   簡單地說,Servlet就是Web應用讓外界訪問的入口。 固然如今直接寫Servlet的愈來愈少, 由於在框架的包裝下,應用程序只須要直接寫Action 或者 Controller就能夠了, 但這並不可否定Servlet的核心和基石地位。

 

JSP & JSTL: 因爲先後端的分離和其餘更優秀的替代技術,如今用JSP當作視圖層也是百裏挑一了, 更多的是在遺留系統中在使用,  JSP確實在走向沒落。

 

JSTL 是JSP Standard Tag Library, 一套標準的標籤庫, JSP不受人待見,JSTL就更不行了。

(擴展閱讀: 《JSP:一個裝配工的沒落》)

 

EJB : 曾經最爲熱門的技術, 寄託了你們最美好的指望,但事實證實EJB 1.x 2.x 簡直就是災難, EJB3.x 雖然吸取了Hibernate的不少優秀特性,奈何你們使用輕量級類庫和框架的習慣已經養成, 沒法翻身了。

 

更要命的是使用EJB須要昂貴、複雜、笨重的應用服務器(如Weblogic, Websphere等), 這也是使用它的巨大障礙,再加上Spring 這個輕量級框架的崛起, EJB被完全打入冷宮。

 

a.EJB實現原理: 就是把原來放到客戶端實現的代碼放到服務器端,並依靠RMI進行通訊。

b.RMI實現原理 :就是經過Java對象可序列化機制實現分佈計算。

 

RMI : 遠程方法調用, 讓Java程序能夠像訪問本地對象同樣來訪問遠程對象的方法, 早期和EJB搭配用的最多, 由於EJB會被部署在分佈式的應用服務器中, 一個機器上的程序須要訪問遠程的EJB,RMI是個基礎的技術。  隨着EJB的失寵, RMI彷佛也用的不多了。

 

RMI應該是RPC的一種實現,只能在Java 世界中使用, 相對於被普遍使用的基於Web、 基於HTTP的RPC調用, RMI更不受待見。

(參見文章《我是一個函數》)

 

JNDI: 這是一個基礎性的技術, 能夠把名稱和對象進行綁定,最多見的就是經過一個名稱來訪問數據源,而不用關心這個數據源到底在什麼地方。 依然在普遍使用。

 

JAXP: XML在Java 中無處不在,Java EE 經過Java API for XML Processing(JAXP)來讀取/解析XML文件,只是這個接口實在是不太好用,學院派氣息過濃, 因此如今你們都用民間開源的JDOM,DOM4J 了。

 

等到JSON開始流行, 「悲劇」又重演了,你們都在用民間的fastjson, jackson , 彷佛選擇性的忘記了 官方的 Java API for JSON Processing。

 

官方的不如民間的,也是Java世界的一大特點。

 

JMS:  Java世界訪問消息隊列的標準方式, 各大消息隊列產品都支持, 沒有理由不用它。

(擴展閱讀《Java帝國之JMS的誕生》)

 

JavaMail : 在Java中發送郵件,又一個基礎性的技術。

 

JTA: Java Transaction API, 主要是爲了在多個數據源之間實現分佈式事務, 可是JTA在在高併發和高性能的場景下表現不佳, 不少時候並無用JTA, 而是用異步的方式來解決問題。

(擴展閱讀:《Java帝國之宮廷內鬥(上)》 《Java帝國之宮廷內鬥(下)》)

 

除了上面列舉的,Java EE還有不少規範

Java API for WebSocket

Java Persistence

Concurrency Utilities for Java EE

Java EE Connector Architecture

Java API for RESTful Web Services (JAX-RS)

Java API for XML-Based RPC (JAX-RPC)

Java Management Extensions (JMX)

JavaBeans Activation Framework (JAF)

......

 

這些規範在平常的Web開發中可能用的更少,SSH/SSM 中也能夠找到對應物, 給你們的感受就是這Java EE的規範沒用了, 要死掉了。

 

我卻是以爲應該是Websphere , Weblogic這些應用服務器不行了, 從上面的描述中能夠看到,活得最滋潤的幾個是JDBC, Servlet, JMS,  最不如意的就是EJB了,  而EJB偏偏是昂貴的商業應用服務器Weblogic , Websphere 的一個核心功能。

 

在雲計算的環境下, 在容器技術、微服務當道的狀況下, 那種集中式的、繁瑣的、笨重的部署註定要走向消失。 如今不少後端開發,用Tomcat這種主要支持Servlet/JSP的Web服務器,再配上輕量級的SSH,或者SSM就足夠了。

 

說了這麼多,可能有人想到這個問題:  這些規範是怎麼制定的的呢?

 

答案是JCP(Java Community Process), 在這個組織中,一些特定的成員(Full Memeber)若是想把某個技術如JDBC變成Java 規範,就須要發起一個叫作Java Specification Request (JSR) 東西,公開讓你們進行評判, 最後由執行委員會投票,決定是否能夠發佈成爲正式規範。

 

理論上每一個人都可以成爲JCP的成員, 可是有發言權的, 能上桌玩牌的仍是一些巨頭,如Oracle, Google, IBM, SAP等等,因此有不少人認爲JCP制定出來的Java EE規範只是考慮大廠商的利益, 不顧普羅大衆的死活,  這種脫離人民羣衆的規範是沒人用的, 是要死掉的。

 

這麼說確實有必定的道理, 我我的以爲Java EE規範中有一些精華會保留下來,被一直使用,直到Java退出歷史舞臺。  至於其餘的Java EE規範, 就讓他們自生自滅去吧。

 

(完)

 

微信公衆號【黃小斜】大廠程序員,互聯網行業新知,終身學習踐行者。關注後回覆「Java」、「Python」、「C++」、「大數據」、「機器學習」、「算法」、「AI」、「Android」、「前端」、「iOS」、「考研」、「BAT」、「校招」、「筆試」、「面試」、「面經」、「計算機基礎」、「LeetCode」 等關鍵字能夠獲取對應的免費學習資料。 

 

                     wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

相關文章
相關標籤/搜索