2016年6月20日 星期一

在 Java 中解析、表達與計算日期時間(二):JSR-310 概述

原本在 Java 7 和更之前的版本中,因為 Java 原生並沒有好的時間類別
因此比較合適的方式是使用 Joda-Time 這個套件,用來表示日期與時間。
不過在 Java 8 當中釋出了 JSR-310,也就是 java.time 套件之後,狀況就不同了
Joda-Time 官方網站中也說明了,如果使用 Java 8 以上版本,應轉移至 JSR-310。

Joda-Time is the de facto standard date and time library for Java prior to Java SE 8. Users are now asked to migrate to java.time (JSR-310).

2016年6月19日 星期日

在 Java 中解析、表達與計算日期時間(一):時間系統與曆法

對大多數人(包括我)來說,大概都不會覺得日期時間有什麼特別的
在參加之前的 Java TWO 以前,其實我也沒有認真看待過這個東西,一直到在 Java TWO 上聽到良葛格談到這個議題
才知道~其實背後隱藏了許多魔鬼,導致這個議題事實上是個相當複雜的問題。

在開始研究如何正確地寫日期與時間相關的程式之前,先了解一下何謂時間、以及時間和曆法的關係為何。

2016年6月16日 星期四

使用 JAX-RS 2 做 HTTP Response 的壓縮

因為前陣子看了一些 RESTful API 的最佳實例(連結可以參考這裡
裡面有提到好的 RESTful API 應該要支援 GZIP 壓縮,對伺服器端或者客戶端都有好處
因此開始在實作 RESTful API 時,就搜尋了一下,Jersey 上應該如何正確地支援 GZIP 壓縮。

對於「正確地支援 GZIP 壓縮」這個問題,當然最簡單的作法,就是每個 RESTful API 都各自把輸出的東西都呼叫 GZIP 壓縮
然後把壓縮好的結果丟去 Response,並且適當地加上 HTTP Header 即可。
但我覺得這種作法應該不是最好的作法,應該有更好的方式可以讓 Jersey 自動幫每個 Response 都做好這些事。
在 Jersey 上,這件事情最適合的方式就是透過 Interceptors 來實作了。

2016年6月15日 星期三

對 Jersey 製作的 RESTful API 做單元測試(一)

在比較完整的專案中,一般都會至少要包含自動化的單元測試
不過 Application 還好,如果是 RESTful API 的話,應該要怎麼測試呢?

原先我自己的想法是使用 JUnit,然後可能是使用內嵌式的 Jetty
讓測試程式執行時,自動打開一台本地端的 Jetty、把專案佈署上去後開始執行測試。
但既有找到的方法(例如 [1]) 感覺整合性都不太高…。
最後想說,也許其實有更簡易的方式,於是變更了關鍵字之後,發現…真的有 XD。
Jersey 原來本身就有涵蓋了對應的測試架構了。

叢集環境的 logging(三):以 JSON 格式輸出 log

在把叢集中的每個 Application 的 log 都集中起來以後,下一個遇到的問題就是如何分析?
收集起來的 log 數量通常不小,而且各個不同節點的 log 全混在一起
要如何有效率一點地解析他們呢?

實務上,比較容易想像的方式大概就是把 log 導到某個能夠做 log 分析的系統上
例如 ELK 架構(Elasticsearch + Logstash + Kibana)。
不過要讓 Logstash 能夠簡單地把集中起來的 log 全部帶走,最好還是能讓 log 都以 JSON 格式輸出
這樣在 Logstash 那邊寫設定檔時,會比較簡單。

2016年6月7日 星期二

叢集環境的 logging(二):辨識集中化 log 的來源

前篇文章中,利用了 logback 的 SocketAppender 和 Receiver 功能,將不同來源的 logs 集中到一個地方
但在沒有特別設計的情況下,其實我們通常會分不出來哪個 log 來自哪裡。
不過這個問題在 logback 裡已經被考慮過了,可以利用 Mapped Diagnostic Context [1-2] 來實現。

叢集環境的 logging(一):透過 slf4j + logback 集中化 log

在叢集環境中,應用程式往往會同時存在在很多個節點上
每個節點的 log 都各自輸出到自己的 console,或者可能輸出成某個檔案,但都四散在每個應用程式自己的節點上。
實務上如果想要觀察 log,通常會希望最起碼 log 可以集中到某個地方
這個需求,如果是使用 logback 作為 logging framework 時,可以透過使用 SocketAppender 和 Receiver 來達成。

2016年6月6日 星期一

使用 Maven 建立 Jersey 專案

當想要新建一個使用 Jersey 的 RESTful 的專案時,可以利用 Maven 直接產生範例 [1]

mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 \
-DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \
-DgroupId=com.example -DartifactId=simple-service -Dpackage=com.example \
-DarchetypeVersion=2.23
從上述的官方範例中,執行後會自動產生 groupId 為 com.example、artifactId 是 simple-service
並且會先建好 com.example 這個 package 的檔案(包含 src 目錄以及 pom.xml)
之後以 eclipse 來說就直接 import 到 eclipse 裡面,就可以開始增加自己需要的東西了。

另外紀錄一件小事,因為最近在 Windows 上習慣用 PowerShell,但上述的語法卻一直不能使用
研究了一段時間之後才發現,錯誤的並不是語法本身,而是在 PowerShell 上必須加上引號 [2]
例如:

mvn archetype:generate "-DarchetypeArtifactId=jersey-quickstart-grizzly2" \
"-DarchetypeGroupId=org.glassfish.jersey.archetypes" "-DinteractiveMode=false" \
"-DgroupId=com.example" "-DartifactId=simple-service" "-Dpackage=com.example" \
"-DarchetypeVersion=2.23"

參考資料:

  1. Jersey - Chapter 1. Getting Started
  2. Maven 3: Maven in 5 minutes “mvn archetype:generate…” command NOT WORKING

2016年6月2日 星期四

推薦的 RESTful API 最佳實踐

想要設計好的 RESTful API,所以花了些時間找了一些文章看
(其實也只不過是去 Google「rest api design best practice」而已)
找到兩篇看完覺得我被說服了的文章
推薦有想要好好設計 RESTful API 的朋友可以參考看看。

參考資料:
  1. Best Practices for Designing a Pragmatic RESTful API
  2. RESTful Service Best Practices - Recommendations for Creating Web Services (PDF) 

FortiGate 的虛擬 IP 設定

參考資料:
  1. Creating a Fortigate Virtual IP – External to internal Port Forwarding