servlet 异常处理_Servlet异常和错误处理示例教程

本文深入探讨Servlet异常和错误处理机制,包括ServletException和404错误的处理,以及如何使用自定义异常处理程序Servlet来改进错误响应,为用户提供更有意义的信息。

servlet 异常处理

Today we will look into Servlet Exception and Error Handling. Sometime back I wrote a post about Exception Handling in Java but when it comes to web application, we need more than normal exception handling in java.

今天,我们将研究Servlet异常和错误处理。 有时候我写了一篇有关Java异常处理的文章,但是当涉及到Web应用程序时,我们需要的不仅仅是Java中的异常处理。

Servlet异常 (Servlet Exception)

If you notice, doGet() and doPost() methods throw javax.servlet.ServletException and IOException, let’s see what happens when we throw these exception from our application. I will write a simple servlet that will throw the ServletException.

如果您注意到,doGet()和doPost()方法会抛出javax.servlet.ServletExceptionIOException ,让我们看看从应用程序中抛出这些异常时会发生什么。 我将编写一个简单的Servlet,它将抛出ServletException。

package com.journaldev.servlet.exception;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/MyExceptionServlet")
public class MyExceptionServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		throw new ServletException("GET method is not supported.");
	}

}

Now when we invoke this servlet through browser with GET method, we get response like below image.

现在,当我们使用GET方法通过浏览器调用此servlet时,将得到如下图所示的响应。

Since browser understand only HTML, when our application throw exception, servlet container processes the exception and generate a HTML response. This logic is specific to servlet container. I am using tomcat and getting this error page. If you will use some other servers like JBoss or Glassfish, you might get different error HTML response.

由于浏览器仅了解HTML,因此当我们的应用程序引发异常时,servlet容器将处理该异常并生成HTML响应。 此逻辑特定于servlet容器。 我正在使用tomcat并获取此错误页面。 如果您将使用其他一些服务器,例如JBoss或Glassfish,则可能会收到不同的错误HTML响应。

The problem with this response is that it’s of no value to user. Also it’s showing our application classes and server details to user that makes no sense to user and it’s not good from security point of view.

此响应的问题在于它对用户没有任何价值。 它还向用户显示了我们的应用程序类和服务器详细信息,这对用户没有意义,并且从安全角度来看也不是一件好事。

Servlet错误 (Servlet Error)

I am sure you must have seen 404 error when you are trying to hit a URL that doesn’t exists. Let’s see how our servlet container responds to 404 error. If we send request for an invalid URL, we get response HTML like below image.

我敢肯定,当您尝试访问不存在的URL时,您一定已经看到404错误。 让我们看看我们的servlet容器如何响应404错误。 如果我们发送无效URL的请求,则会得到响应HTML,如下图所示。

Again it’s a generic HTML generated by server on our application behalf and hold little to no value to the user.

同样,它是服务器代表我们的应用程序生成的通用HTML,对用户几乎没有价值。

Servlet异常和错误处理 (Servlet Exception and Error Handling)

Servlet API provides support for custom Exception and Error Handler servlets that we can configure in deployment descriptor. The whole purpose of these servlets are to handle the Exception or Error raised by application and send useful HTML response to user. We can provide link to application home page or some details to let user know what went wrong.

Servlet API提供对自定义异常和错误处理程序Servlet的支持,我们可以在部署描述符中对其进行配置。 这些servlet的全部目的是处理应用程序引发的异常或错误,并将有用HTML响应发送给用户。 我们可以提供指向应用程序主页的链接或一些详细信息,以使用户知道出了什么问题。

So first of all we need to create a custom Exception and Error Handler servlet. We can have multiple exception and error handler servlets for the application but for simplicity I will create a single servlet and use it for both exceptions and errors.

因此,首先我们需要创建一个自定义的Exception and Error Handler servlet。 我们可以为应用程序提供多个异常和错误处理程序servlet,但为简单起见,我将创建一个servlet,并将其用于异常和错误。

AppExceptionHandler.java

AppExceptionHandler.java

package com.journaldev.servlet.exception;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/AppExceptionHandler")
public class AppExceptionHandler extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processError(request, response);
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processError(request, response);
	}

	private void processError(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		// Analyze the servlet exception
		Throwable throwable = (Throwable) request
				.getAttribute("javax.servlet.error.exception");
		Integer statusCode = (Integer) request
				.getAttribute("javax.servlet.error.status_code");
		String servletName = (String) request
				.getAttribute("javax.servlet.error.servlet_name");
		if (servletName == null) {
			servletName = "Unknown";
		}
		String requestUri = (String) request
				.getAttribute("javax.servlet.error.request_uri");
		if (requestUri == null) {
			requestUri = "Unknown";
		}
		
		// Set response content type
	      response.setContentType("text/html");
	 
	      PrintWriter out = response.getWriter();
	      out.write("<html><head><title>Exception/Error Details</title></head><body>");
	      if(statusCode != 500){
	    	  out.write("<h3>Error Details</h3>");
	    	  out.write("<strong>Status Code</strong>:"+statusCode+"<br>");
	    	  out.write("<strong>Requested URI</strong>:"+requestUri);
	      }else{
	    	  out.write("<h3>Exception Details</h3>");
	    	  out.write("<ul><li>Servlet Name:"+servletName+"</li>");
	    	  out.write("<li>Exception Name:"+throwable.getClass().getName()+"</li>");
	    	  out.write("<li>Requested URI:"+requestUri+"</li>");
	    	  out.write("<li>Exception Message:"+throwable.getMessage()+"</li>");
	    	  out.write("</ul>");
	      }
	      
	      out.write("<br><br>");
	      out.write("<a href=\"index.html\">Home Page</a>");
	      out.write("</body></html>");
	}
}

