一.Servletphp
思考html
1 瀏覽器能夠直接打開JAVA/class文件嗎? 不能夠java
2瀏覽器能夠打開HTML、JS 文件嗎? 能夠程序員
3 JAVA程序能夠生成HTML文件嗎?能夠的,用IO流。web
4 瀏覽器解析的時候是須要HTTP協議的,JAVA普通類有沒有HTTP協議呢? 普通類沒有.sql
JAVA-(class)瀏覽器如何訪問呢?編程
瀏覽器---HTML瀏覽器
A JAVA經過IO流生成HTML--->瀏覽器 緩存
B JAVA 須要加入HTTP協議tomcat
解決上面2個問題能夠經過 Servlet
C 如何經過瀏覽器訪問Servlet
它須要用到一個文件web.xml (webroot-->web-inf--web.xml)
Sevlet它是什麼?
Servlet是一個容器(引擎),它包含協議和支持功能的jar包,它是一個總體。
在使用的時候咱們不用去關內心面的核心程序,咱們只關心業務程序。
業務程序 程序員所寫支持協議的類,有一種特殊的叫法 Serlvet類。
1.三要素是什麼?
入口(login.html) 處理(LoginServlet.java) 出口 (success.jsp)
2.如何訪問servlet
http://IP:port/project/urlpattern
urlpattern ---->web.xml中找
3 request 和 response的區別?
Request請求 Broswer---->Tomcat login.html--->LoginSevlet.java
Response返回 Tomcat---->Broswer
4 doGet 和 doPost的區別?
doGet <a href=url> 超連接用的默認方式 get 不解中文決亂麼
<form action=url method=get >
明文傳遞方式 瀏覽器中能夠看到傳遞的信息
不安全,而且數據量大的時候會缺損數據
doPost <form action=url method=post > 解決中文亂碼
密文傳遞方式 瀏覽器看不到傳遞的信息
安全,而且數據量大的時候不會缺損數據
5如何解決亂碼問題?
Request請求有亂碼
request.setCharacterEncoding("UTF-8");
Reponse返回有亂
response.setCharacterEncoding("UTF-8");
6 如何取得請求中的值 ?
String value=request.getParameter(「控件名」); 單個值
String [] values=request.getParmeterValues(「控件名」); 同名多個值
7 常見的錯誤:404 、500?
404 路徑錯誤---解決思路 跟蹤路徑
500 代碼錯誤---解決思路 jsp/servlet中代碼錯誤
獲取不到值null 在console裏面去找到錯誤的位置。
8 servlet中獲得流的方法?
字符流 response.getWriter( )----->PrintWriter
字節流 response.getOutputStream()-->OutputStream
9 如何跳轉到出口?
//跳轉而且能夠傳遞數據
request.getRequestDispatcher("success.jsp").forward(request, response);
//從新定向 跳轉不傳遞數據
response.sendRedirect("success.html");
10如何將數據傳遞到出口?
//保存數據
request.setAttribute("name", username);
request.setAttribute("password", pwd);
//獲取數據
用戶名是:${ name} ,密碼: ${password}。
11 Servlet的生命週期
Servlet的生命週期是由tomcat服務器來控制的。
1 構造方法:
建立servlet對象的時候調用。默認狀況下,第一訪問servlet就會建立servlet對象只建立一次。說明servlet對象在tomcat中是單實例的。
2初始化 init方法
當建立完servlet對象的時候會調用init()方法,只調用一次。
3 調用服務 service 方法 其中就包含doGet doPost等方法
每次發送請求的時候調用。能夠調用n次。
4 銷燬 destory 方法
銷燬servlet對象的時候調用,中止服務器或者從新部署的web項目的時候銷燬servlet就會調用destory方法
12 Servlet時序圖
13 servlet自動加載
在web.xml中加入
<load-on-startup> 1</load-on-startup>
裏面的數字越小加載級別越高
當tomcat啓動的時候,就去運行web.xml解析裏面的內容,當發現有自動加載的數據時候,就會運行加載。
<servlet> <servlet-name>sl</servlet-name> <servlet-class>com.bw.servlet.LoginServlet</servlet-class> <load-on-startup>3</load-on-startup> </servlet> |
14 ServletConfig 對象
主要是加載servlet的初始化參數,在web應用中能夠存在多個ServletConfig對象
<servlet> <servlet-name>sl</servlet-name> <servlet-class>com.bw.servlet.LoginServlet</servlet-class> <init-param> <param-name>username</param-name> <param-value>godyang</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>123456</param-value> </init-param> </servlet> |
15 ServletContext對象
上下文對象,表示當前的web應用(項目)環境。一個web應用只有一個ServletContext對象
上下文參數配置 它是全局的 全部的servlet均可以訪問
<context-param> <param-name>ecode</param-name> <param-value>UTF-8</param-value> </context-param> |
// 獲取上下文對象 ServletContext sc = this.getServletContext(); String contextParamValue = sc.getInitParameter("ecode"); System.out.println("contextParamValue=" + contextParamValue); |
//項目路徑 String path=sc.getContextPath(); System.out.println("path="+path); //文件發佈後(tomcat/webapps)的真實路徑 String realPath=sc.getRealPath("counter.txt"); System.out.println("realPath="+realPath ); //獲取文件流 InputStream is=sc.getResourceAsStream("C:\\Tomcat\\webapps\\webThree\\WEB-INF\\classes\\counter.txt");
|
二.JSP技術
Jsp技術是用來開發java web的頁面顯示的,全部MVC模型裏面的視圖層,因此視圖層的開發
jsp不是編程語言,java server pages的縮寫
Jsp其實也是繼承Servlet的,屬於在服務器上的開發。Servlet是用於java語言的動態資源開發的技術,而Jsp是把java和html結合,在html中能夠寫java語言,主要用在頁面的顯示開發上。
1.1.Jsp的特色
1.Jsp的運行必須交給tomcat服務器。tomcat的work目錄就是服務器用來存放jsp運行時的臨時文件的
2.Jsp頁面便可直接寫html代碼,也能夠直接寫java代碼
2.Jsp的執行過程
問題1:訪問http://localhost:8080/hello/index.jsp 如何顯示效果?
1.訪問到index.jsp頁面,tomcat掃描到jsp文件,在tomcat/work目錄下把jsp文件翻譯成java源文件
index.jsp-->index_jsp.java(翻譯)
2.tomcat服務器把java源文件編譯成class字節碼文件(編譯)
index_jsp.java-->index_jsp.class
3.tomcat服務器構造index_jsp類對象
4.tomcat服務器調用index_jsp類裏面的方法,返回內容顯示到瀏覽器
若是是第一次訪問當前jsp文件時,執行步驟是:1-->2-->3-->4
第N次訪問jsp時,執行步驟是:4,再也不執行其餘步驟
注意:jsp文件被修改或者jsp的臨時文件被刪除了,要從新走翻譯 1 和編譯 2 的過程
問題2:既然jsp是servlet,那麼jsp的生命週期和servlet的生命週期是否是同樣的?
當jsp文件被翻譯成java的源碼時,能夠在翻譯出來的源碼文件裏看到當前訪問的jsp文件繼承HttpJspBase類,再經過查詢JDK,能夠發現HttpJspBase又是繼承於HttpServlet的。因此,能夠獲得結論,jsp既是一個servlet的程序,而servlet的技術能夠用在jsp程序中,可是並非全部的servlet技術所有適用於jsp程序
Servlet的生命週期:
1.構造方法(第一次訪問執行)默認狀況第一次使用的時候 經過單例模式建立一個servlet對象
2.init方法初始化(第一次訪問執行)當構造了以後就會調用初始化方法 只調用一次
3.service方法(每n次訪問都會執行)每次發出請求的時候調用能夠調用n次
4.destory方法(退出時執行)關閉服務軟件從新部署的時候銷燬 servlet對象
Jsp的生命週期:
1.翻譯:Jsp-->java文件
2.編譯:java-->class文件(servlet程序)
3.構造方法(第一次訪問時執行)
4.init方法(第一次訪問):_JspInit()
5.service方法:_JspService()
6.destory方法:_jspDestory()
問題3:JSP和Servlet做用有什麼區別?
1.Servlet做用: 用java語言開發動態資源( java 流 )的技術.
2.JSP 做用:用java語言開發動態(java 流)+靜態資源(html)的技術
3.Jsp語法
3.1.Jsp模板
JSP 頁面中會自動添加HTML代碼內容,該JSP是模板
這些模板定義了網頁的基本骨架,也就是說定義了頁面的結構和外觀
3.2.Jsp表達式
JSP的表達式做用是向瀏覽器輸出變量的值或表達式計算的結果
語法:<%=變量或表達式 %>
例如<% String name="Eric";%>
<%=name%>
注意:
1.表達式的原理即便翻譯成out.print("變量「);經過該方法向瀏覽器寫出內容。
2.表達式後面不須要帶分好結束
3.3.Jsp的腳本
腳本是指在JSP頁面編寫多行java代碼的,能夠執行java代碼
語法:<%多行java代碼; %>
如:
<%
Date date = new Date();
SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd");
String now = sdFormat.format(date);
out.println(now);
%>
注意
1.原理是把腳本中的java代碼原封不動的拷貝到jspService方法中執行
2.jsp腳本中寫的java是須要加分好的,語法跟java語法是同樣的
3.多個腳本片斷中的代碼能夠相互訪問
4.單個腳本片斷中的java語句能夠是不完整的,可是,多個腳本片斷組合後的結必須是完整的java語句
3.4.Jsp的聲明
JSP的聲明是用來聲明變量或者方法的,若是在index.jsp頁面內聲明一個變量或者方法,則該變量或者方法是index_jsp類的成員變量,成員方法,便是全局變量。這個其實就是在類中寫好方法,而後能夠在jsp_service方法中調用其餘方法。
jsp經過腳本也能夠定義一個變量,可是這個變量是保存在index_jsp類下的jspService方法下的一個變量,因爲是保存在方法下面,全部腳本里是不能夠定義一個方法的,只能經過聲明來定義方法。
注意以上二者的區別,一個是保存在類下面,稱爲成員變量或者成員方法,另外一個則是保存在方法中,稱之爲局部變量
語法:<%! 變量或方法%>
做用:聲明JSP的變量和方法
注意:
1.變量翻譯成成員變量,方法翻譯成成員方法
3.5.Jsp的註釋
jsp的註釋格式:
jsp的註釋:<%!--jsp註釋 --%>
html的註釋:
注意:
1.html的註釋會被翻譯和執行,不管在jsp的頁面翻譯以後的源碼仍是在瀏覽器上查看網站的源碼,都是能夠查看到的。可是jsp的註釋是不會被翻譯和執行的,在翻譯以後源碼裏是不能找到的,從瀏覽器查看源碼也是查看不到的
4.Jsp的三大指令
JSP指令是爲JSP引擎而設計的,他們並不產生任何可見的輸出,只是告訴引擎如何處理jsp頁面中的其他部分。jsp定義的有三大指令,分別是:include,page,tagllb
4.1.Include指令
Include指令的做用是當前頁面包含其餘頁面,主要是導入其餘jsp文件
語法:<%@include file="common/header.jsp%>
注意:
1.原理是把被包含的頁面(header.jsp)的內容翻譯到包含頁面(index.jsp)中,合併並翻譯成一個java源文件,再編譯運行!!,這種包含就加叫靜態包含(源碼包含)
2.若是使用靜態包含,被包含頁面中不須要出現全局的html標籤了,(如html,body,head)
4.2.page指令
page指令的做用是告訴tomcat服務器如何翻譯jsp文件
語法:<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page
language="java" --使用的語言
import="java.util.*" --須要導入的類
pageEncoding="UTF-8" --jsp編碼方式
contentType="text/html; charset=UTF-8" --tomcat將html流發送給瀏覽器的文件類型和編碼方式
errorPage="error.jsp" --當前jsp頁面解析錯誤的時候就會跳轉到error.jsp去
isErrorPage="false" --當前頁面是否是錯誤導向頁面
%>
language="java"--告訴服務器只用什麼動態語言來翻譯jsp文件
import="java.util.*" --告訴服務器java文件使用什麼包,導入多個包時,用逗號隔開
pageEncoding="utf-8" --告訴服務器使用什麼編碼把jsp翻譯成java文件
contentType="text/html; charset=utf-8" --服務器發送瀏覽器的數據類型和內容編碼,在開發工具中,只須要設置pageEncoding便可解決中文亂碼的問題
errorPage="error.jsp" --若是當前頁面出現錯誤信息,則自動調用此處指定的錯誤頁面
isErrorPage="false" --意思是當前頁面爲錯誤頁面,默認爲false,當設置爲true時就認爲是一個錯誤處理頁面,就能夠在頁面中使用<%=exception.getMessage()%>方法來獲取錯誤異常信息,使其在頁面上能夠顯示
全局配置錯誤處理頁面
在web.xml中配置以下:
<!--全局錯誤處理頁面配置-->
<error-page>
<error-code>500</error-code>
<location>common/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>common/404.html</location>
</error-page>
配置以後,不用在jsp頁面中特別指明,會自動跳轉的
session="true" --是否開啓Session功能,false時不能使用Session內置對象,ture時可使用。默認爲true
buffer="8kb" --頁面的緩存區大小。
isELIgnored="false" --是否忽略EL表達式。
page==this 對象 通常用在編譯指令中 <%@ page %>
4.3.tagllb指令
語法<%taglib %>
做用:標籤指令 用來解析標籤效果
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
5.JSP的內置對象
5.1.什麼是內置的對象
service開發中會常常用到一些經常使用的類好比:HttpSession, ServletConfig, ServletContext, HttpServletRequet,用的時候,咱們會直接建立就能夠了,可是在jsp中這會常用到這些類。爲了開發的方便,sun公司在設計jsp的時候,在jsp頁面加載完畢之後就自動幫開發者建立好了這些對象,而開發者只須要直接使用這些對象就能夠了,那麼這些已經建立好的對象有一個統一的名字叫作內置對象,內置對象一共有九個
例如:
在Service中要使用Session,須要先HttpSession session = request.getSession(true); 來建立一個Session對象,而後在使用對象的方法
可是在JSP中,能夠直接使用Session的方法,如session.getId();
九大內置對象
jsp |
servlet |
|
對象名 |
類型 |
使用範圍 |
request |
HttpServletRequest |
請求 瀏覽器--->服務器 |
response |
HttpServletResponse |
返回 服務器--->瀏覽器 |
config |
ServletConfig |
用來獲取web.xml中的信息 |
application |
ServletContext |
整個項目中的全局信息 |
exception |
Thrawable |
捕獲異常 try/catch throws |
page |
this |
當前對象,當前頁面對象 |
out |
JspWriter---->PrintWriter |
當前頁面輸出流 |
pageContext |
PageContext |
當前頁面的上下文,整個頁面 |
Session |
HttpSession |
會話 瀏覽器和服務器通信 |
即:
1.對象名(request)-->類型HttpServletRequest :HTTP請求的時候使用到
2.對象名(response)-->類型HttpServletResponse :HTTP響應的時候用到
3.對象名(config)-->類型ServletConfig :獲取屬於本身的參數
4.對象名(application)-->類型ServletContext :獲取全局參數
5.對象名(exception)-->類型Throwable :異常
6.對象名(page)-->類型 Object(this) :本jsp對象
7.對象名(out)-->類型JspWriter :打印到瀏覽器
8.對象名(pageContext)-->類型PageContext
9.對象名(session)-->類型HttpServletSession :會話管理使用
5.2.Out對象
out 對象 JspWriter 帶緩衝的PrinterWriter 就是輸出流 , 使用範圍是當前頁面,超出了當前頁無效
1.PrintWriter: 直接向瀏覽器輸出內容
用write直接向瀏覽器(輸出)寫出內容
2.JspWrite: 向Jsp 緩衝區寫內容
用write向jsp的緩衝區寫內容,當緩衝區知足一下條件的時候,把內容一塊兒寫到瀏覽器上,性能高於PrintWriter
當知足一下條件之一,JSP緩衝區內容寫出到瀏覽器:
(1) 緩衝區滿了
(2)刷新緩存去:out.flush();
(3)關閉緩衝區:buffer="0kb";
(4)執行完畢JSP頁面
‘out.print()
‘out.println();
5.3.pageContext對象
前面已經有了8個內置對象,這些對象都是在jsp_service方法中被建立的,而後直接使用,可是因爲是在方法中被建立,屬於局部變量,因此很難在其餘方法被調用,全部,使用了PageContext把這八個內置對象封裝起來,這樣傳參的時候只須要傳一個就能夠了,而後經過這個PageContext來調用
除了調用其餘八個內置對象意外,PageContext自己也是一個域對象,能夠傳遞參數,準確的說PageContext是jsp的上下文對象,只能夠在當前jsp文件內傳參
分別介紹PageContext的兩個方法:
1.能夠獲取其餘八個內置對象
源碼分析:
public class 01_hello_jsp {
public void _jspService(request,response){
建立內置對象
HttpSession session =....;
ServletConfig config = ....;
把8個常用的內置對象封裝到PageContext對象中
PageContext pageContext = 封裝;
調用method1方法
method1(pageContext);
}
public void method1(PageContext pageContext){
但願使用內置對象
從PageContext對象中獲取其餘8個內置對象
JspWriter out =pageContext.getOut();
HttpServletRequest rquest = pageContext.getRequest();
........
}
}
注意:調用的時候,使用getout,getrequest等方法來調用
使用場景:在自定義標籤的時候,PageContext對象對象頻繁使用到
2.PageContext自己就是一個域對象
常用的域對象有4個,分別是
ServletContext context域
HttpServletRequest request對象
HttpSession session域
PageContex page域
PageContext域的做用是保存數據和獲取數據,用於共享數據
經常使用方法以下:
保存數據
1.默認狀況下,保存到page域
pageContext.setAttribute("name");
2.能夠向四個域對象保存數據
pageContext.setAttribute("name",域範圍常量)
獲取數據
1.默認狀況下,從page域獲取
pageContext.getAttribute("name")
2.能夠從四個域中獲取數據
pageContext.getAttribute("name",域範圍常量)
3.自動在四個域中搜索數據
pageContext.findAttribute("name");
順序: page域 -> request域 -> session域- > context域(application域)
5.4.page對象 page==this 對象 通常用在編譯指令中 <%@ page %>
5.5.request對象
request 請求 瀏覽器到服務器
當前請求存屬性值 |
request.setAttribute("name","godyang"); |
當前請求取值 |
request.getAttribute("name") |
請求傳遞參數 |
<a href="b.jsp?name=shunshun"> b.jsp</a> 或者 <form action="b.jsp" method=post > <input type=text name="name" value="shunshun" /> </form>
|
取得請求參數的值 |
request.getParameter(參數名); request.getParameterValues(參數名) |
5.6.reponse 對象
reponse 返回 服務器返回到瀏覽器
獲取返回流 |
PrintWriter out = response.getWriter(); |
返回內容形式 |
response.setContentType("text/html"); |
返回的編碼 |
response.setCharacterEncoding("UTF-8"); |
頁面重定向 |
response.sendRedirect("index.jsp"); |
瀏覽器端保存cookie對象 |
response.addCookie() |
|
|
5.7.session對象
session 會話 瀏覽器和服務器通信 當瀏覽器關閉的時候會話結束
當瀏覽器第一訪問服務器的時候就會產生一個會話
保存會話信息 |
session.setAttribute("uname","abc"); |
獲取會話信息 |
session.getAttribute("uname"); |
5.8.application對象
application 應用 tomcat啓動的時候整個項目就是一個應用
當把值存入應用中,只有當tomcat關閉的時候才銷燬
保存應用信息 |
application.setAttribute("app","appInfo"); |
獲取應用信息 |
application.getAttribute("app"); |
5.9.JSP中的四個域對象
四個域度對象
pageContext page域
request request域
session session域
application context域
1.域對象做用
保存數據和獲取數據,用於數據共享
2.域對象方法
setAttribute("name",Object)保存數據
getAttribute("name")獲取數據
removeAttribute("name")消除數據
域對象的做用範圍
page域 :只能在當前jsp頁面中使用(當前頁面)
request : 只能在同一個請求中使用(轉發)
Session : 只能在同一個會話(session對象)中使用(私有的)
context : 只能在同一個web應用中使用(全局的)
5.10.JSP的最佳實踐
Servlet技術:開發動態資源。是一個java類,最擅長寫java代碼
JSP技術:開發動態資源,經過java代碼最擅長輸出html代碼
一個在web項目中涉及到的邏輯:
1.接收參數
2.處理業務邏輯
3.顯示數據到瀏覽器
4.跳轉到其餘頁面
最佳實踐中,對上述邏輯進行分工,由Servlet和JSP聯合完成
Servlet:
1.接收參數
2.處理業務邏輯
3.把結果保存到域對象中
4.跳轉到jsp頁面
JSP:
1.從域對象中取出數據
2.把數據顯示到瀏覽器
Servlet的數據-->JSP頁面
6.EL表達式
6.1.EL表達式的做用
EL表達式也是用在html頁面中的,目的是簡化JSP操做,代碼。
在最佳實踐中,總結得出JSP中儘可能不要寫java代碼,最好的方法就是不寫,因此的邏輯所有放到Servlet中,全部的數據展現放在JSP中
JSP的核心語法: jsp表達式 <%=%>和 jsp腳本<% %>。
如今使用EL表達式來替換到JSP的表達式
EL表達式的做用:向瀏覽器輸出」域對象中的「變量值或表達式計算的結果!,注意必定要是域對象中的
語法:${變量或表達式}
6.2.EL語法
1.輸出基本數據類型便變量
1.1.從四個域獲取
輸出普通字符串: ${name}
若沒有指定域,則域的搜索前後順序: pageScoep / requestScope / sessionScope / applicationScope
1.2.指定域獲取
${pageScope.name},在pageScope域中查找name
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>測試jsp文件</title>
</head>
<body>
<%
String name = "roso";
pageContext.setAttribute("name",name,PageContext.REQUEST_SCOPE);
%>
<br>
EL表達式:${requestScope.name};
<%--
${name}等價於pageContext.findAtribute("name")
--%>
</body>
</html>
2.輸出對象的屬性值
輸出對象屬性: ${student.name} 注意: .name 至關於 .getName()方法
若是咱們定義了一個Student類,並定義了name成員變量,這個時候能夠經過${student.name}來獲取name值
點 . 方法是實際上是調用getXX()方法
3.輸出集合對象
集合對象有List和Map
輸出List集合: ${list[0].name } 注意: [0] 至關於 get(下標)方法
輸出map集合: ${map[key].name} 注意: [key]至關於get(key)方法
中括號[]實際上是調用get
EL表達式沒有遍歷功能,可是能夠結合標籤使用遍歷
4.EL表達式計算
表達式中須要注意的是字符串判空的一種方法${empty name}<br>
示例代碼:
<%@ page import="servers.Student" contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<html>
<head>
<title>測試IE表達式</title>
</head>
<body>
<%--1.EL輸出對象的屬性--%>
<%
//保存數據
Student student = new Student("eric", 20);
//放入域中
pageContext.setAttribute("student",student);
%>
<%--2.EL輸出集合List對象--%>
<%
//List
List<Student> list = new ArrayList<Student>();
list.add(new Student("rose",18));
list.add(new Student("jack",20));
list.add(new Student("luck",38));
//List放到域中
pageContext.setAttribute("list",list);
%>
<%--3.EL輸出集合Map對象--%>
<%
//Map
Map<String,Student> map = new HashMap<String, Student>();
map.put("100",new Student("mark",20));
map.put("101",new Student("maxwell",30));
map.put("102",new Student("Eric",40));
//放入域中
pageContext.setAttribute("map",map);
%>
<%--3.EL表達式--%>
<%--3.1.算術表達式--%>
${10+5}<br>
<%--3.2.比較運算--%>
${10>5} <br>
<%--3.3.邏輯運算--%>
${true && false} <br>
<%--3.4.判空,null或空字符串--%>
判斷null:${name==null}<br>
判斷空字符串:${name==""}<br>
判空: ${name==null || name==""}<br>
判空的另外一個種寫法: ${empty name}<br>
<%--1.使用EL獲取對象--%>
<%--實際調用student的getName方法獲取的值--%>
獲取student的name屬性值:${student.name}
<%--${student.name}的點至關於調用getXX()方法--%>
<br>
<%--2.使用EL獲取List對象--%>
list對象:${list} <br>
獲取list的第一個對象:${list[0]} <br>
獲取list的第一個對象的name和age屬性:${list[0].name} - ${list[0].age}
<br>
<%--${list[0]}等價於(ListpageContext.findAttribute("list)--%>
<%--${list[0]}的中括號至關於調用get()方法--%>
<%--3.使用EL獲取Map對象--%>
獲取Map對象:${map}<br>
獲取key=100的值:${map['100'].name} - ${map['100'].age}
</body>
</html>
7.JSP標籤
7.1.JSP標籤的做用
咱們使用EL表達式來替換JSP的表達式,可是JSP還有一個常常會使用的語法,就是JSP腳本,出於和EL表達式一樣的目的,咱們使用標籤來替代JSP腳本,以達到簡化JSP頁面的目的
因此JSP標籤做用:替換JSP腳本
主要功能有:
1.路程判斷(if,for, 循環)
2.跳轉頁面(轉發,重定向)
3.…………
7.2.JSP標籤的分類
JSP的標籤也分爲幾種類型的
1.內置標籤:,也叫動做標籤,不須要在jsp頁面中導入的標籤
2.JSTL標籤:須要在jsp頁面中導入的標籤
3.自定義標籤:開發者自行定義,須要在jsp頁面導入標籤
7.3.動做標籤
轉發標籤:
參數標籤:
包含標籤:
包含標籤的原理:
包含與被包含的頁面先各自翻譯成java源文件,而後在運行時再合併在一塊兒。(先翻譯再合併),動態包含,使用include指令包含是靜態包含
靜態包含 VS 動態包含
1.語法不一樣
靜態包含語法:<%@inclue file="被包含的頁面"%>
動態包含語法:
2.參數傳遞不一樣
靜態包含不能向被包含頁面傳遞參數
動態包含能夠向被包含頁面傳遞參數
3.原理不一樣
靜態包含: 先合併再翻譯
動態包含: 先翻譯再合併
7.4.JSTL標籤
JSTL的全名是:Java Standard Tag Libarary ---java標準標籤庫
java標準標籤庫有五類,經常使用的是前三類
標籤核心庫(c標籤庫) 每天用
國際化標籤(fmt標籤庫)
EL函數庫(fn函數庫)
xml標籤庫(x標籤庫)
sql標籤庫(sqp標籤庫)
7.5.使用JSTL標籤的步驟
1.導入jstl支持的jar包(標籤背後隱藏的java代碼)
把包放在WEB-INF下的lib包
2.使用tablib指令導入標籤庫
<%@taglib prefix="簡寫" uri="tld文件的uri名稱" %>
uri從jstl.jar包下的META-INF下的tld文件中查找,把uri的值複製過來,prefix的值也是在tld中查找
3.在jsp中使用標籤
核心標籤庫的重點標籤
保存數據:
<c:set></c:set>
獲取數據:
<c:out value=""></c:out>
單條件判斷:
<c:if test=""></c:if>
多條件判斷:
<c:choose></c:choose>
<c:when test=""></c:when>
<c:otherwise></c:otherwise>
循環數據:
<c:forEach></c:forEach>
<c:forTokens items="" delims=""></c:forTokens>
重定向:
<c:redirect></c:redirect>
代碼示例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--導入標籤庫--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>JSTL核心標籤</title>
</head>
<body>
<%--使用標籤--%>
<%--1.set標籤:保存數據(保存到域中),默認保存到page域中,能夠指定--%>
<c:set var="name" value="Eric" scope="request"></c:set>
${name}<br>
${requestScope.name}<br>
<%--2.out標籤:獲取數據(從域中),當value值爲null時,可使用default指定的默認值,escapeXml標明默認值是原樣輸出仍是轉化爲以後再輸出,默認爲true,表示原樣輸出--%>
<%--雙引號內雖然是name,可是現實的是字符串name,由於是在雙引號內--%>
<c:out value="name"/>
<%--調用name的值正確寫法--%>
<c:out value="${name}" default="<h3>標題3</h3>" escapeXml="false"/><br>
<%--3.if標籤:單條件判斷,若是test裏面的EL表達式爲真,則運行if包含的代碼--%>
<c:if test="${10>5}">
條件成立
</c:if>
<%--4.choose標籤+when標籤+otherwirse標籤:多條件的判斷--%>
<c:set var="score" value="86"></c:set>
<c:choose>
<c:when test="${score>=90 && score<=100}">
優秀
</c:when>
<c:when test="${score>=80 && score<=90}">
良好
</c:when>
<c:when test="${score>=70 && score<=80}">
通常
</c:when>
<c:when test="${score>=60 && score<=70}">
及格
</c:when>
<c:otherwise>
不及格
</c:otherwise>
</c:choose>
<br>
<%--5.forEach:循環--%>
<%
//List
List<Student> list = new ArrayList<Student>();
list.add(new Student("rose",18));
list.add(new Student("jack",20));
list.add(new Student("luck",38));
//List放到域中
pageContext.setAttribute("list",list);
%>
<%
//Map
Map<String,Student> map = new HashMap<String, Student>();
map.put("100",new Student("mark",20));
map.put("101",new Student("maxwell",30));
map.put("102",new Student("Eric",40));
//放入域中
pageContext.setAttribute("map",map);
%>
<%--<c:forEach
begin="從哪一個元素開始遍歷,默認從0開始,能夠不寫"
end="到哪一個元素結束,默認到最後一個元素,能夠不寫"
step="步長,默認是1,能夠不寫"
var="每一個元素的名稱"
items="須要遍歷的數據(集合)"
varStatus="當前正在遍歷的元素的狀態對象(count屬性:當前位置,從1開始)"/>--%>
<%--遍歷list--%>
<c:forEach begin="0" end="2" step="1" items="${list}" var="student" varStatus="varSta">
姓名:${varSta.count}--${student.name}--年齡:${student.age}<br>
</c:forEach>
<%--遍歷Map--%>
<c:forEach items="${map}" var="entry">
${entry.key}--姓名:${entry.value.name}--年齡:${entry.value.age}<br>
</c:forEach>
<%--6.forToken標籤:循環特殊字符串--%>
<%
String str = "java-php-net-平面";
pageContext.setAttribute("str",str);
%>
<c:forTokens items="${str}" delims="-" var="s">
${s}<br>
</c:forTokens>
<%--7.重定向--%>
<c:redirect url="http://www.baidu.com"/>
</body>
</html>
8.自定義標籤
8.1.引入
當現有的標籤沒法知足咱們的需求時,就須要本身開發一個適合的標籤
例如,須要向瀏覽器輸入當前客戶端的IP地址,雖然用java程序是能夠的,可是用標籤是沒有這個功能的,如今,咱們來自定以這個標籤
8.2.第一個自定義標籤開發步驟
1.編寫一個普通的類,繼承SimpleTagSupport類,叫作標籤處理器類
/**
* 標籤處理類
* 1.繼承SimpleTagSupport
*/
public class ShowIpTag extends SimpleTagSupport {
/**
* 2.覆蓋doTag方法
*/
@Override
public void doTag() throws JspException, IOException {
//向瀏覽器輸出客戶的IP地址
PageContext pageContext = (PageContext)this.getJspContext();
HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
String ip = request.getRemoteHost();
JspWriter out = pageContext.getOut();
out.write("使用自定義標籤輸出客戶的IP地址:"+ip);
}
}
2.在web項目的WEB-INF目錄下創建net.tld文件,這個tld叫標籤的聲明文件(參考核心標籤庫的寫法)
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<!--標籤庫的版本-->
<tlib-version>1.1</tlib-version>
<!--標籤庫前綴-->
<short-name>net</short-name>
<!--tld文件的惟一標記-->
<uri>http://gz.itcast.cn</uri>
<!--一個標籤的聲明-->
<tag>
<!--標籤名-->
<name>ShoeIp</name>
<!--標籤處理器類的全名-->
<tag-class>tag.ShowIpTag</tag-class>
<!--輸出標籤體內容格式-->
<body-content>scriptless</body-content>
</tag>
</taglib>
3.在jsp頁面的頭部導入自定義標籤庫
<%@taglib prefix="net" uri="http://gz.itcast.cn" %>
4.在jsp中使用自定義標籤
8.3.自定義標籤的執行過程
問題: http://localhost:8080/hello/tag.jsp 如何訪問到自定義標籤?
前提:tomcat服務器啓動時,加載到每一個web應用,加載每一個web應用的WEB-INF目錄下的全部文件,如web.xml, tld文件
訪問步驟:
1.訪問tag.jsp資源
2.tomcat服務器把jsp文件翻譯成java源文件-->編譯class-->構造類對象-->調用_jspService()方法
3.檢查jsp文件的taglib指令,是否存在名爲http://gz.itcast.cn的tld文件,若是沒有,則報錯
4.上一步已經讀取到net.tld文件
5.在tag.jsp中讀到,到net.tld文件中查詢是否存在爲ShoeIp的標籤
6.找到對應的標籤,則讀到內容
7.獲得tag.ShowIpTag
8.構造ShowIpTag對象,而後調用ShowIpTag裏面的方法
8.4.自定義標籤處理類的生命週期
標籤處理器本質上實現的仍是SimpleTag接口,只是對裏面的方法進行了重寫。
SimpleTag接口:
void setJspContext(JspContext pc)
設置pageContext對象,傳入pageContext(必定調用)
void setParent(JspTag parent)
設置父標籤對象,傳入父標籤對象,若是沒有父標籤對象,則調用此方法。經過geetParent()方法獲得父標籤對象
void setXX(值)
設置屬性值
void setJspBody(JSpFragment jspBody)
設置標籤體內容。標籤提內容封裝到JspFragment中,而後傳入JspFragment對象,經過getJspBody()方法獲得標籤體內容,若是沒有標籤體內容,則不會調用此方法
void doTag()
執行標籤時調用的方法(必定會調用)
8.5.自定義標籤的做用
1.控制標籤體內容的是否輸出
2.控制標籤餘下內容是否輸出
3.控制重複輸出標籤體內容
4.改變標籤體內容
5.帶屬性的標籤
//1.聲明屬性的成員變量
private Integer num;
//2.關鍵點: 必須提供公開的setter方法,用於給屬性賦值
public void setNum(Integer num) {
this.num = num;
}
自定義標籤的做用代碼示例:
/**
* 標籤處理器類
*/
public class TagDemo extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
System.out.println("執行了標籤");
/**
*1. 控制標籤內容是否輸出
* 輸出:調用jspFrament.invoke();
* 不輸出:不調用jspFrament.invoke();
*/
//1.1.獲得標籤體內容
JspFragment jspBody = this.getJspBody();
//執行invoke方法:會把標籤體的內容輸出到指定的Writer對象
//1.2.往瀏覽器輸出,writer爲null就是默認往瀏覽器輸出
// JspWriter out = this.getJspContext().getOut();
// jspBody.invoke(out);
jspBody.invoke(null);//等價於上面的兩行代碼
/**
* 3.控制重複輸出標籤體內容
* 方法:執行屢次jspBody.invoke()方法
*/
for (int i=1; i <= 5 ; i++) {
jspBody.invoke(null);
}
/**
* 4.改變標籤提內容
*/
//4.1.建立StringWriter臨時容器
StringWriter sw = new StringWriter();
//4.2.把標籤提內容拷貝到臨時容器
jspBody.invoke(sw);
//4.3.從臨時容器中獲得的標籤
String content = sw.toString();
//4.4.改變內容
content = content.toLowerCase();
//4.5.把改變的內容輸出到瀏覽器
//不能使用jspBody.invoke()來輸出,由於標籤體內的內容並無改變,改變的是容器裏面的
this.getJspContext().getOut().write(content);
/**
* 2.控制標籤餘下內容是否輸出
* 輸出:什麼都不作就會默認輸出
* 不輸出:拋出有SkipPageException()異常則不輸出
*/
throw new SkipPageException();
}
}
8.6.輸出標籤體內容格式
JSP:在傳統標籤中使用。能夠寫和執行jsp的java代碼
scriptless:標籤體不能夠寫jsp的java代碼
empty:必須是空標籤
tagdependent:標籤體內容能夠寫jsp的java代碼,但不會執行
9.JavaBean
JavaBaen,咖啡豆,是一種開發規範,能夠說是一種技術
JavaBaen就是一個普通的java類,只要符合如下規定才能稱之爲javaBean:
1.必須提供無參構造方法
2.類中屬性都必須私有化
3.該類提供公開的getter和setter方法
javaBean的做用:
用於方法數據,保存數據
方法javaBean只能使用getter和seetter方法
javaBean的使用場景:
1.項目中用到實體對象(entity)符合javaBean規範
2.EL表達式訪問對象屬性,${student.name}滴啊用getName()方法,符合javaBean規範
3.jsp標籤中的屬性賦值,setNum(Integet num)。符合javaBean規範
4.jsp頁面中使用javaBean,符合javaBean規範
javaBean在jsp頁面中的使用
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsp頁面中使用javabean</title>
</head>
<body>
<%--建立對象,使用無參構造器--%>
<jsp:useBean id="stu" class="servers.Student"/>
<%--賦值--%>
<jsp:setProperty name="stu" property="name" value="jacky"/>
<%--獲取--%>
<jsp:getProperty name="stu" property="name"/>
</body>
</html>