FreeMarker — Java 模版引擎 (1)

在做專案的時候,身為開發者的我們經常會有「產生動態文字內容」這樣的需求,具體來說像是產生網頁、email內容、甚至寫程式來產生程式碼等等。如果為了一時貪求快速,而把這些文字處理的動作寫在程式裡面,這麼一來整體的維護性就會大打折扣。「模版引擎」(template engine) 就是因應這樣的需求而誕生的!

Java界的模版引擎有很多套,其中比較容易上手,功能也相當完備的,當屬 FreeMarker。 Continue reading →

Facebook Comments

Maven-實作篇 (3)

上一回我們完成了用戶查詢系統–視窗程式的練習,這次我們從Web版開始吧!

請先確認Eclipse 已經整合了Tomcat,如果還沒,請參考Java web app 開發第一步 – 整合Eclipse + Tomcat


Web

  1. 依照以下資訊,建立 Maven 專案 (使用 maven-archetype-webapp)
    • groupId: com.appx
    • artifactId: user-service-web
    • package: com.appx.userservice.web
    • version: 1.0-SNAPSHOT
  2. 將 src/main/webapp/WEB-INF/web.xml 取代為以下內容

    * webapp archetype 預設生成的 web.xml 定義了舊版的 Servlet 2.3的dtd,會使得一些比較新的JSP特性像是EL不能正常運作,因此必須置換為上面的xml
  3. 將user-service-web 專案放上 Tomcat執行

  4. 在 http://localhost:8080/user-service-web/ 看到 “Hello World!” 表示新建的 Maven web 專案運作正常!
  5. 在POM.xml  加入以下 compiler plugin
  6. 移除JUnit dependency ,並加入下列 dependency (servlet-api 的 scope 為  provided,如果忘記的同學可以參考Maven-10-核心概念 dependency management )
  7. 在 src/main 底下建立 java 資料夾,下載以下程式,並放至 src/main/java 底下這個package com.appx.userservice.web
    https://drive.google.com/open?id=0B0C215CJ0AjobThwTlg3WXFkNmM
  8. 在 src/main/webapp 放置以下檔案
    https://drive.google.com/open?id=0B0C215CJ0AjoOHJOeUVzV2JnQWc
  9. 重啟 Tomcat ,確認搜尋功能正常運作
    • 輸入 user id 為 1

    • 搜尋結果為 tom

  10. 執行 mvn package,產生可直接部署的war檔

Facebook Comments

Java web app 開發第一步 – 整合Eclipse + Tomcat

以下帶大家一步一步在Eclipse環境中設定Tomcat

  1. 下載Tomcat  (以Tomcat 8.5 為例)
    https://tomcat.apache.org/download-80.cgi
    網頁裡有如下各種格式的壓縮檔,請依照作業系統來選擇,下載完成執行解壓縮

  2. 在Eclipse 偏好設定 Server –> Runtime Environments –> Add 把 Tomcat 加進來

  3. 選擇 Tomcat 所在位置 , Finish, 設定完成!

  4. 接著,打開 servers view  (Window –> Show View –> Servers)

  5. 點擊 view 裡面的超連結,選擇 Tomcat 8.5,會出現剛才所設定的 server runtime environment,點擊 Finish 完成設定

  6. 我們已經成功把 Tomcat 整合進 Eclipse 開發環境,下一步就是測試一下囉!
    新增一個 Dynamic Web Project,點擊 Next

  7. Project Name –> “HelloWorld”,點擊 Finish

  8. 在 HelloWorld 專案的 WebContent 底下新增 index.jsp

  9. 在 servers view 的 Tomcat 上按右鍵 選擇  “Add and Remove”

  10. 把 HelloWorld 專案加到右邊,Finish

  11. 點擊 servers view 右上方的啟動按鈕

  12. 在console 看到  INFO: Server startup in xxxx ms ,代表啟動成功!我們可以開啟瀏覽器,網址輸入 http://localhost:8080/HelloWorld 看到 index.jsp 的內容

Facebook Comments

Maven-實作篇 (2)

延續上一回的實作,現在我們將從桌面視窗程式開始!

