Servlet與Jsp進階 學習

2020-08-13 08:40:02

思維導圖

在这里插入图片描述

導學

在之前的學習中,我們已經初步認識到什麼是Servlet和Jsp。那麼今天我們再來重新認識一下Servlet和Jsp,本節課需要掌握Java Web的核心特性(請求與響應的結構)、掌握Servlet的核心物件、Jsp九大內建物件(面試筆試中常遇到)等內容

HTTP請求的結構

請求是瀏覽器像伺服器發送的數據包,那麼在請求中其實是包含了三部分的內容的:請求行,請求頭,請求體。
在这里插入图片描述
請求行包括請求的方式,請求的地址,以及請求的HTTP版本
請求頭中,包括很多輔助的請求資訊,能爲請求處理提供額外的支援。
資料(關於請求頭與響應頭):https://www.cnblogs.com/xjcjcsy/p/6135006.html
請求體中,描述了請求的參數內容。注意一下,get請求是將參數寫入URL中,所以get請求是沒有請求體的,只有post請求纔有請求體。

/**
 * Servlet implementation class MethodServlet
 */
@WebServlet("/method")
public class MethodServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public MethodServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().println("This is Get method");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().println("This is Post method");
	}

}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/MyJsp/method" method="get">
		<input name="userName"/>
		<input name="password" type="password"/>
		<input type="submit"/>
	</form>
</body>
</html>

在这里插入图片描述
在这里插入图片描述

利用請求頭開發多端應用

早期的程式,基本都是執行的在電腦上的,我們編寫頁面的時候只要考慮電腦端的情況就可以了。但是隨着個人裝置越來越多,我們需要考慮的顯示裝置也越來越多,那麼我們該如何去嘗試着在Java中進行多種裝置的考量呢?這個時候我們就可以利用請求頭進行判斷分析

/**
 * Servlet implementation class UserAgentServlet
 */
@WebServlet("/useragent")
public class UserAgentServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public UserAgentServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String userAgent = request.getHeader("User-Agent");//獲取請求頭資訊
		response.setContentType("text/html;charset=utf-8");//設定伺服器端響應的編碼方式以及內容解析方式
		response.getWriter().println(userAgent);
		String output = "";
		if(userAgent.indexOf("Windows NT") != -1) {
			output = "<h1>這是PC端</h1>";
		} else if(userAgent.indexOf("iPhone") != -1 ||userAgent.indexOf("Android") != -1 ){
			output = "<h1>這是手機端</h1>";
		}
		response.getWriter().println(output);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

響應的結構

HTTP響應包含三部分:響應行、響應頭、響應體
在这里插入图片描述
HTTP常用狀態碼:
在这里插入图片描述

ContentType的作用

ContentType決定瀏覽器採用何種的方式對響應體進行處理。
在这里插入图片描述

/**
 * Servlet implementation class ContentTypeServlet
 */
@WebServlet("/contenttype")
public class ContentTypeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ContentTypeServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String output = "<h1><a href='www.baidu.com'><span>百度</span></a></h1>";
		/*response.setContentType("text/html;charset=utf-8");*/
		/*response.setContentType("text/plain;charset=utf-8");*///輸出純文字
		/*response.setContentType("text/xml;charset=utf-8");*/
		response.setContentType("application/x-msdownload;charset=utf-8");
		response.getWriter().println(output);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

請求轉發與重定向

在之前的學習中,都是通過一個servlet來完成的程式處理,但在真正的開發中,需要多個servlet進行組合呼叫。從A servlet到B servlet,完成一場「傳值的遊戲」。那麼從A到B之間,如何進行通訊和跳轉呢?
對於多個servlet和jsp之間跳轉有兩鐘方式:

  1. 請求轉發:request.getRequestDispatcher(path).forword(request,response)
  2. 響應重定向:response.sendRedirect(Contextpath工程名稱/對映地址);

區別:
請求轉發是不會改變一開始存取的對映地址
響應重定向是會改變到最後請求的對映地址

請求轉發與重定向的使用

@WebServlet("/direct/index")
public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public IndexServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().println("This is index page");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

/**
 * 使用者校驗頁面
 * @author LiXinRong
 *
 */
