HTML(HyperText Markup Language):超文本標記語言html
HTTP(HyperText Transfer Protocol):超文本傳輸協議java
URL(Uniform Resource Locator):統一資源定位符,以文字的方式來講明因特網上的資源如何取得。web
URN(Uniform Resource Name):表明某個資源獨一無二的名稱,如圖書的ISBN。apache
URI(Uniform Resource Identifier):URL和URN是URI的子集。api
一個簡單的html範例程序:瀏覽器
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>HTML範例</title> </head> <body> <form method="get" action="hello.do" name="sample"> 姓名: <input type="text" name="name"> <br /> <button>發送</button> </form> </body> </html>HTML學習資源: http://www.w3school.com.cn/html/index.asp
HTTP:指架構在TCP/IP之上應用層的一種協議。它的兩個特色:tomcat
一、無狀態(stateless)通訊協議。(無記憶性)服務器
二、基於請求(request)/響應(response)模型。cookie
客戶端對服務器發出一個取得資源的請求,服務器將要求的資源響應給客戶端,每次的聯機只做一次請求/響應,是一種很簡單的通訊協議,沒有請求就沒有響應。架構
在HTTP 協議下,服務器是個健忘的傢伙,服務器響應客戶端以後,就不會記得客戶端的信息,更不會去維護與客戶端有關的狀態,所以HTTP又稱爲無狀態的通訊協議。
瀏覽器在使用http發送請求,最重要的就是GET和POST。
GET:就是向服務器取得指定的資源。
POST請求:就是請求時發佈(POST)信息給服務器。
對於二者如何進行選擇?
一、get方式請求參數長度是有限的,過長的或者如文件上傳應該使用post請求。
二、get請求參數會出如今地址欄。
三、get請求純粹是爲了取得資源,而不改變服務器上的資源的狀態。而post相反。
對於java,JVM(java virtual machine)是java程序惟一認得的操做系統,其可執行文件爲.class文件。
對於JSP/Servlet,Web容器是JSP/Servlet惟一認得的http服務器。
URL編解碼:
import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; /** * Created by N3verL4nd on 2017/1/2. */ public class HelloWorld { public static void main(String[] args) throws UnsupportedEncodingException { System.out.println(URLEncoder.encode("http://www.baidu.com", "UTF-8")); System.out.println(URLDecoder.decode("%3A", "UTF-8")); } }URL編碼針對的字符是UTF-8編碼的8個位數值。
對於ascii字符使用1個字節,非ascii如中文使用3個字節。
import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; /** * Created by N3verL4nd on 2017/1/2. */ public class HelloWorld { public static void main(String[] args) throws UnsupportedEncodingException { System.out.println(URLEncoder.encode("我", "UTF-8")); System.out.println(URLDecoder.decode("%E6%88%91", "UTF-8")); } }HTTP規範下的URL編碼,並不限使用UTF-8,例如在一個BIG5網頁中,若窗體使用get發送中文,則是使用BIG5編碼的參數。
System.out.println(URLEncoder.encode("我", "BIG5"));
第一個Servlet程序(打印http header):
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; /** * Created by N3verL4nd on 2017/1/4. */ @WebServlet(name = "testServlet",urlPatterns = {"/test.do"}) public class testServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>TEST</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Hello World</h1>"); out.println("</body>"); out.println("</html>"); out.close(); } }
/test.do /Servlet /Servlet/test.do host:localhost:8080 connection:keep-alive upgrade-insecure-requests:1 user-agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate, sdch, br accept-language:zh-CN,zh;q=0.8 cookie:JSESSIONID=CDD8329D5BB881383911AC4CFAB4A159; Idea-e643fc73=b918ddfe-f8fa-43a0-b608-e1670a29b80a
@WebServlet(name = "testServlet",urlPatterns = {"/test.do"})這表示該Servlet名稱爲testServlet,當請求的URL是/test.do,如http://localhost:8080/Servlet/test.do就會由testServlet處理。
HttpServletRequest
表明請求對象,封裝了HTTP請求信息。
HttpServletResponse表明對客戶端的響應。
Servlet的編譯(需servlet-api.jar。位於D:\Tomcat\apache-tomcat-9.0.0.M15\lib):
一個簡易的Servlet程序對應的文件目錄結構以下:
E:\MyDocument\Desktop\jspRun\web\WEB-INF>tree /f 文件夾 PATH 列表 卷序列號爲 025427CF 32D1:7CF3 E:. │ web.xml │ ├─classes │ testServlet.class │ └─lib E:\MyDocument\Desktop\jspRun\web\WEB-INF> |
將web.war拷貝到webapps目錄下(D:\Tomcat\apache-tomcat-9.0.0.M15\webapps )
運行bin目錄下的startup.bat
servlet、genericservlet、httpservlet之間的關係:
package javax.servlet; import java.io.IOException; public interface Servlet { public void init(ServletConfig config) throws ServletException; public ServletConfig getServletConfig(); public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; public String getServletInfo(); public void destroy(); }
package javax.servlet; import java.io.IOException; import java.util.Enumeration; public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable { private static final long serialVersionUID = 1L; private transient ServletConfig config; public GenericServlet() { // NOOP } @Override public void destroy() { // NOOP by default } @Override public String getInitParameter(String name) { return getServletConfig().getInitParameter(name); } @Override public Enumeration<String> getInitParameterNames() { return getServletConfig().getInitParameterNames(); } @Override public ServletConfig getServletConfig() { return config; } @Override public ServletContext getServletContext() { return getServletConfig().getServletContext(); } @Override public String getServletInfo() { return ""; } @Override public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init() throws ServletException { // NOOP by default } public void log(String msg) { getServletContext().log(getServletName() + ": " + msg); } public void log(String message, Throwable t) { getServletContext().log(getServletName() + ": " + message, t); } @Override public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; @Override public String getServletName() { return config.getServletName(); } }
package javax.servlet.http; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; import java.text.MessageFormat; import java.util.Enumeration; import java.util.ResourceBundle; import javax.servlet.DispatcherType; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public abstract class HttpServlet extends GenericServlet { private static final long serialVersionUID = 1L; private static final String METHOD_DELETE = "DELETE"; private static final String METHOD_HEAD = "HEAD"; private static final String METHOD_GET = "GET"; private static final String METHOD_OPTIONS = "OPTIONS"; private static final String METHOD_POST = "POST"; private static final String METHOD_PUT = "PUT"; private static final String METHOD_TRACE = "TRACE"; private static final String HEADER_IFMODSINCE = "If-Modified-Since"; private static final String HEADER_LASTMOD = "Last-Modified"; private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings"; private static final ResourceBundle lStrings = ResourceBundle.getBundle(LSTRING_FILE); public HttpServlet() { // NOOP } protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_get_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); } else { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); } } protected long getLastModified(HttpServletRequest req) { return -1; } protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if (DispatcherType.INCLUDE.equals(req.getDispatcherType())) { doGet(req, resp); } else { NoBodyResponse response = new NoBodyResponse(resp); doGet(req, response); response.setContentLength(); } } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_post_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); } else { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); } } ... }Servlet接口:定義了Servlet應當有的基本行爲,全部的Servlet程序都必須實現Servlet接口(GenericServlet或者HttpServlet)。
GenericServlet:實現了Servlet接口,沒有規範任何與HTTP相關的方法,而是由繼承它的HttpServlet來定義。
HttpServlet的service方法流程:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) { long lastModified = getLastModified(req); if (lastModified == -1) { // servlet doesn't support if-modified-since, no reason // to go through further expensive logic doGet(req, resp); } else { long ifModifiedSince; try { ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); } catch (IllegalArgumentException iae) { // Invalid date header - proceed as if none was set ifModifiedSince = -1; } if (ifModifiedSince < (lastModified / 1000 * 1000)) { // If the servlet mod time is later, call doGet() // Round down to the nearest second for a proper compare // A ifModifiedSince of -1 will always be less maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } } } else if (method.equals(METHOD_HEAD)) { long lastModified = getLastModified(req); maybeSetLastModified(resp, lastModified); doHead(req, resp); } else if (method.equals(METHOD_POST)) { doPost(req, resp); } else if (method.equals(METHOD_PUT)) { doPut(req, resp); } else if (method.equals(METHOD_DELETE)) { doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) { doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) { doTrace(req,resp); } else { // // Note that this means NO servlet supports whatever // method was requested, anywhere on this server. // String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[1]; errArgs[0] = method; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); } }當請求到來時,容器會調用Servlet的service()方法。