实习培训——Servlet(6)
实习培训——Servlet(6)
1 Servlet 客户端 HTTP 请求
当浏览器请求网页时,它会向 Web 服务器发送特定信息,这些信息不能被直接读取,因为这些信息是作为 HTTP 请求的头的一部分进行传输的。您可以查看 HTTP 协议 了解更多相关信息。
HTTP Header 请求实例
下面的实例使用 HttpServletRequest 的 getHeaderNames() 方法读取 HTTP 头信息。该方法返回一个枚举,包含与当前的 HTTP 请求相关的头信息。
一旦我们有一个枚举,我们可以以标准方式循环枚举,使用 hasMoreElements() 方法来确定何时停止,使用nextElement() 方法来获取每个参数的名称。
1 package yuan; 2 3 //导入必需的 java 库 4 import java.io.IOException; 5 import java.io.PrintWriter; 6 import java.util.Enumeration; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.annotation.WebServlet; 10 import javax.servlet.http.HttpServlet; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 @WebServlet("/DisplayHeader") 15 16 //扩展 HttpServlet 类 17 public class DisplayHeader extends HttpServlet { 18 19 // 处理 GET 方法请求的方法 20 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 21 { 22 // 设置响应内容类型 23 response.setContentType("text/html;charset=UTF-8"); 24 25 PrintWriter out = response.getWriter(); 26 String title = "HTTP Header 请求实例"; 27 String docType = 28 "<!DOCTYPE html> \n"; 29 out.println(docType + 30 "<html>\n" + 31 "<head><meta charset=\"utf-8\"><title>" + title + "</title></head>\n"+ 32 "<body bgcolor=\"#f0f0f0\">\n" + 33 "<h1 align=\"center\">" + title + "</h1>\n" + 34 "<table width=\"100%\" border=\"1\" align=\"center\">\n" + 35 "<tr bgcolor=\"#949494\">\n" + 36 "<th>Header 名称</th><th>Header 值</th>\n"+ 37 "</tr>\n"); 38 39 Enumeration headerNames = request.getHeaderNames(); 40 41 while(headerNames.hasMoreElements()) { 42 String paramName = (String)headerNames.nextElement(); 43 out.print("<tr><td>" + paramName + "</td>\n"); 44 String paramValue = request.getHeader(paramName); 45 out.println("<td> " + paramValue + "</td></tr>\n"); 46 } 47 out.println("</table>\n</body></html>"); 48 } 49 // 处理 POST 方法请求的方法 50 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 51 doGet(request, response); 52 } 53 }
这次偷懒,不配置web.xml了,因为有 第14行代码
@WebServlet("/DisplayHeader")
它的作用等同于配置了web.xml,结果如下:
cookie太多,显示不是很合理
http://www.runoob.com/servlet/servlet-client-request.html
2 Servlet 服务器 HTTP 响应
HTTP Header 响应实例
您已经在前面的实例中看到 setContentType() 方法,下面的实例也使用了同样的方法,此外,我们会用 setIntHeader() 方法来设置 Refresh 头。
1 package yuan; 2 3 //导入必需的 java 库 4 import java.io.IOException; 5 import java.io.PrintWriter; 6 import java.text.SimpleDateFormat; 7 import java.util.Calendar; 8 import java.util.Date; 9 10 import javax.servlet.ServletException; 11 import javax.servlet.annotation.WebServlet; 12 import javax.servlet.http.HttpServlet; 13 import javax.servlet.http.HttpServletRequest; 14 import javax.servlet.http.HttpServletResponse; 15 16 @WebServlet("/Refresh") 17 18 // 扩展 HttpServlet 类 19 public class Refresh extends HttpServlet { 20 21 // 处理 GET 方法请求的方法 22 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 23 // 设置刷新自动加载时间为 5 秒 24 response.setIntHeader("Refresh", 5); 25 // 设置响应内容类型 26 response.setContentType("text/html;charset=UTF-8"); 27 28 // 使用默认时区和语言环境获得一个日历 29 Calendar cale = Calendar.getInstance(); 30 // 将Calendar类型转换成Date类型 31 Date tasktime = cale.getTime(); 32 // 设置日期输出的格式 33 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 34 // 格式化输出 35 String nowTime = df.format(tasktime); 36 PrintWriter out = response.getWriter(); 37 String title = "自动刷新 Header设置 "; 38 String docType = "<!DOCTYPE html>\n"; 39 out.println( 40 docType + "<html>\n" + "<head><title>" + title + "</title></head>\n" + "<body bgcolor=\"#f0f0f0\">\n" 41 + "<h1 align=\"center\">" + title + "</h1>\n" + "<p>当前时间是:" + nowTime + "</p>\n"); 42 } 43 44 // 处理 POST 方法请求的方法 45 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 46 doGet(request, response); 47 } 48 }
展示结果:时间5s自动刷新
3 Servlet 编写过滤器
Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。
可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet。Servlet 过滤器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 页面。调用 Servlet 前调用所有附加的 Servlet 过滤器。
Servlet 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:
- 在客户端的请求访问后端资源之前,拦截这些请求。
- 在服务器的响应发送回客户端之前,处理这些响应。
根据规范建议的各种类型的过滤器:
- 身份验证过滤器(Authentication Filters)。
- 数据压缩过滤器(Data compression Filters)。
- 加密过滤器(Encryption Filters)。
- 触发资源访问事件过滤器。
- 图像转换过滤器(Image Conversion Filters)。
- 日志记录和审核过滤器(Logging and Auditing Filters)。
- MIME-TYPE 链过滤器(MIME-TYPE Chain Filters)。
- 标记化过滤器(Tokenizing Filters)。
- XSL/T 过滤器(XSL/T Filters),转换 XML 内容。
过滤器通过 Web 部署描述符(web.xml)中的 XML 标签来声明,然后映射到您的应用程序的部署描述符中的 Servlet 名称或 URL 模式。
当 Web 容器启动 Web 应用程序时,它会为您在部署描述符中声明的每一个过滤器创建一个实例。
Filter的执行顺序与在web.xml配置文件中的配置顺序一致,一般把Filter配置在所有的Servlet之前。
Servlet 过滤器实例
以下是 Servlet 过滤器的实例,将输出网站名称和地址。本实例让您对 Servlet 过滤器有基本的了解,您可以使用相同的概念编写更复杂的过滤器应用程序:
1 package yuan; 2 3 //导入必需的 java 库 4 import javax.servlet.*; 5 import java.util.*; 6 7 //实现 Filter 类 8 public class LogFilter implements Filter { 9 public void init(FilterConfig config) throws ServletException { 10 // 获取初始化参数 11 String site = config.getInitParameter("Site"); 12 13 // 输出初始化参数 14 System.out.println("网站名称: " + site); 15 } 16 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException { 17 18 // 输出站点名称 19 System.out.println("站点网址:www.baidu.com"); 20 21 // 把请求传回过滤链 22 chain.doFilter(request,response); 23 } 24 public void destroy( ){ 25 /* 在 Filter 实例被 Web 容器从服务移除之前调用 */ 26 } 27 }
这边使用前文提到的 DisplayHeader.java 为例子:
Web.xml 中的 Servlet 过滤器映射(Servlet Filter Mapping)
定义过滤器,然后映射到一个 URL 或 Servlet,这与定义 Servlet,然后映射到一个 URL 模式方式大致相同。在部署描述符文件 web.xml 中为 filter 标签创建下面的条目:
<filter> <filter-name>LogFilter</filter-name> <filter-class>yuan.LogFilter</filter-class> <init-param> <param-name>site</param-name> <param-value>百度</param-value> </init-param> </filter> <filter-mapping> <filter-name>LogFilter</filter-name> <url-pattern>/DisplayHeader</url-pattern> </filter-mapping>
重启tomcat,展示结果:
出现 网址名称:百度 证明完成了filter的初始化。
输入 http://localhost:8082/Servlet/DisplayHeader 测试,再次查看控制台 Console:
出现了 站点网址:www.baidu.com,证明filter起了作用,如果输入的url后缀不是 /DisplayHeader 则不会打印结果。
增加多个过滤器,可以实现多层过滤。
菜鸟教程