zoukankan      html  css  js  c++  java
  • JSPday05(Servlet)

    Servlet是什么

      Servlet就是一个类,试运行在服务器端的一个程序。当jsp翻译之后就是Servlet。Servlet自身为了能够提高更好的并发性,所以将自身设计为了单实例、多线程的一个类,所以会有线程安全性问题。一般解决方式:
      1.将所有的具有一定的危险性的字段放置在方法之中。
      2.将doXXX方法加入Synchronization(及其不推荐 这会造成无法并发执行)

    Servlet架构

      

    Servlet接口

    源码:

    通过对该接口进行观察,发现在接口下面包含了几个重要的方法:
      init():当前Servlet初始化
      service(ServletRequest,ServletResponse) :完成
      请求的服务响应,处理请求
      destroy(): 销毁Servlet 

    ServletConfig接口

    源码:

      通过观察该接口,能够发现其中的方法主要作用就是获取到Servlet名称、获取上下文、获取初始化参数及获取所有参数的名称的枚举。

    GenericServlet

    源码:

     1 //
     2 // Source code recreated from a .class file by IntelliJ IDEA
     3 // (powered by Fernflower decompiler)
     4 //
     5 
     6 package javax.servlet;
     7 
     8 import java.io.IOException;
     9 import java.io.Serializable;
    10 import java.util.Enumeration;
    11 import java.util.ResourceBundle;
    12 
    13 public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    14     private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
    15     private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings");
    16     private transient ServletConfig config;
    17 
    18     public GenericServlet() {
    19     }
    20 
    21     public void destroy() {
    22     }
    23 
    24     public String getInitParameter(String name) {
    25         ServletConfig sc = this.getServletConfig();
    26         if (sc == null) {
    27             throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
    28         } else {
    29             return sc.getInitParameter(name);
    30         }
    31     }
    32 
    33     public Enumeration<String> getInitParameterNames() {
    34         ServletConfig sc = this.getServletConfig();
    35         if (sc == null) {
    36             throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
    37         } else {
    38             return sc.getInitParameterNames();
    39         }
    40     }
    41 
    42     public ServletConfig getServletConfig() {
    43         return this.config;
    44     }
    45 
    46     public ServletContext getServletContext() {
    47         ServletConfig sc = this.getServletConfig();
    48         if (sc == null) {
    49             throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
    50         } else {
    51             return sc.getServletContext();
    52         }
    53     }
    54 
    55     public String getServletInfo() {
    56         return "";
    57     }
    58 
    59     public void init(ServletConfig config) throws ServletException {
    60         this.config = config;
    61         this.init();
    62     }
    63 
    64     public void init() throws ServletException {
    65     }
    66 
    67     public void log(String msg) {
    68         this.getServletContext().log(this.getServletName() + ": " + msg);
    69     }
    70 
    71     public void log(String message, Throwable t) {
    72         this.getServletContext().log(this.getServletName() + ": " + message, t);
    73     }
    74 
    75     public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    76 
    77     public String getServletName() {
    78         ServletConfig sc = this.getServletConfig();
    79         if (sc == null) {
    80             throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
    81         } else {
    82             return sc.getServletName();
    83         }
    84     }
    85 }
    View Code
    通过观察源代码,发现该抽象类实现了ServletConfig下的接口所声明的方法,而Servlet接口下的方法,都下沉到子类HttpServlet之中了。 

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

      该类中实现了Servlet接口中的一些方法,同时声明处理了大量的HTTP请求相关信息。

     除了实现了doXXX方法之外,还重点实现了service方法,该方法的作用通过源码可以发现,就是处理所有请求的主方法,在该方法中通过使用request.getMethod()获取到请求的方式,然后调用对应的doXXX来处理。

    Servlet生命周期

      实例化对象,Servlet本就是一个单例设计的对象,所以全局只有1个

      init()初始化,能够获取到初始化一些参数,对Servlet进行一些初始设置。

      service()进行处理请求以及响应服务

      destroy():在容器关闭或清空内存时,会调用该方法,执行后销毁当前的servlet方法

       

    使用Servlet完成控制层

       将原有的JSP中的控制层代码转移到Servlet中。需要考虑Servlet自身的特性以及请求的方式,是Get还是Post,在其中request、response、application都不是内置对象,需要自己手动获取。

      手动获取session对象:

      手动获取application

       作为控制层需要完成的任务:

        验证数据

        封装数据对象

        承上启下的请求和响应的处理

    登录Servlet代码演示:

  • 相关阅读:
    发现个atan2的正确使用方式
    Forward+ Shading架构
    fatal: unable to connect to gitee.com: gitee.com[0: 180.97.125.228]: errno=Unknown error 解决方案
    HDFS HA(高可用性)集群规划
    如何使用RTP引擎对语音编码进行转码
    关于 Angular 应用 tsconfig.json 中的 target 属性
    浅谈 Orbeon form builder 的权限控制
    关于 Angular 应用 tsconfig.json 中的 lib 属性
    orbeon form 通过 url 的方式同第三方应用集成的开发明细
    orbeon form 的配置介绍
  • 原文地址:https://www.cnblogs.com/heureuxl/p/13706177.html
Copyright © 2011-2022 走看看