@WebServlet("/direct/check")
public class CheckLoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public CheckLoginServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("使用者登錄成功");
		//請求.請求觸發器.轉發->瀏覽器位址列不會發生改變
		request.getRequestDispatcher("/direct/index").forward(request, response);
        //響應重定向需要增加contextPath->瀏覽器位址列會發生改變
		response.sendRedirect("/sd/direct/index");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

轉發時,是在伺服器內部由第一個servlet跳轉到新的servlet。而轉發是在伺服器處理完第一個servlet後,通知瀏覽器,由瀏覽器再發送一個請求給伺服器的新的servlet。

請求轉發與重定向的原理

雖然請求轉發與重定向都是用於地址的跳轉,但是它們兩個在本質上是完全不一樣的。
請求轉發
請求轉發是在伺服器內部進行跳轉,轉發呼叫的是HttpServletRequest物件中的方法以及轉發時瀏覽器只請求一次伺服器,位址列的url不會發生變化。
在这里插入图片描述
在進行請求轉發時,允許建立自定義屬性。
設定請求屬性:

request.setAttribute(屬性名,屬性值)

獲取請求屬性:

Object attr = request.getAttribute(屬性名)
@WebServlet("/direct/check")
public class CheckLoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public CheckLoginServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("使用者登錄成功");
		request.setAttribute("name", "Jack");
		//請求.請求觸發器.轉發->瀏覽器位址列不會發生改變
		request.getRequestDispatcher("/direct/index").forward(request, response);
		//響應重定向需要增加contextPath
		/*response.sendRedirect("/sd/direct/index");*/
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}
@WebServlet("/direct/index")
public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public IndexServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String name = (String)request.getAttribute("name");
		System.out.println(name);
		System.out.println("index page");
		request.getRequestDispatcher("/direct/index2").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}
@WebServlet("/direct/index2")
public class IndexServlet2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public IndexServlet2() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String name = (String)request.getAttribute("name");
		System.out.println(name);
		System.out.println("index page2");
		request.getRequestDispatcher("/direct/index3").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}
@WebServlet("/direct/index3")
public class IndexServlet3 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public IndexServlet3() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String name = (String)request.getAttribute("name");
		System.out.println(name);
		System.out.println("index page3");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

在servlet中定義的屬性,可以通過請求轉發一直傳遞下去。
重定向
重定向則是瀏覽器端跳轉,會產生兩次請求。
在这里插入图片描述
重定向的時候不會去傳遞屬性。
注意:

  1. 如果需要攜帶數據到要跳轉的介面,建議使用轉發。位址列不會改變。
  2. 如果不需要攜帶數據到要跳轉的介面,建議使用重定向。位址列會改變

Cookie與Session

Cookie

Cookie(小甜餅)是瀏覽器儲存在原生的文字內容,cookie常用於儲存登錄狀態,使用者資料等小文字。cookie是具有時效性的,有效的cookie內容會伴隨着請求發送給Tomcat。比如我們可以使用cookie儲存使用者的登錄資訊,這樣在一定時長內,使用者就可以一直保持登錄狀態了。
在这里插入图片描述
該檔案開啓是一堆亂碼,這是因爲這個檔案往往包含敏感數據,所以瀏覽器對此進行了加密。
在这里插入图片描述
設定Cookie

@WebServlet("/cookies/lg")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public LoginServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("使用者登錄成功");
		//設定使用者七天內保持登錄
		Cookie cookie = new Cookie("user","admin");
        cookie.setMaxAge(60*60*24*7);
		response.addCookie(cookie);
		response.getWriter().println("login success");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

若不設定有效期,則cookie有效期爲當前瀏覽器視窗,若視窗關閉,則cookie清空
在这里插入图片描述
讀取cookie

@WebServlet("/cookies/is")
public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public IndexServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Cookie[] cs = request.getCookies();//用於獲取所用的使用者資訊
		String user = null;
		for(Cookie c :cs) {
			System.out.println(c.getName() + ":" + c.getValue());
			if(c.getName().equals("user")) {
				user = c.getValue();
				break;
			}
		}
		if(user == null) {
			response.getWriter().println("user not login");
		} else {
			response.getWriter().println("user:" + user);
		}
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