Let’s see how we can configure it in deployment descriptor and then we will understand it’s implementation and how it works.

让我们看看如何在部署描述符中配置它,然后我们将了解它的实现及其工作方式。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>ServletExceptionHandling</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  
  <error-page>
  	<error-code>404</error-code>
  	<location>/AppExceptionHandler</location>
  </error-page>
  
  <error-page>
  <exception-type>javax.servlet.ServletException</exception-type>
  <location>/AppExceptionHandler</location>
  </error-page>
</web-app>

As you can see, it’s very easy to specify Exception handler servlets for the application using error-page element. Each error-page element should have either error-code or exception-type element. We define the exception handler servlet in location element.

如您所见,使用error-page元素为应用程序指定异常处理程序servlet非常容易。 每个错误页面元素应具有错误代码异常类型元素。 我们在location元素中定义异常处理程序servlet。

Based on above configuration, if the application throw 404 error or ServletException, it will be handled by AppExceptionHandler servlet.

基于以上配置,如果应用程序抛出404错误或ServletException,它将由AppExceptionHandler Servlet处理。

When such exception and error scenario appears, servlet container will invoke the corresponding HTTP method of the Exception Handler servlet and pass the request and response object. Notice that I have provided implementation of both doGet() and doPost() methods so that it can handle GET and POST requests and using a common method to process them.

当出现此类异常和错误情况时,servlet容器将调用Exception Handler servlet的相应HTTP方法,并传递请求和响应对象。 请注意,我已经提供了doGet()和doPost()方法的实现,以便它可以处理GET和POST请求并使用通用方法来处理它们。

Before servlet container invokes the servlet to handle the exception, it sets some attributes in the request to get useful information about the exception, some of them are javax.servlet.error.exception, javax.servlet.error.status_code, javax.servlet.error.servlet_name and javax.servlet.error.request_uri.

在servlet容器调用servlet来处理异常之前,它会在请求中设置一些属性以获取有关异常的有用信息,其中一些属性是javax.servlet.error.exceptionjavax.servlet.error.status_codejavax.servlet。 error.servlet_namejavax.servlet.error.request_uri

For exception, status code is always 500 that corresponds to the “Internal Server Error”, for other types of error we get different error codes such as 404, 403 etc.

作为例外,状态码始终为500,与“内部服务器错误”相对应,对于其他类型的错误,我们将获得不同的错误代码,例如404、403等。

Using the status code, our implementation presents different types of HTML response to the user. It also provides a hyperlink to the home page of the application.

使用状态代码,我们的实现将不同类型HTML响应呈现给用户。 它还提供了到应用程序主页的超链接。

Now when we will hit our servlet that is throwing ServletException, we will get a response like below image.

现在,当我们点击抛出ServletException的servlet时,我们将得到如下图所示的响应。

If we try to access an invalid URL that will result in 404 response, we will get response like below image.

如果我们尝试访问无效的URL,这将导致404响应,我们将得到如下图所示的响应。

Doesn’t it look good and helps user to easily understand what happened and provides them a way to go to the correct location. It also avoids sending application sensitive information to the user. We should always have exception handlers in place for our web application.

它看起来不是很好,并且可以帮助用户轻松地了解发生了什么并为他们提供前往正确位置的方法。 它还避免了将应用程序敏感信息发送给用户。 我们应该始终为我们的Web应用程序配备异常处理程序。

If you want to handle runtime exceptions and all other exceptions in a single exception handler, you can provide exception-type as Throwable.

如果要在单个异常处理程序中处理运行时异常和所有其他异常,则可以将异常类型提供为Throwable。

<error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/AppExceptionHandler</location>
</error-page>

If there are multiple error-page entries, let’s say one for Throwable and one for IOException and application throws FileNotFoundException then it will be handled by error handler of IOException.

如果有多个错误页面条目,例如对于Throwable一项,对于IOException一项,应用程序抛出FileNotFoundException,那么它将由IOException的错误处理程序处理。

You can also use JSP page as exception handler, just provide the location of jsp file rather than servlet mapping.

您还可以将JSP页面用作异常处理程序,仅提供jsp文件的位置而不是servlet映射。

That’s all for servlet exception handling in web application, I hope you liked it.

这就是Web应用程序中servlet异常处理的全部,希望您喜欢它。

Check out other articles in this series:

查看本系列的其他文章:

  1. Java Web Application

    Java Web应用程序
  2. Java Servlet Tutorial

    Java Servlet教程
  3. Session Management in Java

    Java中的会话管理
  4. Servlet Filter

    Servlet过滤器
  5. Servlet Listeners

    Servlet侦听器
  6. Cookies in Servlets

    Servlet中的Cookie
  7. Servlet File Upload and Download Example

    Servlet文件上传和下载示例

翻译自: https://www.journaldev.com/1973/servlet-exception-and-error-handling-example-tutorial

servlet 异常处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值