zoukankan      html  css  js  c++  java
  • 2.Servlet基础总结

    一.简介

    1.什么是Servlet 

    Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。

    Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
    最早支持Servlet标准的是JavaSoft的Java Web Server,此后,一些其它的基于Java的Web服务器开始支持标准的Servlet。

    Servlet 为创建基于 web 的应用程序提供了基于组件、独立于平台的方法,可以不受 CGI 程序的性能限制。Servlet 有权限访问所有的 Java API,包括访问企业级数据库的 JDBC API。

    Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

    使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。

    Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:

    • 性能明显更好。
    • Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
    • Servlet 是独立于平台的,因为它们是用 Java 编写的。
    • 服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
    • Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。

     

    与 JSP 比较

    JSP 和 Servlet 的区别到底在应用上有哪些体现,很多人搞不清楚。简单的说,SUN 首先发展出 Servlet,其功能比较强劲,体系设计也很先进,只是,它输出 HTML 语句还是采用了老的 CGI 方式,是一句一句输出,所以,编写和修改 HTML 非常不方便。
    Java Server Pages(JSP)是一种实现普通静态HTML 和动态 HTML 混合编码的技术,JSP 并没有增加任何本质上不能用 Servlet 实现的功能。但是,在 JSP 中编写静态HTML 更加方便,不必再用 println语 句来输出每一行 HTML 代码。更重要的是,借助内容和外观的分离,页面制作中不同性质的任务可以方便地分开:比如,由页面设计者进行 HTML设计,同时留出供 Servlet 程序员插入动态内容的空间。
    后来 SUN 推出了类似于 ASP 的镶嵌型的 JSP,把 JSP TAG 镶嵌到 HTML 语句中,这样,就大大简化和方便了网页的设计和修改。新型的网络语言如 ASP,PHP,JSP 都是镶嵌型的语言。 这是 JSP 和 Servlet 区别的运作原理层面。
    从网络三层结构的角度看 JSP 和 Servlet 的区别,一个网络项目最少分三层:data layer(数据层),business layer(业务层),presentation layer(表现层)。当然也可以更复杂。Servlet 用来写 business layer 是很强大的,但是对于写 presentation layer 就很不方便。JSP 则主要是为了方便写 presentation layer 而设计的。当然也可以写 business layer。写惯了 ASP,PHP,CGI的朋友,经常会不自觉的把 presentation layer 和 business layer 混在一起。
    根据 SUN 自己的推荐,JSP中应该仅仅存放与 presentation layer 有关的东西,也就是说,只放输出 HTML 网页的部分。而所有的数据计算,数据分析,数据库联结处理,统统是属于 business layer,应该放在 Java BEANS 中。通过 JSP 调用 Java BEANS,实现两层的整合。

    2.Servlet 架构

    下图显示了 Servlet 在 Web 应用程序中的位置。

    3.服务器支持

    在市场上有许多 Web 服务器支持 Servlet。有些 Web 服务器是免费下载的,Tomcat 就是其中的一个。

    Apache Tomcat 是一款 Java Servlet 和 JavaServer Pages 技术的开源软件实现,可以作为测试 Servlet 的独立服务器,而且可以集成到 Apache Web 服务器。

    从 http://tomcat.apache.org/ 上下载最新版本的 Tomcat。

    4.maven依赖(JSP,Servlet)

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency> 
       <groupId>javax.servlet.jsp</groupId> 
       <artifactId>jsp-api</artifactId> 
       <version>2.1</version> 
       <scope>provided</scope>
    </dependency>

    5.生命周期

    Servlet 生命周期

    Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

    • Servlet 通过调用 init () 方法进行初始化:

      init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。
    • Servlet 调用 service() 方法来处理客户端的请求:

      Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

      当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重载 doGet() 或 doPost() 即可。

    • Servlet 通过调用 destroy() 方法终止(结束):

      destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

      在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。

    • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

     6.get和post请求

    GET 方法

    GET 方法向页面请求发送已编码的用户信息。页面和已编码的信息中间用 ? 字符分隔,如下所示

    http://www.test.com/hello?key1=value1&key2=value2

    GET 方法是默认的从浏览器向 Web 服务器传递信息的方法,它会产生一个很长的字符串,出现在浏览器的地址栏中。如果您要向服务器传递的是密码或其他的敏感信息,请不要使用 GET 方法。GET 方法有大小限制:请求字符串中最多只能有 1024 个字符

    这些信息使用 QUERY_STRING 头传递,并可以通过 QUERY_STRING 环境变量访问,Servlet 使用 doGet() 方法处理这种类型的请求。

    POST 方法

    另一个向后台程序传递信息的比较可靠的方法是 POST 方法。

    POST 方法打包信息的方式与 GET 方法基本相同,但是 POST 方法不是把信息作为 URL 中 ? 字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息。

    消息以标准输出的形式传到后台程序,您可以解析和使用这些标准输出。Servlet 使用 doPost() 方法处理这种类型的请求。

    使用 Servlet 读取表单数据

    Servlet 处理表单数据,这些数据会根据不同的情况使用不同的方法自动解析:

    • getParameter():您可以调用 request.getParameter() 方法来获取表单参数的值。
    • getParameterValues():如果参数出现一次以上,则调用该方法,并返回多个值,例如复选框。
    • getParameterNames():如果您想要得到当前请求中的所有参数的完整列表,则调用该方法。

      7.Servlet 客户端 HTTP 请求

      当浏览器请求网页时,它会向 Web 服务器发送特定信息,这些信息不能被直接读取,因为这些信息是作为 HTTP 请求的头的一部分进行传输的。您可以查看 HTTP 协议 了解更多相关信息。

      以下是来自于浏览器端的重要头信息,您可能在 Web 编程中频繁使用:

      头信息描述
      Accept 这个头信息指定浏览器或其他客户端可以处理的 MIME 类型。值 image/png 或 image/jpeg 是最常见的两种可能值。
      Accept-Charset 这个头信息指定浏览器可以用来显示信息的字符集。例如 ISO-8859-1。
      Accept-Encoding 这个头信息指定浏览器知道如何处理的编码类型。值 gzip 或 compress 是最常见的两种可能值。
      Accept-Language 这个头信息指定客户端的首选语言,在这种情况下,Servlet 会产生多种语言的结果。例如,en、en-us、ru 等。
      Authorization 这个头信息用于客户端在访问受密码保护的网页时识别自己的身份。
      Connection 这个头信息指示客户端是否可以处理持久 HTTP 连接。持久连接允许客户端或其他浏览器通过单个请求来检索多个文件。值 Keep-Alive 意味着使用了持续连接。
      Content-Length 这个头信息只适用于 POST 请求,并给出 POST 数据的大小(以字节为单位)。
      Cookie 这个头信息把之前发送到浏览器的 cookies 返回到服务器。
      Host 这个头信息指定原始的 URL 中的主机和端口。
      If-Modified-Since 这个头信息表示只有当页面在指定的日期后已更改时,客户端想要的页面。如果没有新的结果可以使用,服务器会发送一个 304 代码,表示 Not Modified 头信息。
      If-Unmodified-Since 这个头信息是 If-Modified-Since 的对立面,它指定只有当文档早于指定日期时,操作才会成功。
      Referer 这个头信息指示所指向的 Web 页的 URL。例如,如果您在网页 1,点击一个链接到网页 2,当浏览器请求网页 2 时,网页 1 的 URL 就会包含在 Referer 头信息中。
      User-Agent 这个头信息识别发出请求的浏览器或其他客户端,并可以向不同类型的浏览器返回不同的内容。

      读取 HTTP 头的方法

      下面的方法可用在 Servlet 程序中读取 HTTP 头。这些方法通过 HttpServletRequest 对象可用。

      序号方法 & 描述
      1 Cookie[] getCookies()
      返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。
      2 Enumeration getAttributeNames()
      返回一个枚举,包含提供给该请求可用的属性名称。
      3 Enumeration getHeaderNames()
      返回一个枚举,包含在该请求中包含的所有的头名。
      4 Enumeration getParameterNames()
      返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。
      5 HttpSession getSession()
      返回与该请求关联的当前 session 会话,或者如果请求没有 session 会话,则创建一个。
      6 HttpSession getSession(boolean create)
      返回与该请求关联的当前 HttpSession,或者如果没有当前会话,且创建是真的,则返回一个新的 session 会话。
      7 Locale getLocale()
      基于 Accept-Language 头,返回客户端接受内容的首选的区域设置。
      8 Object getAttribute(String name)
      以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。
      9 ServletInputStream getInputStream()
      使用 ServletInputStream,以二进制数据形式检索请求的主体。
      10 String getAuthType()
      返回用于保护 Servlet 的身份验证方案的名称,例如,"BASIC" 或 "SSL",如果JSP没有受到保护则返回 null。
      11 String getCharacterEncoding()
      返回请求主体中使用的字符编码的名称。
      12 String getContentType()
      返回请求主体的 MIME 类型,如果不知道类型则返回 null。
      13 String getContextPath()
      返回指示请求上下文的请求 URI 部分。
      14 String getHeader(String name)
      以字符串形式返回指定的请求头的值。
      15 String getMethod()
      返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
      16 String getParameter(String name)
      以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。
      17 String getPathInfo()
      当请求发出时,返回与客户端发送的 URL 相关的任何额外的路径信息。
      18 String getProtocol()
      返回请求协议的名称和版本。
      19 String getQueryString()
      返回包含在路径后的请求 URL 中的查询字符串。
      20 String getRemoteAddr()
      返回发送请求的客户端的互联网协议(IP)地址。
      21 String getRemoteHost()
      返回发送请求的客户端的完全限定名称。
      22 String getRemoteUser()
      如果用户已通过身份验证,则返回发出请求的登录用户,或者如果用户未通过身份验证,则返回 null。
      23 String getRequestURI()
      从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。
      24 String getRequestedSessionId()
      返回由客户端指定的 session 会话 ID。
      25 String getServletPath()
      返回调用 JSP 的请求的 URL 的一部分。
      26 String[] getParameterValues(String name)
      返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null。
      27 boolean isSecure()
      返回一个布尔值,指示请求是否使用安全通道,如 HTTPS。
      28 int getContentLength()
      以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1。
      29 int getIntHeader(String name)
      返回指定的请求头的值为一个 int 值。
      30 int getServerPort()
      返回接收到这个请求的端口号。

      8.Servlet 服务器 HTTP 响应

    • 如前面的章节中讨论的那样,当一个 Web 服务器响应一个 HTTP 请求时,响应通常包括一个状态行、一些响应报头、一个空行和文档。一个典型的响应如下所示:

      HTTP/1.1 200 OK
      Content-Type: text/html
      Header2: ...
      ...
      HeaderN: ...
        (Blank Line)
      <!doctype ...>
      <html>
      <head>...</head>
      <body>
      ...
      </body>
      </html>

      状态行包括 HTTP 版本(在本例中为 HTTP/1.1)、一个状态码(在本例中为 200)和一个对应于状态码的短消息(在本例中为 OK)。

    • 下表总结了从 Web 服务器端返回到浏览器的最有用的 HTTP 1.1 响应报头,您会在 Web 编程中频繁地使用它们:

      头信息描述
      Allow 这个头信息指定服务器支持的请求方法(GET、POST 等)。
      Cache-Control 这个头信息指定响应文档在何种情况下可以安全地缓存。可能的值有:public、private 或 no-cache 等。Public 意味着文档是可缓存,Private 意味着文档是单个用户私用文档,且只能存储在私有(非共享)缓存中,no-cache 意味着文档不应被缓存。
      Connection 这个头信息指示浏览器是否使用持久 HTTP 连接。值 close 指示浏览器不使用持久 HTTP 连接,值 keep-alive 意味着使用持久连接。
      Content-Disposition 这个头信息可以让您请求浏览器要求用户以给定名称的文件把响应保存到磁盘。
      Content-Encoding 在传输过程中,这个头信息指定页面的编码方式。
      Content-Language 这个头信息表示文档编写所使用的语言。例如,en、en-us、ru 等。
      Content-Length 这个头信息指示响应中的字节数。只有当浏览器使用持久(keep-alive)HTTP 连接时才需要这些信息。
      Content-Type 这个头信息提供了响应文档的 MIME(Multipurpose Internet Mail Extension)类型。
      Expires 这个头信息指定内容过期的时间,在这之后内容不再被缓存。
      Last-Modified 这个头信息指示文档的最后修改时间。然后,客户端可以缓存文件,并在以后的请求中通过 If-Modified-Since 请求头信息提供一个日期。
      Location 这个头信息应被包含在所有的带有状态码的响应中。在 300s 内,这会通知浏览器文档的地址。浏览器会自动重新连接到这个位置,并获取新的文档。
      Refresh 这个头信息指定浏览器应该如何尽快请求更新的页面。您可以指定页面刷新的秒数。
      Retry-After 这个头信息可以与 503(Service Unavailable 服务不可用)响应配合使用,这会告诉客户端多久就可以重复它的请求。
      Set-Cookie 这个头信息指定一个与页面关联的 cookie。

      设置 HTTP 响应报头的方法

      下面的方法可用于在 Servlet 程序中设置 HTTP 响应报头。这些方法通过 HttpServletResponse 对象可用。

      序号方法 & 描述
      1 String encodeRedirectURL(String url)
      为 sendRedirect 方法中使用的指定的 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变。
      2 String encodeURL(String url)
      对包含 session 会话 ID 的指定 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变。
      3 boolean containsHeader(String name)
      返回一个布尔值,指示是否已经设置已命名的响应报头。
      4 boolean isCommitted()
      返回一个布尔值,指示响应是否已经提交。
      5 void addCookie(Cookie cookie)
      把指定的 cookie 添加到响应。
      6 void addDateHeader(String name, long date)
      添加一个带有给定的名称和日期值的响应报头。
      7 void addHeader(String name, String value)
      添加一个带有给定的名称和值的响应报头。
      8 void addIntHeader(String name, int value)
      添加一个带有给定的名称和整数值的响应报头。
      9 void flushBuffer()
      强制任何在缓冲区中的内容被写入到客户端。
      10 void reset()
      清除缓冲区中存在的任何数据,包括状态码和头。
      11 void resetBuffer()
      清除响应中基础缓冲区的内容,不清除状态码和头。
      12 void sendError(int sc)
      使用指定的状态码发送错误响应到客户端,并清除缓冲区。
      13 void sendError(int sc, String msg)
      使用指定的状态发送错误响应到客户端。
      14 void sendRedirect(String location)
      使用指定的重定向位置 URL 发送临时重定向响应到客户端。
      15 void setBufferSize(int size)
      为响应主体设置首选的缓冲区大小。
      16 void setCharacterEncoding(String charset)
      设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8。
      17 void setContentLength(int len)
      设置在 HTTP Servlet 响应中的内容主体的长度,该方法设置 HTTP Content-Length 头。
      18 void setContentType(String type)
      如果响应还未被提交,设置被发送到客户端的响应的内容类型。
      19 void setDateHeader(String name, long date)
      设置一个带有给定的名称和日期值的响应报头。
      20 void setHeader(String name, String value)
      设置一个带有给定的名称和值的响应报头。
      21 void setIntHeader(String name, int value)
      设置一个带有给定的名称和整数值的响应报头。
      22 void setLocale(Locale loc)
      如果响应还未被提交,设置响应的区域。
      23 void setStatus(int sc)
      为该响应设置状态码。

      9.Servlet HTTP 状态码

      HTTP 请求和 HTTP 响应消息的格式是类似的,结构如下:

      • 初始状态行 + 回车换行符(回车+换行)
      • 零个或多个标题行+回车换行符
      • 一个空白行,即回车换行符
      • 一个可选的消息主体,比如文件、查询数据或查询输出

      例如,服务器的响应头如下所示:

      HTTP/1.1 200 OK
      Content-Type: text/html
      Header2: ...
      ...
      HeaderN: ...
        (Blank Line)
      <!doctype ...>
      <html>
      <head>...</head>
      <body>
      ...
      </body>
      </html>

      状态行包括 HTTP 版本(在本例中为 HTTP/1.1)、一个状态码(在本例中为 200)和一个对应于状态码的短消息(在本例中为 OK)。

      以下是可能从 Web 服务器返回的 HTTP 状态码和相关的信息列表:

      代码消息描述
      100 Continue 只有请求的一部分已经被服务器接收,但只要它没有被拒绝,客户端应继续该请求。
      101 Switching Protocols 服务器切换协议。
      200 OK 请求成功。
      201 Created 该请求是完整的,并创建一个新的资源。
      202 Accepted 该请求被接受处理,但是该处理是不完整的。
      203 Non-authoritative Information  
      204 No Content  
      205 Reset Content  
      206 Partial Content  
      300 Multiple Choices 链接列表。用户可以选择一个链接,进入到该位置。最多五个地址。
      301 Moved Permanently 所请求的页面已经转移到一个新的 URL。
      302 Found 所请求的页面已经临时转移到一个新的 URL。
      303 See Other 所请求的页面可以在另一个不同的 URL 下被找到。
      304 Not Modified  
      305 Use Proxy  
      306 Unused 在以前的版本中使用该代码。现在已不再使用它,但代码仍被保留。
      307 Temporary Redirect 所请求的页面已经临时转移到一个新的 URL。
      400 Bad Request 服务器不理解请求。
      401 Unauthorized 所请求的页面需要用户名和密码。
      402 Payment Required 您还不能使用该代码。
      403 Forbidden 禁止访问所请求的页面。
      404 Not Found 服务器无法找到所请求的页面。.
      405 Method Not Allowed 在请求中指定的方法是不允许的。
      406 Not Acceptable 服务器只生成一个不被客户端接受的响应。
      407 Proxy Authentication Required 在请求送达之前,您必须使用代理服务器的验证。
      408 Request Timeout 请求需要的时间比服务器能够等待的时间长,超时。
      409 Conflict 请求因为冲突无法完成。
      410 Gone 所请求的页面不再可用。
      411 Length Required "Content-Length" 未定义。服务器无法处理客户端发送的不带 Content-Length 的请求信息。
      412 Precondition Failed 请求中给出的先决条件被服务器评估为 false。
      413 Request Entity Too Large 服务器不接受该请求,因为请求实体过大。
      414 Request-url Too Long 服务器不接受该请求,因为 URL 太长。当您转换一个 "post" 请求为一个带有长的查询信息的 "get" 请求时发生。
      415 Unsupported Media Type 服务器不接受该请求,因为媒体类型不被支持。
      417 Expectation Failed  
      500 Internal Server Error 未完成的请求。服务器遇到了一个意外的情况。
      501 Not Implemented 未完成的请求。服务器不支持所需的功能。
      502 Bad Gateway 未完成的请求。服务器从上游服务器收到无效响应。
      503 Service Unavailable 未完成的请求。服务器暂时超载或死机。
      504 Gateway Timeout 网关超时。
      505 HTTP Version Not Supported 服务器不支持"HTTP协议"版本。

      设置 HTTP 状态代码的方法

      下面的方法可用于在 Servlet 程序中设置 HTTP 状态码。这些方法通过 HttpServletResponse 对象可用。

      序号方法 & 描述
      1 public void setStatus ( int statusCode )
      该方法设置一个任意的状态码。setStatus 方法接受一个 int(状态码)作为参数。如果您的反应包含了一个特殊的状态码和文档,请确保在使用 PrintWriter 实际返回任何内容之前调用 setStatus。
      2 public void sendRedirect(String url)
      该方法生成一个 302 响应,连同一个带有新文档 URL 的 Location 头。
      3 public void sendError(int code, String message)
      该方法发送一个状态码(通常为 404),连同一个在 HTML 文档内部自动格式化并发送到客户端的短消息。

      HTTP 状态码实例

      下面的例子把 407 错误代码发送到客户端浏览器,浏览器会显示 "Need authentication!!!" 消息。

      // 导入必需的 java 库
      import java.io.*;
      import javax.servlet.*;
      import javax.servlet.http.*;
      import java.util.*;
      
      // 扩展 HttpServlet 类
      public class showError extends HttpServlet {
       
        // 处理 GET 方法请求的方法
        public void doGet(HttpServletRequest request,
                          HttpServletResponse response)
                  throws ServletException, IOException
        {
            // 设置错误代码和原因
            response.sendError(407, "Need authentication!!!" );
        }
        // 处理 POST 方法请求的方法
        public void doPost(HttpServletRequest request,
                           HttpServletResponse response)
            throws ServletException, IOException {
           doGet(request, response);
        }
      }

       10.Servlet 异常处理

    • Servlet 异常处理

      当一个 Servlet 抛出一个异常时,Web 容器在使用了 exception-type 元素的 web.xml 中搜索与抛出异常类型相匹配的配置。

      您必须在 web.xml 中使用 error-page 元素来指定对特定异常 或 HTTP 状态码 作出相应的 Servlet 调用。

      web.xml 配置

      假设,有一个 ErrorHandler 的 Servelt 在任何已定义的异常或错误出现时被调用。以下将是在 web.xml 中创建的项。

      <!-- servlet 定义 -->
      <servlet>
              <servlet-name>ErrorHandler</servlet-name>
              <servlet-class>ErrorHandler</servlet-class>
      </servlet>
      <!-- servlet 映射 -->
      <servlet-mapping>
              <servlet-name>ErrorHandler</servlet-name>
              <url-pattern>/ErrorHandler</url-pattern>
      </servlet-mapping>
      
      <!-- error-code 相关的错误页面 -->
      <error-page>
          <error-code>404</error-code>
          <location>/ErrorHandler</location>
      </error-page>
      <error-page>
          <error-code>403</error-code>
          <location>/ErrorHandler</location>
      </error-page>
      
      <!-- exception-type 相关的错误页面 -->
      <error-page>
          <exception-type>
                javax.servlet.ServletException
          </exception-type >
          <location>/ErrorHandler</location>
      </error-page>
      
      <error-page>
          <exception-type>java.io.IOException</exception-type >
          <location>/ErrorHandler</location>
      </error-page>

      以下是关于上面的 web.xml 异常处理要注意的点:

      • Servelt ErrorHandler 与其他的 Servelt 的定义方式一样,且在 web.xml 中进行配置。
      • 如果有错误状态代码出现,不管为 404(Not Found 未找到)或 403(Forbidden 禁止),则会调用 ErrorHandler 的 Servlet。
      • 如果 Web 应用程序抛出 ServletException 或 IOException,那么 Web 容器会调用 ErrorHandler 的 Servlet。
      • 您可以定义不同的错误处理程序来处理不同类型的错误或异常。上面的实例是非常通用的,希望您能通过实例理解基本的概念。

        请求属性 - 错误/异常

        以下是错误处理的 Servlet 可以访问的请求属性列表,用来分析错误/异常的性质。

        序号属性 & 描述
        1 javax.servlet.error.status_code
        该属性给出状态码,状态码可被存储,并在存储为 java.lang.Integer 数据类型后可被分析。
        2 javax.servlet.error.exception_type
        该属性给出异常类型的信息,异常类型可被存储,并在存储为 java.lang.Class 数据类型后可被分析。
        3 javax.servlet.error.message
        该属性给出确切错误消息的信息,信息可被存储,并在存储为 java.lang.String 数据类型后可被分析。
        4 javax.servlet.error.request_uri
        该属性给出有关 URL 调用 Servlet 的信息,信息可被存储,并在存储为 java.lang.String 数据类型后可被分析。
        5 javax.servlet.error.exception
        该属性给出异常产生的信息,信息可被存储,并在存储为 java.lang.Throwable 数据类型后可被分析。
        6 javax.servlet.error.servlet_name
        该属性给出 Servlet 的名称,名称可被存储,并在存储为 java.lang.String 数据类型后可被分析。

        11.Servlet Cookies 处理

        1、cookie机制和session机制的区别

          具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。
          同时我们也看到,由于在服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上还有其他选择。
        2、会话cookie和持久cookie的区别
          如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
          如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。
          存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。
        3、如何利用实现自动登录
          当用户在某个网站注册后,就会收到一个惟一用户ID的cookie。客户后来重新连接时,这个用户ID会自动返回,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户无需给出明确的用户名和密码,就可以访问服务器上的资源。
        4、如何根据用户的爱好定制站点
          网站可以使用cookie记录用户的意愿。对于简单的设置,网站可以直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制,网站只需仅将一个惟一的标识符发送给用户,由服务器端的数据库存储每个标识符对应的页面设置。
        5、cookie的发送
        1.创建Cookie对象
        2.设置最大时效
        3.将Cookie放入到HTTP响应报头
          如果你创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie:存储在浏览器的内存中,用户退出浏览器之后被删除。如果你希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该 cookie。
          发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个 Set-Cookie HTTP请求报头中。由于这个方法并不修改任何之前指定的Set-Cookie报头,而是创建新的报头,因此我们将这个方法称为是addCookie,而非setCookie。同样要记住响应报头必须在任何文档内容发送到客户端之前设置。
        6、cookie的读取
        1.调用request.getCookie
          要获取有浏览器发送来的cookie,需要调用HttpServletRequest的getCookies方法,这个调用返回Cookie对象的数组,对应由HTTP请求中Cookie报头输入的值。
        2.对数组进行循环,调用每个cookie的getName方法,直到找到感兴趣的cookie为止

        Cookies 是存储在客户端计算机上的文本文件,并保留了各种跟踪信息。Java Servlet 显然支持 HTTP Cookies。

        识别返回用户包括三个步骤:

        • 服务器脚本向浏览器发送一组 Cookies。例如:姓名、年龄或识别号码等。
        • 浏览器将这些信息存储在本地计算机上,以备将来使用。
        • 当下一次浏览器向 Web 服务器发送任何请求时,浏览器会把这些 Cookies 信息发送到服务器,服务器将使用这些信息来识别用户。

          Cookie 剖析

          Cookies 通常设置在 HTTP 头信息中(虽然 JavaScript 也可以直接在浏览器上设置一个 Cookie)。设置 Cookie 的 Servlet 会发送如下的头信息:

          HTTP/1.1 200 OK
          Date: Fri, 04 Feb 2000 21:03:38 GMT
          Server: Apache/1.3.9 (UNIX) PHP/4.0b3
          Set-Cookie: name=xyz; expires=Friday, 04-Feb-07 22:03:38 GMT; 
                           path=/; domain=w3cschool.cn
          Connection: close
          Content-Type: text/html

          正如您所看到的,Set-Cookie 头包含了一个名称值对、一个 GMT 日期、一个路径和一个域。名称和值会被 URL 编码。expires 字段是一个指令,告诉浏览器在给定的时间和日期之后"忘记"该 Cookie。

          如果浏览器被配置为存储 Cookies,它将会保留此信息直到到期日期。如果用户的浏览器指向任何匹配该 Cookie 的路径和域的页面,它会重新发送 Cookie 到服务器。浏览器的头信息可能如下所示:

          GET / HTTP/1.0
          Connection: Keep-Alive
          User-Agent: Mozilla/4.6 (X11; I; Linux 2.2.6-15apmac ppc)
          Host: zink.demon.co.uk:1126
          Accept: image/gif, */*
          Accept-Encoding: gzip
          Accept-Language: en
          Accept-Charset: iso-8859-1,*,utf-8
          Cookie: name=xyz

          Servlet 就能够通过请求方法 request.getCookies() 访问 Cookie,该方法将返回一个 Cookie 对象的数组。

          Servlet Cookies 方法

          以下是在 Servlet 中操作 Cookies 时可使用的有用的方法列表。

          序号方法 & 描述
          1 public void setDomain(String pattern)
          该方法设置 cookie 适用的域,例如 w3cschool.cn。
          2 public String getDomain()
          该方法获取 cookie 适用的域,例如 w3cschool.cn。
          3 public void setMaxAge(int expiry)
          该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie 只会在当前 session 会话中持续有效。
          4 public int getMaxAge()
          该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示 cookie 将持续下去,直到浏览器关闭。
          5 public String getName()
          该方法返回 cookie 的名称。名称在创建后不能改变。
          6 public void setValue(String newValue)
          该方法设置与 cookie 关联的值。
          7 public String getValue()
          该方法获取与 cookie 关联的值。
          8 public void setPath(String uri)
          该方法设置 cookie 适用的路径。如果您不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。
          9 public String getPath()
          该方法获取 cookie 适用的路径。
          10 public void setSecure(boolean flag)
          该方法设置布尔值,表示 cookie 是否应该只在加密的(即 SSL)连接上发送。
          11 public void setComment(String purpose)
          该方法规定了描述 cookie 目的的注释。该注释在浏览器向用户呈现 cookie 时非常有用。
          12 public String getComment()
          该方法返回了描述 cookie 目的的注释,如果 cookie 没有注释则返回 null。

          通过 Servlet 设置 Cookies

          通过 Servlet 设置 Cookies 包括三个步骤:

          (1) 创建一个 Cookie 对象:您可以调用带有 cookie 名称和 cookie 值的 Cookie 构造函数,cookie 名称和 cookie 值都是字符串。

          Cookie cookie = new Cookie("key","value");

          请记住,无论是名字还是值,都不应该包含空格或以下任何字符:

          [ ] ( ) = , " / ? @ : ;

          (2) 设置最大生存周期:您可以使用 setMaxAge 方法来指定 cookie 能够保持有效的时间(以秒为单位)。下面将设置一个最长有效期为 24 小时的 cookie。

          cookie.setMaxAge(60*60*24); 

          (3) 发送 Cookie 到 HTTP 响应头:您可以使用 response.addCookie 来添加 HTTP 响应头中的 Cookies,如下所示:

        • response.addCookie(cookie);

          通过 Servlet 删除 Cookies

          删除 Cookies 是非常简单的。如果您想删除一个 cookie,那么您只需要按照以下三个步骤进行:

          • 读取一个现有的 cookie,并把它存储在 Cookie 对象中。
          • 使用 setMaxAge() 方法设置 cookie 的年龄为零,来删除现有的 cookie。
          • 把这个 cookie 添加到响应头。您可以手动在 Internet Explorer 中删除 Cookies。在"工具"菜单,选择"Internet 选项"。如果要删除所有的 Cookies,请按"删除 Cookies"。

            360浏览器清除Cookies:ctrl + alt +delete

          • Cookies的阻止和打开:工具-->选项-->高级设置-->网页设置-->网页内容高级设置

          •  有时候存储Cookie需要点如下保存才可以:

          • 12.Servlet Session 跟踪

            HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录。

            但是仍然有以下三种方式来维持 Web 客户端和 Web 服务器之间的 session 会话:

            Cookies

            一个 Web 服务器可以分配一个唯一的 session 会话 ID 作为每个 Web 客户端的 cookie,对于客户端的后续请求可以使用接收到的 cookie 来识别。

            这可能不是一个有效的方法,因为很多浏览器不支持 cookie,所以我们建议不要使用这种方式来维持 session 会话。

            隐藏的表单字段

            一个 Web 服务器可以发送一个隐藏的 HTML 表单字段,以及一个唯一的 session 会话 ID,如下所示:

            <input type="hidden" name="sessionid" value="12345">
            

            该条目意味着,当表单被提交时,指定的名称和值会被自动包含在 GET 或 POST 数据中。每次当 Web 浏览器发送回请求时,session_id 值可以用于保持不同的 Web 浏览器的跟踪。

            这可能是一种保持 session 会话跟踪的有效方式,但是点击常规的超文本链接(<A HREF...>)不会导致表单提交,因此隐藏的表单字段也不支持常规的 session 会话跟踪。

            URL 重写

            您可以在每个 URL 末尾追加一些额外的数据来标识 session 会话,服务器会把该 session 会话标识符与已存储的有关 session 会话的数据相关联。

            例如,http://w3cschool.cn/file.htm;sessionid=12345,session 会话标识符被附加为 sessionid=12345,标识符可被 Web 服务器访问以识别客户端。

            URL 重写是一种更好的维持 session 会话的方式,它在浏览器不支持 cookie 时能够很好地工作,但是它的缺点是会动态生成每个 URL 来为页面分配一个 session 会话 ID,即使是在很简单的静态 HTML 页面中也会如此。

            HttpSession 对象

            除了上述的三种方式,Servlet 还提供了 HttpSession 接口,该接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式。

            Servlet 容器使用这个接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。会话持续一个指定的时间段,跨多个连接或页面请求。

            您会通过调用 HttpServletRequest 的公共方法 getSession() 来获取 HttpSession 对象,如下所示:

            HttpSession session = request.getSession();
            

            你需要在向客户端发送任何文档内容之前调用 request.getSession()。下面总结了 HttpSession 对象中可用的几个重要的方法:

            序号方法 & 描述
            1 public Object getAttribute(String name)
            该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。
            2 public Enumeration getAttributeNames()
            该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。
            3 public long getCreationTime()
            该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
            4 public String getId()
            该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。
            5 public long getLastAccessedTime()
            该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
            6 public int getMaxInactiveInterval()
            该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。
            7 public void invalidate()
            该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。
            8 public boolean isNew(
            如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。
            9 public void removeAttribute(String name)
            该方法将从该 session 会话移除指定名称的对象。
            10 public void setAttribute(String name, Object value) 
            该方法使用指定的名称绑定一个对象到该 session 会话。
            11 public void setMaxInactiveInterval(int interval)
            该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。

            // 导入必需的 java 库
            import java.io.*;
            import javax.servlet.*;
            import javax.servlet.http.*;
            import java.util.*;
             
            // 扩展 HttpServlet 类
            public class SessionTrack extends HttpServlet {
             
              public void doGet(HttpServletRequest request,
                                HttpServletResponse response)
                        throws ServletException, IOException
              {
                  // 如果不存在 session 会话,则创建一个 session 对象
                  HttpSession session = request.getSession(true);
                  // 获取 session 创建时间
                  Date createTime = new Date(session.getCreationTime());
                  // 获取该网页的最后一次访问时间
                  Date lastAccessTime = 
                                    new Date(session.getLastAccessedTime());
            
                  String title = "欢迎回到我的网站";
                  Integer visitCount = new Integer(0);
                  String visitCountKey = new String("visitCount");
                  String userIDKey = new String("userID");
                  String userID = new String("ABCD");
            
                  // 检查网页上是否有新的访问者
                  if (session.isNew()){
                     title = "欢迎来到我的网站";
                     session.setAttribute(userIDKey, userID);
                  } else {
                     visitCount = (Integer)session.getAttribute(visitCountKey);
                     visitCount = visitCount + 1;
                     userID = (String)session.getAttribute(userIDKey);
                  }
                  session.setAttribute(visitCountKey,  visitCount);
            
                  // 设置响应内容类型
                  response.setContentType("text/html");
                  PrintWriter out = response.getWriter();
            
                  String docType =
                  "<!doctype html public "-//w3c//dtd html 4.0 " +       "transitional//en">
            ";
                  out.println(docType +
                            "<html>
            " +
                            "<head><title>" + title + "</title></head>
            " +
                            "<body bgcolor="#f0f0f0">
            " +
                            "<h1 align="center">" + title + "</h1>
            " +
                             "<h2 align="center">Session 信息</h2>
            " +
                            "<table border="1" align="center">
            " +
                            "<tr bgcolor="#949494">
            " +
                            "  <th>Session 信息</th><th>值</th></tr>
            " +
                            "<tr>
            " +
                            "  <td>id</td>
            " +
                            "  <td>" + session.getId() + "</td></tr>
            " +
                            "<tr>
            " +
                            "  <td>Creation Time</td>
            " +
                            "  <td>" + createTime + 
                            "  </td></tr>
            " +
                            "<tr>
            " +
                            "  <td>Time of Last Access</td>
            " +
                            "  <td>" + lastAccessTime + 
                            "  </td></tr>
            " +
                            "<tr>
            " +
                            "  <td>User ID</td>
            " +
                            "  <td>" + userID + 
                            "  </td></tr>
            " +
                            "<tr>
            " +
                            "  <td>Number of visits</td>
            " +
                            "  <td>" + visitCount + "</td></tr>
            " +
                            "</table>
            " +
                            "</body></html>");
              }
            }

            删除 Session 会话数据

            当您完成了一个用户的 session 会话数据,您有以下几种选择:

            • 移除一个特定的属性:您可以调用 public void removeAttribute(String name) 方法来删除与特定的键相关联的值。 to delete the value associated with a particular key.
            • 删除整个 session 会话:您可以调用 public void invalidate() 方法来丢弃整个 session 会话。
            • 设置 session 会话过期时间:您可以调用 public void setMaxInactiveInterval(int interval) 方法来单独设置 session 会话超时。
            • 注销用户:如果使用的是支持 servlet 2.4 的服务器,您可以调用 logout 来注销 Web 服务器的客户端,并把属于所有用户的所有 session 会话设置为无效。
            • web.xml 配置:如果您使用的是 Tomcat,除了上述方法,您还可以在 web.xml 文件中配置 session 会话超时,如下所示:
              <session-config>
                  <session-timeout>15</session-timeout>
                </session-config>

              13. Servletcontext 对象

            • ServletContext是一个全局的储存信息的空间,服务器开始就存在,服务器关闭才释放。为了方便大家理解,我们将ServletContext和Cookie、Session做一个简单对比,如下图:
            • 1)、ServletContext使用方法
              this.getServletContext(); 
              this.getServletConfig().getServletContext();

              2)、你可以把它想象成一张表,这个和Session非常相似:每一行就是一个属性,如下:

              名字(String)值(Object)
                 
                 


              添加属性:setAttribute(String name, Object obj);

              得到值:getAttribute(String name),这个方法返回Object

            • 3)、生命周期 

              ServletContext中的属性的生命周期从创建开始,到服务器关闭结束。

              删除属性:removeAttribute(String name)

            • 粗看之下,这个运行结果和Session,Cookie的应用似乎没什么区别,但事实上则完全不一样的。只要不关闭Tomcat或者reload该应用,当我们关闭当前的浏览器,或者是换一个浏览器,比如从360浏览器换到了IE浏览器再次访问Servlet2,我们依然可以看到这个结果!这就是和和Session,Cookie最大的不同了。之所以会造成这种补贴,是因为ServletContext存在于服务器内存中的一个公共空间,它可以供所有的用户客户端访问。

            • ServletContext应用

              1、多个Servlet可以通过ServletContext对象来实现数据间的共享

              类似于Session,通过ServletContext对象我们也可以实现数据共享,但值得注意的是,Session是只能在一个客户端中共享数据,而ServletContext中的数据是在所有客户端中都可以实现数据共享的。

              2、实现Servlet的请求转发

              之前我们学过的请求转发是通过request对象的: 

            • request.getRequestDispatcher("/url").forward(request, response);

              这里要说明的是,ServletContext也可以实现请求转发:

              this.getServletContext().getRequestDispatcher("/url").forward(request, response);

              3、获取Web应用的初始化参数

            • 我们可以用<init-param>标签为servlet配置初始化参数,然后使用ServletConfig对象获取这些参数,假如有如下的MyServlet,它的配置为:

                  • <servlet>  
                        <servlet-name>MyServlet</servlet-name>  
                        <servlet-class>com.gavin.servlet.MyServlet</servlet-class>  
                        <init-param>  
                            <param-name>encoding</param-name>  
                            <param-value>utf-8</param-value>  
                        </init-param>  
                    </servlet>  

                    可以看到它配置了一个初始化参数:encoding=utf-8,那么我们在MyServlet的源代码中需要这样去得到这个参数:

                    String encoding = this.getServletConfig().getInitParameter("encoding");
                    或者
                    String encoding = this.getInitParameter("encoding");

                    注意:如果使用@WebServlet("/MyServlet")的方式测无法获取 web.xml中配置的init-param 的值 ,需要使用如下

                        <servlet>
                              <servlet-name>SetError</servlet-name>
                              <servlet-class>com.my.web.SetError</servlet-class>
                              <init-param>  
                                  <param-name>servletParam</param-name>  
                                  <param-value>bbb</param-value>  
                            </init-param>  
                         <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SetError</servlet-name> <url-pattern>/SetError</url-pattern> </servlet-mapping>
                  • load-on-startup作用:
                    1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。

                    2)它的值必须是一个整数,表示servlet应该被载入的顺序

                    2)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;

                    3)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。

                    4)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。

                    5)当值相同时,容器就会自己选择顺序来加载。

                    所以,<load-on-startup>x</load-on-startup>,中x的取值1,2,3,4,5代表的是优先级,而非启动延迟时间。

            • 1.上述的参数配置方法只针对一个特定的Servlet有效,我们可以通过ServletContext来获取全局的、整个Web应用的初始化参数,全局的初始化参数是这样配置在web.xml文件中的:

            • <!-- 如果希望所有的Servlet都可以使用该配置,则必须这么做 -->
              <context-param>
                  <param-name>name</param-name>
                  <param-value>gavin</param-value>
              </context-param>

              然后我们可以在任意一个Servlet中使用ServletContext获取这个参数:

              String name = this.getServletContext().getInitParameter("name");

              4、利用ServletContext对象读取资源文件(比如properties文件) 

              4.1:文件在WebRoot文件夹下,即Web应用的根目录。这时候我们可以使用ServletContext来读取该资源文件。

              假设我们Web根目录下有一个配置数据库信息的dbinfo.properties文件,里面配置了name和password属性,这时候可以通过ServletContext去读取这个文件:

              // 这种方法的默认读取路径就是Web应用的根目录
              InputStream stream = this.getServletContext().getResourceAsStream("dbinfo.properties");
              // 创建属性对象
              Properties properties = new Properties();
              properties.load(stream);
              String name = properties.getProperty("name");
              String password = properties.getProperty("password");
              out.println("name="+name+";password="+password);

              4.2:如果这个文件放在了src目录下,这时就不能用ServletContext来读取了,必须要使用类加载器去读取。

              / 类加载器的默认读取路径是src根目录
              InputStream stream = MyServlet.class.getClassLoader().getResourceAsStream("dbinfo.properties")

              如果这个文件此时还没有直接在src目录下,而是在src目录下的某个包下,比如在com.gavin包下,此时类加载器要加上包的路径,如下:

              InputStream stream = MyServlet.class.getClassLoader().getResourceAsStream("com/gavin/dbinfo.properties")

              补充一点,ServletContext只有在读取的文件在web应用的根目录下时,才能获取文件的全路径。比如我们在WebRoot文件夹下有一个images文件夹,images文件夹下有一个Servlet.jpg图片,为了得到这个图片的全路径,如下:

              // 如何读取到一个文件的全路径,这里会得到在Tomcat的全路径
              String path = this.getServletContext().getRealPath("/images/Servlet.jpg");

              在网站开发中,有很多功能要使用ServletContext,比如 

              1. 网站计数器 

              2. 网站的在线用户显示 

              3. 简单的聊天系统

              总之,如果是涉及到不同用户共享数据,而这些数据量不大,同时又不希望写入数据库中,我们就可以考虑使用ServletContext实现。

              ServletContext使用建议

              因为存在ServletContext中的数据在服务器中会长时间,这样就会占用很多内存,因此在使用ServletContext时,建议不要往里面添加过大的数据!


            • 14.@WebServlet用法

            • @WebServlet 用于将一个类声明为 Servlet,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为 Servlet。该注解具有下表给出的一些常用属性(以下所有属性均为可选属性,但是 vlaue 或者 urlPatterns 通常是必需的,且二者不能共存,如果同时指定,通常是忽略 value 的取值)
            •   在servlet3.0以后,我们可以不用再web.xml里面配置servlet,只需要加上@WebServlet注解就可以修改该servlet的属性了。

              下面是@WebServlet的属性列表。

              属性名类型描述
              name String 指定Servlet 的 name 属性,等价于 <servlet-name>。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。
              value String[] 该属性等价于 urlPatterns 属性。两个属性不能同时使用。
              urlPatterns String[] 指定一组 Servlet 的 URL 匹配模式。等价于<url-pattern>标签。
              loadOnStartup int 指定 Servlet 的加载顺序,等价于 <load-on-startup>标签。
              initParams WebInitParam[] 指定一组 Servlet 初始化参数,等价于<init-param>标签。
              asyncSupported boolean 声明 Servlet 是否支持异步操作模式,等价于<async-supported> 标签。
              description String 该 Servlet 的描述信息,等价于 <description>标签。
              displayName String 该 Servlet 的显示名,通常配合工具使用,等价于 <display-name>标签。
              从上表可见,web.xml可以配置的servlet属性,在@WebServlet中都可以配置。
              package roseindia.net;  
              import java.io.IOException;  
              import java.io.PrintWriter;  
              import javax.servlet.ServletConfig;  
              import javax.servlet.ServletException;  
              import javax.servlet.annotation.WebServlet;  
              import javax.servlet.annotation.WebInitParam;  
              import javax.servlet.http.HttpServlet;  
              import javax.servlet.http.HttpServletRequest;  
              import javax.servlet.http.HttpServletResponse;  
                
              @WebServlet(  
                  name = "WebInitParamExample", urlPatterns = {"/hello"}  
                  ,initParams = {  
                  @WebInitParam(name= "Site :", value="http://roseindia.net"),  
                  @WebInitParam(name= "Rose", value= "India"),  
                  }  
              )  
              public class WebInitParamExample extends HttpServlet{  
                  public void doGet(HttpServletRequest request, HttpServletResponse response)  
                  throws ServletException, IOException  
                  {  
                      response.setContentType("text/html");  
                      PrintWriter out = response.getWriter();  
                      out.println("<h2>Init Param Servlet Example</h2>");  
                      ServletConfig config= getServletConfig();  
                      String pValue= config.getInitParameter("Site :");  
                      out.println("Param Value : "+pValue);  
                      String pValue1= config.getInitParameter("Rose");  
                      out.println("<br>Param Value : "+pValue1);  
                      out.close();  
                  }  
              }  

              15.Servlet 网页重定向

            • Servlet 网页重定向

              当文档移动到新的位置,我们需要向客户端发送这个新位置时,我们需要用到网页重定向。当然,也可能是为了负载均衡,或者只是为了简单的随机,这些情况都有可能用到网页重定向。

              重定向请求到另一个网页的最简单的方式是使用 response 对象的 sendRedirect() 方法。下面是该方法的定义: 将请求重定向到另一页的最简单的方法是,用方法的sendRedirect()的响应对象。

              两种方法

              response.sendRedirect("http://localhost:8080/myWeb/showName.jsp");
              String site = "http://www.newpage.com" ;
              response.setStatus(response.SC_MOVED_TEMPORARILY);
              response.setHeader("Location", site);

               16.网页自动刷新

              response.setIntHeader("Refresh", 5);
  • 相关阅读:
    正则去掉 html标签
    app内嵌 h5页面 再滑动的时候 触发击穿底下的一些touchstart事件
    设置按钮不能连续点击并触发点击事件
    使用NPOI导入导出标准Excel
    ASP.NET导出word实例
    常用SQL语句大全总结
    判断以及防止SQL注入
    javascript 正则表达式总结
    前端页面优化技巧
    自我介绍
  • 原文地址:https://www.cnblogs.com/lukelook/p/9246659.html
Copyright © 2011-2022 走看看