servlet-2


表单数据

当你需要从浏览器到 Web 服务器传递一些信息并最终传回到后台程序时,你一定遇到了许多情况。浏览器使用两种方法向 Web 服务器传递信息。这些方法是 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():如果你想要得到一个当前请求的所有参数的完整列表,那么调用该方法。

使用 URL 的 GET 方法实例

这是一个简单的 URL,使用 GET 方法将两个值传递给 HelloForm 程序。

  • http://localhost:8080/HelloForm?first_name=ZARA&last_name=ALI

下面是 HelloForm.java servlet 程序,处理由 web 浏览器给定的输入。我们将使用 getParameter() 方法,使访问传递的信息变得非常容易:

在 web.xml 文件中创建以下条目:

现在在你浏览器的地址栏中输入 http://localhost:8080/HelloForm?first_name=ZARA&last_name=ALI ,并在浏览器中触发上述命令之前,确保你已经启动 Tomcat 服务器。这将产生如下所示的结果:

使用表单的 GET 方法实例

下面是一个简单的实例,使用 HTML 表单和提交按钮传递两个值。我们将使用相同的 Servlet HelloForm 来处理这个输入。

将这个 HTML 保存到 hello.htm 文件中,并把它放在 /webapps/ROOT 目录下。当你访问 http://localhost:8080/Hello.htm 时,下面是上述表单的实际输出。

尝试输入姓名,然后点击提交按钮来在 tomcat 运行的本地计算机上查看结果。基于提供的输入,它会产生与上述例子中相似的结果。

使用表单的 POST 方法实例

让我们对上述 servlet 做一点修改,以便它可以处理 GET 方法和 POST 方法。下面是 HelloForm.java servlet 程序,使用 GET 和 POST 方法处理由 web 浏览器给出的输入。

现在编译,部署上述 Servlet,并使用带有 POST 方法的 Hello.htm 测试它,如下所示:

这是上述表单的实际输出,尝试输入姓名,然后点击提交按钮,在 tomcat 运行的本地计算机上查看结果。

将复选框数据传递到 Servlet 程序

这是一个 HTML 代码实例,CheckBox.htm,一个表单带有两个复选框。

下面是 CheckBox.java servlet 程序,来为复选框按钮处理 web 浏览器给定的输入。


读取所有的表单参数

以下是使用 HttpServletRequest 的 getParameterNames() 方法的通用实例来读取所有可用的表单参数。该方法返回一个枚举,包含了未指定顺序的参数名称。

一旦我们得到一个枚举,我们可以以标准方式循环这个枚举,使用 hasMoreElements() 方法来确定何时停止循环,使用 nextElement() 方法来获取每个参数的名称。

现在,用下面的表单尝试上述 servlet:

现在使用上述表单调用 servlet 将产生如下所示结果:


客户端 HTTP 请求

当浏览器请求网页时,它会向 web 服务器发送大量信息,这些信息不能被直接读取,因为这些信息是作为 HTTP 请求头的一部分行进的。

下述方法可以用于读取 servlet 程序中的 HTTP 头信息。通过 HttpServletRequest 对象这些方法是可用的。

下述例子使用了 HttpServletRequest 的 getHeaderNames() 方法来读取 HTTP 头信息。该方法返回了一个枚举,包含与当前的 HTTP 请求相关的头信息。

一旦我们得到一个枚举,我们可以以标准方式循环这个枚举,使用 hasMoreElements() 方法来确定何时停止循环,使用 nextElement() 方法来获取每个参数的名称。

现在,调用上述 servlet 会产生如下所示的结果:


服务器 HTTP 响应

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

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

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

在前面的实例中你已经了解了 setContentType() 方法的工作方式,下面的实例也会用到同样的方法,此外,我们会用 setIntHeader() 方法来设置 Refresh 头信息。

现在调用上述 servlet,每 5 秒后就会显示当前的系统时间,如下所示。运行 servlet 并等着看结果:


