• Servlet


    Servlet

    • Servlet是Java提供的一门动态web资源开发技术,其实就是一个接口(规范),将来我们需要自定义Servlet类实现Servlet接口即可,并由web服务器运行Servlet。

    快速入门

    • 创建Web项目,导入Servlet依赖坐标
        1. <dependency>
        2. <groupId>javax.servletgroupId>
        3. <artifactId>javax.servlet-apiartifactId>
        4. <version>3.1.0version>
        5. <scope>providedscope>
        6. dependency>
    • 定义一个类,实现Servlet接口,并重写其中的方法,并在service方法中输出一句话
    • 使用注解方式配置@WebServlet,配置该Servlet的访问路径(就是这个Servlet处理哪些请求)
    • 访问,启动tomcat,输入url地址,访问对应的Servlet类
      • 通过maven插件的方式来启动tomcat服务器,然后在浏览器中输入对应的url地址

    Servlet执行流程

    • Servlet由web服务器创建,其中的方法也由web服务器来调用

    Servlet生命周期

    • Servlet运行在web服务器中(Servlet容器)、其生命周期由容器管理,分为四个阶段
      • 加载实例化:默认情况下,在Servlet第一次被访问时,有容器创建Servlet对象
        • loadStartup
          • 负整数:Servlet对象第一次被访问是创建
          • 正整数或0:服务器启动时,创建Servlet对象,数字越小优先级越高
      • 初始化:在Servlet实例化之后,容器调用其中的init()方法初始化Servlet对象,完成加载配置文件、创建连接等功能,该方法只调用一次
      • 处理请求每当请求Servelt时,Servlet容器都会调用Servlet的service()方法对请求进行处理
      • 服务终止:当释放内存或容器关闭的时候,容器都会调用Servlet中的destroy()方法,完成资源的释放,在destroy()方法调用之后,容器会释放这个Servlet实例对象,该实例对象随后会被Java的垃圾回收器所回收。

    Servlet体系结构

    • 方法
      • 除了上述三个必须执行的方法之外,还有两个方法
          1. // 获取ServletConfig对象
          2. public ServletConfig getServletConfig() {
          3. return null;
          4. }
          5. // 获取Servlet信息
          6. public String getServletInfo() {
          7. return null;
          8. }
    • 体系结构
      • GenericServlet类实现类Servlet接口,HttpServlet类(对HTTP协议封装的Servlet类)继承GenericServlet类
      • 我们将来开发B/S框架的web项目,都是针对HTTP协议,所以我们自定义Servlet,继承HttpServlet即可,在自定义的Servlet类中编写处理get/post请求的方法即可。
    • HttpServlet中为什么要根据请求方式的不同,调用不同的方法,以及如何调用
      • 在接口Servlet的Service方法中,会对请求的参数信息进行处理,但是不同请求的参数位置不同,get请求的请求参数就在请求行中,post请求的请求参数在请求体中,所以要使用不同的请求逻辑。而这些逻辑被封装到HttpServlet类中,我们创建的Servlet类直接继承HttpServlet类即HttpServlet类的源码如下()
          1. //
          2. // Source code recreated from a .class file by IntelliJ IDEA
          3. // (powered by FernFlower decompiler)
          4. //
          5. package javax.servlet.http;
          6. import java.io.IOException;
          7. import java.lang.reflect.Method;
          8. import java.text.MessageFormat;
          9. import java.util.Enumeration;
          10. import java.util.ResourceBundle;
          11. import javax.servlet.GenericServlet;
          12. import javax.servlet.ServletException;
          13. import javax.servlet.ServletOutputStream;
          14. import javax.servlet.ServletRequest;
          15. import javax.servlet.ServletResponse;
          16. public abstract class HttpServlet extends GenericServlet {
          17. private static final String METHOD_DELETE = "DELETE";
          18. private static final String METHOD_HEAD = "HEAD";
          19. private static final String METHOD_GET = "GET";
          20. private static final String METHOD_OPTIONS = "OPTIONS";
          21. private static final String METHOD_POST = "POST";
          22. private static final String METHOD_PUT = "PUT";
          23. private static final String METHOD_TRACE = "TRACE";
          24. private static final String HEADER_IFMODSINCE = "If-Modified-Since";
          25. private static final String HEADER_LASTMOD = "Last-Modified";
          26. private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";
          27. private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");
          28. public HttpServlet() {
          29. }
          30. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          31. String protocol = req.getProtocol();
          32. String msg = lStrings.getString("http.method_get_not_supported");
          33. if (protocol.endsWith("1.1")) {
          34. resp.sendError(405, msg);
          35. } else {
          36. resp.sendError(400, msg);
          37. }
          38. }
          39. protected long getLastModified(HttpServletRequest req) {
          40. return -1L;
          41. }
          42. protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          43. NoBodyResponse response = new NoBodyResponse(resp);
          44. this.doGet(req, response);
          45. response.setContentLength();
          46. }
          47. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          48. String protocol = req.getProtocol();
          49. String msg = lStrings.getString("http.method_post_not_supported");
          50. if (protocol.endsWith("1.1")) {
          51. resp.sendError(405, msg);
          52. } else {
          53. resp.sendError(400, msg);
          54. }
          55. }
          56. protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          57. String protocol = req.getProtocol();
          58. String msg = lStrings.getString("http.method_put_not_supported");
          59. if (protocol.endsWith("1.1")) {
          60. resp.sendError(405, msg);
          61. } else {
          62. resp.sendError(400, msg);
          63. }
          64. }
          65. protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          66. String protocol = req.getProtocol();
          67. String msg = lStrings.getString("http.method_delete_not_supported");
          68. if (protocol.endsWith("1.1")) {
          69. resp.sendError(405, msg);
          70. } else {
          71. resp.sendError(400, msg);
          72. }
          73. }
          74. private Method[] getAllDeclaredMethods(Classextends HttpServlet> c) {
          75. Class clazz = c;
          76. Method[] allMethods;
          77. for(allMethods = null; !clazz.equals(HttpServlet.class); clazz = clazz.getSuperclass()) {
          78. Method[] thisMethods = clazz.getDeclaredMethods();
          79. if (allMethods != null && allMethods.length > 0) {
          80. Method[] subClassMethods = allMethods;
          81. allMethods = new Method[thisMethods.length + allMethods.length];
          82. System.arraycopy(thisMethods, 0, allMethods, 0, thisMethods.length);
          83. System.arraycopy(subClassMethods, 0, allMethods, thisMethods.length, subClassMethods.length);
          84. } else {
          85. allMethods = thisMethods;
          86. }
          87. }
          88. return allMethods != null ? allMethods : new Method[0];
          89. }
          90. protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          91. Method[] methods = this.getAllDeclaredMethods(this.getClass());
          92. boolean ALLOW_GET = false;
          93. boolean ALLOW_HEAD = false;
          94. boolean ALLOW_POST = false;
          95. boolean ALLOW_PUT = false;
          96. boolean ALLOW_DELETE = false;
          97. boolean ALLOW_TRACE = true;
          98. boolean ALLOW_OPTIONS = true;
          99. for(int i = 0; i < methods.length; ++i) {
          100. String methodName = methods[i].getName();
          101. if (methodName.equals("doGet")) {
          102. ALLOW_GET = true;
          103. ALLOW_HEAD = true;
          104. } else if (methodName.equals("doPost")) {
          105. ALLOW_POST = true;
          106. } else if (methodName.equals("doPut")) {
          107. ALLOW_PUT = true;
          108. } else if (methodName.equals("doDelete")) {
          109. ALLOW_DELETE = true;
          110. }
          111. }
          112. StringBuilder allow = new StringBuilder();
          113. if (ALLOW_GET) {
          114. allow.append("GET");
          115. }
          116. if (ALLOW_HEAD) {
          117. if (allow.length() > 0) {
          118. allow.append(", ");
          119. }
          120. allow.append("HEAD");
          121. }
          122. if (ALLOW_POST) {
          123. if (allow.length() > 0) {
          124. allow.append(", ");
          125. }
          126. allow.append("POST");
          127. }
          128. if (ALLOW_PUT) {
          129. if (allow.length() > 0) {
          130. allow.append(", ");
          131. }
          132. allow.append("PUT");
          133. }
          134. if (ALLOW_DELETE) {
          135. if (allow.length() > 0) {
          136. allow.append(", ");
          137. }
          138. allow.append("DELETE");
          139. }
          140. if (ALLOW_TRACE) {
          141. if (allow.length() > 0) {
          142. allow.append(", ");
          143. }
          144. allow.append("TRACE");
          145. }
          146. if (ALLOW_OPTIONS) {
          147. if (allow.length() > 0) {
          148. allow.append(", ");
          149. }
          150. allow.append("OPTIONS");
          151. }
          152. resp.setHeader("Allow", allow.toString());
          153. }
          154. protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          155. String CRLF = "\r\n";
          156. StringBuilder buffer = (new StringBuilder("TRACE ")).append(req.getRequestURI()).append(" ").append(req.getProtocol());
          157. Enumeration reqHeaderEnum = req.getHeaderNames();
          158. while(reqHeaderEnum.hasMoreElements()) {
          159. String headerName = (String)reqHeaderEnum.nextElement();
          160. buffer.append(CRLF).append(headerName).append(": ").append(req.getHeader(headerName));
          161. }
          162. buffer.append(CRLF);
          163. int responseLength = buffer.length();
          164. resp.setContentType("message/http");
          165. resp.setContentLength(responseLength);
          166. ServletOutputStream out = resp.getOutputStream();
          167. out.print(buffer.toString());
          168. }
          169. protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          170. String method = req.getMethod();
          171. long lastModified;
          172. if (method.equals("GET")) {
          173. lastModified = this.getLastModified(req);
          174. if (lastModified == -1L) {
          175. this.doGet(req, resp);
          176. } else {
          177. long ifModifiedSince = req.getDateHeader("If-Modified-Since");
          178. if (ifModifiedSince < lastModified) {
          179. this.maybeSetLastModified(resp, lastModified);
          180. this.doGet(req, resp);
          181. } else {
          182. resp.setStatus(304);
          183. }
          184. }
          185. } else if (method.equals("HEAD")) {
          186. lastModified = this.getLastModified(req);
          187. this.maybeSetLastModified(resp, lastModified);
          188. this.doHead(req, resp);
          189. } else if (method.equals("POST")) {
          190. this.doPost(req, resp);
          191. } else if (method.equals("PUT")) {
          192. this.doPut(req, resp);
          193. } else if (method.equals("DELETE")) {
          194. this.doDelete(req, resp);
          195. } else if (method.equals("OPTIONS")) {
          196. this.doOptions(req, resp);
          197. } else if (method.equals("TRACE")) {
          198. this.doTrace(req, resp);
          199. } else {
          200. String errMsg = lStrings.getString("http.method_not_implemented");
          201. Object[] errArgs = new Object[]{method};
          202. errMsg = MessageFormat.format(errMsg, errArgs);
          203. resp.sendError(501, errMsg);
          204. }
          205. }
          206. private void maybeSetLastModified(HttpServletResponse resp, long lastModified) {
          207. if (!resp.containsHeader("Last-Modified")) {
          208. if (lastModified >= 0L) {
          209. resp.setDateHeader("Last-Modified", lastModified);
          210. }
          211. }
          212. }
          213. public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
          214. if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
          215. HttpServletRequest request = (HttpServletRequest)req;
          216. HttpServletResponse response = (HttpServletResponse)res;
          217. this.service(request, response);
          218. } else {
          219. throw new ServletException("non-HTTP request or response");
          220. }
          221. }
          222. }
        • 我们可以看到其中对于Http中的其中不同的请求方式都进行了判断,并且进行了封装,我们自定义的Servlet类继承HttpServlet类就可以,然后重写其中的不同的方法来处理不同类型的请求即可,简单讲就是HttpServlet类帮我们完成了url请求的类型的判断,我们只需要完成对于不同请求类型的处理逻辑即可。

    Servlet urlPattern配置

    • urlParttern就是设置Servlet类访问路径,即该请求被哪一个Servlert来进行逻辑处理,在实际的开发过程中,前后端应该是通过需求文档来确定访问路径的(产品经理提供好)
    • 一个Servlet可以配置多个访问路径
    • urlParttern配置规则
      • 精确匹配
      • 目录匹配
      • 拓展名匹配
      • 任意匹配
      • /和/*的区别(这两个在以后的servlet访问路劲中尽量不要使用)
        • 当我们的项目中的Servlet配置了“/”,会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上的时候,就会调用该默认的servlet,该默认Servlet会处理项目中静态资源的访问,如果覆盖掉就无法范文静态资源(html页面等.)。
        • 当我们项目中的配置了“/*“,意味该Servlet匹配任意访问路径
      • 优先级
        • 精确路径》目录路径》拓展名路径》/*》/
        • 精确度来划分(在一个项目应该指挥只会使用一种方式来进行配置)

    xml配置方式编写Servlet

    • 以后学习框架很多都是全注解开发,就是用注解来讲xml配置方式给替代掉,使用起来非常方柏霓,但学习xml配置方式也有助于我理解注解配置方式,要理解xml配置方式,就需要学习Spring的原理了,可以参考我在Spring专栏的相关文章。
    • 编写好Servlet类之后,我们需要在web.xml配置文件中,进行对应的映射
  • 相关阅读:
    笔试强训第18天
    【kubernetes】k8s对象☞pod
    开发笔记 03,为什么不要问别人在做什么小产品?
    JSP如何使用request获取当前访问者的真实IP呢?
    安装Docker
    【Cisco Packet Tracer】管理方式,命令,接口trunk,VLAN
    Ambari 安装多个impala deamon节点(apache impala)
    成绩 (爱思创算法四)(期中测试)(答案记录)
    如何保卫您的网站:解决DDoS攻击与CC攻击
    component 动态组件的用法
  • 原文地址:https://blog.csdn.net/weixin_64939936/article/details/133699353