精华内容
下载资源
问答
  • java 中返回状态码

    千次阅读 2020-09-07 18:01:01
    10状态码定义 每个状态代码如下所述,包括可以遵循哪些方法以及响应中需要的任何元信息的描述。 10.1信息1xx 此类状态码表示临时响应,仅由状态行和可选标头组成,并由空行终止。此类状态代码没有必需的标题。由于...

    10状态码定义
    每个状态代码如下所述,包括可以遵循哪些方法以及响应中需要的任何元信息的描述。

    10.1信息1xx
    此类状态码表示临时响应,仅由状态行和可选标头组成,并由空行终止。此类状态代码没有必需的标题。由于HTTP / 1.0没有定义任何1xx状态代码,因此除实验条件外,服务器不得向HTTP / 1.0客户端发送1xx响应。

    客户端必须准备在定期响应之前接受一个或多个1xx状态响应,即使客户端不期望100(继续)状态消息。意外的1xx状态响应可能被用户代理忽略。

    代理必须转发1xx响应,除非代理与其客户端之间的连接已关闭,或者除非代理本身请求生成1xx响应。(例如,如果a

    代理在转发请求时添加“Expect:100-continue”字段,则不需要转发相应的100(Continue)响应。)

    10.1.1 100继续 — Continue
    客户应该继续请求。该临时响应用于通知客户端请求的初始部分已被接收,并且尚未被服务器拒绝。客户端应该继续发送请求的剩余部分,或者如果请求已经完成,则忽略此响应。服务器必须在请求完成后发送最终响应。有关使用和处理此状态代码的详细讨论,请参见第8.2.3节。

    10.1.2 101切换协议 — Switching Protocols
    服务器通过升级消息头字段(第14.42节)了解并愿意遵守客户端的请求,以便在此连接上使用的应用协议进行更改。服务器将在终止101响应的空行之后立即将协议切换到由响应的“升级”头域定义的协议。

    只有在有利的情况下才应该切换协议。例如,切换到较新版本的HTTP比旧版本更有利,并且当递送使用这些特征的资源时,切换到实时同步协议可能是有利的。

    10.2成功2xx
    此类状态码表示客户端的请求已成功接收,理解并被接受。

    10.2.1 200 OK
    请求成功。与响应一起返回的信息取决于请求中使用的方法,例如:

    GET响应中发送对应于所请求资源的实体;

    HEAD与请求的资源对应的实体头字段在没有任何消息体的响应中发送;

    POST一个描述或包含动作结果的实体;

    TRACE包含终端服务器接收到的请求消息的实体。

    10.2.2创建201 — Created
    该请求已经实现,并导致创建一个新的资源。新创建的资源可以由响应实体中返回的URI引用,由位置头字段给出的资源最具体的URI。响应应该包括一个实体,其中包含一个资源特征和位置列表,用户或用户代理可从中选择最合适的一个。实体格式由Content-Type头域中指定的媒体类型指定。原始服务器必须在返回201状态代码之前创建资源。如果该操作无法立即执行,服务器应该以202(Accepted)响应来响应。

    201响应可以包含ETag响应头字段,指示刚创建的请求变体的实体标签的当前值,请参见第14.19节。

    10.2.3 202接受 — Accepted
    该请求已被接受处理,但处理尚未完成。请求可能或可能不会最终被执行,因为在处理实际发生时可能不允许。没有从这样的异步操作重新发送状态代码的功能。

    202回应是故意不提交的。其目的是允许服务器接受一些其他进程的请求(可能是每天只运行一次的批处理过程),而不要求用户代理与服务器的连接持续到进程完成为止。该响应返回的实体应该包括请求的当前状态的指示,以及指向状态监视器的指针,或者用户何时可以期望请求被满足的估计。

    10.2.4 203非授权信息 —Non-Authoritative Information
    实体头中返回的元信息不是从源服务器可用的确定集,而是从本地或第三方副本收集的。所呈现的集合可能是原始版本的子集或超集。例如,包括有关资源的本地注释信息可能会导致源服务器已知的元信息的超集。不需要使用此响应代码,仅当响应为200(OK)时才适用。

    10.2.5 204无内容 — No Content
    服务器已经完成了请求,但不需要返回一个实体,并且可能希望返回更新的元信息。响应可以以实体头部的形式包括新的或更新的元信息,如果存在,则应该与所请求的变体相关联。

    如果客户端是用户代理,则不应将其文档视图与导致请求发送的文档视图进行更改。此响应主要是为了允许进行操作的输入,而不会导致更改用户代理的活动文档视图,尽管任何新的或更新的元信息应该应用于当前在用户代理的活动视图中的文档。

    204响应不能包含消息体,因此总是在头字段之后的第一个空行终止。

    10.2.6 205重置内容 — Reset Content
    服务器已经满足了请求,用户代理应该重置导致发送请求的文档视图。该响应主要旨在允许通过用户输入进行动作的输入,随后清除输入的形式,使得用户可以容易地启动另一个输入动作。答复不能包含实体。

    10.2.7 206部分内容 — Partial Content
    服务器已经满足了资源的部分GET请求。请求必须包括一个指示期望范围的范围标题字段(第14.35节),并且可能包括一个If-Range头字段(第14.27节)来使请求成为条件。

    响应必须包括以下标题字段:

      -  Content-Range头域(第14.16节)指示
        该响应包含的范围,或多部分/ byteranges
        Content-Type包含每个部分的Content-Range字段。如果一个
        Content-Length头域存在于响应中
        值必须匹配传输的OCTET的实际数量
        消息体。
      - 日期
      -  ETag和/或Content-Location,如果标题将被发送
        在200响应相同的请求
      - 如果字段值可能,则到期,Cache-Control和/或Vary
        不同于以前在任何响应中发送的
        变种
    

    如果206响应是使用强缓存验证器的If-Range请求的结果(见第13.3.3节),响应应不包括其他实体头。如果响应是使用弱验证器的If-Range请求的结果,则响应不得包括其他实体头; 这可以防止缓存的实体和更新的头文件之间的不一致。否则,响应必须包括所有返回的实体标题,并且返回200(OK)响应到相同的请求。

    如果ETag或Last-Modified头部不完全匹配,则缓存不得将206响应与其他先前缓存的内容组合,请参见第13.5.4节。

    不支持Range和Content-Range标头的缓存不能缓存206(Partial)响应。

    10.3重定向3xx
    这类状态码表示用户代理需要采取进一步的操作才能完成请求。只有当第二个请求中使用的方法是GET或HEAD时,所需的操作可以由用户代理执行,而不与用户交互。客户端应该检测无限重定向循环,因为这样的循环为每个重定向生成网络流量。

      注意:此规范的以前版本推荐a
      最多五个重定向。内容开发人员应该知道
      可能有客户端实施这样一个固定的
      局限性。
    

    10.3.1 300多项选择 — Multiple Choices
    所请求的资源对应于一组表示中的任何一个,每个具有其自己的特定位置,并且正在提供代理驱动的协商信息(部分12),使得用户(或用户代理)可以选择优选的表示并将其重定向请求到该位置。

    除非是HEAD请求,响应应该包括一个包含资源特征和位置列表的实体,用户或用户代理可从中选择最合适的一个。实体格式由Content-Type头域中指定的媒体类型指定。取决于格式和功能

    用户代理,选择最合适的选择可以自动执行。然而,本规范没有定义这种自动选择的任何标准。

    如果服务器具有首选的表示形式,那么它应该在“位置”字段中包含该表示的特定URI; 用户代理可以使用位置字段值进行自动重定向。除非另有说明,否则此响应是可缓存的。

    10.3.2 301永久移动 — Moved Permanently
    所请求的资源已被分配了一个新的永久URI,并且将来对此资源的引用应该使用返回的URI之一。具有链接编辑功能的客户端应该可能地自动将对Request-URI的引用重新链接到服务器返回的一个或多个新引用。除非另有说明,否则此响应是可缓存的。

    新的永久URI应该由响应中的位置字段给出。除非请求方法是HEAD,否则响应的实体应该包含一个带有超链接到新的URI的短超文本注释。

    如果响应于GET或HEAD之外的请求接收到301状态码,用户代理不得自动重定向请求,除非用户可以确认,否则可能会更改发出请求的条件。

      注意:自动重定向POST请求后
      接收一个301状态码,一些现有的HTTP / 1.0用户代理
      将错误地将其更改为GET请求。
    

    10.3.3 302发现 —Found
    请求的资源暂时驻留在不同的URI下。由于重定向有时可能被更改,所以客户端应该继续使用Request-URI以供将来的请求使用。如果由Cache-Control或Expires头字段指示,此响应只能缓存。

    临时URI应该由响应中的位置字段给出。除非请求方法是HEAD,否则响应的实体应该包含一个带有超链接到新的URI的短超文本注释。

    如果响应于GET或HEAD之外的请求接收到302状态码,用户代理不得自动重定向请求,除非用户可以确认,否则可能会更改发出请求的条件。

      注意:RFC 1945和RFC 2068指定不允许客户端
      更改重定向请求的方法。但是,大多数
      现有的用户代理实现将302看作是303
      响应,在位置字段值上执行GET
      的原始请求方法。状态码303和307有
      被添加到希望明确清楚哪个服务器
      预计客户会有一些反应。
    

    10.3.4 303见其他 — See Other
    对请求的响应可以在不同的URI下找到,并且应该使用该资源上的GET方法来检索。此方法主要用于允许输出POST激活的脚本将用户代理重定向到所选资源。新的URI不是原始请求的资源的替代参考。303响应不能被缓存,但对第二个(重定向)请求的响应可能是可缓存的。

    响应中的位置字段应该给出不同的URI。除非请求方法是HEAD,否则响应的实体应该包含一个带有超链接到新的URI的短超文本注释。

      注意:许多HTTP / 1.1之前的用户代理不明白303
      状态。当与这样的客户端的互操作性是一个问题时,
      可以使用302状态代码,因为大多数用户代理作出反应
      到302所述的302响应。
    

    10.3.5 304未修改 — Not Modified
    如果客户端执行了条件GET请求,并且允许访问,但文档尚未被修改,服务器应该使用该状态代码进行响应。304响应不能包含消息体,因此总是在头字段之后的第一个空行终止。

    响应必须包括以下标题字段:

      - 日期,除非第14.18.1条规定其不作为
    

    如果无时钟源服务器遵守这些规则,并且代理和客户端将自己的Date添加到任何没有接收到的响应(如[RFC 2068]第14.19节已经指定的)),缓存将正常运行。

      -  ETag和/或Content-Location,如果标题将被发送
        在200响应相同的请求
      - 如果字段值可能,则到期,Cache-Control和/或Vary
        不同于以前在任何响应中发送的
        变种
    

    如果条件GET使用强缓存验证器(见第13.3.3节),响应应不包括其他实体头。否则(即,条件GET使用弱验证器),响应不得包括其他实体头; 这可以防止缓存的实体和更新的头文件之间的不一致。

    如果304响应指示当前未缓存的实体,则高速缓存必须忽略该响应并重复该请求而不使用条件。

    如果缓存使用接收到的304响应来更新高速缓存条目,则高速缓存务必更新该条目以反映响应中给出的任何新的字段值。

    10.3.6 305使用代理 — Use Proxy
    请求的资源必须通过“位置”字段给出的代理进行访问。位置字段给出代理的URI。收件人预计将通过代理重复此单一请求。305响应必须只能由源服务器生成。

      注意:RFC 2068并不清楚305是为了重定向一个
      单一请求,仅由原始服务器生成。不
      观察这些限制具有重大的安全后果。
    

    10.3.7 306(未使用)— Unused
    306状态码在规范的先前版本中使用,不再使用,代码被保留。

    10.3.8 307临时重定向 — Temporary Redirect
    请求的资源暂时驻留在不同的URI下。由于重定向可能有时被更改,所以客户端应该继续使用Request-URI来应对未来的请求。如果由Cache-Control或Expires头字段指示,此响应只能缓存。

    临时URI应该由响应中的位置字段给出。除非请求方法是HEAD,否则响应的实体应该包含一个具有到新URI的超链接的短超文本注释,因为许多HTTP / 1.1之前的用户代理不了解307状态。因此,该笔记应包含用户在新的URI上重复原始请求所需的信息。

    如果响应于GET或HEAD之外的请求接收到307状态码,用户代理不得自动重定向请求,除非用户可以确认,否则可能会更改发出请求的条件。

    10.4客户端错误4xx
    4xx类的状态码适用于客户端似乎有错误的情况。除了响应HEAD请求之外,服务器应该包含一个包含错误情况说明的实体,以及它是一个临时的还是永久的。这些状态码适用于任何请求方式。用户代理应该向用户显示任何包含的实体。

    如果客户端正在发送数据,那么在服务器关闭输入连接之前,使用TCP的服务器实现应该小心,以确保客户端确认收到包含响应的数据包。如果客户端在关闭后继续向服务器发送数据,则服务器的TCP堆栈将向客户端发送重置数据包,这可能会擦除客户端未确认的输入缓冲区,然后才能被HTTP应用程序读取和解释。

    10.4.1 400错误请求 — Bad Request
    由于格式错误,服务器无法理解该请求。客户端不要重复请求而不进行修改。

    10.4.2 401未经授权 — Unauthorized
    该请求需要用户认证。响应必须包括一个WWW-Authenticate头字段(第14.47节),其中包含适用于所请求资源的挑战。客户端可以使用适当的授权头域重复该请求(第14.8节)。如果请求已经包含授权凭据,则401响应表明已经为这些凭据拒绝授权。如果401响应包含与先前响应相同的挑战,并且用户代理已经尝试了至少一次认证,则应该向用户呈现在响应中给出的实体,因为该实体可能包括相关的诊断信息。HTTP访问认证在“HTTP认证:基本和摘要访问认证” [43]中进行了说明。

    10.4.3 402付款需要 — Payment Required
    此代码保留供将来使用。

    10.4.4 403禁止 — Forbidden
    服务器了解该请求,但拒绝履行该请求。授权不会有帮助,请求不可重复。如果请求方法不是HEAD,并且服务器希望公开为什么请求尚未实现,则应该描述拒绝实体的原因。如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到)。

    10.4.5 404未找到 — Not Found
    服务器没有找到任何匹配Request-URI的内容。没有指示条件是暂时的还是永久的。如果服务器通过一些内部可配置的机制知道旧资源是永久不可用且没有转发地址,则应该使用410(Gone)状态码。当服务器不希望明确指出请求被拒绝的原因,或者当没有其他响应适用时,这种状态代码是常用的。

    10.4.6 405不允许的方法 — Method Not Allowed
    由Request-URI标识的资源不允许在Request-Line中指定的方法。响应必须包含一个Allow标头,其中包含所请求资源的有效方法列表。

    10.4.7 406不可接受 — Not Acceptable
    由请求标识的资源仅能够根据请求中发送的接受头来生成内容特征不可接受的响应实体。

    除非是HEAD请求,响应应该包括一个包含可用实体特征和位置列表的实体,用户或用户代理可从中选择最合适的一个。实体格式由Content-Type头域中指定的媒体类型指定。根据用户代理的格式和功能,可以自动执行最合适的选择。然而,本规范没有定义这种自动选择的任何标准。

      注意:允许HTTP / 1.1服务器返回响应
      根据发送的接收头不能接受
      请求。在某些情况下,甚至可能会发送
      406回应。鼓励用户代理检查头文件
      一个传入的响应,以确定它是否可以接受。
    

    如果响应不可接受,则用户代理应该暂时停止接收更多数据,并询问用户对进一步的操作做出决定。

    10.4.8 407需要代理验证 — Proxy Authentication Required
    此代码类似于401(未授权),但表示客户端必须首先使用代理身份验证身份。代理务必返回一个Proxy-Authenticate头域(第14.33节),其中包含适用于所请求资源的代理的挑战。客户端可以使用合适的代理授权头域重复该请求(第14.34节)。HTTP访问认证在“HTTP认证:基本和摘要访问认证” [43]中进行了说明。

    10.4.9 408请求超时 — Request Timeout
    客户端在服务器准备等待的时间内没有产生请求。客户可以随时重复请求而无需修改。

    10.4.10 409冲突 — Conflict
    由于与资源的当前状态冲突,请求无法完成。只有在预期用户可能能够解决冲突并重新提交请求的情况下,才允许使用此代码。响应机构应该包括足够的

    用户识别冲突来源的信息。理想情况下,响应实体将包括足够的信息供用户或用户代理解决问题; 然而,这可能是不可能的,不是必需的。

    冲突最有可能发生在响应PUT请求。例如,如果正在使用版本控制,并且包含PUT的实体更改为与早期(第三方)请求所产生的资源冲突的资源,则服务器可能会使用409响应来指示它无法完成请求。在这种情况下,响应实体可能包含由响应Content-Type定义的格式的两个版本之间的差异列表。

    10.4.11 410 — Gone
    所请求的资源在服务器上不再可用,并且没有转发地址是已知的。这种情况有望被认为是永久性的。具有链接编辑功能的客户端应该在用户批准后删除对Request-URI的引用。如果服务器不知道,或者无法确定条件是否永久,则应该使用状态代码404(未找到)。除非另有说明,否则此响应是可缓存的。

    410响应主要旨在通过向收件人通知资源是有意不可用的,并且服务器所有者希望删除该资源的远程链接来帮助Web维护任务。这种事件对于有限时间,促销服务以及属于不再在服务器站点工作的个人的资源是常见的。没有必要将所有永久不可用的资源标记为“已经”或将标记保持在任何时间长度 - 这由服务器所有者决定。

    10.4.12 411需要长度 — Length Required
    服务器拒绝接受请求而没有定义的Content-Length。如果客户端在请求消息中添加了包含消息体长度的有效Content-Length头字段,则客户端可以重复该请求。

    10.4.13 412前提条件失败 — Precondition Failed
    在服务器上测试的一个或多个请求头字段中给出的前提条件被评估为false。该响应代码允许客户端在当前资源元信息(头字段数据)上放置前提条件,从而防止所请求的方法被应用于除预期的资源之外的资源。

    10.4.14 413请求实体太大 — Request Entity Too Large
    服务器拒绝处理请求,因为请求实体大于服务器愿意或能够处理的请求实体。服务器可能会关闭连接,以防止客户端继续请求。

    如果条件是临时的,服务器应该包括一个Retry-After头域,以指示它是临时的,并且在什么时候客户端可以再次尝试。

    10.4.15 414请求URI太长 — Request-URI Too Long
    服务器拒绝服务请求,因为Request-URI比服务器愿意解释更长。当客户端已经下降到重定向的URI“黑洞”(例如,指向重定向的URI前缀)时,当客户端将POST请求正确转换为具有长查询信息的GET请求时,这种罕见的条件才可能发生本身的后缀),或当服务器受到客户端的攻击时,尝试利用固定长度的缓冲区来利用一些服务器中存在的安全漏洞来读取或操作Request-URI。

    10.4.16 415不支持的介质类型 — Unsupported Media Type
    服务器拒绝服务请求,因为请求的实体是请求的方法所请求资源不支持的格式。

    10.4.17 416请求范围不满意 — Requested Range Not Satisfiable
    如果请求包含Range请求头字段(第14.35节),服务器应该返回一个具有该状态码的响应,并且此字段中的范围说明符值中没有一个与所选资源的当前范围重叠,并且请求没有包括一个If-Range请求头字段。(对于字节范围,这意味着所有字节范围规范值的第一个字节位数大于所选资源的当前长度。)

    当返回一个字节范围请求的状态码时,响应应该包括一个Content-Range实体头字段,指定所选资源的当前长度(见第14.16节 )。此响应不得使用multipart / byteranges内容类型。

    10.4.18 417期望失败 — Expectation Failed
    在Expect请求头字段(见第14.20节)中给出的期望不能被该服务器满足,或者如果服务器是代理服务器,则服务器具有明确的证据,即下一跳服务器无法满足该请求。

    10.5服务器错误5xx
    以数字“5”开头的响应状态代码表示服务器知道它已经发生错误或无法执行请求的情况。除了响应HEAD请求之外,服务器应该包含一个包含错误情况说明的实体,以及它是一个临时的还是永久的。用户代理应该向用户显示任何包含的实体。这些响应代码适用于任何请求方法。

    10.5.1 500内部服务器错误
    服务器遇到意外的情况,阻止它满足请求。

    10.5.2 501未实施 — Not Implemented
    服务器不支持完成请求所需的功能。当服务器无法识别请求方法并且不能支持任何资源时,这是适当的响应。

    10.5.3 502坏网关 — Bad Gateway
    作为网关或代理的服务器在尝试完成请求时从其访问的上游服务器接收到无效响应。

    10.5.4 503服务不可用 — Service Unavailable
    由于服务器的临时重载或维护,服务器目前无法处理该请求。这意味着这是一个暂时的条件,在一段延迟之后将被缓解。如果知道,则可以在Retry-After报头中指示延迟的长度。如果没有提供Retry-After,客户端应该处理响应,就像500次响应一样。

      注意:503状态代码的存在并不意味着a
      服务器必须在超载时使用它。有些服务器可能希望
      简单地拒绝连接。
    

    10.5.5 504网关超时 — Gateway Timeout
    作为网关或代理服务器的服务器没有从URI(例如HTTP,FTP,LDAP)或其他辅助服务器(例如DNS)指定的上游服务器及时响应,以尝试完成访问请求。

      注意:实现者注意事项:已知一些已部署的代理
      当DNS查找超时时返回400或500。
    

    10.5.6 505不支持HTTP版本 — HTTP Version Not Supported
    服务器不支持或拒绝支持请求消息中使用的HTTP协议版本。服务器指示它不能或不愿意使用与客户端相同的主要版本来完成请求,如第3.1节所述 ,而不是此错误消息。响应应该包含一个实体,描述为什么不支持该版本,以及该服务器支持哪些其他协议。

    原链接:https://blog.csdn.net/daichangxia/article/details/78139324?locationNum=7&fps=1

    展开全文
  • Servlet 接口定义了一套网络请求的规范 2.Servlet 是 javaweb 的三大组件之一。 javaweb 的三大组件分为 Servlet程序、Filter 过滤器、Listener 监听器 3.Servlet 是运行在服务器上的一个 java 程序。作为来自 ...

    一.Servlet

    1.概念

    什么是Servlet?
    1.Servlet 是 java EE 的规范之一。也就是接口。Servlet 接口定义了一套网络请求的规范
    
     2.Servlet 是 javaweb 的三大组件之一。 javaweb 的三大组件分为 Servlet程序、Filter 过滤器、Listener 监听器
    
     3.Servlet 是运行在服务器上的一个 java 程序。作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层(可以接收客户端发送的请求,并且响应 数据给客户端)。
    
    
    * 概念:
    		* 定义了一个类被浏览器访问的规则。是一个接口。
    		* 功能:
    			* 接受请求
    			* 处理请求
    			* 作出响应
    	* 快速入门:
    		0.创建web项目
    		1.定义一个Java类,实现Servlet接口
    		2.重写所有未实现方法 service()方法里面写句话
    		3.配置Servlet,web/WEB-INF/web.xml 配置Servlet
    			  <!-- 配置Servlet,为了配置Servlet的访问路径 -->
    			  <servlet>
    				<servlet-name>demo1</servlet-name>
    				<servlet-class>cn.itcast.servlet.ServletDemo1</servlet-class>
    			  </servlet>
      
    			  <servlet-mapping>
    				<servlet-name>demo1</servlet-name>
    				<!-- 设置访问路径,以/开头  -->
    				<url-pattern>/demo</url-pattern>
    			  </servlet-mapping>
    		4.发布项目
    		5.访问/demo路径访问该Servlet
    		浏览器中:http://127.0.0.1:8080/项目名/web.xml中配置的虚拟路径名
    

    在这里插入图片描述

    Java类,需要实现Servlet方法

    package org.westos.demo;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class MyServlet implements Servlet {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
    
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
        
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("请求来了");
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
        @Override
        public void destroy() {
    
        }
    }
    
    

    配置文件 web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        
        <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>org.westos.demo.MyServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <!--配置映射路径-->
            <url-pattern>/demo</url-pattern>
        </servlet-mapping>
    </web-app>
    

    客户端浏览器发送请求:

    在这里插入图片描述

    服务器收到请求
    在这里插入图片描述

    2.Servlet的生命周期

    Servlet的原理:
    		* 服务器通过反射的方式 创建Servlet对象,调用其方法
    		
    * servlet生命周期:
    		* 被创建:默认情况下,Servlet第一次被访问时,被创建,调用init()方法。
    				  只执行一次。Servlet是单例的。可能会存在线程安全问题,尽量不要定义成员变量。
    				  可以配置Servlet的创建时机。在web.xml的<servlet>标签中配置<load-on-startup>
    						<!-- 修改servlet的创建时机:
    							* 负整数:默认值 -1,在第一次被访问时创建
    							* 非负整数:在服务器启动时创建
    								* 数字越小,优先级越高
    						-->
    						<load-on-startup>0</load-on-startup>
    		
    		* 提供服务:每一次被访问时,会调用service()方法提供服务
    		
    		* 被销毁:服务器关闭时,servlet被销毁。
    				  服务器正常关闭是,在销毁Servlet之前,会调用destory()方法
    				  
      
         Servlet的生命周期方法
         生命周期:一个事物从生到死,所经历的一个过程。
        
         Servlet的生命周期方法:Servlet从被创建 到 销毁,在不同阶段,所要调用的一些生命周期方法。
        
           init()----service()----destroy()
         				  
    

    MyServlet2.java

    package org.westos.demo;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class MyServlet2 implements Servlet {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            //被创建:默认情况下,Servlet第一次被访问时,Servlet通过构造被创建,调用init() 方法。
            //init()只调用一次。那么这个方法里面,可以做一下准备工作。
            System.out.println("init()方法调用了");
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            //*提供服务:每一次被访问时,会调用service() 方法提供服务
            //service() 每次请求都会调用
            System.out.println("service()方法调用了");
        }
    
        @Override
        public void destroy() {
            //正常关闭服务器时,服务器会销毁servlet,那么销毁之前,就会调用destroy()方法
            System.out.println("destory()方法调用了");
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
    }
    
    

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>org.westos.demo.MyServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <!--配置映射路径-->
            <url-pattern>/demo</url-pattern>
        </servlet-mapping>
    
        <!--多加一个Servlet,就要多配置一个xml路径-->
        <servlet>
            <servlet-name>MyServlet2</servlet-name>
            <servlet-class>org.westos.demo.MyServlet2</servlet-class>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>MyServlet2</servlet-name>
            <url-pattern>/demo2</url-pattern>
        </servlet-mapping>
    </web-app>
    

    在这里插入图片描述

    3.配置Servlet的创建时机

    修改servlet的创建时机:
    					* 负整数:默认值 -1,在第一次被访问时创建
    					* 非负整数:在服务器启动时创建
    					* 数字越小,优先级越高
    					
    					<load-on-startup>0</load-on-startup>
    					
    如果优先级相同,会按照web.xml文件从上到下加载
    

    MyServlet1.java

    package org.westos.demo;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class MyServlet implements Servlet {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            System.out.println("Servlet1创建了");
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("请求来了");
        }
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
    }
    
    

    MyServlet2.java

    package org.westos.demo;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class MyServlet2 implements Servlet {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            System.out.println("Servlet2创建了");
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    
        }
        @Override
        public void destroy() {
    
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
    }
    
    

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        
        <!--配置servlet-->
        <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>org.westos.demo.MyServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <url-pattern>/demo</url-pattern>
        </servlet-mapping>
    
        <servlet>
            <servlet-name>MyServlet2</servlet-name>
            <servlet-class>org.westos.demo.MyServlet2</servlet-class>
            <load-on-startup>0</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>MyServlet2</servlet-name>
            <url-pattern>/demo2</url-pattern>
        </servlet-mapping>
    </web-app>
    

    在这里插入图片描述

    4.ServletConfig

    * ServletConfig对象: ServletConfig 配置对象,是个接口,他的对象由服务器创建,然后传递给init方法
    
    * 功能
    			1.获取servlet初始化参数
    				*  String getInitParameter(String name)键找值  
    				*  Enumeration getInitParameterNames()  拿出集合后再键找值
    				
    	例子:
    		System.out.println(config.getInitParameter("src"));
    		System.out.println(config.getInitParameter("href"));
    		Enumeration<String> names = config.getInitParameterNames();
    		while (names.hasMoreElements()) {
    			String key = names.nextElement();
    			System.out.println(key);
    			System.out.println(config.getInitParameter(key));
    
    		}
    
    				初始化参数可在 web.xml中配置
    <servlet>
        <servlet-name>demo3</servlet-name>
        <servlet-class>com.click369.servlet.ServletDemo3</servlet-class>
    <!--配置一些初始化参数-->
        <init-param>
          <param-name>src</param-name>
          <param-value>c://a.txt</param-value>
        </init-param>
        <init-param>
          <param-name>href</param-name>
          <param-value>d://a.txt</param-value>
        </init-param>
      </servlet>
      <servlet-mapping>
        <servlet-name>demo3</servlet-name>
        <url-pattern>/demo3</url-pattern>
      </servlet-mapping>
      
      作用2:
      	获取ServletContext全局上下文对象   因为 ServletContext对象是由服务器创建出来的 我们要获取其对象 得通过ServletConfig对象中的方法才能获取出来
      	* ServletContext getServletContext()
        
    	//ServletContext:全局上下文对象,代表你整个web应用。全局上下文对象,由服务器来创建,服务器一启动,就会创建
    	//ServletContext:全局上下文对象,你是通过配置对象获取出来用。
    	
    	作用3.获取servlet配置的名称 就是在web.xml中给servlet起的名字
    				* String getServletName() 
                    
    		* Servlet中对应getServletConfig方法。要想使用该方法获取config对象。
    			则需要提升config对象的作用域。
    				1.声明成员变量ServletConfig 
    				2.在init方法中赋值
    				3.在getServletConfig方法中获取
    

    MyServlet3.java

    package org.westos.demo;
    
    import javax.servlet.*;
    import java.io.IOException;
    import java.util.Enumeration;
    
    public class MyServlet3 implements Servlet {
        //提升变量作用域,让他在其他方法中也能使用,不局限于init方法
        private ServletConfig servletConfig=null;
    
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            //servletConfig配置对象   ServletConfig是一个接口 在Servlet初始化的时候 有服务器创建其子类对象传递给 init()方法
            //servlet 容器使用的 servlet 配置对象,该对象在初始化期间将信息传递给 servlet。
    
            this.servletConfig=servletConfig;
            System.out.println(servletConfig);
            //org.apache.catalina.core.StandardWrapperFacade@2392c6c
    
            //作用:1.可以获取web.xml中 配置的一些初始化参数
            //两种方式: 键找值
            String username = servletConfig.getInitParameter("username");
            String password = servletConfig.getInitParameter("password");
            /*张三
            123456*/
            System.out.println(username);
            System.out.println(password);
    
            //遍历方式:
            Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
            while (initParameterNames.hasMoreElements()){
                String key = initParameterNames.nextElement();
                String value = servletConfig.getInitParameter(key);
                System.out.println("key:=="+key+"value:=="+value);
                /*
                * key:==password value:==123456
                    key:==username value:==张三
                * */
            }
            System.out.println("===========================================");
            //ServletConfig 作用:2. 可以获取 ServletContext 全局上下文对象。
            ServletContext servletContext = servletConfig.getServletContext();
            //ServletContext:全局上下文对象,代表你整个web应用。全局上下文对象,由服务器来创建,服务器一启动,就会创建
            //ServletContext:全局上下文对象,你是通过配置对象获取出来用。
            System.out.println(servletConfig);
    		//org.apache.catalina.core.StandardWrapperFacade@25f12241
            
            //ServletConfig 作用:3. 可以获取web.xml中配置的Servlet的名字。
            String servletName = servletConfig.getServletName();
            System.out.println(servletName);
            //MyServlet3
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            //我想在service()方法里面用到这个配置对象。
            // servletConfig.getInitParameter("username");
            ServletConfig servletConfig = getServletConfig();
        }
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
    }
    
    

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>org.westos.demo.MyServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <!--配置映射路径-->
            <url-pattern>/demo</url-pattern>
        </servlet-mapping>
    
        <!--多加一个Servlet,就要多配置一个xml路径-->
        <servlet>
            <servlet-name>MyServlet2</servlet-name>
            <servlet-class>org.westos.demo.MyServlet2</servlet-class>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>MyServlet2</servlet-name>
            <url-pattern>/demo2</url-pattern>
        </servlet-mapping>
        
        <servlet>
            <servlet-name>MyServlet3</servlet-name>
            <servlet-class>org.westos.demo.MyServlet3</servlet-class>
    
            <!--配置初始化参数-->
            <init-param>
                <param-name>username</param-name>
                <param-value>张三</param-value>
            </init-param>
            <init-param>
                <param-name>password</param-name>
                <param-value>123456</param-value>
            </init-param>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>MyServlet3</servlet-name>
            <url-pattern>/demo3</url-pattern>
        </servlet-mapping>
    </web-app>
    

    在这里插入图片描述

    5.Servlet的三种创建方式

    		1. 实现Servlet
    		2. 继承GenericServlet
    			1.适配器
    			2.对ServletConfig进行优化。提升config对象的作用域
    			3.实现了ServletConfig接口,简化对config对象的使用方式
    		3. 继承HttpServlet:对http协议的封装
    			* 重写doGet()和doPost()...方法      注意去掉super.doGet(); 和 super.doPost();
    

    在这里插入图片描述
    在这里插入图片描述

    方式2:继承GenericServlet

    GenericServlet.java源码

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package javax.servlet;
    
    import java.io.IOException;
    import java.io.Serializable;
    import java.util.Enumeration;
    
    public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
        private static final long serialVersionUID = 1L;
        private transient ServletConfig config;
    
        public GenericServlet() {
        }
    
        public void destroy() {
        }
    
        public String getInitParameter(String name) {
            return this.getServletConfig().getInitParameter(name);
        }
    
        public Enumeration<String> getInitParameterNames() {
            return this.getServletConfig().getInitParameterNames();
        }
    
        public ServletConfig getServletConfig() {
            return this.config;
        }
    
        public ServletContext getServletContext() {
            return this.getServletConfig().getServletContext();
        }
    
        public String getServletInfo() {
            return "";
        }
    
        public void init(ServletConfig config) throws ServletException {
            this.config = config;
            this.init();
        }
    
        public void init() throws ServletException {
        }
    
        public void log(String msg) {
            this.getServletContext().log(this.getServletName() + ": " + msg);
        }
    
        public void log(String message, Throwable t) {
            this.getServletContext().log(this.getServletName() + ": " + message, t);
        }
    
        public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    
        public String getServletName() {
            return this.config.getServletName();
        }
    }
    
    

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>org.westos.demo.MyServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <!--配置映射路径-->
            <url-pattern>/demo</url-pattern>
        </servlet-mapping>
    
        <!--多加一个Servlet,就要多配置一个xml路径-->
        <servlet>
            <servlet-name>MyServlet2</servlet-name>
            <servlet-class>org.westos.demo.MyServlet2</servlet-class>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>MyServlet2</servlet-name>
            <url-pattern>/demo2</url-pattern>
        </servlet-mapping>
        
        <servlet>
            <servlet-name>MyServlet3</servlet-name>
            <servlet-class>org.westos.demo.MyServlet3</servlet-class>
    
            <!--配置初始化参数-->
            <init-param>
                <param-name>username</param-name>
                <param-value>张三</param-value>
            </init-param>
            <init-param>
                <param-name>password</param-name>
                <param-value>123456</param-value>
            </init-param>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>MyServlet3</servlet-name>
            <url-pattern>/demo3</url-pattern>
        </servlet-mapping>
        
        <servlet>
            <servlet-name>MyServlet4</servlet-name>
            <servlet-class>org.westos.demo2.MyServlet4</servlet-class>
            
            <init-param>
                <param-name>username</param-name>
                <param-value>李白</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>MyServlet4</servlet-name>
            <url-pattern>/demo4</url-pattern>
        </servlet-mapping>
    </web-app>
    

    MyServlet4.java

    package org.westos.demo2;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class MyServlet4 extends GenericServlet {
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            ServletConfig servletConfig = this.getServletConfig();
            ServletContext servletContext = servletConfig.getServletContext();
            System.out.println(servletConfig);//org.apache.catalina.core.StandardWrapperFacade@9d71d74
            System.out.println(servletContext);//org.apache.catalina.core.ApplicationContextFacade@710f23e
            
              //从父类中继承而来
             String username = this.getInitParameter("username");
            System.out.println(username);//李白
            
          
            String username1=servletConfig.getInitParameter("username");
            System.out.println(username1);//李白
        }
    }
    
    

    方式3:继承HttpServlet:对http协议的封装

    package org.westos.demo2;
    
    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;
    
    //以注解的方式配置Servlet的名称  ,       映射路径
    @WebServlet(name = "MyServlet5", value = "/demo5")
    public class MyServlet5 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("get请求来了");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("post请求来了");
            this.doPost(request, response);
        }
    }
    
    

    6. ServletContext全局域对象

    * 特点:
    		* 由服务器创建
    		* 单例
    
    	* 功能:
    		* 域对象:在域的范围内共享数据
    			* 范围:整个web应用
    			* 存储所有用户共享的数据,这四个方法四个域对象都有
    				* setAttribute():
    				* getAttribute():
    				* removeAttribute():
    
    * JavaWeb中四大域对象:
    1.ServletContext 他是一个全局域对象,域,就是范围的意思,域对象可以在他所代表				的范围内进行数据的共享。
    2.HttpSession:会话域
    3.ServletRequest:请求域
    4.PageContext:页面域
    
     四个域对象存取数据,删除数据的方法。
            context.setAttribute();
            context.getAttribute()
            context.removeAttribute();
    
    
    * 获取文件mime类型:
    			* getMimeType(文件名称):
    		* 获取文件运行的真实路径:
    			* 真实路径:指服务器路径
    			* getRealPath():
    				 * 1.webRoot下:项目根目录下
    				 * 2.WEB-INF下: 项目根目录下/WEB-INF
    				 * 3.src下: 项目根目录下/WEB-INF/classes
    				 
    				 * *注意:如果getRealPath("/"),获取的路径是项目的根目录
    
    				//根目录
    					ServletContext context = this.getServletContext();
    					String rootpath = context.getRealPath("/");
    					//System.out.println(rootpath);
    					//1.webRoot
    					String b = context.getRealPath("/b.txt");
    					System.out.println(b);
    					//2.WEB-INF
    					String c = context.getRealPath("/WEB-INF/c.txt");
    					System.out.println(c);
    					//3.src
    					String a = context.getRealPath("/WEB-INF/classes/a.txt");
    					System.out.println(a);
    
    				* ServletContext只能用于web环境。如果是非web环境,则使用ClassLoader来获取真实路径
    
    					比如我web项目里有一个普通的java工具类 我想获取文件的真实路径 那我就用不了 ServletContext
    					//1.获取该类对应的类加载器对象
    					ClassLoader loader = this.getClass().getClassLoader();
    					//2.获取文件运行的真实路径
    					URL url = loader.getResource("a.txt");
    					String path = url.getPath();
    					//注意类加载器来获取路径也有局限性 只能获取src目录下的文件
        					// 方式2
    					InputStream stream = MyUtil.class.getClassLoader().getResourceAsStream("/a.txt");
    					System.out.println(stream);
    
    

    编写两个类来模拟

    MyServlet.java

    package org.westos.demo;
    
    import javax.servlet.ServletContext;
    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;
    
    @WebServlet(name = "MyServlet", value = "/demo")
    public class MyServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("请求来了");
            //获取全局域对象
            ServletContext context = this.getServletConfig().getServletContext();
            //往域中存储数据
            context.setAttribute("username","zs");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    
    

    MyServlet2.java

    package org.westos.demo;
    
    import javax.servlet.ServletContext;
    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;
    
    @WebServlet(name = "MyServlet2", value = "/demo2")
    public class MyServlet2 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            //  ServletContext 全局上下文对象,服务器已开启,就会创建,他代表了整个web应用。
            /* 特点:
             由服务器创建
              单例
    
            //web 中的四大域对象。
            ServletContext 他是一个全局域对象,域,就是范围的意思,域对象可以在他所代表的范围内进行数据的共享。
            Session 会话域
             Request 请求域
             PageContext 页面域
    
            四个域对象存取数据,删除数据的方法。
            context.setAttribute();
            context.getAttribute()
            context.removeAttribute();*/
            ServletContext context = this.getServletConfig().getServletContext();
            //获取域中的数据
            String username = (String) context.getAttribute("username");
            System.out.println(username);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    
    

    7.本地项目与Web项目

    	本地项目是可以在自己计算机上访问到的项目,以前的JavaSE所有项目都属于本地项目,本地项目的路径是写死的;
    	Web项目是你将写好的项目打成war包发送给运维人员,放到公司服务器上,而这个项目仍然可以在你公司的服务器上运行,这就要求我们不能把路径写死,否则这个项目可能只会在你自己的计算机上运行
    	注意:打成war包后项目的路径有所改变,且war包下没有src路径
    

    本地项目的方式:

    这种直接把路径给写死了

    package org.westos.demo;
    
    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.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    @WebServlet(name = "MyServlet", value = "/demo")
    public class MyServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("demo 请求来了");
            //我在web目录下有一个a.txt
            //web/WEB-INF/ 有一个b.txt
            //在 src 下有一个c.txt
            FileInputStream in = new FileInputStream(new File("D:\\develop\\apache-tomcat-8.5.43\\webapps\\demo\\WEB-INF\\classes\\c.txt"));
            System.out.println(in);
    
            FileInputStream in2 = new FileInputStream(new File("D:\\develop\\apache-tomcat-8.5.43\\webapps\\demo\\a.txt"));
    
            System.out.println(in2);
    
            FileInputStream in3 = new FileInputStream(new File("D:\\develop\\apache-tomcat-8.5.43\\webapps\\demo\\WEB-INF\\b.txt"));
    
            System.out.println(in3);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    
    

    8.获取文件运行的真实路径

    * 获取文件mime类型:
    			* getMimeType(文件名称):
    		* 获取文件运行的真实路径:
    			* 真实路径:指服务器路径
    			* getRealPath():
    				 * 1.webRoot下:项目根目录下
    				 * 2.WEB-INF下: 项目根目录下/WEB-INF
    				 * 3.src下: 项目根目录下/WEB-INF/classes
    				 
    				 * *注意:如果getRealPath("/"),获取的路径是项目的根目录
    
    				//根目录
    					ServletContext context = this.getServletContext();
    					String rootpath = context.getRealPath("/");
    					//System.out.println(rootpath);
    					//1.webRoot
    					String b = context.getRealPath("/b.txt");
    					System.out.println(b);
    					//2.WEB-INF
    					String c = context.getRealPath("/WEB-INF/c.txt");
    					System.out.println(c);
    					//3.src
    					String a = context.getRealPath("/WEB-INF/classes/a.txt");
    					System.out.println(a);
    
    				* ServletContext只能用于web环境。如果是非web环境,则使用ClassLoader来获取真实路径
    
    					比如我web项目里有一个普通的java工具类 我想获取文件的真实路径 那我就用不了 ServletContext
    					//1.获取该类对应的类加载器对象
    					ClassLoader loader = this.getClass().getClassLoader();
    					//2.获取文件运行的真实路径
    					URL url = loader.getResource("a.txt");
    					String path = url.getPath();
    					//注意类加载器来获取路径也有局限性 只能获取src目录下的文件
        					// 方式2
    					InputStream stream = MyUtil.class.getClassLoader().getResourceAsStream("/a.txt");
    					System.out.println(stream);
    
    

    获取web环境下的真实路径

    package org.westos.demo;
    
    import javax.servlet.ServletContext;
    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.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    @WebServlet(name = "MyServlet2", value = "")
    public class MyServlet2 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //继承自GenericServlet.clas
            ServletContext context = this.getServletContext();
            System.out.println(context);
            //  org.apache.catalina.core.ApplicationContextFacade@2566f84d
            String realPath = context.getRealPath("/");
            System.out.println(realPath);
            //D:\develop\apache-tomcat-8.5.43\webapps\demo\
    
            FileInputStream in1 = new FileInputStream(new File(realPath + "a.txt"));
            System.out.println(in1);
            //java.io.FileInputStream@764bb5c2
    
            FileInputStream in2 = new FileInputStream(new File(realPath + "WEB-INF\\b.txt"));
            System.out.println(in2);
            //java.io.FileInputStream@72742fd3
    
            FileInputStream in3 = new FileInputStream(new File(realPath + "WEB-INF\\classes\\c.txt"));
            System.out.println(in3);
            //java.io.FileInputStream@3776bff9
    
            String mimeType = context.getMimeType(realPath + "a.txt");
            System.out.println(mimeType);//text/plain
    
             new MyUtils().test();
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    
    

    读取web工程下普通的java类

      如果是web工程中普通的Java类,想要读取src下的文件,通过类加载器
    
    package org.westos.utils;
    
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    import java.net.URL;
    
    public class MyUtils {
        public void test() throws FileNotFoundException {
            //如果是web工程中普通的Java类,想要读取src下的文件,只能通过类加载器
            InputStream resourceAsStream = MyUtils.class.getClassLoader().getResourceAsStream("c.txt");
            System.out.println(resourceAsStream);
    
            URL url = MyUtils.class.getClassLoader().getResource("c.txt");
            System.out.println(url);//file:/D:/develop/apache-tomcat-8.5.43/webapps/demo/WEB-INF/classes/c.txt
            String path = url.getPath();
            System.out.println(path);//  /D:/develop/apache-tomcat-8.5.43/webapps/demo/WEB-INF/classes/c.txt
    
        }
    }
    
    

    二.MIME类型

    1、什么是MIME类型

    根据百度百科的解释:MIME:全称Multipurpose Internet Mail Extensions,多功能Internet邮件扩充服务。它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器。MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
    
    说白了也就是文件的媒体类型。浏览器可以根据它来区分文件,然后决定什么内容用什么形式来显示。
    

    2.部分文件的MIMEType

    文件拓展名 MIMEType
    png image/png
    bmp\dib image/bmp
    jpg\jpeg\jpg image/ipeg
    gif image/gif
    mp3 audio/mpeg
    mp4\mpg4\m4v\mp4v video/mp4
    js application/javascript
    pdf application/pdf
    text\txt text/plan
    json application/json
    xml text/xml

    3.为什么要获取MIMEType

    关于为什么要获取MIMEType的原因,是因为在进行文件上传的时候,需要在POST请求体中传递相应的参数,来进行文件的上传操作
    
    ​```
    说明:当然你也可以直接传递application/octet-stream,此参数表示通用的二进制类型。
    ​```
    

    三.常用的头信息

    请求头
    	Accept: text/html,image/*	--告诉服务器当前客户端可以接收的文档的类型。其实这里包含了*/*,就表示什么都可以接收;  大类型/小类型 比如 text/css text/javascript
    	Accept-Charset: ISO-8859-1	--告诉服务器,客户端提交的表单可能使用的编码类型
    	Accept-Encoding: gzip		--浏览器发给服务器,声明浏览器支持的编码类型
    	Accept-Language:zh-cn 		--语言环境
    	Host: localhost:8080		--访问主机
    	If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT	 客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过:
    后面跟的时间是本地浏览器存储的文件修改时间
    
    	Referer: http://www.baidu.com/index.jsp	 --来自哪个页面、防盗链
    	User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
    	Cookie
    	Connection:Keep-Alive   	--链接状态 长链接
    	Date: Tue, 11 Jul 2000 18:23:51 GMT	--时间
    
    
    响应头
    Location: http://www.baidu.org/index.jsp 	--跳转方向 302重定向
    Server:apache tomcat			--服务器型号
    Content-Encoding: gzip 			--数据压缩
    Content-Length: 80 			--数据长度
    Content-Language: zh-cn 		--语言环境
    Content-Type: text/html; charset=GB2312 --告诉浏览器,服务器返回的文本采用什么编码
    Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT	在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,
    Refresh: 3;url=http://www.hehe.org		--延时3s跳转页面
    Content-Disposition: attachment; filename=aaa.zip	--下载
    Set-Cookie:SS=Q0=5Lb_nQ; path=/search
    Expires: -1					--缓存  就是让页面立即过期
    Cache-Control: no-cache  --浏览器和缓存服务器都不应该缓存页面信息强制每次请求直接发送给源服务器,而不经过本地缓存版本的校验
    Connection: Keep-Alive   			--保持连接 长链接
    Date: Tue, 11 Jul 2000 18:23:51 GMT
    
    
    
    
    
    
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("进入了demo11,接下来3秒钟后进入demo10");
            response.setHeader("refresh", "3;url=/ResponseDemo/ResponseDemo10"); //设置刷新头延时3秒跳转页面
        }
    

    四.Servlet是单例多线程

    Servlet如何处理多个请求访问?
    Servlet容器默认是采用单实例多线程的方式处理多个请求的:
    1.当web服务器启动的时候(或客户端发送请求到服务器时),Servlet就被加载并实例化(只存在一个Servlet实例);
    2.容器初始化化Servlet主要就是读取配置文件(例如tomcat,可以通过servlet.xml的<Connector>设置线程池中线程数目,初始化线程池通过web.xml,初始化每个参数值等等。
    3.当请求到达时,Servlet容器通过调度线程(Dispatchaer Thread) 调度它管理下线程池中等待执行的线程(Worker Thread)给请求者;
    4.线程执行Servlet的service方法;
    5.请求结束,放回线程池,等待被调用;
    (注意:避免使用实例变量(成员变量),因为如果存在成员变量,可能发生多线程同时访问该资源时,都来操作它,照成数据的不一致,因此产生线程安全问题)
    
    从上面可以看出:
    第一:Servlet单实例,减少了产生servlet的开销;
    第二:通过线程池来响应多个请求,提高了请求的响应时间;
    第三:Servlet容器并不关心到达的Servlet请求访问的是否是同一个Servlet还是另一个Servlet,直接分配给它一个新的线程;如果是同一个Servlet的多个请求,那么Servlet的service方法将在多线程中并发的执行;
    第四:每一个请求由ServletRequest对象来接受请求,由ServletResponse对象来响应该请求;
    
    Servlet/JSP技术和ASP、PHP等相比,由于其多线程运行而具有很高的执行效率。由于Servlet/JSP默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的安全性问题。 
    
    JSP的中存在的多线程问题: 
    当客户端第一次请求某一个JSP文件时,服务端把该JSP编译成一个CLASS文件,并创建一个该类的实例,然后创建一个线程处理CLIENT端的请求。如果有多个客户端同时请求该JSP文件,则服务端会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可大大降低对系统的资源需求,提高系统的并发量及响应时间. 
    
    对JSP中可能用的的变量说明如下: 
    实例变量: 实例变量是在堆中分配的,并被属于该实例的所有线程共享,所以不是线程安全的. 
    JSP系统提供的8个类变量 
    JSP中用到的OUT,REQUEST,RESPONSE,SESSION,CONFIG,PAGE,PAGECONXT是线程安全的(因为每个线程对应的request,respone对象都是不一样的,不存在共享问题), APPLICATION在整个系统内被使用,所以不是线程安全的. 
    
    局部变量: 局部变量在堆栈中分配,因为每个线程都有它自己的堆栈空间,所以是线程安全的. 
    静态类: 静态类不用被实例化,就可直接使用,也不是线程安全的. 
    
    外部资源: 在程序中可能会有多个线程或进程同时操作同一个资源(如:多个线程或进程同时对一个文件进行写操作).此时也要注意同步问题. 
    
    使它以单线程方式执行,这时,仍然只有一个实例,所有客户端的请求以串行方式执行。这样会降低系统的性能 
    
    问题 
    问题一. 说明其Servlet容器如何采用单实例多线程的方式来处理请求 
    问题二. 如何在开发中保证servlet是单实例多线程的方式来工作(也就是说如何开发线程安全的servelt)。 
    
    一. Servlet容器如何同时来处理多个请求 
    
    Java的内存模型JMM(Java Memory Model) 
    JMM主要是为了规定了线程和内存之间的一些关系。根据JMM的设计,系统存在一个主内存(Main Memory),Java中所有实例变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存由缓存和堆栈两部分组成,缓存中保存的是主存中变量的拷贝,缓存可能并不总和主存同步,也就是缓存中变量的修改可能没有立刻写到主存中;堆栈中保存的是线程的局部变量,线程之间无法相互直接访问堆栈中的变量。根据JMM,我们可以将论文中所讨论的Servlet实例的内存模型抽象为图所示的模型。 
    
     
    
    工作者线程Work Thread:执行代码的一组线程。 
    调度线程Dispatcher Thread:每个线程都具有分配给它的线程优先级,线程是根据优先级调度执行的。 
    
    Servlet采用多线程来处理多个请求同时访问。servlet依赖于一个线程池来服务请求。线程池实际上是一系列的工作者线程集合。Servlet使用一个调度线程来管理工作者线程。 
    
    当容器收到一个Servlet请求,调度线程从线程池中选出一个工作者线程,将请求传递给该工作者线程,然后由该线程来执行Servlet的service方法。当这个线程正在执行的时候,容器收到另外一个请求,调度线程同样从线程池中选出另一个工作者线程来服务新的请求,容器并不关心这个请求是否访问的是同一个Servlet.当容器同时收到对同一个Servlet的多个请求的时候,那么这个Servlet的service()方法将在多线程中并发执行。 
    Servlet容器默认采用单实例多线程的方式来处理请求,这样减少产生Servlet实例的开销,提升了对请求的响应时间,对于Tomcat可以在server.xml中通过<Connector>元素设置线程池中线程的数目。 
    
    就实现来说: 
    调度者线程类所担负的责任如其名字,该类的责任是调度线程,只需要利用自己的属性完成自己的责任。所以该类是承担了责任的,并且该类的责任又集中到唯一的单体对象中。而其他对象又依赖于该特定对象所承担的责任,我们就需要得到该特定对象。那该类就是一个单例模式的实现了。 
    
    
    注意:服务器可以使用多个实例来处理请求,代替单个实例的请求排队带来的效益问题。服务器创建一个Servlet类的多个Servlet实例组成的实例池,对于每个请求分配Servlet实例进行响应处理,之后放回到实例池中等待下此请求。这样就造成并发访问的问题。 
    此时,局部变量(字段)也是安全的,但对于全局变量和共享数据是不安全的,需要进行同步处理。而对于这样多实例的情况SingleThreadModel接口并不能解决并发访问问题。 SingleThreadModel接口在servlet规范中已经被废弃了。
    
    二 如何开发线程安全的Servlet 
      1、实现 SingleThreadModel 接口 
    
      该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要将前面的Concurrent Test类的类头定义更改为: 
    
    Public class Concurrent Test extends HttpServlet implements SingleThreadModel { 
    ………… 
    } 
    
      2、同步对共享数据的操作 
    
      使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中的Servlet可以通过同步块操作来保证线程的安全。同步后的代码如下: 
    
    ………… 
    Public class Concurrent Test extends HttpServlet { ………… 
    Username = request.getParameter ("username"); 
    Synchronized (this){ 
    Output = response.getWriter (); 
    Try { 
    Thread. Sleep (5000); 
    } Catch (Interrupted Exception e){} 
    output.println("用户名:"+Username+"<BR>"); 
    } 
    } 
    } 
    
      3、避免使用实例变量 
    
      本实例中的线程安全问题是由实例变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。 
    
      修正上面的Servlet代码,将实例变量改为局部变量实现同样的功能,代码如下: 
    
    …… 
    Public class Concurrent Test extends HttpServlet {public void service (HttpServletRequest request, HttpServletResponse 
    Response) throws ServletException, IOException { 
    Print Writer output; 
    String username; 
    Response.setContentType ("text/html; charset=gb2312"); 
    …… 
    } 
    } 
    
    
     ** 对上面的三种方法进行测试,可以表明用它们都能设计出线程安全的Servlet程序。但是,如果一个Servlet实现了SingleThreadModel接口,Servlet引擎将为每个新的请求创建一个单独的Servlet实例,这将引起大量的系统开销。SingleThreadModel在Servlet2.4中已不再提倡使用;同样如果在程序中使用同步来保护要使用的共享的数据,也会使系统的性能大大下降。这是因为被同步的代码块在同一时刻只能有一个线程执行它,使得其同时处理客户请求的吞吐量降低,而且很多客户处于阻塞状态。另外为保证主存内容和线程的工作内存中的数据的一致性,要频繁地刷新缓存,这也会大大地影响系统的性能。所以在实际的开发中也应避免或最小化 Servlet 中的同步代码;在Serlet中避免使用实例变量是保证Servlet线程安全的最佳选择。从Java 内存模型也可以知道,方法中的临时变量是在栈上分配空间,而且每个线程都有自己私有的栈空间,所以它们不会影响线程的安全。
    更加详细的说明:
    
    1,变量的线程安全:这里的变量指字段和共享数据(如表单参数值)。 
    a,将 参数变量 本地化。多线程并不共享局部变量.所以我们要尽可能的在servlet中使用局部变量。 
    例如:String user = ""; 
    user = request.getParameter("user"); 
    
    b,使用同步块Synchronized,防止可能异步调用的代码块。这意味着线程需要排队处理。在使用同板块的时候要尽可能的缩小同步代码的范围,不要直接在sevice方法和响应方法上使用同步,这样会严重影响性能。 
    
    2,属性的线程安全:ServletContext,HttpSession,ServletRequest对象中属性。 
    ServletContext:(线程是不安全的) 
    ServletContext是可以多线程同时读/写属性的,线程是不安全的。要对属性的读写进行同步处理或者进行深度Clone()。所以在Servlet上下文中尽可能少量保存会被修改(写)的数据,可以采取其他方式在多个Servlet中共享,比方我们可以使用单例模式来处理共享数据。 
    HttpSession:(线程是不安全的) 
    HttpSession对象在用户会话期间存在,只能在处理属于同一个Session的请求的线程中被访问,因此Session对象的属性访问理论上是线程安全的。 
    当用户打开多个同属于一个进程的浏览器窗口,在这些窗口的访问属于同一个Session,会出现多次请求,需要多个工作线程来处理请求,可能造成同时多线程读写属性。这时我们需要对属性的读写进行同步处理:使用同步块Synchronized和使用读/写器来解决。 
    ServletRequest:(线程是安全的) 
    对于每一个请求,由一个工作线程来执行,都会创建有一个新的ServletRequest对象,所以ServletRequest对象只能在一个线程中被访问。ServletRequest是线程安全的。注意:ServletRequest对象在service方法的范围内是有效的,不要试图在service方法结束后仍然保存请求对象的引用。 
    
    4,不要在Servlet中创建自己的线程来完成某个功能。 
    Servlet本身就是多线程的,在Servlet中再创建线程,将导致执行情况复杂化,出现多线程安全问题。 
    
    5,在多个servlet中对外部对象(比方文件)进行修改操作一定要加锁,做到互斥的访问。 
    
    6,javax.servlet.SingleThreadModel接口是一个标识接口,如果一个Servlet实现了这个接口,那Servlet容器将保证在一个时刻仅有一个线程可以在给定的servlet实例的service方法中执行。将其他所有请求进行排队。 
    
    
    PS:
    Servlet并非只是单例的. 当container开始启动,或是客户端发出请求服务时,Container会按照容器的配置负责加载和实例化一个Servlet(也可以配置为多个,不过一般不这么干).不过一般来说一个servlet只会有一个实例。
    1) Struts2的Action是原型,非单实例的;会对每一个请求,产生一个Action的实例来处理。 
    2) Struts1的Action,Spring的Ioc容器管理的bean 默认是单实例的. 
    
    Struts1 Action是单实例的,spring mvc的controller也是如此。因此开发时要求必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。 
    Spring的Ioc容器管理的bean 默认是单实例的。
    Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)。
    当Spring管理Struts2的Action时,bean默认是单实例的,可以通过配置参数将其设置为原型。(scope="prototype )
    
    
    
    
    Servlet的生命周期:
    
    1.      Servlet在web服务器启动时被加载并实例化,容器运行其init方法初始化,请求到达时运行其service方法;
    
    2.      service运行请求对应的doXXX(doGet,doPost)方法;
    
    3.      服务器销毁实例,运行其destory方法;
    
    Servlet的生命周期由Servlet容器管理;
    
    (三个概念的理解:
    
    Servlet容器<Web容器<应用服务器?
    
    Servlet容器的主要任务就是管理Servlet的生命周期;
    
    Web容器也称之为web服务器,主要任务就是管理和部署web应用的;
    
    应用服务器的功能非常强大,不仅可以管理和部署web应用,也可以部署EJB应用,实现容器管理的事务等等。。。
    
    
    Web服务器就是跟基于HTTP的请求打交道,而EJB容器更多是跟数据库,事务管理等服务接口交互,所以应用服务器的功能是很多的。
    
    常见的web服务器就是Tomcat,但Tomcat同样也是Servlet服务器;
    
    常见的应用服务器有WebLogic,WebSphere,但都是收费的;
    
    没有Servlet容器,可以用Web容器直接访问静态Html页面,比如安装了apache等;如果需要显示Jsp/Servlet,就需要安装一个Servlet容器;但是光有servlet容器也是不够的,它需要被解析为html显示,所以仍需要一个web容器;所以,我们常把web容器和Servlet容器视为一体,因为他们两个容器都有对方的功能实现了,都没有独立的存在了,比如tomcat!
    
    )
    

    在这里插入图片描述

    五.响应状态吗

    
    http状态返回代码 1xx(临时响应)
    表示临时响应并需要请求者继续执行操作的状态代码。
    
    http状态返回代码 代码   说明
    100   (继续) 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。 
    101   (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。
    
    http状态返回代码 2xx (成功)
    表示成功处理了请求的状态代码。
    
    http状态返回代码 代码   说明
    200   (成功)  服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
    201   (已创建)  请求成功并且服务器创建了新的资源。
    202   (已接受)  服务器已接受请求,但尚未处理。
    203   (非授权信息)  服务器已成功处理了请求,但返回的信息可能来自另一来源。
    204   (无内容)  服务器成功处理了请求,但没有返回任何内容。
    205   (重置内容) 服务器成功处理了请求,但没有返回任何内容。
    206   (部分内容)  服务器成功处理了部分 GET 请求。
    
    http状态返回代码 3xx (重定向)
    表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
    
    http状态返回代码 代码   说明
    300   (多种选择)  针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
    301   (永久移动)  请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
    302   (临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
    303   (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
    304   (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
    305   (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
    307   (临时重定向)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
    
    http状态返回代码 4xx(请求错误)
    这些状态代码表示请求可能出错,妨碍了服务器的处理。
    
    http状态返回代码 代码   说明
    400   (错误请求) 服务器不理解请求的语法。
    401   (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
    403   (禁止) 服务器拒绝请求。
    404   (未找到) 服务器找不到请求的网页。
    405   (方法禁用) 禁用请求中指定的方法。
    406   (不接受) 无法使用请求的内容特性响应请求的网页。
    407   (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
    408   (请求超时)  服务器等候请求时发生超时。
    409   (冲突)  服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
    410   (已删除)  如果请求的资源已永久删除,服务器就会返回此响应。
    411   (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
    412   (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
    413   (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
    414   (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
    415   (不支持的媒体类型) 请求的格式不受请求页面的支持。
    416   (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
    417   (未满足期望值) 服务器未满足"期望"请求标头字段的要求。
    
    http状态返回代码 5xx(服务器错误)
    这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
    
    http状态返回代码 代码   说明
    500   (服务器内部错误)  服务器遇到错误,无法完成请求。
    501   (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
    502   (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
    503   (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
    504   (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。
    505   (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。 
    一些常见的http状态返回代码为:
    
    200 - 服务器成功返回网页
    404 - 请求的网页不存在
    503 - 服务不可用
    
     
    
    

    六.响应对象

    1.概述

    	当服务器收到浏览器的请求后,服务器会创建Servlet对象,也会去创建请求对象和响应对象,请求对象,会把浏览器的请求的信息封装到,
    	请求对象里面,然后服务器,通过方式调用service()方法, 然后把请求对象和响应对象,传给该方法,你就可以在service()方法 中取出这两个对象来用。
       如果你要设置响应信息,你就把响应的数据设置到响应对象里面,服务器在正式响应浏览器之前,会从响应对象里面取出响应
       的数据,给浏览器响应回去,但这次请求响应完成之后,服务器就会这次创建的请求对象和响应对象
    

    2.重定向

     请求对象和响应对象,由服务器创建,管理,和销毁,你只是拿来用。
    
    response:设置响应消息
    	  设置响应行: HTTP/1.1   200   ok
    		setStatus(int code);设置响应状态码
    		重定向  302
    		 特点:1.两次请求,两次响应
    		         2.地址栏发生变化
    		        3.不仅可以访问内部资源,也可访问外部资源
    
    		      代码:
    		// 设置状态码 302 重定向
    		response.setStatus(302);
    		// 设置响应头 location
    		response.setHeader("location","http://127.0.0.1:8080/MyServlet/index.jsp");
    		// 以上两步可以合成一个简便方法
    		response.sendRedirect("http://www.baidu.com");
    
    		
                      设置响应头: 例如:content-type:text/html;charset=utf-8
    		setHeader(String headName,String headValue); 设置响应头的名称和值
    		setDateHeader(String name,long date); 设置日期头
    		setIntHeader(String name,int count); 设置数字头
    	设置响应体:响应体响应的是数据  得通过流的方式
    	                获取输出流写出数据
    		
    		**PrintWriter getWriter();发送字符数据的对象
    
    		// 为了防止乱码,我们设置一下服务器对字符流的编码 默认服务器用的是ISO-8859-1
    		// 所以在获取流之前告诉服务器用什么编码
    		response.setCharacterEncoding("utf-8");
    		//告诉浏览器我们用的是什么编码 ,好让浏览器用响应的编码去解码
    		response.setHeader("content-type","text/html;charset=utf-8");
    		//以上两个方法可以合二为一
    		response.setContentType("text/html;charset=utf-8");//作用:设置字符打印输出流的编码,并告诉浏览器用相应的编码去解码
    		
    
    		**ServletOutputStream getOutputStream(); 发送字节数据的对象	
    	  	
    		// 获取字节流 用流向浏览器写出一张图片
    		ServletOutputStream sos = response.getOutputStream();
    		// 获取图片的真实路径
    		String realPath = this.getServletContext().getRealPath("/302.png");
    		// 获取输入流读取图片
    		FileInputStream fis = new FileInputStream(new File(realPath));
    		byte[] by = new byte[1024];
    		int len = 0;
    		while ((len = fis.read(by)) != -1) {
    			sos.write(by, 0, len);
    		}
    

    MyServlet3.java

    package org.westos.demo2;
    
    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;
    
    @WebServlet(name = "MyServlet3", value = "/demo3")
    public class MyServlet3 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 请求对象和响应对象,由服务器创建,管理,和销毁,你只是拿来用。
            /*
            *  当服务器收到浏览器的请求后,服务器会创建Servlet对象,也会去创建请求对象和响应对象,
            * 请求对象,会把浏览器的请求的信息封装到,请求对象里面,然后服务器,通过方式调用service()方法,
            * 然后把请求对象和响应对象,传给该方法,你就可以在service()方法 中取出这两个对象来用。
            * 如果你要设置响应信息,你就把响应的数据设置到响应对象里面,服务器在正式响应浏览器之前,会从响应对象里面取出响应
            * 的数据,给浏览器响应回去,但这次请求响应完成之后,服务器就会这次创建的请求对象和响应对象。*/
            System.out.println(request);
            System.out.println(response);
    
            System.out.println("servlet1,收到请求了");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    
    

    MyServlet4.java

    package org.westos.demo2;
    
    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;
    
    @WebServlet(name = "MyServlet4", value = "/demo4")
    public class MyServlet4 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("demo4收到请求了");
            //设置响应状态码
            response.setStatus(302);
            response.setHeader("location","http://www.baidu.com");
    
            //跳转到我们自己站点中的资源
            //response.setHeader("location", "/20200816___war_exploded/index.jsp");
            //response.setHeader("location", "/20200816___war_exploded/demo3");
            /*
            *           重定向  302
    		         特点:1.两次请求,两次响应
    		         2.地址栏发生变化
    		        3.不仅可以访问内部资源,也可访问外部资源
            *
            *
            *
            * */
            //重定向,以上两步,综合为一步,只需调用sendRedirec()
            //response.sendRedirect("https://www.baidu.com");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    
    
    展开全文
  • Java WebHTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。检验客户程序是否支持 ...
    Java WebHTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。检验客户程序是否支持 HTTP 1.1。这些代码分为5类:
    * 100-199 100 到 199 间的代码都是信息性的,标示客户应该采取的其他动作。
    * 200-299 200 到 299 间的值表示请求成功。
    * 300-399 300 到 399 间的值用于那些已经移走的文件,常常包括 Location 报头,指出新的地址。
    * 400-499 400 到 499 间的值表明由客户引发的错误。
    * 500-599 500 到 599 间的代码表示由服务器引发的错误。
    目录

    定义
    1xx 消息
    1. 100 Continue
    2. 101 Switching Protocol
    3. 102 Processing
    2xx 成功
    1. 200 OK 请求成功
    2. 201 Created
    3. 202 Accepted
    4. 203 Non-Authoritative Information
    5 . 204 No Content
    6. 205 Reset Content
    7. 206 Partial Content
    8. 207 Multi-Statu
    3xx 重定向
    1. 300 Multiple Choice
    2. 301 Moved Permanently --- 永久性重定向
    3. 302 Found 找到但转移位置了 临时转移
    4. 303 See Other
    5. 304 Not Modified 告诉客户端没有修改无需再重新下载
    6. 305 Use Proxy
    7. 306 Switch Proxy
    8. 307 Temporary Redirect ---
    4xx 请求错误
    1. 400 Bad Request 错误请求
    2. 401 Unauthorized 没有认证
    3. 402 Payment Required
    4. 403 Forbidden 被屏蔽
    5. 404 Not Found 没有找到
    6. 405 Method Not Allowed 如doGet没有实现不能使用get方式访问
    7. 406 Not Acceptable
    8. 407 Proxy Authentication Required
    9. 408 Request Timeout
    10. 409 Conflict
    11. 410 Gone
    12. 411 Length Required
    13. 412 Precondition Failed
    14. 413 Request Entity Too Large
    15. 414 Request-URI Too Long
    16. 415 Unsupported Media Type
    17. 416 Requested Range Not Satisfiable
    18. 417 Expectation Failed
    19. 422 Unprocessable Entity
    20. 424 Failed Dependency
    21. 425 Unordered Collection
    22. 426 Upgrade Required
    23. 449 Retry With
    5xx 服务器错误
    1. 500 Internal Server Error ---服务器内部错误
    2. 501 Not Implemented
    3. 502 Bad Gateway
    4. 503 Service Unavailable
    5. 504 Gateway Timeout
    6. 505 HTTP Version Not Supported
    7. 506 Variant Also Negotiate
    8. 507 Insufficient Storage
    9. 509 Bandwidth Limit Exceeded
    10. 510 Not Extended

    HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。  
    所有状态码的第一个数字代表了响应的五种状态之一。编辑本段1xx 消息  这一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。由于 HTTP/1.0 协议中没有定义任何 1xx 状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送 1xx 响应。100 Continue  客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。101 Switching Protocol  服务器已经理解了客户端的请求,并将通过 Upgrade 消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到在 Upgrade 消息头中定义的那些协议。  只有在切换新的协议更有好处的时候才应该采取类似措施。例如,切换到新的 HTTP 版本比旧版本更有优势,或者切换到一个实时且同步的协议以传送利用此类特性的资源。102 Processing  由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。编辑本段2xx 成功  这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。200 OK  请求已成功,请求所希望的响应头或数据体将随此响应返回。201 Created  请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其 URI 已经随 Location 头信息返回。假如需要的资源无法及时建立的话,应当返回 '202 Accepted'。202 Accepted  服务器已接受请求,但尚未处理。正如它可能被拒绝一样,最终该请求可能会也可能不会被执行。在异步操作的场合下,没有比发送这个状态码更方便的做法了。  返回202状态码的响应的目的是允许服务器接受其他过程的请求(例如某个每天只执行一次的基于批处理的操作),而不必让客户端一直保持与服务器的连接直到批处理操作全部完成。在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息,以及指向处理状态监视器或状态预测的指针,以便用户能够估计操作是否已经完成。203 Non-Authoritative Information  服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝。当前的信息可能是原始版本的子集或者超集。例如,包含资源的元数据可能导致原始服务器知道元信息的超级。使用此状态码不是必须的,而且只有在响应不使用此状态码便会返回200 OK的情况下才是合适的。204 No Content  服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息。响应可能通过实体头部的形式,返回新的或更新后的元信息。如果存在这些头部信息,则应当与所请求的变量相呼应。  如果客户端是浏览器的话,那么用户浏览器应保留发送了该请求的页面,而不产生任何文档视图上的变化,即使按照规范新的或更新后的元信息应当被应用到用户浏览器活动视图中的文档。  由于204响应被禁止包含任何消息体,因此它始终以消息头后的第一个空行结尾。205 Reset Content  服务器成功处理了请求,且没有返回任何内容。但是与204响应不同,返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后,立即重置表单,以便用户能够轻松地开始另一次输入。  与204响应一样,该响应也被禁止包含任何消息体,且以消息头后的第一个空行结束。206 Partial Content  服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP 下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。  该请求必须包含 Range 头信息来指示客户端希望得到的内容范围,并且可能包含 If-Range 来作为请求条件。  响应必须包含如下的头部域:  Content-Range 用以指示本次响应中返回的内容的范围;如果是 Content-Type 为 multipart/byteranges 的多段下载,则每一 multipart 段中都应包含 Content-Range 域用以指示本段的内容范围。假如响应中包含 Content-Length,那么它的数值必须匹配它返回的内容范围的真实字节数。  Date  ETag 和/或 Content-Location,假如同样的请求本应该返回200响应。  Expires, Cache-Control,和/或 Vary,假如其值可能与之前相同变量的其他响应对应的值不同的话。  假如本响应请求使用了 If-Range 强缓存验证,那么本次响应不应该包含其他实体头;假如本响应的请求使用了 If-Range 弱缓存验证,那么本次响应禁止包含其他实体头;这避免了缓存的实体内容和更新了的实体头信息之间的不一致。否则,本响应就应当包含所有本应该返回200响应中应当返回的所有实体头部域。  假如 ETag 或 Last-Modified 头部不能精确匹配的话,则客户端缓存应禁止将206响应返回的内容与之前任何缓存过的内容组合在一起。  任何不支持 Range 以及 Content-Range 头的缓存都禁止缓存206响应返回的内容。207 Multi-Statu  由WebDAV(RFC 2518)扩展的状态码,代表之后的消息体将是一个XML消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。编辑本段3xx 重定向  这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明。  当且仅当后续的请求所使用的方法是 GET 或者 HEAD 时,用户浏览器才可以在没有用户介入的情况下自动提交所需要的后续请求。客户端应当自动监测无限循环重定向(例如:A->A,或者 A->B->C->A),因为这会导致服务器和客户端大量不必要的资源消耗。按照 HTTP/1.0 版规范的建议,浏览器不应自动访问超过5次的重定向。300 Multiple Choice  被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。  除非这是一个 HEAD 请求,否则该响应应当包括一个资源特性及地址的列表的实体,以便用户或浏览器从中选择最合适的重定向地址。这个实体的格式由 Content-Type 定义的格式所决定。浏览器可能根据响应的格式以及浏览器自身能力,自动作出最合适的选择。当然,RFC 2616规范并没有规定这样的自动选择该如何进行。  如果服务器本身已经有了首选的回馈选择,那么在 Location 中应当指明这个回馈的 URI;浏览器可能会将这个 Location 值作为自动重定向的地址。此外,除非额外指定,否则这个响应也是可缓存的。301 Moved Permanently  被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。  新的永久性的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。  如果这不是一个 GET 或者 HEAD 请求,因此浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。  注意:对于某些使用 HTTP/1.0 协议的浏览器,当它们发送的 POST 请求得到了一个301响应的话,接下来的重定向请求将会变成 GET 方式。302 Found  请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。  新的临时性的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。  如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。  注意:虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将302响应视作为303响应,并且使用 GET 方式访问在 Location 中规定的 URI,而无视原先请求的方法。状态码303和307被添加了进来,用以明确服务器期待客户端进行何种反应。303 See Other  对应当前请求的响应可以在另一个 URI 上被找到,而且客户端应当采用 GET 的方式访问那个资源。这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源。这个新的 URI 不是原始资源的替代引用。同时,303响应禁止被缓存。当然,第二个请求(重定向)可能被缓存。  新的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。  注意:许多 HTTP/1.1 版以前的 浏览器不能正确理解303状态。如果需要考虑与这些浏览器之间的互动,302状态码应该可以胜任,因为大多数的浏览器处理302响应时的方式恰恰就是上述规范要求客户端处理303响应时应当做的。304 Not Modified  如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304响应禁止包含消息体,因此始终以消息头后的第一个空行结尾。  该响应必须包含以下的头信息:  Date,除非这个服务器没有时钟。假如没有时钟的服务器也遵守这些规则,那么代理服务器以及客户端可以自行将 Date 字段添加到接收到的响应头中去(正如RFC 2068中规定的一样),缓存机制将会正常工作。  ETag 和/或 Content-Location,假如同样的请求本应返回200响应。  Expires, Cache-Control,和/或 Vary,假如其值可能与之前相同变量的其他响应对应的值不同的话。  假如本响应请求使用了强缓存验证,那么本次响应不应该包含其他实体头;否则(例如,某个带条件的 GET 请求使用了弱缓存验证),本次响应禁止包含其他实体头;这避免了缓存了的实体内容和更新了的实体头信息之间的不一致。  假如某个304响应指明了当前某个实体没有缓存,那么缓存系统必须忽视这个响应,并且重复发送不包含限制条件的请求。  假如接收到一个要求更新某个缓存条目的304响应,那么缓存系统必须更新整个条目以反映所有在响应中被更新的字段的值。305 Use Proxy  被请求的资源必须通过指定的代理才能被访问。 Location 域中将给出指定的代理所在的 URI 信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能建立305响应。  注意:RFC 2068中没有明确305响应是为了重定向一个单独的请求,而且只能被原始服务器建立。忽视这些限制可能导致严重的安全后果。306 Switch Proxy  在最新版的规范中,306状态码已经不再被使用。307 Temporary Redirect  请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。  新的临时性的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。因为部分浏览器不能识别307响应,因此需要添加上述必要信息以便用户能够理解并向新的 URI 发出访问请求。  如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。4xx 请求错误  这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个 HEAD 请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。  如果错误发生时客户端正在传送数据,那么使用TCP的服务器实现应当仔细确保在关闭客户端与服务器之间的连接之前,客户端已经收到了包含错误信息的数据包。如果客户端在收到错误信息后继续向服务器发送数据,服务器的TCP栈将向客户端发送一个重置数据包,以清除该客户端所有还未识别的输入缓冲,以免这些数据被服务器上的应用程序读取并干扰后者。400 Bad Request  1、语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。  2、请求参数有误。401 Unauthorized  当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。客户端可以重复提交一个包含恰当的 Authorization 头信息的请求。如果当前请求已经包含了 Authorization 证书,那么401响应代表着服务器验证已经拒绝了那些证书。如果401响应包含了与前一个响应相同的身份验证询问,且浏览器已经至少尝试了一次验证,那么浏览器应当向用户展示响应中包含的实体信息,因为这个实体信息中可能包含了相关诊断信息。参见RFC 2617。402 Payment Required  该状态码是为了将来可能的需求而预留的。403 Forbidden  服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个 HEAD 请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息。404 Not Found  请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。405 Method Not Allowed  请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow 头信息用以表示出当前资源能够接受的请求方法的列表。  鉴于 PUT,DELETE 方法会对服务器上的资源进行写操作,因而绝大部分的网页服务器都不支持或者在默认配置下不允许上述请求方法,对于此类请求均会返回405错误。406 Not Acceptable  请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。  除非这是一个 HEAD 请求,否则该响应就应当返回一个包含可以让用户或者浏览器从中选择最合适的实体特性以及地址列表的实体。实体的格式由 Content-Type 头中定义的媒体类型决定。浏览器可以根据格式及自身能力自行作出最佳选择。但是,规范中并没有定义任何作出此类自动选择的标准。407 Proxy Authentication Required  与401响应类似,只不过客户端必须在代理服务器上进行身份验证。代理服务器必须返回一个 Proxy-Authenticate 用以进行身份询问。客户端可以返回一个 Proxy-Authorization 信息头用以验证。参见RFC 2617。408 Request Timeout  请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。409 Conflict  由于和被请求的资源的当前状态之间存在冲突,请求无法完成。这个代码只允许用在这样的情况下才能被使用:用户被认为能够解决冲突,并且会重新提交新的请求。该响应应当包含足够的信息以便用户发现冲突的源头。  冲突通常发生于对 PUT 请求的处理中。例如,在采用版本检查的环境下,某次 PUT 提交的对特定资源的修改请求所附带的版本信息与之前的某个(第三方)请求向冲突,那么此时服务器就应该返回一个409错误,告知用户请求无法完成。此时,响应实体中很可能会包含两个冲突版本之间的差异比较,以便用户重新提交归并以后的新版本。410 Gone  被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址。这样的状况应当被认为是永久性的。如果可能,拥有链接编辑功能的客户端应当在获得用户许可后删除所有指向这个地址的引用。如果服务器不知道或者无法确定这个状况是否是永久的,那么就应该使用404状态码。除非额外说明,否则这个响应是可缓存的。  410响应的目的主要是帮助网站管理员维护网站,通知用户该资源已经不再可用,并且服务器拥有者希望所有指向这个资源的远端连接也被删除。这类事件在限时、增值服务中很普遍。同样,410响应也被用于通知客户端在当前服务器站点上,原本属于某个个人的资源已经不再可用。当然,是否需要把所有永久不可用的资源标记为'410 Gone',以及是否需要保持此标记多长时间,完全取决于服务器拥有者。411 Length Required  服务器拒绝在没有定义 Content-Length 头的情况下接受请求。在添加了表明请求消息体长度的有效 Content-Length 头之后,客户端可以再次提交该请求。412 Precondition Failed  服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。这个状态码允许客户端在获取资源时在请求的元信息(请求头字段数据)中设置先决条件,以此避免该请求方法被应用到其希望的内容以外的资源上。413 Request Entity Too Large  服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。此种情况下,服务器可以关闭连接以免客户端继续发送此请求。  如果这个状况是临时的,服务器应当返回一个 Retry-After 的响应头,以告知客户端可以在多少时间以后重新尝试。414 Request-URI Too Long  请求的 URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。这比较少见,通常的情况包括:  本应使用 POST 方法的表单提交变成了 GET 方法,导致查询字符串(Query String)过长。  重定向 URI “黑洞”,例如每次重定向把旧的 URI 作为新的 URI 的一部分,导致在若干次重定向后 URI 超长。  客户端正在尝试利用某些服务器中存在的安全漏洞攻击服务器。这类服务器使用固定长度的缓冲读取或操作请求的 URI,当 GET 后的参数超过某个数值后,可能会产生缓冲区溢出,导致任意代码被执行[1]。没有此类漏洞的服务器,应当返回414状态码。415 Unsupported Media Type  对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。416 Requested Range Not Satisfiable  如果请求中包含了 Range 请求头,并且 Range 中指定的任何数据范围都与当前资源的可用范围不重合,同时请求中又没有定义 If-Range 请求头,那么服务器就应当返回416状态码。  假如 Range 使用的是字节范围,那么这种情况就是指请求指定的所有数据范围的首字节位置都超过了当前资源的长度。服务器也应当在返回416状态码的同时,包含一个 Content-Range 实体头,用以指明当前资源的长度。这个响应也被禁止使用 multipart/byteranges 作为其 Content-Type。417 Expectation Failed  在请求头 Expect 中指定的预期内容无法被服务器满足,或者这个服务器是一个代理服务器,它有明显的证据证明在当前路由的下一个节点上,Expect 的内容无法被满足。  421 There are too many connections from your internet address  从当前客户端所在的IP地址到服务器的连接数超过了服务器许可的最大范围。通常,这里的IP地址指的是从服务器上看到的客户端地址(比如用户的网关或者代理服务器地址)。在这种情况下,连接数的计算可能涉及到不止一个终端用户。422 Unprocessable Entity  请求格式正确,但是由于含有语义错误,无法响应。(RFC 4918 WebDAV)423 Locked  当前资源被锁定。(RFC 4918 WebDAV)424 Failed Dependency  由于之前的某个请求发生的错误,导致当前请求失败,例如 PROPPATCH。(RFC 4918 WebDAV)425 Unordered Collection  在WebDav Advanced Collections 草案中定义,但是未出现在《WebDAV 顺序集协议》(RFC 3658)中。426 Upgrade Required  客户端应当切换到TLS/1.0。(RFC 2817)449 Retry With  由微软扩展,代表请求应当在执行完适当的操作后进行重试。编辑本段5xx 服务器错误  这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个 HEAD 请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。  这些状态码适用于任何响应方法。500 Internal Server Error  服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器的程序码出错时出现。501 Not Implemented  服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。502 Bad Gateway  作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。503 Service Unavailable  由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个 Retry-After 头用以标明这个延迟时间。如果没有给出这个 Retry-After 信息,那么客户端应当以处理500响应的方式处理它。  注意:503状态码的存在并不意味着服务器在过载的时候必须使用它。某些服务器只不过是希望拒绝客户端的连接。504 Gateway Timeout  作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。  注意:某些代理服务器在DNS查询超时时会返回400或者500错误505 HTTP Version Not Supported  服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本。这暗示着服务器不能或不愿使用与客户端相同的版本。响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体。506 Variant Also Negotiate  由《透明内容协商协议》(RFC 2295)扩展,代表服务器存在内部配置错误:被请求的协商变元资源被配置为在透明内容协商中使用自己,因此在一个协商处理中不是一个合适的重点。507 Insufficient Storage  服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。WebDAV (RFC 4918)509 Bandwidth Limit Exceeded  服务器达到带宽限制。这不是一个官方的状态码,但是仍被广泛使用。510 Not Extended  获取资源所需要的策略并没有没满足。(RFC 2774)1.302 Found。302返回码指示资源临时在另一个位置,该位置通过Location指定。如果302响应对应的请求方法不是GET或者 HEAD,那么客户端在获得用户许可之前是不能自动进行重定向的,因为这有可能会改变请求的条件。在RFC1045和RFC2068中指明客户端在响应重定向时是不可以改变请求的方法的。但是在多数实现中,总是使用GET方法来获取新位置的资源。这样就将其实现为303的要求了。2.303 See Other。请求的资源可以在另一个URI处找到,客户端必须使用GET方法来获取新位置的资源。不能缓存303响应,但是可以缓存第二次请求的响应。 This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource.很多客户端识别303状态码,302状态码的实现其实就是对303状态码的响应。3.307 Temporary Redirect。同303一样,对于非GET和HEAD请求不能自动重定向。与302的区别是: The Web client issues a request to the new location of the resource using the same request method it used in the current transaction (rather than always using GET).也就是说307相较于302来说,后续请求资源的方法是使用与当前交互相同的方法而不是全部使用GET。由此可见:303和307的出现是明确了302中的混乱状态。建议以后使用303和307,302在以后将会被淘汰掉。response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);response.setHeader("Location", "new");
    展开全文
  • HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。检验客户程序是否支持 HTTP 1.1。...
    HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。

    检验客户程序是否支持 HTTP 1.1。这些代码分为5类:

    * 100-199
    100 到 199 间的代码都是信息性的,标示客户应该采取的其他动作。
    * 200-299
    200 到 299 间的值表示请求成功。
    * 300-399
    300 到 399 间的值用于那些已经移走的文件,常常包括 Location 报头,指出新的地址。
    * 400-499
    400 到 499 间的值表明由客户引发的错误。
    * 500-599
    500 到 599 间的代码表示由服务器引发的错误。



    目录

    定义
    1xx 消息

    1. 100 Continue
    2. 101 Switching Protocol
    3. 102 Processing

    2xx 成功

    1. 200 OK 请求成功
    2. 201 Created
    3. 202 Accepted
    4. 203 Non-Authoritative Information
    5. 204 No Content
    6. 205 Reset Content
    7. 206 Partial Content
    8. 207 Multi-Statu

    3xx 重定向

    1. 300 Multiple Choice
    2. 301 Moved Permanently --- 永久性重定向
    3. 302 Found 找到但转移位置了 临时转移
    4. 303 See Other
    5. 304 Not Modified 告诉客户端没有修改无需再重新下载
    6. 305 Use Proxy
    7. 306 Switch Proxy
    8. 307 Temporary Redirect ---

    4xx 请求错误

    1. 400 Bad Request 错误请求
    2. 401 Unauthorized 没有认证
    3. 402 Payment Required
    4. 403 Forbidden 被屏蔽
    5. 404 Not Found 没有找到
    6. 405 Method Not Allowed 如doGet没有实现不能使用get方式访问
    7. 406 Not Acceptable
    8. 407 Proxy Authentication Required
    9. 408 Request Timeout
    10. 409 Conflict
    11. 410 Gone
    12. 411 Length Required
    13. 412 Precondition Failed
    14. 413 Request Entity Too Large
    15. 414 Request-URI Too Long
    16. 415 Unsupported Media Type
    17. 416 Requested Range Not Satisfiable
    18. 417 Expectation Failed
    19. 422 Unprocessable Entity
    20. 424 Failed Dependency
    21. 425 Unordered Collection
    22. 426 Upgrade Required
    23. 449 Retry With

    5xx 服务器错误

    1. 500 Internal Server Error ---服务器内部错误
    2. 501 Not Implemented
    3. 502 Bad Gateway
    4. 503 Service Unavailable
    5. 504 Gateway Timeout
    6. 505 HTTP Version Not Supported
    7. 506 Variant Also Negotiate
    8. 507 Insufficient Storage
    9. 509 Bandwidth Limit Exceeded
    10. 510 Not Extended

    定义
    1xx 消息

    1. 100 Continue
    2. 101 Switching Protocol
    3. 102 Processing

    2xx 成功

    1. 200 OK
    2. 201 Created
    3. 202 Accepted
    4. 203 Non-Authoritative Information
    5. 204 No Content
    6. 205 Reset Content
    7. 206 Partial Content
    8. 207 Multi-Statu

    3xx 重定向

    1. 300 Multiple Choice
    2. 301 Moved Permanently
    3. 302 Found
    4. 303 See Other
    5. 304 Not Modified
    6. 305 Use Proxy
    7. 306 Switch Proxy
    8. 307 Temporary Redirect

    4xx 请求错误

    1. 400 Bad Request
    2. 401 Unauthorized
    3. 402 Payment Required
    4. 403 Forbidden
    5. 404 Not Found
    6. 405 Method Not Allowed
    7. 406 Not Acceptable
    8. 407 Proxy Authentication Required
    9. 408 Request Timeout
    10. 409 Conflict
    11. 410 Gone
    12. 411 Length Required
    13. 412 Precondition Failed
    14. 413 Request Entity Too Large
    15. 414 Request-URI Too Long
    16. 415 Unsupported Media Type
    17. 416 Requested Range Not Satisfiable
    18. 417 Expectation Failed
    19. 422 Unprocessable Entity
    20. 424 Failed Dependency
    21. 425 Unordered Collection
    22. 426 Upgrade Required
    23. 449 Retry With

    5xx 服务器错误

    1. 500 Internal Server Error
    2. 501 Not Implemented
    3. 502 Bad Gateway
    4. 503 Service Unavailable
    5. 504 Gateway Timeout
    6. 505 HTTP Version Not Supported
    7. 506 Variant Also Negotiate
    8. 507 Insufficient Storage
    9. 509 Bandwidth Limit Exceeded
    10. 510 Not Extended


    展开

    编辑本段定义
      HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。
      所有状态码的第一个数字代表了响应的五种状态之一。
    编辑本段1xx 消息
      这一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。由于 HTTP/1.0 协议中没有定义任何 1xx 状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送 1xx 响应。
    100 Continue
      客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。
    101 Switching Protocol
      服务器已经理解了客户端的请求,并将通过 Upgrade 消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到在 Upgrade 消息头中定义的那些协议。
      只有在切换新的协议更有好处的时候才应该采取类似措施。例如,切换到新的 HTTP 版本比旧版本更有优势,或者切换到一个实时且同步的协议以传送利用此类特性的资源。
    102 Processing
      由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。
    编辑本段2xx 成功
      这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。
    200 OK
      请求已成功,请求所希望的响应头或数据体将随此响应返回。
    201 Created
      请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其 URI 已经随 Location 头信息返回。假如需要的资源无法及时建立的话,应当返回 '202 Accepted'。
    202 Accepted
      服务器已接受请求,但尚未处理。正如它可能被拒绝一样,最终该请求可能会也可能不会被执行。在异步操作的场合下,没有比发送这个状态码更方便的做法了。
      返回202状态码的响应的目的是允许服务器接受其他过程的请求(例如某个每天只执行一次的基于批处理的操作),而不必让客户端一直保持与服务器的连接直到批处理操作全部完成。在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息,以及指向处理状态监视器或状态预测的指针,以便用户能够估计操作是否已经完成。
    203 Non-Authoritative Information
      服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝。当前的信息可能是原始版本的子集或者超集。例如,包含资源的元数据可能导致原始服务器知道元信息的超级。使用此状态码不是必须的,而且只有在响应不使用此状态码便会返回200 OK的情况下才是合适的。
    204 No Content
      服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息。响应可能通过实体头部的形式,返回新的或更新后的元信息。如果存在这些头部信息,则应当与所请求的变量相呼应。
      如果客户端是浏览器的话,那么用户浏览器应保留发送了该请求的页面,而不产生任何文档视图上的变化,即使按照规范新的或更新后的元信息应当被应用到用户浏览器活动视图中的文档。
      由于204响应被禁止包含任何消息体,因此它始终以消息头后的第一个空行结尾。
    205 Reset Content
      服务器成功处理了请求,且没有返回任何内容。但是与204响应不同,返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后,立即重置表单,以便用户能够轻松地开始另一次输入。
      与204响应一样,该响应也被禁止包含任何消息体,且以消息头后的第一个空行结束。
    206 Partial Content
      服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP 下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。
      该请求必须包含 Range 头信息来指示客户端希望得到的内容范围,并且可能包含 If-Range 来作为请求条件。
      响应必须包含如下的头部域:
      Content-Range 用以指示本次响应中返回的内容的范围;如果是 Content-Type 为 multipart/byteranges 的多段下载,则每一 multipart 段中都应包含 Content-Range 域用以指示本段的内容范围。假如响应中包含 Content-Length,那么它的数值必须匹配它返回的内容范围的真实字节数。
      Date
      ETag 和/或 Content-Location,假如同样的请求本应该返回200响应。
      Expires, Cache-Control,和/或 Vary,假如其值可能与之前相同变量的其他响应对应的值不同的话。
      假如本响应请求使用了 If-Range 强缓存验证,那么本次响应不应该包含其他实体头;假如本响应的请求使用了 If-Range 弱缓存验证,那么本次响应禁止包含其他实体头;这避免了缓存的实体内容和更新了的实体头信息之间的不一致。否则,本响应就应当包含所有本应该返回200响应中应当返回的所有实体头部域。
      假如 ETag 或 Last-Modified 头部不能精确匹配的话,则客户端缓存应禁止将206响应返回的内容与之前任何缓存过的内容组合在一起。
      任何不支持 Range 以及 Content-Range 头的缓存都禁止缓存206响应返回的内容。
    207 Multi-Statu
      由WebDAV(RFC 2518)扩展的状态码,代表之后的消息体将是一个XML消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。
    编辑本段3xx 重定向
      这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明。
      当且仅当后续的请求所使用的方法是 GET 或者 HEAD 时,用户浏览器才可以在没有用户介入的情况下自动提交所需要的后续请求。客户端应当自动监测无限循环重定向(例如:A->A,或者 A->B->C->A),因为这会导致服务器和客户端大量不必要的资源消耗。按照 HTTP/1.0 版规范的建议,浏览器不应自动访问超过5次的重定向。
    300 Multiple Choice
      被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。
      除非这是一个 HEAD 请求,否则该响应应当包括一个资源特性及地址的列表的实体,以便用户或浏览器从中选择最合适的重定向地址。这个实体的格式由 Content-Type 定义的格式所决定。浏览器可能根据响应的格式以及浏览器自身能力,自动作出最合适的选择。当然,RFC 2616规范并没有规定这样的自动选择该如何进行。
      如果服务器本身已经有了首选的回馈选择,那么在 Location 中应当指明这个回馈的 URI;浏览器可能会将这个 Location 值作为自动重定向的地址。此外,除非额外指定,否则这个响应也是可缓存的。
    301 Moved Permanently
      被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
      新的永久性的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。
      如果这不是一个 GET 或者 HEAD 请求,因此浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。
      注意:对于某些使用 HTTP/1.0 协议的浏览器,当它们发送的 POST 请求得到了一个301响应的话,接下来的重定向请求将会变成 GET 方式。
    302 Found
      请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
      新的临时性的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。
      如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。
      注意:虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将302响应视作为303响应,并且使用 GET 方式访问在 Location 中规定的 URI,而无视原先请求的方法。状态码303和307被添加了进来,用以明确服务器期待客户端进行何种反应。
    303 See Other
      对应当前请求的响应可以在另一个 URI 上被找到,而且客户端应当采用 GET 的方式访问那个资源。这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源。这个新的 URI 不是原始资源的替代引用。同时,303响应禁止被缓存。当然,第二个请求(重定向)可能被缓存。
      新的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。
      注意:许多 HTTP/1.1 版以前的 浏览器不能正确理解303状态。如果需要考虑与这些浏览器之间的互动,302状态码应该可以胜任,因为大多数的浏览器处理302响应时的方式恰恰就是上述规范要求客户端处理303响应时应当做的。
    304 Not Modified
      如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304响应禁止包含消息体,因此始终以消息头后的第一个空行结尾。
      该响应必须包含以下的头信息:
      Date,除非这个服务器没有时钟。假如没有时钟的服务器也遵守这些规则,那么代理服务器以及客户端可以自行将 Date 字段添加到接收到的响应头中去(正如RFC 2068中规定的一样),缓存机制将会正常工作。
      ETag 和/或 Content-Location,假如同样的请求本应返回200响应。
      Expires, Cache-Control,和/或 Vary,假如其值可能与之前相同变量的其他响应对应的值不同的话。
      假如本响应请求使用了强缓存验证,那么本次响应不应该包含其他实体头;否则(例如,某个带条件的 GET 请求使用了弱缓存验证),本次响应禁止包含其他实体头;这避免了缓存了的实体内容和更新了的实体头信息之间的不一致。
      假如某个304响应指明了当前某个实体没有缓存,那么缓存系统必须忽视这个响应,并且重复发送不包含限制条件的请求。
      假如接收到一个要求更新某个缓存条目的304响应,那么缓存系统必须更新整个条目以反映所有在响应中被更新的字段的值。
    305 Use Proxy
      被请求的资源必须通过指定的代理才能被访问。 Location 域中将给出指定的代理所在的 URI 信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能建立305响应。
      注意:RFC 2068中没有明确305响应是为了重定向一个单独的请求,而且只能被原始服务器建立。忽视这些限制可能导致严重的安全后果。
    306 Switch Proxy
      在最新版的规范中,306状态码已经不再被使用。
    307 Temporary Redirect
      请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
      新的临时性的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。因为部分浏览器不能识别307响应,因此需要添加上述必要信息以便用户能够理解并向新的 URI 发出访问请求。
      如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。


    4xx 请求错误
      这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个 HEAD 请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。
      如果错误发生时客户端正在传送数据,那么使用TCP的服务器实现应当仔细确保在关闭客户端与服务器之间的连接之前,客户端已经收到了包含错误信息的数据包。如果客户端在收到错误信息后继续向服务器发送数据,服务器的TCP栈将向客户端发送一个重置数据包,以清除该客户端所有还未识别的输入缓冲,以免这些数据被服务器上的应用程序读取并干扰后者。
    400 Bad Request
      1、语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。
      2、请求参数有误。
    401 Unauthorized
      当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。客户端可以重复提交一个包含恰当的 Authorization 头信息的请求。如果当前请求已经包含了 Authorization 证书,那么401响应代表着服务器验证已经拒绝了那些证书。如果401响应包含了与前一个响应相同的身份验证询问,且浏览器已经至少尝试了一次验证,那么浏览器应当向用户展示响应中包含的实体信息,因为这个实体信息中可能包含了相关诊断信息。参见RFC 2617。
    402 Payment Required
      该状态码是为了将来可能的需求而预留的。
    403 Forbidden
      服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个 HEAD 请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息。
    404 Not Found
      请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。
    405 Method Not Allowed
      请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow 头信息用以表示出当前资源能够接受的请求方法的列表。
      鉴于 PUT,DELETE 方法会对服务器上的资源进行写操作,因而绝大部分的网页服务器都不支持或者在默认配置下不允许上述请求方法,对于此类请求均会返回405错误。
    406 Not Acceptable
      请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。
      除非这是一个 HEAD 请求,否则该响应就应当返回一个包含可以让用户或者浏览器从中选择最合适的实体特性以及地址列表的实体。实体的格式由 Content-Type 头中定义的媒体类型决定。浏览器可以根据格式及自身能力自行作出最佳选择。但是,规范中并没有定义任何作出此类自动选择的标准。
    407 Proxy Authentication Required
      与401响应类似,只不过客户端必须在代理服务器上进行身份验证。代理服务器必须返回一个 Proxy-Authenticate 用以进行身份询问。客户端可以返回一个 Proxy-Authorization 信息头用以验证。参见RFC 2617。
    408 Request Timeout
      请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。
    409 Conflict
      由于和被请求的资源的当前状态之间存在冲突,请求无法完成。这个代码只允许用在这样的情况下才能被使用:用户被认为能够解决冲突,并且会重新提交新的请求。该响应应当包含足够的信息以便用户发现冲突的源头。
      冲突通常发生于对 PUT 请求的处理中。例如,在采用版本检查的环境下,某次 PUT 提交的对特定资源的修改请求所附带的版本信息与之前的某个(第三方)请求向冲突,那么此时服务器就应该返回一个409错误,告知用户请求无法完成。此时,响应实体中很可能会包含两个冲突版本之间的差异比较,以便用户重新提交归并以后的新版本。
    410 Gone
      被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址。这样的状况应当被认为是永久性的。如果可能,拥有链接编辑功能的客户端应当在获得用户许可后删除所有指向这个地址的引用。如果服务器不知道或者无法确定这个状况是否是永久的,那么就应该使用404状态码。除非额外说明,否则这个响应是可缓存的。
      410响应的目的主要是帮助网站管理员维护网站,通知用户该资源已经不再可用,并且服务器拥有者希望所有指向这个资源的远端连接也被删除。这类事件在限时、增值服务中很普遍。同样,410响应也被用于通知客户端在当前服务器站点上,原本属于某个个人的资源已经不再可用。当然,是否需要把所有永久不可用的资源标记为'410 Gone',以及是否需要保持此标记多长时间,完全取决于服务器拥有者。
    411 Length Required
      服务器拒绝在没有定义 Content-Length 头的情况下接受请求。在添加了表明请求消息体长度的有效 Content-Length 头之后,客户端可以再次提交该请求。
    412 Precondition Failed
      服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。这个状态码允许客户端在获取资源时在请求的元信息(请求头字段数据)中设置先决条件,以此避免该请求方法被应用到其希望的内容以外的资源上。
    413 Request Entity Too Large
      服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。此种情况下,服务器可以关闭连接以免客户端继续发送此请求。
      如果这个状况是临时的,服务器应当返回一个 Retry-After 的响应头,以告知客户端可以在多少时间以后重新尝试。
    414 Request-URI Too Long
      请求的 URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。这比较少见,通常的情况包括:
      本应使用 POST 方法的表单提交变成了 GET 方法,导致查询字符串(Query String)过长。
      重定向 URI “黑洞”,例如每次重定向把旧的 URI 作为新的 URI 的一部分,导致在若干次重定向后 URI 超长。
      客户端正在尝试利用某些服务器中存在的安全漏洞攻击服务器。这类服务器使用固定长度的缓冲读取或操作请求的 URI,当 GET 后的参数超过某个数值后,可能会产生缓冲区溢出,导致任意代码被执行[1]。没有此类漏洞的服务器,应当返回414状态码。
    415 Unsupported Media Type
      对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。
    416 Requested Range Not Satisfiable
      如果请求中包含了 Range 请求头,并且 Range 中指定的任何数据范围都与当前资源的可用范围不重合,同时请求中又没有定义 If-Range 请求头,那么服务器就应当返回416状态码。
      假如 Range 使用的是字节范围,那么这种情况就是指请求指定的所有数据范围的首字节位置都超过了当前资源的长度。服务器也应当在返回416状态码的同时,包含一个 Content-Range 实体头,用以指明当前资源的长度。这个响应也被禁止使用 multipart/byteranges 作为其 Content-Type。
    417 Expectation Failed
      在请求头 Expect 中指定的预期内容无法被服务器满足,或者这个服务器是一个代理服务器,它有明显的证据证明在当前路由的下一个节点上,Expect 的内容无法被满足。
      421 There are too many connections from your internet address
      从当前客户端所在的IP地址到服务器的连接数超过了服务器许可的最大范围。通常,这里的IP地址指的是从服务器上看到的客户端地址(比如用户的网关或者代理服务器地址)。在这种情况下,连接数的计算可能涉及到不止一个终端用户。
    422 Unprocessable Entity
      请求格式正确,但是由于含有语义错误,无法响应。(RFC 4918 WebDAV)423 Locked
      当前资源被锁定。(RFC 4918 WebDAV)
    424 Failed Dependency
      由于之前的某个请求发生的错误,导致当前请求失败,例如 PROPPATCH。(RFC 4918 WebDAV)
    425 Unordered Collection
      在WebDav Advanced Collections 草案中定义,但是未出现在《WebDAV 顺序集协议》(RFC 3658)中。
    426 Upgrade Required
      客户端应当切换到TLS/1.0。(RFC 2817)
    449 Retry With
      由微软扩展,代表请求应当在执行完适当的操作后进行重试。
    编辑本段5xx 服务器错误
      这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个 HEAD 请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。
      这些状态码适用于任何响应方法。
    500 Internal Server Error
      服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器的程序码出错时出现。
    501 Not Implemented
      服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。
    502 Bad Gateway
      作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
    503 Service Unavailable
      由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个 Retry-After 头用以标明这个延迟时间。如果没有给出这个 Retry-After 信息,那么客户端应当以处理500响应的方式处理它。
      注意:503状态码的存在并不意味着服务器在过载的时候必须使用它。某些服务器只不过是希望拒绝客户端的连接。
    504 Gateway Timeout
      作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。
      注意:某些代理服务器在DNS查询超时时会返回400或者500错误
    505 HTTP Version Not Supported
      服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本。这暗示着服务器不能或不愿使用与客户端相同的版本。响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体。
    506 Variant Also Negotiate
      由《透明内容协商协议》(RFC 2295)扩展,代表服务器存在内部配置错误:被请求的协商变元资源被配置为在透明内容协商中使用自己,因此在一个协商处理中不是一个合适的重点。
    507 Insufficient Storage
      服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。WebDAV (RFC 4918)
    509 Bandwidth Limit Exceeded
      服务器达到带宽限制。这不是一个官方的状态码,但是仍被广泛使用。
    510 Not Extended
      获取资源所需要的策略并没有没满足。(RFC 2774)














    1.302 Found。302返回码指示资源临时在另一个位置,该位置通过Location指定。如果302响应对应的请求方法不是GET或者 HEAD,那么客户端在获得用户许可之前是不能自动进行重定向的,因为这有可能会改变请求的条件。在RFC1045和RFC2068中指明客户端在响应重定向时是不可以改变请求的方法的。但是在多数实现中,总是使用GET方法来获取新位置的资源。这样就将其实现为303的要求了。

    2.303 See Other。请求的资源可以在另一个URI处找到,客户端必须使用GET方法来获取新位置的资源。不能缓存303响应,但是可以缓存第二次请求的响应。 This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource.很多客户端识别303状态码,302状态码的实现其实就是对303状态码的响应。

    3.307 Temporary Redirect。同303一样,对于非GET和HEAD请求不能自动重定向。与302的区别是: The Web client issues a request to the new location of the resource using the same request method it used in the current transaction (rather than always using GET).也就是说307相较于302来说,后续请求资源的方法是使用与当前交互相同的方法而不是全部使用GET。

    由此可见:303和307的出现是明确了302中的混乱状态。建议以后使用303和307,302在以后将会被淘汰掉。



    response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
    response.setHeader("Location", "new");

    转载于:https://www.cnblogs.com/jqmtony/p/3711045.html

    展开全文
  • HTML状态码

    2011-12-08 09:43:59
    HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。 目录 定义 1xx 消息 2xx...
  • HTTP请求状态码

    2014-02-12 15:54:38
    2012-04-01 10:54:07| 分类: Java | 标签:http 状态码 |举报 |字号 订阅 ...由于 HTTP/1.0 协议中没有定义任何 1xx 状态码,所以除非在某些试验条件下,服务器禁止向 HTTP/1.0 客户端...
  • Java Web程序设计——请求和响应 请求和响应的概述 ... 响应:服务器根据浏览器发送请求,返回数据到浏览器在网页上进行显示,这个过程就称为...在HttpServletResponse接口中定义了向客户端发送响应状态码、响应消息头...
  • http状态码 对于http状态码,可以使用springframework包下的HttpStatus常量定义,涵盖100-511的状态响应码,方便好用
  • java枚举

    2012-05-03 14:58:48
    在一个Server/Client程序中,对Client端的每个请求,Server端返回的结果中均包含响应状态码和响应内容两部分。对于状态码的处理,以前的做法通常是用一系列public static final int常量来定义。调用者往往要写一些...
  • java源码包---java 源码 大量 实例

    千次下载 热门讨论 2013-04-18 23:15:26
     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...
  • Java项目构建基础

    2020-03-25 13:37:26
    统一结果返回 目前的前后端开发大部分数据的...响应状态码; 状态码描述; 响应数据 其他标识符 结果类枚举 前三者可定义结果枚举,如:success,code,message @Getter public enum ResultCodeEnum { SUCCESS(tr...
  • 自定义响应消息体

    2020-03-12 22:16:56
    定义一个枚举类来存储全局错误状态码和消息,方便后面管理修改 package com.xiaomin.springboot_shiro.enums; /** * @author 晓敏 * @create 2020-03-12 15:36 * 全局错误状态码定义 * 使用枚举来进行定义...
  • Java项目规范构建总结

    2020-03-26 09:57:00
    作者:永动的图灵机 juejin.im/post/5e073980f265da33f8653f2e 统一结果返回 目前的前后端开发大部分数据的传输格式都... 响应状态码; 状态码描述; 响应数据 其他标识符 结果类枚举 前三...
  • 1.3 Java平台的划分..................................................................................................................4 1.4 各种Java平台的不同之处...........................................
  • 1.3 Java平台的划分..................................................................................................................4 1.4 各种Java平台的不同之处.........................................
  • 1Java项目构建基础:统一结果,统一异常,统一日志 统一结果返回 ... 响应状态码; 状态码描述; 响应数据 其他标识符 结果类枚举 前三者可定义结果枚举,如:success,code,m...
  • java源码包2

    千次下载 热门讨论 2013-04-20 11:28:17
     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...
  • 1Java项目构建基础:统一结果,统一异常,统一日志 统一结果返回 ... 响应状态码; 状态码描述; 响应数据 其他标识符 结果类枚举 前三者可定义结果枚举,如:success,code,mess...
  • Java项目构建基础:统一结果,统一异常,统一日志 ...响应状态码 状态码描述 响应数据 其他标识符 结果类枚举 前三者可定义结果枚举,如:success,code,message @Getter public enum ResultCo...
  • java源码包3

    千次下载 热门讨论 2013-04-20 11:30:13
     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...
  • Java枚举使用一例

    千次阅读 2007-12-01 20:01:00
    在一个Server/Client程序中,对Client端的每个请求,Server端返回的结果中均包含响应状态码和响应内容两部分。对于状态码的处理,以前的做法通常是用一系列public static final int常量来定义。调用者往往要写一些...
  • java源码包4

    千次下载 热门讨论 2013-04-20 11:31:44
     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...
  • Java知识荟萃(2019年4月18日) 纯洁的微笑 SpringBoot中自定义异常...使用HTTP响应码来命名页面,如404.html、405.html 直接定义4xx.html,表示400-499的状态都显示改页面 默认在classpath:/static/error/下定义页面:...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 134
精华内容 53
关键字:

java定义响应状态码

java 订阅