主要內容介紹
數據共享與頁面跳轉
1. 為什么要有跳轉:
Servlet需要跳轉到其它Servlet中,因為我們需要職責分明,不同Servlet來完成不同的功能
Servlet跳轉到JSP中,Servlet輸出動態頁面實現惡心,咱們需要使用JSP來做頁面的顯示
2. 為什么要共享:
http是無狀態的,因為在不斷的跳轉過程中我們需要對數據進行共享。昨天咱們已經學習了一個數據共享Session了。
Web頁面跳轉和信息共享
.Servlet作用域對象
.動態網頁:JSP
請求轉發(forward)
需求:AServlet中沒有做完的事情跳轉到BServlet中繼續執行
語法:req.getRequestDispatcher(String path).forward(ServletRequest req,ServletResponse resp);
getRequestDispatcher : 獲得轉發器
path : 跳轉到哪里?
特點
-
轉發過程中瀏覽器地址欄路徑沒變
-
只發了一個請求
-
共享同一個請求(同一個請求對象),在請求中共享數據;
-
響應由最后一個決定
-
只能夠訪問當前應用中的資源,不能夠跨域跳轉(老師我想跳轉到源代碼官網去看視頻...)可以使用相對路徑,不推薦
-
可以訪問WEB-INF中的資源
-
從html頁面跳轉到Servlet需要先加上server.xml中的path(如果有),Servlet中的跳轉是不需要加的!
-
疑問: 既然可以訪問WEB-INF中的資源了,那怎么之前又說放在里安全呢?
a) 程序沒有提供的路徑就不能夠訪問;b) 在跳轉之前可以做權限判斷
URL重定向(redirect)
需求:AServlet中沒有做完的事情跳轉到BServlet中繼續執行
語法:resp.sendRedirect(String path);
特點: 測試下面每個點請留意瀏覽器地址欄!!!
-
瀏覽器中地址會變,相當於訪問了兩次
注意: path中應該加上server.xml中的path的值,如果有的話
-
發送了兩個請求
-
因為是不同的請求,所以不能夠共享請求中的數據
-
最終的響應是由最后一個Servlet決定
-
可以跨域訪問資源(嘗試訪問itsource.cn)
請求包含(include-不用)
需求:AServlet中沒有做完的事情跳轉到BServlet中繼續執行
語法:req.getRequestDispatcher(String path).include(ServletRequest req,ServletResponse resp);
特點: 基本上和forward一樣,只是把兩次響應的結果都輸出了
-
常見面試題:
1. 請求轉發forward和URL重定向的區別?
回答方式:
① 分別解釋各自的定義
② 羅列各自的特點(最好是表格對比)
③ 各自的使用場景(其實也是來源於特點)
2. 兩者如何選擇?
①如果需要共享請求中的數據,只能用請求轉發
②若要訪問WEB-INF中的資源 ,只能用請求轉發
③若要跨域訪問,只能用URL重定向
④請求轉發可能造成表單重復提交問題
-
數據共享與作用域對象
作用域對象意義;web組件之間傳遞和共享 數據 作用域經典案例(測試)
@WebServlet("/scope/main")
public class MainServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//request
if(req.getAttribute("count")==null){
req.setAttribute("count", 1);
}else{
req.setAttribute("count", ((Integer)(req.getAttribute("count"))+1));
}
//session
HttpSession session = req.getSession();
if(session.getAttribute("count")==null){
session.setAttribute("count", 1);
}else{
session.setAttribute("count", ((Integer)(session.getAttribute("count"))+1));
}
//application
ServletContext application = req.getServletContext();
if(application.getAttribute("count")==null){
application.setAttribute("count", 1);
}else{
application.setAttribute("count", ((Integer)(application.getAttribute("count"))+1));
}
req.getRequestDispatcher("result").forward(req, resp);
}
} -
-
-
@WebServlet("/scope/result")
public class ResultServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//request
int count1 = (Integer)request.getAttribute("count");
response.getWriter().println("request:"+count1);
//session
HttpSession session = request.getSession();
int count2 = (Integer)session.getAttribute("count");
response.getWriter().println("session:"+count2);
//application
ServletContext app = request.getServletContext();
int count3 = (Integer)app.getAttribute("count");
response.getWriter().println("application:"+count3);
}
}ServletContext對象
- 獲得ServletContext對象的方式:
super.getServletContext()
this.getServletContext()
getServletContext()
都是一樣的,提示我們這個方法是父類中的
ServletContext中的常用方法
String getContextPath():獲取當前應用的上下文路徑.
就是 Tomcat/conf/server.xml中的path值
String getRealPath(String path):獲取某個資源的絕對路徑.
例如獲得 : F:\workspace\servlet_jsp\webapp
String getInitParameter(String paramName);全局初始化參數:
先看傳統的Servlet的初始化參數:
因為配置在當前ServletContextDemo中,所以只能被ServletContextDemo使用,其他Servlet無法使用.
而在開發中,多個Web組件(Servlet/Filter)可以擁有共同的初始化參數,此時只能配置N次,不利於維護.
解決方案:使用全局的初始化參數,Web組件都可以共用,配置問web.xml文件中.
-
面試題1:
req.getParameter("")和req.getAttribute("")的區別?
req.getParameter :用戶傳過來的
req.getAttribute :從作用域里拿的(必需是放到作用域里的)
面試題2:
ServletConfig.getInitParameter
application.getInitParameter 有什么區別
ServletConfig.getInitParameter 只作為於一個Servlet
application.getInitParameter 整個應用都可以拿到
配置的不同
JSP原理分析(第一個JSP頁面) 一個jsp其實就是一個Servlet;
動態網頁:JSP
- Java Server Pages:Java的服務網頁(Java動態網頁)
-
從訪問方式來看:
html, 通過tomcat和直接訪問效果是一樣的
jsp 如果直接放在瀏覽器中顯示源碼,通過tomcat獲得是正常內容
jsp運行在服務器中
訪問方式 : http://localhost/xx/hellojsp/Hello.jsp
JSP三大指令
page指令: 設置當前JSP配置信息.
-
errorPage="/myerror.jsp" :如果當前頁面出錯,就跳轉到對應的頁面
isErrorPage="true" :這個頁面是否是錯誤頁面(當我們要在頁面上直接使用exception的時候就可以加上它)
演示1: 局部錯誤頁面跳轉
演示2: 全局錯誤頁面
在項目的web.xml中配置
include指令: JSP包含其他文件.
:taglib指令: 引人標簽庫.
JSP九大內置對象和四大作用域對象
application
JSP語法
- 注釋
- <!-- html注釋--> 直接寫html注釋,會輸出到頁面上讓用戶看到
- <%-- jsp注釋--%> 用戶從頁面上是看不到的
2.輸出數據到頁面 <%=hello%>
3. JSP中的Java腳本片段 <% 語句1;語句2;%>
4.定義類的成員<% String str; void testMethod(){} %>