日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java Web 学习与总结(一)Servlet基础

發(fā)布時(shí)間:2023/11/30 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java Web 学习与总结(一)Servlet基础 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

配置環(huán)境:https://www.cnblogs.com/qq965921539/p/9821374.html

簡介:

  Servlet是Sun公司提供的一種實(shí)現(xiàn)動態(tài)網(wǎng)頁的解決方案,在制定J2EE時(shí)引入它作為實(shí)現(xiàn)了基于Java語言的動態(tài)技術(shù),目前流行的Web框架基本都基于Servlet技術(shù),只有掌握了Servlet,才能真正掌握J(rèn)ava Web編程的核心和精髓。

  Servlet是運(yùn)行在Servlet容器中的Java類,它能處理Web客戶的HTTP請求,并產(chǎn)生HTTP響應(yīng)。

  Servlet對請求的處理和響應(yīng)過程可進(jìn)一步細(xì)分為以下幾個(gè)步驟:

    1.接收HTTP請求

    2.取得請求信息,包括請求頭和請求參數(shù)數(shù)據(jù)

    3.調(diào)用其它Java類方法,完成具體的業(yè)務(wù)功能

    4.實(shí)現(xiàn)到其他Web組件的跳轉(zhuǎn)(包括重定向或請求轉(zhuǎn)發(fā))

    5.生成HTTP響應(yīng)(包括HTML或非HTML響應(yīng))

?

優(yōu)點(diǎn):

  Servlet有以下幾個(gè)優(yōu)點(diǎn):

    1.高效,在Servlet中,每個(gè)請求由一個(gè)輕量級的java線程處理;

    2.方便,提供了大量實(shí)用工具例程,這個(gè)在后面會慢慢敘述;

    3.功能強(qiáng)大,繼承了Java的優(yōu)點(diǎn),能夠直接和Web服務(wù)器交互,還能夠在各個(gè)程序之間共享數(shù)據(jù);

    4.可移植性好,Servlet由Java語言編寫,并且其API具有完善的標(biāo)準(zhǔn),支持Servlet規(guī)范的容器都可以運(yùn)行Servlet程序,如Tomcat和Resin等。

Servlet體系結(jié)構(gòu):

  Servlet是使用Servlet API及相關(guān)類和方法的Java程序,Servlet API包含兩個(gè)軟件包:

    javax.servlet包:包含支持所有協(xié)議的通用的Web組件接口和類,如ServletRequest接口,ServletResponse接口

    javax.servlet.http包:包含支持HTTP協(xié)議的接口和類,如HttpServletRequest接口,HttpServletResponse接口

  Servet API的主要接口和類之間的關(guān)系為:

    

Servlet接口:

  所有的Servlet都必須直接或間接地實(shí)現(xiàn)javax.servlet.Servlet接口。Servlet接口規(guī)定了必須由Servlet類實(shí)現(xiàn)并且由Servlet引擎識別和管理的方法集。Servlet接口的基本目標(biāo)是提供與Servlet生命周期相關(guān)的方法,如init(),service()和destory()等,下述示例為Servlet接口的源代碼:

1 package javax.servlet; 2 3 import java.io.IOException; 4 5 public interface Servlet { 6 void init(ServletConfig var1) throws ServletException; 7 8 ServletConfig getServletConfig(); 9 10 void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; 11 12 String getServletInfo(); 13 14 void destroy(); 15 }

  1.init(),初始化servlet對象,Servlet實(shí)例化后,容器調(diào)用該方法進(jìn)行初始化工作。ServletAPI規(guī)定該方法只能被調(diào)用一次,如果此方法沒有正常結(jié)束就會拋出一個(gè)ServletException異常,一旦拋出該異常,Servlet將不再執(zhí)行。

  2.service(ServletRequest var1, ServletResponse var2),接受客戶端請求對象,執(zhí)行業(yè)務(wù)操作,利用響應(yīng)對象響應(yīng)客戶端請求。

  3.destroy(),當(dāng)容器監(jiān)測到一個(gè)servlet從服務(wù)中被移除時(shí),容器調(diào)用該方法,釋放資源,調(diào)用該方法前必須給service()足夠時(shí)間來結(jié)束執(zhí)行。

  4.getServletConfig(),ServletConfig是容器向servlet傳遞參數(shù)的載體,此方法可以讓Servlet在任何時(shí)候獲得ServletConfig對象。

  5.getServletInfo(),返回一個(gè)String對象獲取servlet相關(guān)信息。

