tomcat和HTTP
1.tomcat的關閉和啟動
啟動:sudo /opt/tomcat/bin/startup.sh
關閉:sudo /opt/tomcat/bin/shutdown.sh
2.tomcat的文檔目錄結構
2.1.tomcat的文檔結構
tomcat根目錄下:
|-bin:存放tomcat的命令,例如啟動和關閉命令
|-conf:存放tomcat的配置信息,其中server.xml文件是核心的配置文件。
|-lib:支持tomcat運行的jar包,其中還有技術支持包,如servlet,jsp等
|-logs:運行過程的日志信息
|-temp:臨時目錄
|-work:tomcat的運行目錄。jsp運行時產生的臨時文件就存放在這里
|-webapps“共享資源目錄,web應用目錄(注意不能以單獨的文件進行共享,要以這個項目為一個整體來共享)
2.2.webapps的文檔目錄結構
WebRoot根目錄下:
靜態資源(html+css+js+image+vedio)
|-WEB-INF:固定寫法
|-WEB-INF/classes:(可選)固定寫法,存放class字節碼文件
|-WEB-INF/lib:(可選)固定寫法,存放jar包文件
|-WEB-INF/web.xml:配置文件
注意:
1.WEB-INF目錄里面的資源不能通過瀏覽器直接訪問
2.如果希望訪問到WEB-INF里面的資源,就必須把資源配置到一個叫web.xml的文件中
3.HTTP協議
3.1.GET和POST的區別
GET方式提交:
1.地址欄(URI)會跟上參數數據。以?開頭,多個參數之間用&分割
2.GET提交參數數據有限制,不超過1kb
3.GET方式不適合提交敏感信息,如密碼
4.注意:瀏覽器直接訪問的請求,默認提交方式是GET
POST方式提交:
1.參數不會跟着URI后面,而是跟在請求的實體內容中,沒有?開頭,多個參數之間使用&分割
2.POST提交的參數數據沒有限制
3.POST方式提交敏感數據
3.2.HttpServletRequest獲取請求數據
瀏覽器通過Http請求獲取數據信息,可是如果我們想獲取這個Http請求內的信息時用什么方法呢?
可以使用HttpServletRequest這里類,這個類是用在服務器端的。主要包含一下一個API
請求行:
request.getMethod();
請求方式
request.getRequetURI()/request.getRequetURL()
請求資源
request.getProtocol()
請求http協議版本
請求頭:
request.getHeader("名稱")
根據請求頭獲取請求值
request.getHeaderNames()
獲取所有的請求頭名稱
實體內容:
request.getInputStream()
獲取實體內容數據
代碼示例:
/**
* HttpServletRequest類方法的測試
*/
@WebServlet(name = "RequestServer")
public class RequestServer extends HttpServlet {
/**
* 這個類在創建的時候,服務器就已經幫我們做了下面兩件事情,所以我們只需要獲取就可以了
* 1.tomcat服務器接收到瀏覽器發送的請求數據,然后封裝到HttpServetRequest對象
* 2.tomcat服務器調用doGet方法,然后把request對象傳入到servlet中。
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 3.從reques對象取出請求數據
*/
//3.1請求行(GET /index HTTP/1.1)
RequestLine(request);
//3.2請求頭
RequestHeader(request);
//3.3請求的實體內容
RequestContent(request);
}
//3.1請求行
private void RequestLine(HttpServletRequest request) {
//請求的http協議
System.out.println("請求的http協議:"+request.getProtocol());
//請求的資源
System.out.println("請求的資源URI:"+request.getRequestURI());
System.out.println("請求的資源URL:"+request.getRequestURL());
//請求的方式
System.out.println("請求的方式:"+request.getMethod());
}
//3.2請求頭
private void RequestHeader(HttpServletRequest request) {
//根據頭名稱得到頭內容
System.out.println(request.getHeader("請求頭:"+"Host"));
//得到所有的請求頭名稱列表
Enumeration<String> enums = request.getHeaderNames();
while (enums.hasMoreElements()){
String headerName = enums.nextElement();
System.out.println("所有請求頭分別是:"+enums);
}
}
//3.3請求的實體內容
private void RequestContent(HttpServletRequest request) throws IOException {
InputStream in = request.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len=in.read())!=-1){
String str = new String(buf,0,len);
System.out.println(str);
}
}
}
3.3.如何獲取GET和POST的請求參數
GET方式:參數放在URI后面
POST方式:參數放在實體內容中
雖然位置不一樣,但是都是適用於同一個api方法。
request.getParameter("參數名");
根據參數名獲取參數值(注意,只能獲取一個值的參數)
request.getParameterValue("參數名“);
根據參數名獲取參數值(可以獲取多個值的參數)
request.getParameterNames();
獲取所有參數名稱列表
3.4.請求參數的編碼問題
由於請求參數的時候,方法會把編碼解碼,然后再編碼,這個過程會造成亂碼的現象。
為了解決這個問題,需要在doPost和doGet方法下先重新設置編碼格式,然后再讀取參數。
注意,重新設置編碼格式必須放在請求參數之前
修改POST方式參數編碼:
POST方式可以一鍵解碼
request.setCharacterEncoding("utf-8");
修改GET方式參數編碼:
GET解碼需要對每個請求重新編碼
手動解碼:String name = new String(name.getBytes("iso-8859-1"),"utf-8");
示例代碼:
/**
* 測試如何獲取GET和POST的請求參數
*/
@WebServlet(name = "RequestArgs")
public class RequestArgs extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收POST方式接收的參數
/*
System.out.println("POS提交的參數");
InputStream in = request.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len=in.read())!=-1){
System.out.println(new String(buf,0,len));
}
*/
//正確做法:統一方便的索取請求參數的方法
request.setCharacterEncoding("utf-8");
this.doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收GET方式提交的參數
/*
//笨方法
String value = request.getQueryString();
System.out.println(value);
*/
//正確做法:統一方便的索取請求參數的方法
//根據參數名得到參數值,只能獲取一個值的參數
String name = request.getParameter("name");//返回name參數值
//編碼
if ("GET".equals(request.getMethod())){
name = new String(name.getBytes("iso-8859-1"),"utf-8");
}
String passw = request.getParameter("passwd");//返回passwd參數值
if ("GET".equals(request.getMethod())){
passw = new String(passw.getBytes("iso-8859-1"),"utf-8");
}
System.out.println(name+"="+passw);
//根據參數名獲取多個同名參數
request.getParameterValues("hobit");
//得到所有的參數
Enumeration<String> enums = request.getParameterNames();
while (enums.hasMoreElements()){
String paramName = enums.nextElement();
String paramValue = request.getParameter(paramName);
if ("GET".equals(request.getMethod())){
paramValue = new String(paramValue.getBytes("iso-8859-1"),"utf-8");
}
System.out.println(paramName+"="+paramValue);
}
}
}
4.HTTP響應
4.1.狀態碼
每一個HTTP響應都有一個狀態碼來標識服務器處理這個請求的結果是什么樣的
常見的狀態碼有:
100~199:表示成功接收請求,要去客戶端繼續提交下一次請求才能完成整個處理過程
200~299:表示成功接收請求並完成整個處理過程,常用200表示請求完美處理,並返回
300~399:為完成請求,需進一步細化請求,例如請求的資源已經移動一個新的地址。常用302
400~499:客戶端的請求有錯誤,常用404表示請求的資源找不到
500~599:服務器出現錯誤
4.2.HttpServletResponse修改HTTP響應信息
HttpServletResponse對象修改響應信息:
響應行
response.setStatus()
設置狀態碼
響應頭
response.setHeader("name","value")
設置響應頭
實體內容
response.getWriter().writer();
發送字符實體內容
response.getOutputStream().writer()
發送字節實體內容
代碼示例:
/**
*測試 HttpServletResponse對象修改響應信息
*/
@WebServlet(name = "ResponseDemo")
public class ResponseDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
/**
* 在調用doGet方法之前,服務器已經做了一下操作
* 1.tomcat服務器把請求信息封裝到HttpServervletRequest對象,且把響應信息封裝到HttpServletResponse
* 2.tomcat服務器調用doGet方法,傳入request,response
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 3.通過response對象改變響應信息
*/
//3.1.響應行
// response.setStatus(404);//只修改狀態碼,不改變頁面
// response.sendError(404);//發送404狀態碼+404錯誤頁面
//3.2.響應頭
response.setHeader("server","JBos");//改變服務器類型
//3.3.實體內容(瀏覽器直接能夠看到的內容就是實體內容)
//方法1:
response.getWriter().write("hello World");//字符內容
//方法2:
response.getOutputStream().write("hello World".getBytes());//字節內容
}
/**
* 4.tomcat服務器把response對象內容自動轉換成響應格式內容,再發送給瀏覽器解析
*/
}
4.3.案例分析
請求重定向
/**
* 請求重定向
*/
@WebServlet(name = "RodirectDemo")
public class RodirectDemo extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 需求:跳轉到adv.html
* 使用請求重定向:發送一個302狀態碼+localtion的響應頭
*/
//方法1:
response.setStatus(302);
response.setHeader("location","/adv.html");
//方法2:
response.sendRedirect("/adv.html");
}
}
定時刷新
/**
* 定時刷新
*/
@WebServlet(name = "RefreshDemo")
public class RefreshDemo extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 定時刷新
* 原理:瀏覽器認識refresh頭,得到refresh頭之后重新請求當前資源
*/
//每隔1秒刷新一次
response.setHeader("refresh","1");
//每隔3秒跳轉到另外的資源
response.setHeader("refresh", "3;url=/adv.html");
}
}
content-Type作用
Content-Type: text/html; charset=GB2312 --表示服務器發送給瀏覽器的數據類型及內容編碼
/**
* content-Type作用
*/
@WebServlet(name = "ContentTypeDemo")
public class ContentTypeDemo extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 1.服務器發送給瀏覽器的數據類型
*/
response.setContentType("text/html");
//等價於上面,推薦使用上面的
response.setHeader("content-type","text/html");
response.setContentType("image/jpg");
}
}