Desktop

  1. 依照以下資訊,建立 Maven 專案 (使用 maven-archetype-quickstart)
    • groupId: com.appx
    • artifactId: user-service-desktop
    • package: com.appx.userservice.desktop
    • version: 1.0-SNAPSHOT
  2. 這次不實作unit test,所以把 src/test/java 底下 AppTest.java 刪除,同時也移除 POM.xml 裡面 junit 的 dependency
  3. 在 POM.xml 增加以下 plugin 設定,除了 compiler plugin,也使用了 maven-shade-plugin 用來把整個桌面視窗程式打包成單一 jar 檔(包含dependency),可以看到在 package 這個lifecycle build phase 綁定了 shade goal,並且必須指定 main 方法所在的class
    (maven lifecycle的概念非常重要,請參考之前的文章)
  4. 加入 core 專案作為 dependency
  5. 下載以下程式,並放至 src/main/java 底下這個package com.appx.userservice.desktop
    https://drive.google.com/open?id=0B0C215CJ0AjoX2tPLVpVZlJYQkk
  6. 執行 mvn package ,可以發現 target 資料夾底下多了兩個 jar,其中 user-service-desktop-1.0-SNAPSHOT.jar 包含了相關的 dependencies

  7. 可以使用 jar -tf 指令來比較兩個 jar 的內容

    jar -tf user-service-desktop-1.0-SNAPSHOT.jar
    jar -tf original-user-service-desktop-1.0-SNAPSHOT.jar

  8. 執行 jar ,確認一切都 ok,id可以輸入 1 ~ 3,會看到查詢結果

Facebook Comments

Maven-實作篇 (1)

接下來會帶大家動手實作幾個 Maven 專案,從練習過程中我們會更進一步了解到 Maven 所帶來各種方便的特性!

我們將會建立一個簡單的用戶查詢系統,由三個專案所組成,分別是 core, desktop, web,其中 desktop, web 專案會將core 當作 dependency,如下圖所示:

  • core 專案代表整個系統的核心功能所在
  • desktop 專案負責視窗程式的操作介面
  • web 專案負責網頁的操作介面

Continue reading →

Facebook Comments

[Java101 基礎篇] 三張圖 搞懂 Shallow Copy 以及 Deep Copy

前言
有些時候,我們會需要將資料(物件) 覆製一份,
方便獨立操作 ~ 卻發現結果跟想像的不一樣。

 

讓我們從程式碼來做個說明~

Sample Code

一個正常的物件  Person p = new Person();

Object Structure
單一物件的結構

 

Shadow Copy

java101_referenceCopy
有二個參考點(References)指到同一份資料

Deep Copy

Deep Copy Result
二個完全獨立的物件

對了~

對參考點的概念(Reference) 還不是很清楚?!
對建構子的運用 還想更進一步嗎?!           可以參考我們提供的教育訓練

 

參考資料:
https://dzone.com/articles/java-copy-shallow-vs-deep-in-which-you-will-swim

 

Facebook Comments

Maven-10-核心概念 dependency management

對於開發者來說,Maven最強大的功能莫過於 dependency management了!

在之前文章 Maven-05-一個簡單的POM範例 我們看到POM裡定義了一組 junit 的dependency,所以在執行 mvn install 時,Maven 會先檢查本機的 repository 是否有 junit 相關的 artifact ,如果沒有就會從網路上下載,然後放到 ~/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar

這邊我們可以觀察到 Maven 自動下載的東西除了jar 檔,還包括了其他檔案像是包了原始碼的jar,還有一個很關鍵的 junit-3.8.1.pom,為什麼 Maven 還會下載 junit的POM呢?

大家可以試著想想,如果今天我們需要的不是junit 這麼單純的套件,我們需要在專案裡使用 Hibernate,從它的 POM 我們得知 Hibernate 本身也有許多 dependencies,難道我們必須在自己專案的 POM 把這些 Hibernate 的 dependency 也全部都寫出來嗎??

答案當然是:NO !!

我們只需要定義 Hibernate dependency,Maven 就會自動把它關聯的 dependency 也一併下載回來,這種機制稱為 “transitive dependencies”, 實際上的運作方式是 Maven 會去查看 dependency 的 POM,並確認是否有相關的 dependency

在junit 的 <dependency> 定義裡,有一個 <scope>test</scope>,這是另一個重要的概念 ,常用的 dependency scope 有下列幾種:

  • compile: 如果沒有定義<scope>, 預設值就是 compile,顧名思義指的是在編譯專案程式碼時需要這個 dependency
  • test: 指的是在這兩個 goal compiler:testCompile (編譯測試程式碼), surefire:test (執行unit test) 才會引用的dependency,正式產出的 jar (或其它格式) 並不會包含 scope 為 test 的 dependency
  • provided: 通當在 web 專案比較常看到這種 scope,指的是在編譯時有需要,但在正式產出war時並不會包含在一起,像是  jsp, servlet 這種 dependency,我們會在開發時用到相關的api,但實際提供這些 dependency 的是運行 web app 的 ap server