注意cookie是作用於本目錄及其子目錄,如果發送cookis那個檔案的對映地址是/cookies/login,那麼想要獲取的那個也必須是/cookies/xx

@WebServlet("/cookie/is")//該地址獲取不到對應的cookie
public class IndexServlet2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public IndexServlet2() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Cookie[] cs = request.getCookies();//用於獲取所用的使用者資訊
		String user = null;
		for(Cookie c :cs) {
			System.out.println(c.getName() + ":" + c.getValue());
			if(c.getName().equals("user")) {
				user = c.getValue();
				break;
			}
		}
		if(user == null) {
			response.getWriter().println("user not login");
		} else {
			response.getWriter().println("user:" + user);
		}
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

session

cookie是儲存在我們原生的數據,但是這個數據不一定可靠,儲存在本地遲早會被破解,而且設定cookie之後,每次發送請求都會攜帶cookie,增加了瀏覽器的頻寬負擔。於是,我們有了一個新的解決方案session,用於將數據儲存在伺服器上。
session特點:

  1. Sesstion(使用者對談)用於儲存"瀏覽器視窗"對應的數據
  2. Session的數據儲存在Tomcat伺服器的記憶體中,具有時效性(無人存取時長爲30分鐘)
  3. Session通過瀏覽器Cookie的SessionId(瀏覽器的session識別碼)值提取用戶數據,每個瀏覽器的SessionId都不一樣。
@WebServlet("/session/sl")
public class SessionLoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public SessionLoginServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("使用者登錄成功");
		//獲取使用者對談session
		HttpSession session = request.getSession();
		session.setAttribute("name", "張三");
		String sessionId = session.getId();
		System.out.println(sessionId);
		request.getRequestDispatcher("/session/id").forward(request,response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
@WebServlet("/session/sil")
public class SessionIndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public SessionIndexServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		String sessionId = session.getId();
		System.out.println(sessionId);
		String name = (String)session.getAttribute("name");
		response.setContentType("text/html;charset=utf-8");//設定返回內容解碼方式
		response.getWriter().println("這是首頁,當前使用者爲:" + name);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
session使用的原理

session 物件是由伺服器自動建立的與使用者請求相關的物件。伺服器爲每個使用者都生成一個session物件,用於儲存該使用者的資訊,跟蹤使用者的操作狀態,伺服器建立的每個session物件互不幹 不乾涉。session是對談級別的變數,我們一般使用 session 處理使用者的登陸資訊。
簡單的理解,開啓一個瀏覽器,無論你開啓多少標籤頁, 用 session 儲存的變數都會存在,除非使用 session.removeAttribute() 將其顯式銷燬。
其實可以將session看做在Tomcat中儲存的與用戶端瀏覽器視窗系結的數據儲存空間。在使用的時候只需要使用setAttribute和getAttribute進行存值和取值即可。但是在底層卻不是簡單,是如何實現的呢?
當瀏覽器第一次建立session物件的時候會tomcat會在記憶體空間中開闢一個空間存放session數據,並且給session空間一個sessionid,tomcat在返迴響應數據的時候會把sessionid一起返回給瀏覽器,瀏覽器把sessionid儲存在cookie中,之後從瀏覽器傳送過來的數據都通過sessionid來查詢session的位置來儲存數據。
在这里插入图片描述
session在工程的使用是非常廣泛的,最常用的就是根據session可以與瀏覽器對應的原理,用於儲存每個使用者的登錄資訊。

ServletContext

ServletContext(Servlet上下文物件),是web應用的上下文物件。在一個Web應用程式中只會存在一個ServletContext物件,該物件在Tomcat啓動的時候建立,在Tomcat關閉的時候銷燬。
在这里插入图片描述
類似於這種網站備案資訊和版權資訊,會顯示於整個網站全域性,這個時候我們就可以使用ServletContext這種全域性物件來進行設定。

@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public ServletContextInitServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//獲取應用程式上下文物件,其實也就是應用程式物件
		ServletContext sc = request.getServletContext();
		//利用該物件的特性,設定作用範圍爲全域性的自定義屬性
		sc.setAttribute("copyright", "Powered by EduSoho v8.6.4 ©2014-2020 課程存檔 \n課程內容版權均歸 南通在渡教育諮詢有限公司 所有 蘇ICP備18015371號");
		//sc.setAttribute("copyright","");如果設定了相同的屬性名,則新的屬性值會覆蓋舊的屬性值,其他設定request自定義屬性和session自定義屬性也是相同的道理
		sc.setAttribute("title", "渡課IT教育");
		response.getWriter().println("init success");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}
