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代码演示:

  • 相关阅读:
    常用的正则表达式,字符串,地址操作
    倒计时工具
    Java—集合框架List
    Java—包装类、Date和SimpleDateFormat、Calendar类
    Java—字符串
    Java —异常
    Java—多态
    Java—继承
    Java—封装
    Java —类和对象
  • 原文地址:https://www.cnblogs.com/heureuxl/p/13706177.html
Copyright © 2011-2022 走看看