SlideShare une entreprise Scribd logo
1  sur  135
Télécharger pour lire hors ligne
1
通用API
學習目標
• 使用日誌API
• 瞭解國際化基礎
• 運用規則表示式
• 處理數字
• 走訪堆疊追蹤
2
簡介日誌API
• java.util.logging套件提供了日誌功能
相關類別與介面,它們是從JDK1.4之後加入
標準API
• 在JDK9支援模組化之後,
java.util.logging套件被劃分至
java.logging模組
3
簡介日誌API
• 要取得Logger實例,必須使用Logger的靜
態方法getLogger():
4
簡介日誌API
• 呼叫getLogger()時,必須指定Logger實
例所屬名稱空間(Name space)
• 名稱空間以"."作為階層區分,名稱空間階層
相同的Logger,其父Logger組態相同
5
簡介日誌API
• 取得Logger實例之後,可以使用log()方
法輸出訊息,輸出訊息時可以使用Level的
靜態成員指定訊息層級(Level):
6
簡介日誌API
7
簡介日誌API
• Logger有階層關係,名稱空間階層相同的
Logger,父Logger組態會相同
• 每個Logger處理完自己的日誌動作後,會向
父Logger傳播,讓父Logger也可以處理日
誌
8
指定日誌層級
• Logger與Handler預設都會先依Level過
濾訊息
• 如果沒有作任何修改,取得的Logger實例之
父Logger組態,就是
Logger.GLOBAL_LOGGER_NAME名稱空間
Logger實例的組態,這個實例的Level設
定為INFO
9
指定日誌層級
• 可透過Logger實例的getParent()取得父
Logger實例,可透過getLevel()取得設
定的Level實例
10
指定日誌層級
• 在沒有作任何組態設定的情況下,預設取得
的Logger實例,層級必須大於或等於
Logger.GLOBAL_LOGGER_NAME名稱空間
Logger實例設定的Level.INFO,才有可
能輸出訊息
11
指定日誌層級
• 可以透過Logger的setLevel()指定Level實例:
– Level.OFF(Integer.MAX_VALUE)
– Level.SEVERE(1000)
– Level.WARNING(900)
– Level.INFO(800)
– Level.CONFIG(700)
– Level.FINE(500)
– Level.FINER(400)
– Level.FINEST(300)
– Level.ALL(Integer.MIN_VALUE)
12
指定日誌層級
• 在經過Logger過濾之後,還得再經過
Handler的過濾
• 一個Logger可以擁有多個Handler,可透
過Logger的addHandler()新增Handler
實例
13
指定日誌層級
• 實際上進行訊息輸出時,目前Logger的
Handler處理完,還會傳播給父Logger的
所有Handler處理(在通過父Logger層級
的情況下)
14
指定日誌層級
• 可透過getHandlers()方法來取得目前已
有的Handler實例陣列:
15
指定日誌層級
• 在沒有作任何組態設定的情況下,取得的
Logger實例,只會使用
Logger.GLOBAL_LOGGER_NAME名稱空間
Logger實例擁有的Handler
• 預設是使用ConsoleHandler,為
Handler的子類別,作用是在主控台下輸出
日誌訊息,預設的層級是Level.INFO
16
指定日誌層級
• 若要顯示INFO以下的訊息,不僅要將
Logger的層級設定為Level.INFO,也得
將Handler的層級設定為Level.INFO
17
指定日誌層級
• JDK8帶入了Lambda之後,severe()、
warning()、info()、config()、
fine()、finer()、finest()方法也多
了重載版本
18
使用Handler與Formatter
19
使用Handler與Formatter
• Logger可以使用addHandler()新增
Handler實例,使用removeHandler()移
除Handler:
20
使用Handler與Formatter
• FileHandler預設會以XML格式儲存:
21
使用Handler與Formatter
• FileHandler預設的Formatter是
XMLFormatter,先前看過的
ConsoleHandler預設則使用
SimpleFormatter
• 這兩個類別是Formatter的子類別,可以透
過Handler的setFormatter()方法設定
Formatter
22
使用Handler與Formatter
• 如果你不想讓父Logger的Handler處理日
誌,可以呼叫Logger實例的
setUseParentHandlers()設定為false
• 可以使用Logger實例的setParent()方法
指定父Logger
23
自訂Handler、Formatter與Filter
• 可以繼承Handler類別,實作抽象方法
publish()、flush()與close()方法來
自訂Handler
24
自訂Handler、Formatter與Filter
25
自訂Handler、Formatter與Filter
• Handler有預設的isLoggable()實作
26
自訂Handler、Formatter與Filter
• 如果要自訂Formatter,可以繼承
Formatter後實作抽象方法format(),這
個方法會傳入LogRecord,儲存有所有日誌
訊息
27
自訂Handler、Formatter與Filter
28
自訂Handler、Formatter與Filter
• Logger與Handler都有setFilter()方法,
可以指定Filter實作物件,
• 如果想讓Logger與Handler除了依層級過
濾之外,還可以加入額外過濾條件,就可以
實作Filter介面:
29
使用logging.properties
30
31
國際化基礎、日期
• 應用程式根據不同地區使用者,呈現不同語
言、日期格式等稱為本地化(Localization)
• 如果應用程式設計時,可在不修改應用程式
情況下,根據不同使用者直接採用不同語言、
日期格式等,這樣的設計考量稱為國際化
(internationalization),簡稱i18n
32
關於i18n
• 在程式中有很多字串訊息會被寫死在程式中..
33
關於i18n
34
關於i18n
• 地區資訊代表了特定的地理、政治或文化區,
地區資訊可由一個語言編碥(Language code)
與可選的地區編碼(Country code)來指定
• 地區(Locale)資訊的對應類別是Locale
35
關於i18n
• 資源包中包括了特定地區的相關資訊,
ResourceBundle物件,就是JVM中資源包
的代表物件
• 代表同一組訊息但不同地區的各個資源包會
共用相同的基礎名稱
• 使用ResourceBundle的getBundle()時
指定的名稱,就是在指定基礎名稱
36
關於i18n
• ResourceBundle的getBundle()時若僅
指定“messages”,會嘗試用預設Locale
(由Locale.getDefault()取得的物件)
取得.properties檔案
– 若預設Locale代表zh_TW,則
ResourceBundle的getBundle()時若指定
"messages",則會嘗試取得
messages_zh_TW.properties檔案中的訊息,若找
不到,再嘗試找messages.properties檔案中的訊息
37
• 可以在messages_zh_TW.txt中撰寫以下內容:
• 從JDK9開始支援UTF-8編碼的.properties檔
案
• JDK8或早期版本的話…
38
關於i18n
• 如果想將Unicode編碼表示的.properties轉回
中文,則可以使用-reverse引數
39
關於i18n
• 如果執行先前的Hello類別,而你的系統預
設Locale為zh_TW,則會顯示“哈囉!世界!”
的結果
• 如果你提供messages_en_US.properties:
40
關於i18n
• 如果如下撰寫程式,就是顯示"Hi!Earth!" :
41
關於i18n
• 使用ResourceBundle時,如何根據基礎名
稱取得對應的訊息檔案:
– 使用指定的Locale物件取得訊息檔案
– 使用Locale.getDefault()取得的物件取得
訊息檔案
– 使用基礎名稱取得訊息檔案
42
簡介規則表示式
43
簡介規則表示式
• 規則表示式是規則表示式,在Java中要將規
則表示式撰寫在""中是另一回事
• 首先得瞭解規則表示式如何定義 …
44
簡介規則表示式
• 字面字元(Literals)
– 按照字面意義比對的字元
• 詮譯字元(Metacharacters)
– 不按照字面比對,在不同情境有不同意義的字元
• 找出並理解詮譯字元想要詮譯的概念,對於
規則表示式的閱讀非常重要
45
46
簡介規則表示式
• 詮譯字元在規則表示式中有特殊意義,例如! $ ^
* ( ) + = { } [ ] |  : . ?等
• 若要比對這些字元,則必須加上忽略符號,例如要
比對!,則必須使用!,要比對$字元,則必須使用
$
• 如果不確定哪些標點符號字元要加上忽略符號,可
以在每個標點符號前加上,例如比對逗號也可以
寫,
47
定義規則表示式
• 若有個Java字串是“Justin+Monica+Irene”,
想使用split()方法依+切割
– 使用的規則表示式是+
– 要將+放至""之間時,按照Java字串的規定,必
忽略+的,所以必須撰寫為"+"
48
簡介規則表示式
• 如果規則表示式為XY,那麼表示比對「X之
後要跟隨著Y」
• 如果想表示「X或Y」,可以使用X|Y
• 如果有多個字元要以「或」的方式表示,例
如「X或Y或Z」,則可以使用稍後會介紹的
字元類表示為[XYZ]
49
簡介規則表示式
• 想使用split()方法依||切割,要使用的規
則表示式是||,要將||放至""之間時,
按照Java字串規定必須忽略|的,就必須撰
寫為"||"
50
簡介規則表示式
• 如果有個字串是“JustinMonicaIrene”,也
就是原始文字是JustinMonicaIrene以Java字
串表示
• 若想使用split()方法依切割,要使用的
規則表示式是,那就得如下撰寫:
51
簡介規則表示式
• 規則表示式中,多個字元可以歸類在一起,
成為一個字元類(Character class)
• 字元類會比對文字中是否有「任一個」字元
符合字元類中某個字元
• 規則表示式中被放在[]中的字元就成為一個
字元類
52
簡介規則表示式
• 想要依1或2或3切割字串:
53
簡介規則表示式
54
簡介規則表示式
• 如果想使用者輸入的手機號碼格式是否為
XXXX-XXXXXXX,其中X為數字,規則表
示式可以使用dddd-dddddd
• 不過更簡單的寫法是d{4}-d{6}
55
簡介規則表示式
• 看到貪婪量詞時,比對器(Matcher)會把剩
餘文字整個吃掉,再逐步吐出(back-off)文
字,看看是否符合貪婪量詞後的規則表示式,
如果吐出部份符合,而吃下部份也符合貪婪
量詞就比對成功
• 貪婪量詞會儘可能找出長度最長的符合文字
56
簡介規則表示式
• 文字xfooxxxxxxfoo,使用規則表示式.*foo
比對
– 比對器根據.*吃掉整個xfooxxxxxxfoo,再吐出foo
符合foo部份
• 得到的符合字串就是整個xfooxxxxxxfoo
57
簡介規則表示式
• 如果在貪婪量詞表示法後加上?,將會成為逐
步量詞(Reluctant quantifier)
• 比對器是一邊吃,一邊比對文字是否符合量
詞與之後的規則表示式
• 逐步量詞會儘可能找出長度最短的符合文字
58
簡介規則表示式
• 文字xfooxxxxxxfoo若用規則表示式.*?foo
比對
– 比對器在吃掉xfoo後發現符合.*?與foo,接著
繼續吃掉xxxxxxfoo發現符合.*?與foo
• 得到xfoo與xxxxxxfoo兩個符合文字
59
簡介規則表示式
• 如果在貪婪量詞表示法後加上+,將會成為獨
吐量詞(Possessive quantifier)
• 比對器會將符合量詞的文字全部吃掉,而且
不再回吐
60
簡介規則表示式
• 文字xfooxxxxxxfoo,若使用規則表示式
x*+foo比對
– x符合x*+被吃了,後續foo符合foo,得到xfoo
符合
– 接著xxxxxx符合x*+被吃了,後續foo符合foo,
得到xxxxxxfoo符合
61
簡介規則表示式
• 文字xfooxxxxxxfoo,若使用規則表示
式.*+foo比對
– 整個xfooxxxxxxfoo會因符合.*+全被比對器吃了
– 因為沒有剩餘文字符合foo部份,所以結果就是
沒有任何文字符合
62
簡介規則表示式
63
簡介規則表示式
• 可以使用b標出單字邊界,例如bdogb,
這就只會比對出dog單字
64
簡介規則表示式
65
簡介規則表示式
• 可以使用()來將規則表示式分組,除了作為
子規則表示式之外,還可以搭配量詞使用
• 驗證電子郵件格式,@後網域名稱可以有數層,
必須是大小寫英文字元或數字,規則表示式
可以寫為([a-zA-Z0-9]+.)+
66
簡介規則表示式
• 分組計數是遇到的左括號來計數
• 如果有個規則表示式((A)(B(C))),其中
有四個分組:
– ((A)(B(C)))
– (A)
– (B(C))
– (C)
67
簡介規則表示式
• 分組回頭參考時,是在後加上分組計數,表
示參考第幾個分組的比對結果
• dd要求比對兩個數字,(dd)1的話,
表示要輸入四個數字,輸入的前兩個數字與
後兩個數字必須相同
68
簡介規則表示式
• [“‘][^”’]* [“‘]比對單引號或雙引號中0
或多個字元,但沒有比對兩個都要是單引號
或雙引號
• (["'])[^"']*1則比對出前後引號必須一
致
69
擴充標記
• 規則表示式中的(?…)代表擴充標記
• 括號中首個字元必須是?,而之後的字元(也
就是…的部份),進一步決定了規則表示式
的組成意義
• 可以使用(?:…)來表示不捕捉分組
70
• 可以使用(?<name>…)來為分組命名,在同
一個規則表示式中使用k<name>取用分組
– (dd)1是使用號碼取用分組
– 想以名稱取用分組,也可以使用
(?<tens>dd)k<tens>
71
• 如果想比對出的對象,之後必須跟隨或沒有
跟隨著特定文字,可以使用(?=…)或(?!…)
• 分別稱為Lookahead與Negative lookahead
72
• 如果想比對出的對象,前面必須有或沒有著
特定文字,可以使用(?<=…)或(?<!…)
• 分別稱為Lookbehind與Negative lookbehind
73
• quote()靜態方法,可以對規則表示式的詮
譯字元進行轉換
74
• quote()方法實際上會在指定的字串前後加
上Q與E
• 在Java中用來表示Q與E間的全部字元,都
不當成詮譯字元
75
• 有些字元不能直接作為取代用的字串內容
• 例如$會在取代過程被誤為是規則表示式的分
組符號
76
• 對於這類情況,必須使用"$"
• 或者是使用java.util.regex.Matcher
提供的quoteReplacement()靜態方法
77
Pattern與Matcher
• 剖析、驗證規則表示式往往是最耗時間階段
• 將剖析、驗證過後的規則表示式重複使用,
對效率將會有所幫助。
78
• 指定旗標Pattern.LITERAL,不用迴避詮
譯字元(不過還是得迴避,以免與字串表示
法衝突)
• 嵌入旗標表示法
79
• Pattern.CASE_INSENSITIVE:(?i)
• Pattern.COMMENTS:(?x)
• Pattern.MULTILINE:(?m)
• Pattern.DOTALL:(?s)
• Pattern.UNIX_LINES:(?d)
• Pattern.UNICODE_CASE:(?u)
• Pattern.UNICODE_CHARACTER_CLASS:(?U)
80
• 若因規則表示式有誤而導致compile()呼叫
失敗,會拋出PatternSyntaxException
– getDescription()取得錯誤說明
– getIndex()取得錯誤索引
– getPattern()取得錯誤的規則表示式
– getMessage()會以多行顯示錯誤的索引、描述
等綜合訊息
81
取得Matcher
82
• 如果設定了命名分組,group()方法可以指
定名稱來取得分組:
83
• 如果規則表示有分組設定,在使用
replaceAll()時,可以使用$n來捕捉被分
組匹配的文字
• 如果是命名分組,使用的是${name}形式:
84
85
• Java 9對Matcher做了些增強
86
Unicode規則表示式
• 若是規則表示式想指定U+0000至U+FFFF範
圍內的字元進行比對,可以使用表15.1看過
的uhhhh
• hhhh表示碼元
87
• 若字元不在BMP範圍內呢?
• 例如,高音譜記號 的Unicode碼點為
U+1D11E,字串表示是"uD834uDD1E"
• 若要以規則表示式來比對,也可以採用代理
對,規則表示式寫法是uD834uDD1E
88
• 或者使用表15.1看過的x{h…h}來表示
• h…h表示碼點:
89
• Unicode字元集為世界大部份文字系統做了整
理,規則表示式是為了比對文字
• 為了能令規則表示式支援Unicode,Unicode
組織在〈UNICODE REGULAR
EXPRESSIONS〉做了規範
90
Unicode特性轉譯
• 每個Unicode字元會隸屬於某個分類
• 在〈General Category Property〉可看到Letter
、Uppercase Letter等一般分類,每個分類也
給予了L、Lu等縮寫名稱
• 隸屬於Letter分類的字元都是字母
– a到z、A到Z、全形的a到z、A到Z、希臘字母
α、β、γ等
91
• 特性的支援上,使用p、P的方式
• 例如,p{L}表示字母(Letter),p{N}表
示數字(Number)等
• 可以進一步指定子特性,例如p{Lu}表示大
寫字母、p{Ll}表示小寫字母:
92
• ²³¹¼ ½ ¾ ㉛㉜㉝
ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯⅰⅱⅲⅳⅴⅵⅶ
ⅷⅸⅹ都是數字
93
• 可以加上Is來表示二元特性,例如p{IsL}
、p{IsLu}等
• 若是單字元表示特性,例如p{L},可以省
略{}寫為pL
• 也可以使用p{general_category=Lu}
或簡寫為p{gc=Lu}。
94
• 有的語言可能會使用多種文字來書寫,例如
日語就包含了漢字、平假名、片假名等文字
• 有的語言只使用一種文字,例如泰文
• Unicode將書寫組織為文字(Script)特性,
可參考〈UNICODE SCRIPT PROPERTY〉
95
• 可以使用IsHan、script=Han或sc=Han
的方式來指定特性
• 例如測試漢字(Han包含了正體中文、簡體
中文,以及日、韓、越南文的全部漢字):
96
• 對於Unicode碼點區塊(block),可以使用
InCJKUnifiedIdeographs、
block=CJKUnifiedIdeographs或
blk=CJKUnifiedIdeographs
• 例如,測試中文時常用的Unicode碼點範圍為
U+4E00到U+9FFF,也就是CJK Unified
Ideographs的範圍:
97
Unicode大小寫與字元類
• Pattern.UNICODE_CASE
• Pattern.UNICODE_CHARACTER_CLASS
98
• 在設定Pattern.CASE_INSENSITIVE 時
,可以加上Pattern.UNICODE_CASE啟用
Unicode版本的忽略大小寫
• 例如,比較Ä (U+00C4)與ä(U+00E4)其
實是同一字母的大小寫:
99
• 預定義字元類沒有考量Unicode規範,例如w
預設只比對ASCII字元
• 若要令w可以比對比對Unicode字元,可以設
置(?U)(對應
Pattern.UNICODE_CHARACTER_CLASS
)
100
• 𝟏𝟐𝟑𝟜𝟝𝟞𝟩𝟪𝟫𝟬𝟭𝟮𝟯𝟺𝟻𝟼都是十進位數字
• "𝟏𝟐𝟑𝟜𝟝𝟞𝟩𝟪𝟫𝟬𝟭𝟮𝟯𝟺𝟻𝟼
".matches("d*")會是false
• "𝟏𝟐𝟑𝟜𝟝𝟞𝟩𝟪𝟫𝟬𝟭𝟮𝟯𝟺𝟻𝟼
".matches("(?U)d*")會是true
101
使用BigInteger
• 想要表示9223372036854775808
102
使用BigInteger
• 若要進行加、減、乘、除等運算,可以使用
add()、subtract()、multiply()、
divide()等方法
• 在餘除運算上,提供了mod()與
divideAndRemainder()方法
• 在比較、條件運算上,提供了equals()與
compareTo​()方法
103
使用BigInteger
• BigInteger.valueOf()接受long型態整
數轉換為BigInteger
• valueOf()方法會維護或重用已建構之
BigInteger實例
104
使用BigInteger
• 想將BigInteger轉換為基本型態,可以使
用intValue()、longValue()方法
• 若原本的數字無法在int或long中容納,這
兩個方法傳回的整數會失去精度
• 若想在原本的數字無法容納時拋出
ArithmeticException例外,可以使用
shortValueExtract()、
intValueExtract()、
longValueExtract()方法 105
使用BigInteger
• 也可以使用floatValue()、
doubleValue()方法,將BigInteger代
表的數字轉換為基本型態的float或
double
106
使用BigDecimal
• 建構BigDecimal實例時,最基本的方式就
是使用字串來表示BigDecimal實例將代表
的浮點數
107
使用BigDecimal
108
使用BigDecimal
• 可以使用unscaledValue​()取得非量級值
,使用scale()方法取得量級
• 若要設定量級,可以使用setScale()方法
,這會傳回新的BigDecimal實例
• 由於量級改變可能會導致位數的減少,因此
必須知道該怎麼處理進位捨去,這時就必須
指定RoundingMode
109
使用BigDecimal
• 可以使用unscaledValue​()取得非量級值
,使用scale()方法取得量級
• 若要設定量級,可以使用setScale()方法
,這會傳回新的BigDecimal實例
• 由於量級改變可能會導致位數的減少,因此
必須知道該怎麼處理進位捨去,這時就必須
指定RoundingMode
110
使用BigDecimal
111
使用BigDecimal
• round()是向最接近數字方向的捨入操作,
因此結果為-5
• ceil()是往正方向的捨入,因此,-5.4的正
方向就是-5.0
• floor()是往負方向的捨入,-5.4的負方向
是-6.0
112
113
使用BigDecimal
• 建構BigDecimal時,有的建構式可以指定
java.math.MathContext實例,而有的
方法也接受MathContext
• MathContext本身也提供了DECIMAL128
、DECIMAL64、DECIMAL32常數來表示對
應的IEEE 754R浮點數格式
114
• 自行建構MathContext實例時,可以指定
最大精度(Precision),這是指從數字最左
邊不是0的數字開始,直到最右邊使用的數字
個數
115
數字的格式化
116
數字的格式化
• 這些方法都有個接受Locale的版本
117
數字的格式化
118
數字的格式化
119
取得StackTraceElement
• 每個執行緒都會有自己專屬的JVM Stack,
是個先進後出結構,每呼叫一個方法,JVM
就會建立一個Stack Frame來儲存區域變數、
方法、類別等資訊並置放至JVM Stack
• 方法呼叫結束後Stack Frame就從JVM Stack
中跳出銷毀
120
取得StackTraceElement
• JDK從1.4開始就在Throwable與Thread類
別上提供了getStackTrace()方法
• 以StackTraceElement陣列傳回JVM Stack中
全部的Stack Frame
121
取得StackTraceElement
• 可以使用StackTraceElement的
getClassName()、getFileName()、
getLineNumber()、getMethodName()
• 或者是JDK9新增的getModuleName()、
getModuleVersion()、
getClassLoaderName()等方法取得對應
的資訊
122
123
124
125
取得StackTraceElement
• getStackTrace()會取得全部的Stack
Frame,如果你只是想察看前幾個,就會顯
得沒有效率
• 若是想取得方法所在的類別資訊呢?
126
Stack-Walking API
• JDK9新增了Stack-Walking API
• 可以透過java.lang.StackWalker的
getInstance()方法,取得StackWalker
實例
• 運用forEach()方法來循序走訪
StackWalker.StackFrame
• 每個StackFrame代表著JVM Stack中的一個
Stack Frame
127
128
129
130
Stack-Walking API
• 如果你只對某幾個StackFrame感興趣,或
者想對StackFrame做轉換或過濾,可以使
用StackWalker實例的walk()方法
131
132
133
134
Stack-Walking API
• 如果要在StackWalker.getInstance()
時指定多個選項
• 如果你想限制可取得的Stack Frame深度
135

Contenu connexe

Plus de Justin Lin

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring BootJustin Lin
 
Ch13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityJustin Lin
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走Justin Lin
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMailJustin Lin
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Justin Lin
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫Justin Lin
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤Justin Lin
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTLJustin Lin
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSPJustin Lin
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Justin Lin
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理Justin Lin
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應Justin Lin
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletJustin Lin
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式Justin Lin
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題Justin Lin
 
13.並行、平行與非同步
13.並行、平行與非同步13.並行、平行與非同步
13.並行、平行與非同步Justin Lin
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能Justin Lin
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組Justin Lin
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換Justin Lin
 
9. 資料結構
9. 資料結構9. 資料結構
9. 資料結構Justin Lin
 

Plus de Justin Lin (20)

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring Boot
 
Ch13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/Security
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMail
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTL
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSP
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 Servlet
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題
 
13.並行、平行與非同步
13.並行、平行與非同步13.並行、平行與非同步
13.並行、平行與非同步
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換
 
9. 資料結構
9. 資料結構9. 資料結構
9. 資料結構
 

CH15:通用API