更多 dependency scope 可參考
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

Facebook Comments

Maven-09-核心概念 repositories

我們之前在 Maven-04-建置專案 裡執行了 mvn install 指令,如果是初次執行的話,會發現 maven 會自動從遠端 repository 下載很多 plugin 相關的檔案,這些檔案會存放在本機個人目錄下 .m2/repository 資料夾裡。現在我們一起來了解有關 repository 更多資訊吧!

Maven 官方預設的遠端 repository 在 http://repo1.maven.org/maven2/ ,如果有需要的話,像是公司內部私有專案的需求, Maven 也支援自行架設的 repository,其中比較有名的像是:

只要修改 maven 安裝目錄下的 conf/settings.xml 就可以指向自行架設的 repository

Maven repository 儲存了大大小小專案的成品 (project artifact),其中的目錄結構完全符合我們先前介紹過的 Maven coordinates,大家可以試著從官方的 http://repo1.maven.org/maven2/  來觀察,這邊以 hibernate-core  版本 5.1.0.Final 為例子來說明

  • hibernate-core  版本 5.1.0.Final 的 coordinates 如下,完整 POM 可參考這裡

    (packaging 預設 為 jar)
  • jar 檔的完整路徑如下
    http://repo1.maven.org/maven2/org/hibernate/hibernate-core/5.1.0.Final/hibernate-core-5.1.0.Final.jar
  • 路徑的組成,都遵照一定的格式
    repository_location/groupId/artifactId/version/artifactIdversion.packaging

Maven 從遠端下載的 project artifacts 會存在放本機 local repository 裡 (預設是 個人目錄 .m2/repository,也可以透過 settings.xml 修改),之後當有需要在專案裡引用這些 artifacts 時,Maven 就會直接參考 local repository 而不再從網路上尋找,順帶一提,local repository 裡面的資料夾結構,也和遠端 repository 一樣

mvn install 執行之後產生的project artifact,最後就會放置在  local repository 裡,這麼做的目的是日後可以供其它專案來參照引用。在下一篇,我們將為大家介紹對開發人員來說 Maven 最最最重要的功能 — dependency 管理

Facebook Comments

[Java101 基礎篇] – Java 8 Lambda 的崛起

雖然Java 8 已經出來好一陣子了~  (記得是 2014的三月)
但還是有不少人會詢問什麼是 Lambda,什麼是 匿名類別 Anonymous class
藉著最近專案的機會,分享一下我們對 Lambda的了解,希望能有所幫助。

預計這一系列的文章,會有

  • Java 8 Lambda 的崛起
  • Java 8 Lambda 的語法
  • Java 8 Lambda 跟集合物件的應用
  • Java 8 Lambda 跟File I/O的應用

 

今天就先針對 Java 8 Lambda 的出現,先做個應用的說明 ~

讓我們從一個很常用的例子開始~  「使用者在畫面上按下按鈕,然後秀出 HelloWorld」
(*這部份機制,可應用在 Java Swing/FX  以及 Android )

 

以Java Swing 視窗程式為例,在 Lambda出現之前,我們可能的做法有下列幾項 ~

  1. 寫一個完全獨立的新類別  來實作 ActionListener,然後在JButton呼叫addActionListener時,當成參數傳入。

     
  2. 寫一個在main主程式 類別的內部類別(Inner class),然後在也是一樣,在JButton呼叫addActionListener時,當成參數傳入。

     
  3. 使用匿名類別(Anonymous Inner class),在JButton物件呼叫addActionListener 時,當成參數傳入

 

 

在Java 8 Lambda 出現後,我們可以用下列的寫法

jb.addActionListener( (a)-> System.out.println(“Hello”));
沒錯,就只要寫 一行,就可以有同樣的效果~~~

剩下的,就讓Java 8 Compiler 將程式碼 編譯成跟之前 actionListener 一樣的class code !!!

是不是很方便~~~ 趕快試試看囉~~

 

對了~

匿名類別 (Anonymous class)還不是很清楚?! 可以參考我們提供的教育訓練

 

 

參考資料:
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

http://www.coreservlets.com/java-8-tutorial/#setup

Facebook Comments