GenericServlet類:

  GenericServlet類是一個(gè)抽象類,是Servlet接口的直接實(shí)現(xiàn),除service()方法之外還提供了其他有關(guān)Servlet生命周期的方法。這意味著只需通過簡單地?cái)U(kuò)展GenericServlet和實(shí)現(xiàn)servlet方法就可以編寫一個(gè)基本的Servlet。

1 package javax.servlet; 2 3 import java.io.IOException; 4 import java.io.Serializable; 5 import java.util.Enumeration; 6 7 public abstract class GenericServlet implements Servlet, ServletConfig, Serializable { 8 private static final long serialVersionUID = 1L; 9 private transient ServletConfig config; 10 11 public GenericServlet() { 12 } 13 14 public void destroy() { 15 } 16 17 public String getInitParameter(String name) { 18 return this.getServletConfig().getInitParameter(name); 19 } 20 21 public Enumeration<String> getInitParameterNames() { 22 return this.getServletConfig().getInitParameterNames(); 23 } 24 25 public ServletConfig getServletConfig() { 26 return this.config; 27 } 28 29 public ServletContext getServletContext() { 30 return this.getServletConfig().getServletContext(); 31 } 32 33 public String getServletInfo() { 34 return ""; 35 } 36 37 public void init(ServletConfig config) throws ServletException { 38 this.config = config; 39 this.init(); 40 } 41 42 public void init() throws ServletException { 43 } 44 45 public void log(String msg) { 46 this.getServletContext().log(this.getServletName() + ": " + msg); 47 } 48 49 public void log(String message, Throwable t) { 50 this.getServletContext().log(this.getServletName() + ": " + message, t); 51 } 52 53 public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; 54 55 public String getServletName() { 56 return this.config.getServletName(); 57 } 58 }

  init(ServletConfig config:該方法來源于Servlet接口,覆寫該方法,必須調(diào)用super.init(config)

  init():該方法重載Servlet.init(ServletConfig config)方法而無需調(diào)用super.init(config)。而ServletConfig對象依然可以通過調(diào)用getServletConfig()方法獲得。

  destory()方法作用與Servlet接口中的方法相同,略。

  getInitParameter():返回一個(gè)包含初始化變量的值的字符串,如果變量不存在則返回null,該方法從servlet的ServletConfig變量獲得命名變量的值。

  getInitParameterNames():該方法返回一個(gè)包含所有初始化變量的枚舉函數(shù)。如果沒有初始化變量,則返回一個(gè)空枚舉函數(shù)。

  getServletConfig():返回一個(gè)servlet的ServletConfig對象getServletContext()方法與ServletConfig.getServletContext()相同,略。

  getServletInfo():該方法來源于Servlet接口,覆寫該方法以產(chǎn)生有意義的信息。(如:版本號、版權(quán)、作者等)

  log(java.lang.String msg):public void log(java.lang.String msg)該方法把指定的信息寫入一個(gè)日志文件,見ServletContext.log(String)。

  log(java.lang.String message,java.lang.Throwable t):public void log(java.lang.String message,java.lang.Throwable t) 該方法把解釋性的內(nèi)容和拋出的例外信息寫入一個(gè)日志文件。

  service():這是一個(gè)抽象的方法,當(dāng)為執(zhí)行網(wǎng)絡(luò)請求繼承GenericServlet類時(shí)必須實(shí)現(xiàn)它,該方法必須由servlet容器調(diào)用以允許servlet 對請求作出響應(yīng)。見Servlet.service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)。

  getServletName():見ServletConfig.getServletName()。

HttpServlet類:

  這個(gè)是重點(diǎn)啦(拍桌子)!HttpServlet類擴(kuò)展了GenericServlet類并且對Servlet接口提供了與HTTP相關(guān)的實(shí)現(xiàn),是在Web開發(fā)中定義Servlet最常使用的類。HttpServlet類中的主要方法的源代碼如下所示:

1 // 2 // Source code recreated from a .class file by IntelliJ IDEA 3 // (powered by Fernflower decompiler) 4 // 5 6 package javax.servlet.http; 7 8 import java.io.IOException; 9 import java.lang.reflect.InvocationTargetException; 10 import java.lang.reflect.Method; 11 import java.text.MessageFormat; 12 import java.util.Enumeration; 13 import java.util.ResourceBundle; 14 import javax.servlet.DispatcherType; 15 import javax.servlet.GenericServlet; 16 import javax.servlet.ServletException; 17 import javax.servlet.ServletOutputStream; 18 import javax.servlet.ServletRequest; 19 import javax.servlet.ServletResponse; 20 21 public abstract class HttpServlet extends GenericServlet { 22 private static final long serialVersionUID = 1L; 23 private static final String METHOD_DELETE = "DELETE"; 24 private static final String METHOD_HEAD = "HEAD"; 25 private static final String METHOD_GET = "GET"; 26 private static final String METHOD_OPTIONS = "OPTIONS"; 27 private static final String METHOD_POST = "POST"; 28 private static final String METHOD_PUT = "PUT"; 29 private static final String METHOD_TRACE = "TRACE"; 30 private static final String HEADER_IFMODSINCE = "If-Modified-Since"; 31 private static final String HEADER_LASTMOD = "Last-Modified"; 32 private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings"; 33 private static final ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings"); 34 35 public HttpServlet() { 36 } 37 38 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 39 String protocol = req.getProtocol(); 40 String msg = lStrings.getString("http.method_get_not_supported"); 41 if (protocol.endsWith("1.1")) { 42 resp.sendError(405, msg); 43 } else { 44 resp.sendError(400, msg); 45 } 46 47 } 48 49 protected long getLastModified(HttpServletRequest req) { 50 return -1L; 51 } 52 53 protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 54 if (DispatcherType.INCLUDE.equals(req.getDispatcherType())) { 55 this.doGet(req, resp); 56 } else { 57 NoBodyResponse response = new NoBodyResponse(resp); 58 this.doGet(req, response); 59 response.setContentLength(); 60 } 61 62 } 63 64 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 65 String protocol = req.getProtocol(); 66 String msg = lStrings.getString("http.method_post_not_supported"); 67 if (protocol.endsWith("1.1")) { 68 resp.sendError(405, msg); 69 } else { 70 resp.sendError(400, msg); 71 } 72 73 } 74 75 protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 76 String protocol = req.getProtocol(); 77 String msg = lStrings.getString("http.method_put_not_supported"); 78 if (protocol.endsWith("1.1")) { 79 resp.sendError(405, msg); 80 } else { 81 resp.sendError(400, msg); 82 } 83 84 } 85 86 protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 87 String protocol = req.getProtocol(); 88 String msg = lStrings.getString("http.method_delete_not_supported"); 89 if (protocol.endsWith("1.1")) { 90 resp.sendError(405, msg); 91 } else { 92 resp.sendError(400, msg); 93 } 94 95 } 96 97 private static Method[] getAllDeclaredMethods(Class<?> c) { 98 if (c.equals(HttpServlet.class)) { 99 return null; 100 } else { 101 Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass()); 102 Method[] thisMethods = c.getDeclaredMethods(); 103 if (parentMethods != null && parentMethods.length > 0) { 104 Method[] allMethods = new Method[parentMethods.length + thisMethods.length]; 105 System.arraycopy(parentMethods, 0, allMethods, 0, parentMethods.length); 106 System.arraycopy(thisMethods, 0, allMethods, parentMethods.length, thisMethods.length); 107 thisMethods = allMethods; 108 } 109 110 return thisMethods; 111 } 112 } 113 114 protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 115 Method[] methods = getAllDeclaredMethods(this.getClass()); 116 boolean ALLOW_GET = false; 117 boolean ALLOW_HEAD = false; 118 boolean ALLOW_POST = false; 119 boolean ALLOW_PUT = false; 120 boolean ALLOW_DELETE = false; 121 boolean ALLOW_TRACE = true; 122 boolean ALLOW_OPTIONS = true; 123 Class clazz = null; 124 125 try { 126 clazz = Class.forName("org.apache.catalina.connector.RequestFacade"); 127 Method getAllowTrace = clazz.getMethod("getAllowTrace", (Class[])null); 128 ALLOW_TRACE = (Boolean)getAllowTrace.invoke(req, (Object[])null); 129 } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassNotFoundException var14) { 130 ; 131 } 132 133 for(int i = 0; i < methods.length; ++i) { 134 Method m = methods[i]; 135 if (m.getName().equals("doGet")) { 136 ALLOW_GET = true; 137 ALLOW_HEAD = true; 138 } 139 140 if (m.getName().equals("doPost")) { 141 ALLOW_POST = true; 142 } 143 144 if (m.getName().equals("doPut")) { 145 ALLOW_PUT = true; 146 } 147 148 if (m.getName().equals("doDelete")) { 149 ALLOW_DELETE = true; 150 } 151 } 152 153 String allow = null; 154 if (ALLOW_GET) { 155 allow = "GET"; 156 } 157 158 if (ALLOW_HEAD) { 159 if (allow == null) { 160 allow = "HEAD"; 161 } else { 162 allow = allow + ", HEAD"; 163 } 164 } 165 166 if (ALLOW_POST) { 167 if (allow == null) { 168 allow = "POST"; 169 } else { 170 allow = allow + ", POST"; 171 } 172 } 173 174 if (ALLOW_PUT) { 175 if (allow == null) { 176 allow = "PUT"; 177 } else { 178 allow = allow + ", PUT"; 179 } 180 } 181 182 if (ALLOW_DELETE) { 183 if (allow == null) { 184 allow = "DELETE"; 185 } else { 186 allow = allow + ", DELETE"; 187 } 188 } 189 190 if (ALLOW_TRACE) { 191 if (allow == null) { 192 allow = "TRACE"; 193 } else { 194 allow = allow + ", TRACE"; 195 } 196 } 197 198 if (ALLOW_OPTIONS) { 199 if (allow == null) { 200 allow = "OPTIONS"; 201 } else { 202 allow = allow + ", OPTIONS"; 203 } 204 } 205 206 resp.setHeader("Allow", allow); 207 } 208 209 protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 210 String CRLF = "\r\n"; 211 StringBuilder buffer = (new StringBuilder("TRACE ")).append(req.getRequestURI()).append(" ").append(req.getProtocol()); 212 Enumeration reqHeaderEnum = req.getHeaderNames(); 213 214 while(reqHeaderEnum.hasMoreElements()) { 215 String headerName = (String)reqHeaderEnum.nextElement(); 216 buffer.append(CRLF).append(headerName).append(": ").append(req.getHeader(headerName)); 217 } 218 219 buffer.append(CRLF); 220 int responseLength = buffer.length(); 221 resp.setContentType("message/http"); 222 resp.setContentLength(responseLength); 223 ServletOutputStream out = resp.getOutputStream(); 224 out.print(buffer.toString()); 225 out.close(); 226 } 227 228 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 229 String method = req.getMethod(); 230 long lastModified; 231 if (method.equals("GET")) { 232 lastModified = this.getLastModified(req); 233 if (lastModified == -1L) { 234 this.doGet(req, resp); 235 } else { 236 long ifModifiedSince; 237 try { 238 ifModifiedSince = req.getDateHeader("If-Modified-Since"); 239 } catch (IllegalArgumentException var9) { 240 ifModifiedSince = -1L; 241 } 242 243 if (ifModifiedSince < lastModified / 1000L * 1000L) { 244 this.maybeSetLastModified(resp, lastModified); 245 this.doGet(req, resp); 246 } else { 247 resp.setStatus(304); 248 } 249 } 250 } else if (method.equals("HEAD")) { 251 lastModified = this.getLastModified(req); 252 this.maybeSetLastModified(resp, lastModified); 253 this.doHead(req, resp); 254 } else if (method.equals("POST")) { 255 this.doPost(req, resp); 256 } else if (method.equals("PUT")) { 257 this.doPut(req, resp); 258 } else if (method.equals("DELETE")) { 259 this.doDelete(req, resp); 260 } else if (method.equals("OPTIONS")) { 261 this.doOptions(req, resp); 262 } else if (method.equals("TRACE")) { 263 this.doTrace(req, resp); 264 } else { 265 String errMsg = lStrings.getString("http.method_not_implemented"); 266 Object[] errArgs = new Object[]{method}; 267 errMsg = MessageFormat.format(errMsg, errArgs); 268 resp.sendError(501, errMsg); 269 } 270 271 } 272 273 private void maybeSetLastModified(HttpServletResponse resp, long lastModified) { 274 if (!resp.containsHeader("Last-Modified")) { 275 if (lastModified >= 0L) { 276 resp.setDateHeader("Last-Modified", lastModified); 277 } 278 279 } 280 } 281 282 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { 283 HttpServletRequest request; 284 HttpServletResponse response; 285 try { 286 request = (HttpServletRequest)req; 287 response = (HttpServletResponse)res; 288 } catch (ClassCastException var6) { 289 throw new ServletException("non-HTTP request or response"); 290 } 291 292 this.service(request, response); 293 } 294 }

