Servlet的生命週期方法
通過Log輸出的方式,查看Servlet的生命週期方法,下面模擬發起的是get請求
public class ServletTest01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
resp.getWriter().write("this is a pig...........");
System.out.println("---doGet------wyk--->");
}
@Override
public void init() throws ServletException {
System.out.println("----init--wyk>");
super.init();
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
resp.getWriter().write("this is a test demo");
System.out.println("----service--wyk>");
super.service(req, resp);
}
@Override
public void destroy() {
System.out.println("----destroy--wyk>");
super.destroy();
}
}
輸出結果
----init--wyk>
----service--wyk>
---doGet------wyk--->
----destroy--wyk>
可以得知執行順序: init—–>service—–>doGet——>destroy
生命週期方法的職責:
方法 | 作用 |
---|---|
init | Servlet被創建的時候調用 |
service | 每次請求過來會被調用,將請求進行分發,將請求傳遞給doGet()或doPost()或者其他請求方法 |
destroy | Servlet被移除出服務器的時候調用 |
HttpRequest
1.獲取請求信息
public class MyHttpServlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod(); //請求方式
String uri = req.getRequestURI(); //請求資源
String protocol = req.getProtocol(); //協議版本
System.out.println("請求行:--請求方式---->" + method + "--請求資源---->" +uri + "--協議版本--->" +protocol);
//獲取請求頭信息
Enumeration<String> requestHeaders = req.getHeaderNames();
for(;requestHeaders.hasMoreElements();){
String name = requestHeaders.nextElement();
String header = req.getHeader(name);
System.out.println("------請求頭信息------>" + name +"-----value--"+header);
}
// 打印的信息:
//
// --請求方式---->GET--請求資源---->/HelloWorld/MyHttpServlet--協議版本--->HTTP/1.1
// ------請求頭信息------>host-----value--localhost:8080
// ------請求頭信息------>user-agent-----value--Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
// ------請求頭信息------>accept-----value--text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
// ------請求行信息------>accept-language-----value--zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
// ------請求頭信息------>accept-encoding-----value--gzip, deflate
// ------請求頭信息------>connection-----value--keep-alive
// ------請求頭信息------>upgrade-insecure-requests-----value--1
}
}
2.通過請求頭獲取用戶目前使用的瀏覽器類型
public class MyHttpServlet02 extends HttpServlet{
/**
* 注意:contains("") 區分字母大小寫的
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String user_agent = req.getHeader("user-agent");
if(user_agent.contains("chrome")){
System.out.println("谷歌");
}
if(user_agent.contains("ie")){
System.out.println("IE瀏覽器");
}
if(user_agent.contains("Firefox")){
System.out.println("火狐");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req,resp);
}
}
3.防盜鏈功能
public class MyHttpServlet03 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//setContentType():修改response(默認碼錶爲iso8859-1)默認的碼錶,
//但如果輸出中文,瀏覽器可能還是亂碼,
//因爲並沒告訴瀏覽器用哪種碼錶解碼,所以瀏覽器還是使用了默認的碼錶,
//下面的api可以解決這一問題
//response.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=UTF-8");
PrintWriter writer = resp.getWriter();
String header = req.getHeader("referer");
if(header=="" || header.contains("ad.html")){
writer.write("下載中...");
}else{
writer.write("非官方鏈接下載,無效!!!");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
4.使用緩存
/**
* 如果Servlet的代碼需要使用緩存,那麼一定要重寫getLastModified方法
* 進到HttpServlet的源碼裏看Service方法,可以看到doGet和doPost就是在service方法進行判斷調用的,
* 在裏面可以看到當請求方式爲get的時候,會去判別是否使用瀏覽器的緩存,
* 可以看到是否使用緩存的關鍵點是getLastModified這個方法,而這個getLastModified方法的默認返回值爲-1,
* 所以如果我們需要用到緩存,那麼就需要重寫getLastModified這個方法來獲取服務端文件的最近修改時間去返回,
* 這樣當get請求的時候,纔可能用到瀏覽器的緩存
*
* 如果請求的是一個靜態頁面,一般情況下瀏覽器會使用緩存的;
* 動態web資源除了get請求以外,其他都不使用緩存的,而Servlet的get請求默認也是不使用緩存的
*/
public class MyHttpServlet04 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
FileInputStream inputStream = new FileInputStream("D:\\ddd.txt");
OutputStream outputStream = response.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=inputStream.read(buf))!=-1){
outputStream.write(buf,0,len);
}
inputStream.close();
}catch(Exception ex){
//
}
System.out.println("========請求服務端資源成功=========");
}
@Override
protected long getLastModified(HttpServletRequest req) {
File file = new File("D:\\ddd.txt");
return file.lastModified();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
HttpResponse
1.通過響應頭告知瀏覽器要以下載的方式處理文件
public class DownLoadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
File file = new File("d:\\yh.png");
System.out.println("====Name===>" + file.getName());
//可以從瀏覽器拿到的響應頭 看到 content-disposition: attachment;filename=yh.png(content設置:附件、文件名)
// response.setHeader("content-disposition","attachment");通知瀏覽器以文件下載的形式處理
//文件下載的時候對文件名稱進行URL編碼,使用utf-8,各大廠商定的規則
response.setHeader("content-disposition","attachment;filename="+URLEncoder.encode(file.getName(),"utf-8"));
OutputStream outputStream = response.getOutputStream();
FileInputStream inputStream = new FileInputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while((len=inputStream.read(buf))!=-1){
outputStream.write(buf,0,len);
}
inputStream.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
2.將文件進行壓縮後輸出到瀏覽器
public class GzipServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//告訴瀏覽器我傳輸給你的文件是gzip壓縮的,先解壓再顯示
resp.setHeader("content-encoding", "gzip");
OutputStream outputStream = resp.getOutputStream();
StringBuilder builder = new StringBuilder();
for(int i=0;i<150;i++){
builder.append("abcde" + i);
}
System.out.println("----No Gzip---->" + builder.toString().length()); //1090
//壓縮之後,通過谷歌瀏覽器的請求頭信息查看大小是310
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
gzipOutputStream.write(builder.toString().getBytes());
gzipOutputStream.finish();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
3.設置響應頭,讓其重定向,頁面重新跳轉
public class LocationServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*response.setStatus(302); //302是重定向;
response.setHeader("location","/HelloWorld/ad.html");*/
response.sendRedirect("/HelloWorld/ad.html"); //該代碼==上面的兩句
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
4.通知瀏覽器不要產生緩存文件
/**
* Expires: -1 --不緩存
* Cache-Control: no-cache --不緩存
* Pragma: no-cache --不緩存
*/
public class NoCacheServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//不同瀏覽器所需要的頭不一樣, 凡是涉及到密碼的頁面信息都不要產生緩存文件,
//容易造成信息外泄。(所以三種都寫)
response.setHeader("Expires", "-1");
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma", "no-cache");
//response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("當前的系統時間==" + System.currentTimeMillis());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
5.設置瀏覽器定時刷新或跳轉
public class RefreshServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//response.setHeader("refresh", "1"); //告知瀏覽器,每秒刷新一次
response.setHeader("refresh","3;url=/HelloWorld/index.jsp");//指定秒數,然後定時跳轉
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
補充
get和post請求方式的區別
1.get的數據攜帶在Url後面,post的數據則在實體內容;
2.get攜帶的數據信息不可大於1kb,post則無限制;
3.get不能用於提交敏感數據,post可用於提交敏感數據;
4.get提交方式會產生緩存文件,post提交方式不會產生緩存文件