实习培训——Servlet(7)
1 Servlet 异常处理
当一个 Servlet 抛出一个异常时,Web 容器在使用了 exception-type 元素的 web.xml 中搜索与抛出异常类型相匹配的配置。
您必须在 web.xml 中使用 error-page 元素来指定对特定异常 或 HTTP 状态码 作出相应的 Servlet 调用。
如果您想对所有的异常有一个通用的错误处理程序,那么应该定义下面的 error-page,而不是为每个异常定义单独的 error-page 元素:
1 <error-page> 2 <exception-type>java.lang.Throwable</exception-type > 3 <location>/ErrorHandler</location> 4 </error-page>
以下是关于上面的 web.xml 异常处理要注意的点:
- Servelt ErrorHandler 与其他的 Servelt 的定义方式一样,且在 web.xml 中进行配置。
- 如果有错误状态代码出现,不管为 404(Not Found 未找到)或 403(Forbidden 禁止),则会调用 ErrorHandler 的 Servlet。
- 如果 Web 应用程序抛出 ServletException 或 IOException,那么 Web 容器会调用 ErrorHandler 的 Servlet。
- 您可以定义不同的错误处理程序来处理不同类型的错误或异常。上面的实例是非常通用的,希望您能通过实例理解基本的概念。
Servlet 错误处理程序实例
以下是 Servlet 实例,将应对任何您所定义的错误或异常发生时的错误处理程序。
本实例让您对 Servlet 中的异常处理有基本的了解,您可以使用相同的概念编写更复杂的异常处理应用程序:
1 package yuan; 2 //导入必需的 java 库 3 import java.io.*; 4 import javax.servlet.*; 5 import javax.servlet.http.*; 6 import java.util.*; 7 8 //扩展 HttpServlet 类 9 public class ErrorHandler extends HttpServlet { 10 11 // 处理 GET 方法请求的方法 12 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 13 { 14 Throwable throwable = (Throwable) 15 request.getAttribute("javax.servlet.error.exception"); 16 Integer statusCode = (Integer) 17 request.getAttribute("javax.servlet.error.status_code"); 18 String servletName = (String) 19 request.getAttribute("javax.servlet.error.servlet_name"); 20 if (servletName == null){ 21 servletName = "Unknown"; 22 } 23 String requestUri = (String) 24 request.getAttribute("javax.servlet.error.request_uri"); 25 if (requestUri == null){ 26 requestUri = "Unknown"; 27 } 28 // 设置响应内容类型 29 response.setContentType("text/html;charset=UTF-8"); 30 31 PrintWriter out = response.getWriter(); 32 String title = " Error/Exception 信息"; 33 34 String docType = "<!DOCTYPE html>\n"; 35 out.println(docType + 36 "<html>\n" + 37 "<head><title>" + title + "</title></head>\n" + 38 "<body bgcolor=\"#f0f0f0\">\n"); 39 out.println("<h1>异常信息实例演示</h1>"); 40 if (throwable == null && statusCode == null){ 41 out.println("<h2>错误信息丢失</h2>"); 42 out.println("请返回 <a href=\"" + 43 response.encodeURL("http://localhost:8082/") + 44 "\">主页</a>。"); 45 }else if (statusCode != null) { 46 out.println("错误代码 : " + statusCode); 47 }else{ 48 out.println("<h2>错误信息</h2>"); 49 out.println("Servlet Name : " + servletName + 50 "</br></br>"); 51 out.println("异常类型 : " + 52 throwable.getClass( ).getName( ) + 53 "</br></br>"); 54 out.println("请求 URI: " + requestUri + 55 "<br><br>"); 56 out.println("异常信息: " + 57 throwable.getMessage( )); 58 } 59 out.println("</body>"); 60 out.println("</html>"); 61 } 62 // 处理 POST 方法请求的方法 63 public void doPost(HttpServletRequest request, 64 HttpServletResponse response) 65 throws ServletException, IOException { 66 doGet(request, response); 67 } 68 }
接下来配置web.xml,同配置servlet类似,但是多了<error-page> </error-page>
<servlet> <servlet-name>ErrorHandler</servlet-name> <servlet-class>yuan.ErrorHandler</servlet-class> </servlet> <servlet-mapping> <servlet-name>ErrorHandler</servlet-name> <url-pattern>/ErrorHandler</url-pattern> </servlet-mapping> <error-page> <error-code>404</error-code> <location>/ErrorHandler</location> </error-page> <error-page> <exception-type>java.lang.Throwable</exception-type > <location>/ErrorHandler</location> </error-page>
输入http://localhost:8082/Servlet/xxxxx ,xxxx代表某些错误的指向。
2 Servlet Cookie 处理
Cookie 是存储在客户端计算机上的文本文件,并保留了各种跟踪信息。Java Servlet 显然支持 HTTP Cookie。
识别返回用户包括三个步骤:
- 服务器脚本向浏览器发送一组 Cookie。例如:姓名、年龄或识别号码等。
- 浏览器将这些信息存储在本地计算机上,以备将来使用。
- 当下一次浏览器向 Web 服务器发送任何请求时,浏览器会把这些 Cookie 信息发送到服务器,服务器将使用这些信息来识别用户。
本章将向您讲解如何设置或重置 Cookie,如何访问它们,以及如何将它们删除。
2.1 通过Servlet设置Cookie
实例
让我们修改我们的 表单数据实例,为名字和姓氏设置 Cookie。
1 package yuan; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.net.URLEncoder; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.annotation.WebServlet; 9 import javax.servlet.http.Cookie; 10 import javax.servlet.http.HttpServlet; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 /** 15 * Servlet implementation class HelloServlet 16 */ 17 @WebServlet("/HelloFormCookie") 18 public class HelloFormCookie extends HttpServlet { 19 private static final long serialVersionUID = 1L; 20 21 /** 22 * @see HttpServlet#HttpServlet() 23 */ 24 public HelloFormCookie() { 25 super(); 26 // TODO Auto-generated constructor stub 27 } 28 29 /** 30 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 31 */ 32 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 33 { 34 // 为名字和姓氏创建 Cookie 35 Cookie name = new Cookie("name", 36 URLEncoder.encode(request.getParameter("name"), "UTF-8")); // 中文转码 37 Cookie url = new Cookie("url", 38 request.getParameter("url")); 39 40 // 为两个 Cookie 设置过期日期为 24 小时后 41 name.setMaxAge(60*60*24); 42 url.setMaxAge(60*60*24); 43 44 // 在响应头中添加两个 Cookie 45 response.addCookie( name ); 46 response.addCookie( url ); 47 48 // 设置响应内容类型 49 response.setContentType("text/html;charset=UTF-8"); 50 51 PrintWriter out = response.getWriter(); 52 String title = "设置 Cookie 实例"; 53 String docType = "<!DOCTYPE html>\n"; 54 out.println(docType + 55 "<html>\n" + 56 "<head><title>" + title + "</title></head>\n" + 57 "<body bgcolor=\"#f0f0f0\">\n" + 58 "<h1 align=\"center\">" + title + "</h1>\n" + 59 "<ul>\n" + 60 " <li><b>站点名:</b>:" 61 + request.getParameter("name") + "\n</li>" + 62 " <li><b>站点 URL:</b>:" 63 + request.getParameter("url") + "\n</li>" + 64 "</ul>\n" + 65 "</body></html>"); 66 } 67 68 /** 69 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 70 */ 71 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 72 // TODO Auto-generated method stub 73 doGet(request, response); 74 } 75 76 }
最后尝试下面的 HTML 页面来调用 Servlet。名字为cookie.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>百度</title> </head> <body> <form action="HelloFormCookie" method="GET"> 站点名 :<input type="text" name="name"> <br /> 站点 URL:<input type="text" name="url" /><br> <input type="submit" value="提交" /> </form> </body> </html>
输入:http://localhost:8082/Servlet/cookie.html 可以自己设置name和url
2.2 通过 Servlet 读取 Cookie
要读取 Cookie,您需要通过调用 HttpServletRequest 的 getCookies( ) 方法创建一个 javax.servlet.http.Cookie 对象的数组。然后循环遍历数组,并使用 getName() 和 getValue() 方法来访问每个 cookie 和关联的值。
实例
让我们读取上面的实例中设置的 Cookie
1 package yuan; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.net.URLDecoder; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.annotation.WebServlet; 9 import javax.servlet.http.Cookie; 10 import javax.servlet.http.HttpServlet; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 /** 15 * Servlet implementation class ReadCookies 16 */ 17 @WebServlet("/ReadCookies") 18 public class ReadCookies extends HttpServlet { 19 private static final long serialVersionUID = 1L; 20 21 /** 22 * @see HttpServlet#HttpServlet() 23 */ 24 public ReadCookies() { 25 super(); 26 // TODO Auto-generated constructor stub 27 } 28 29 /** 30 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 31 */ 32 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 33 { 34 Cookie cookie = null; 35 Cookie[] cookies = null; 36 // 获取与该域相关的 Cookie 的数组 37 cookies = request.getCookies(); 38 39 // 设置响应内容类型 40 response.setContentType("text/html;charset=UTF-8"); 41 42 PrintWriter out = response.getWriter(); 43 String title = "Delete Cookie Example"; 44 String docType = "<!DOCTYPE html>\n"; 45 out.println(docType + 46 "<html>\n" + 47 "<head><title>" + title + "</title></head>\n" + 48 "<body bgcolor=\"#f0f0f0\">\n" ); 49 if( cookies != null ){ 50 out.println("<h2>Cookie 名称和值</h2>"); 51 for (int i = 0; i < cookies.length; i++){ 52 cookie = cookies[i]; 53 if((cookie.getName( )).compareTo("name") == 0 ){ 54 cookie.setMaxAge(0); 55 response.addCookie(cookie); 56 out.print("已删除的 cookie:" + 57 cookie.getName( ) + "<br/>"); 58 } 59 out.print("名称:" + cookie.getName( ) + ","); 60 out.print("值:" + URLDecoder.decode(cookie.getValue(), "utf-8") +" <br/>"); 61 } 62 }else{ 63 out.println( 64 "<h2 class=\"tutheader\">No Cookie founds</h2>"); 65 } 66 out.println("</body>"); 67 out.println("</html>"); 68 } 69 70 /** 71 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 72 */ 73 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 74 // TODO Auto-generated method stub 75 doGet(request, response); 76 } 77 78 }
输入 http://localhost:8082/Servlet/ReadCookies
2.3 通过 Servlet 删除 Cookie
删除 Cookie 是非常简单的。如果您想删除一个 cookie,那么您只需要按照以下三个步骤进行:
- 读取一个现有的 cookie,并把它存储在 Cookie 对象中。
- 使用 setMaxAge() 方法设置 cookie 的年龄为零,来删除现有的 cookie。
- 把这个 cookie 添加到响应头。
实例
下面的例子将删除现有的名为 "url" 的 cookie,当您下次运行 ReadCookies 的 Servlet 时,它会返回 url 为 null。
package yuan; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class DeleteCookies */ @WebServlet("/DeleteCookies") public class DeleteCookies extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public DeleteCookies() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = null; Cookie[] cookies = null; // 获取与该域相关的 Cookie 的数组 cookies = request.getCookies(); // 设置响应内容类型 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String title = "删除 Cookie 实例"; String docType = "<!DOCTYPE html>\n"; out.println(docType + "<html>\n" + "<head><title>" + title + "</title></head>\n" + "<body bgcolor=\"#f0f0f0\">\n" ); if( cookies != null ){ out.println("<h2>Cookie 名称和值</h2>"); for (int i = 0; i < cookies.length; i++){ cookie = cookies[i]; if((cookie.getName( )).compareTo("url") == 0 ){ cookie.setMaxAge(0); response.addCookie(cookie); out.print("已删除的 cookie:" + cookie.getName( ) + "<br/>"); } out.print("名称:" + cookie.getName( ) + ","); out.print("值:" + cookie.getValue( )+" <br/>"); } }else{ out.println( "<h2 class=\"tutheader\">No Cookie founds</h2>"); } out.println("</body>"); out.println("</html>"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
运行 http://localhost:8082/Servlet/DeleteCookies
再次读取http://localhost:8082/Servlet/ReadCookies,可以看到之前创建的cookie已经消失。
菜鸟教程