HttpServlet雖然看起來很長,但由于前兩個(gè)類的結(jié)構(gòu)已趨于完善,主要方法也不多:

service(ServletRequest req, ServletResponse res):HttpServlet在實(shí)現(xiàn)Servlet接口時(shí),重寫了service()方法,該方法會自動判斷用戶的請求方式:若為GET請求,則調(diào)用doGet()方法,若為POST請求,則調(diào)用doPost方法。如果Servlet收到一個(gè)HTTP請求而沒有重載相應(yīng)的do方法,它就返回一個(gè)說明此方法對本資源不可用的標(biāo)準(zhǔn)HTTP錯(cuò)誤

doGet(ServletRequest req, ServletResponse res):被本類的service方法調(diào)用,用來處理一個(gè)HTTP GET請求

doPost(ServletRequest req, ServletResponse res):被本類的service方法調(diào)用,用來處理一個(gè)HTTP POST請求

HttpServlet作為HTTP請求的分發(fā)器,除了提供對GET和POST請求的處理方法doGet()和doPost()之外,對于其他請求類型如HEAD,OPTIONS,DELETE,PUT,TRACE也提供了相應(yīng)的處理方法,如doHead(),doOptions等等

HttpServlet指能夠處理HTTP請求的Servlet,開發(fā)人員在編寫Servlet時(shí),通常應(yīng)繼承這個(gè)類,而避免去直接實(shí)現(xiàn)Servlet接口