HTTP 状态码

HTTP 状态码相关知识见 HTTP状态码

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

java public void setStatus ( int statusCode ) 该方法设置一个任意的状态码。setStatus 方法接受一个 int(状态码)作为参数。如果您的反应包含了一个特殊的状态码和文档,请确保在使用 PrintWriter 实际返回任何内容之前调用 setStatus。

HTTP 状态码实例: 下述例子将发送 407 错误代码到客户端浏览器,且浏览器会向你显示 “需要身份验证!!!”的消息。


过滤器

Servlet 过滤器是 Java 类,可用于 Servlet 编程中的下述目的:

  • 在它们访问后端资源之前,拦截这些来自客户端的请求。

  • 在它们发送回客户端之前,处理这些来自服务器端的响应。

这是规范建议的各种类型的过滤器:

  • 身份验证过滤器。

  • 数据压缩过滤器。

  • 加密过滤器。

  • 触发访问事件资源的过滤器。

  • 图像转换过滤器。

  • 日志记录和审核过滤器。

  • MIME-类型链过滤器。

  • Tokenizing 过滤器。

  • 转换 XML 内容的 XSL/T 过滤器。

过滤器在部署描述符文件 web.xml 中被部署,然后被映射到 servlet 名称或你的应用程序的部署描述符中的 URL 模式。

当 web 容器启动你的 web 应用程序时,它会为每个在部署描述符中已声明的过滤器创建一个实例。过滤器按照它们在部署描述符中声明的顺序执行。

过滤器仅仅是一个实现了 javax.servlet.Filter 接口的 Java 类。javax.servlet.Filter 接口定义了三种方法:

Servlet 过滤器实例

以下是 Servlet 过滤器的实例,将输出客户端的 IP 地址和当前的日期时间。这个例子使你对 Servlet 过滤器有了基本的了解,但是你可以使用相同的概念编写更复杂的过滤器应用程序:


异常处理

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

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

考虑这种情况,你有一个 ErrorHandler servelt,当任何已定义的异常或错误出现时就会被调用。以下是要在 web.xml 中创建的条目。

如果你想对所有的异常有一个通用的错误处理程序,那么你应该定义如下所示的 error-page,而不是为每个异常定义单独的 error-page 元素:

以下是异常处理中有关上述 web.xml 需要注意的点:

  • Servelt ErrorHandler 与其他的 servelt 的定义方式一样,且在 web.xml 中配置。

  • 如果状态码有任何错误出现,不管是 404(未找到)还是 403(禁止),那么 ErrorHandler servlet 会被调用。

  • 如果 web 应用程序抛出 ServletException 或 IOException,那么 web 容器就会调用 /ErrorHandler servlet。

  • 你可以定义不同的错误处理程序来处理不同类型的错误或异常。上述例子非常通用,希望它达到了让你理解基本概念的目的。

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

以下是 Servlet 实例,用于任何你定义的 servlet 出现任何错误或异常时的情况。

这个例子让你对 Servlet 中的异常处理有了基本的了解,但是你可以使用相同的概念编写更复杂的异常处理应用程序:

以常用的方式编译 ErrorHandler.java 并把你的类文件放入/webapps/ROOT/WEB-INF/classes 中。

让我们将下述配置添加到 web.xml 文件中来处理异常:

现在,尝试使用一个会产生任何异常的 servlet 或者输入一个错误的 URL,这将触发 Web 容器调用 ErrorHandler servlet 并显示适当的消息。例如,如果你输入了一个错误的 URL,那么它将显示如下所示的结果:

上述代码在一些 web 浏览器中可能无法工作。因此请尝试使用 Mozilla 和 Safari 浏览器,这样上述代码应该能正常工作。


Source & Reference

  • https://wiki.jikexueyuan.com/project/servlet/writing-filters.html

  • https://wiki.jikexueyuan.com/project/servlet/form-data.html

  • https://wiki.jikexueyuan.com/project/servlet/cookies-handling.html