@WebServlet("/servletcontext/defualt")
public class ServletContextDefaultServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public ServletContextDefaultServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext sc = request.getServletContext();
		String copyright = (String)sc.getAttribute("copyright");
		String title = (String)sc.getAttribute("title");
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().println("<h1>" + title + "</h1>" + copyright);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

}

Java Web三大作用域

  • HttpServletRequest -請求物件
  • HttpSession - 使用者對談物件
  • ServletContext - web應用全域性物件

這三個物件的作用域,從上到下是依次遞增的。
請求物件,它的生命週期最短,當瀏覽器發送請求到Tomcat,則請求物件就被建立,當servlet處理完成並返迴響應到瀏覽器時,當前的請求物件就會被銷燬。
使用者對談物件用於儲存與瀏覽器視窗對應的數據,該物件是在使用者第一次向瀏覽器發送請求的時候被建立,預設情況下,這個物件如果在三十分鐘後沒有存取就會被銷燬。注意一下,關閉瀏覽器該物件不會被銷燬,銷燬的是儲存在瀏覽器cookie中的sessionId。就好像銀行卡與存在銀行中的錢一樣,丟失了銀行卡,但是銀行中的錢還在,只是取不出來這筆錢而已。
全域性物件在web應用啓動的時候就被建立了,只有在web應用程式關閉或重新啓動的時候纔會被銷燬。
有個注意點,爲了程式維護的需要和資源避免浪費的情況,如果能用小作用域完成的任務就不用大作用域完成,所以request請求物件是以後使用的最多的物件

中文亂碼

中文亂碼的核心就是解析字元集不支援中文,所以解決中文亂碼的關鍵就是將預設字元集變成UTF-8,servlet中的請求與響應都需要設定爲UTF-8。

Post請求中文亂碼

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/servlet_advanced/charset/process" method="post">
		姓名:<input name="ename">
		地址:<input name="address">
		<input type="submit" value="提交">
	</form>
</body>
</html>
@WebServlet("/charset/process")
public class CharsetServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public CharsetServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//request.setCharacterEncoding方法用於將請求體中的字元集轉換爲UTF-8,對於get請求,沒有請求體,所以該方法只對post請求生效。
		request.setCharacterEncoding("UTF-8");
		String ename = request.getParameter("ename");
		String address = request.getParameter("address");
		System.out.println(ename + ":" + address);
		//通過字串構造器將字串的解析字元集轉換爲utf-8,但是不怎麼方便,所以使用setCharacterEncoding方法
		//String utf8Ename = new String(ename.getBytes("iso-8859-1") , "utf-8");
		//String utf8Address = new String(address.getBytes("iso-8859-1") , "utf-8");
		//System.out.println(utf8Ename + ":" + utf8Address);
	}

}

Get請求與響應中文亂碼

@WebServlet("/charset/process")
public class CharsetServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public CharsetServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//對於Tomcat8.x的版本,預設get請求發送中文就是UTF-8的格式,因此無需轉換
		String ename = request.getParameter("ename");
		String address = request.getParameter("address");
		System.out.println(ename + ":" + address);
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().println(ename + ":" + address);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

web.xml的常用設定

在本章節中,我們將做到以下功能:

  • 修改web應用預設首頁
  • Servlet萬用字元對映及初始化參數
  • 設定404,500等狀態碼首頁

修改web應用預設首頁

<welcome-file-list>
	<!-- 指定預設首頁,二級目錄下的頁面也可以作爲預設首頁,使用的時候需要在地址後面注意加/ -->
    <welcome-file>index.html</welcome-file>
    <welcome-file>default.html</welcome-file>
  </welcome-file-list>