?

下面是一個(gè)正常能夠處理請求的Servlet基本結(jié)構(gòu),我們在后面也主要使用這種結(jié)構(gòu):

1 package com.Servlet; 2 3 import javax.servlet.ServletConfig; 4 import javax.servlet.ServletException; 5 import javax.servlet.annotation.WebServlet; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 import java.io.IOException; 10 11 @WebServlet(name = "SimpleServlet") 12 public class SimpleServlet extends HttpServlet { 13 public SimpleServlet(){ 14 super(); 15 } 16 17 public void init(ServletConfig servletConfig) throws ServletException{ 18 //初始化方法 19 } 20 21 public void destroy() { 22 //銷毀方法 23 } 24 25 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 26 //處理POST請求時(shí)調(diào)用的方法 27 } 28 29 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 30 //處理GET請求時(shí)調(diào)用的方法 31 } 32 }

Servlet生命周期:

Servlet生命周期有七種狀態(tài):創(chuàng)捷,初始化,服務(wù)可用,服務(wù)不可用,處理請求,終止服務(wù),銷毀

根據(jù)七種狀態(tài)可以又分為四個(gè)階段:

1.加載和實(shí)例化:在服務(wù)器運(yùn)行中,客戶機(jī)首次向Servlet發(fā)出請求時(shí)或者再重新裝入Servlet時(shí)(如服務(wù)器重新啟動,Servlet被修改)或配置了自動裝入選項(xiàng)時(shí)(load-on-startup),服務(wù)器在啟動時(shí)會自動裝入此Servlet

2.初始化:調(diào)用上面方法中的init(ServletConfig config)來對Servlet實(shí)例進(jìn)行初始化,成功時(shí)進(jìn)入服務(wù)可用狀態(tài),失敗時(shí)Servlet容器會從運(yùn)行環(huán)境中清除掉該實(shí)例,運(yùn)行出現(xiàn)異常時(shí)進(jìn)入服務(wù)不可用狀態(tài),維護(hù)人員也可以設(shè)置不可用狀態(tài)或從不可用變成可用

3.處理請求:服務(wù)器收到客戶端請求時(shí)會為該請求創(chuàng)建一個(gè)“請求”對象和一個(gè)相應(yīng)對象并調(diào)用service()方法,service()方法可能被多次調(diào)用,多個(gè)客戶端訪問某個(gè)Servlet的service方法時(shí),服務(wù)器會為每個(gè)請求創(chuàng)建一個(gè)線程來減少等待時(shí)間

4.銷毀:當(dāng)Servlet容器需要終止Servlet時(shí),它會先調(diào)用destroy()方法來釋放資源,調(diào)用該方法前必須讓所有service()的線程完成實(shí)行,該方法完成后,Servlet容器必須釋放該實(shí)例以便被垃圾回收

時(shí)序圖:

?

轉(zhuǎn)載于:https://www.cnblogs.com/qq965921539/p/10161340.html

總結(jié)

以上是生活随笔為你收集整理的Java Web 学习与总结(一)Servlet基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。