萬用字元對映,利用地址傳參(非get提交)

public class PatternServlet extends HttpServlet{

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//查詢員工的基本資訊
		//獲取當前存取的URL
		String url = request.getRequestURL().toString();
		System.out.println(url);
		String id = url.substring(url.lastIndexOf("/") + 1);
		int eid =  Integer.parseInt(id);
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println(id);
		if(eid == 1) {
			out.println("張三");
		}else if(eid == 2) {
			out.println("李四");
		}else {
			out.println("其他員工");
		}
		
	}
	
}
<servlet>
  	<servlet-name>patternServlet</servlet-name>
  	<servlet-class>com.dodoke.servlet.pattern.PatternServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>patternServlet</servlet-name>
	<!-- 使用*作爲萬用字元,指的是pattern/後面不管是什麼地址,都會被該servlet攔截請求 -->
  	<url-pattern>/pattern/*</url-pattern>
  </servlet-mapping>

設定全域性參數
在之前的學習中,我們在設定網站備案資訊和版權資訊時,是將內容寫死在程式中的,這其實對我們的程式來說不算友好,現在我們可以嘗試着將這些全域性資訊寫入到組態檔中。

<context-param>
  	<param-name>copyright</param-name>
  	<param-value>Powered by EduSoho v8.6.4 ©2014-2020 課程存檔 \n課程內容版權均歸 南通在渡教育諮詢有限公司 所有 蘇ICP備18015371號</param-value>
  </context-param>
  <context-param>
  	<param-name>title</param-name>
  	<param-value>渡課IT教育</param-value>
  </context-param>
@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public ServletContextInitServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext context = request.getServletContext();
		//獲取ServletContext物件通過組態檔設定的初始化參數
		String copyright = context.getInitParameter("copyright");
		context.setAttribute("copyright", copyright);
		String title = context.getInitParameter("title");
		context.setAttribute("title", title);
		response.getWriter().println("init success");
	}

}

設定404,500等狀態碼首頁

<!-- 指定錯誤頁面 -->
  <error-page>
  	<error-code>404</error-code>
  	<location>/error/404.html</location>
  </error-page>
  <error-page>
  	<error-code>500</error-code>
  	<location>/error/500.jsp</location>
  </error-page>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	資源不存在
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	伺服器內部錯誤,請聯繫管理員 
</body>
</html>

JSP九大內建物件

內建物件,又叫做隱含物件,不需要預先宣告就可以在指令碼程式碼和表達式中隨意使用

  1. 由JSP規範提供,不用編寫者範例化。
  2. 通過Web容器實現和管理
  3. 所有JSP頁面均可使用
  4. 只有在指令碼元素的表達式或程式碼段中纔可使用

在这里插入图片描述

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		String url = request.getRequestURL().toString(); // HttpServletRequest
		response.getWriter().println(url);//HttpServletResponse
	%>
	<% out.println("<br>ABCCC"); 
		session.setAttribute("user", "張三");
		out.println((String)session.getAttribute("user"));
	%>
	<%
		String cp = application.getInitParameter("copyright") ; //ServletContext
		out.println("<hr/>");
		out.println(cp);
		//pageContext可以幫助我們快速獲取其他物件
		pageContext.getRequest();
		pageContext.getResponse();
		pageContext.getSession();
		pageContext.getServletContext();
	%>
</body>
</html>

利用exception物件顯示錯誤資訊。

<!-- isErrorPage表示該頁面專門用於顯示錯誤 -->
<%@ page contentType="text/html;charset=utf-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	伺服器內部錯誤,請聯繫管理員 ,錯誤資訊如下:
	<%
		String msg = exception.getMessage();
		out.print("<br>" + exception.getClass().getSimpleName() + ":" + msg);
	%>
</body>
</html>

Java Web的打包與發佈

在編寫完成程式碼後,就需要正式的進行程式的上線了,那麼我們該如何進行程式的上線呢?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
直接將這樣的war包,儲存到Tomcat的webapp目錄中,啓動Tomcat就可以了。
注意:

  • 埠可以改爲80,避免輸入埠號
  • 專案路徑可以只保留斜槓,避免輸入專案路徑
  • 在这里插入图片描述