Servlet异常和错误处理示例教程

有时我写了一篇有关Java异常处理的文章,但是当涉及到Web应用程序时,我们需要的不仅仅是Java中的异常处理。

Servlet异常

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

MyExceptionServlet.java

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.");}}

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

Servlet异常用户

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

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

Servlet错误

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

Servlet-404错误

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

Servlet异常和错误处理

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

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

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 exceptionThrowable 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 typeresponse.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>");}
}

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

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://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>

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

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

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

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

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

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

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

Servlet异常处理500代码

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

Servlet错误处理404

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

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

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

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

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

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

  • 下载ServletExceptionHandling项目

参考:我们的JCG合作伙伴 Pankaj Kumar在Developer Recipes博客上的Servlet异常和错误处理示例教程 。

翻译自: https://www.javacodegeeks.com/2013/08/servlet-exception-and-error-handling-example-tutorial.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python数据结构与算法13_python 数据结构与算法 (13)

python 数据结构与算法 (13)选择排序 (Selection sort) 是? 种简单直观的排序算法. 它的? 作原理如 下.? 先在未排序序列中找到最?(?)元素, 存放到排序序列的起始位 置, 然后, 再从剩余未排序元素中继续寻找最?(?)元素, 然后放到已排 序序列的末尾. 以此类推, 直到所有元…

小程序如何发红包

咳咳&#xff0c;直入主题。敲黑板&#xff0c;请看下面一段对话。 产品&#xff1a;我想要小程序发红包这个功能 程序员&#xff1a;目前不支持啊 产品&#xff1a;我不管&#xff01; 程序员&#xff1a;做不到啊&#xff0c;这。。。 产品&#xff1a;我不管&#xff01;我不…

如何实现REST资源的输入验证

如何实现REST资源的输入验证 我正在使用的SaaS平台具有一个RESTful接口&#xff0c;该接口可以接受XML有效负载。 实施REST资源 对于像我们这样的Java商店&#xff0c;使用JAX-B从XML Schema生成JavaBean类是有意义的。 在像Jersey的JAX-RS环境中&#xff0c;使用JAX-B处理X…

Linux系统下,MySQL以及禅道的安装/卸载

1、MySQL卸载&#xff1a; &#xff08;通过yum命令卸载之前安装的mysql&#xff0c; find命令找到mysql文件&#xff0c;再用rm –rf 强制删除/var/lib/mysql&#xff09; 2、MySQL安装&#xff1a; &#xff08;使用yum命令安装mysql&#xff0c;安装完成后启动数据库&#x…

winform 点击全选

代码如下&#xff1a; #region 全选//chkAll_Checked即全选控键的点击事件private void chkAll_CheckedChanged(object sender, EventArgs e){if (chkAll.Checked){chkSun.Checked true;chkMon.Checked true;chkThu.Checked true;chkTue.Checked true;chkWed.Checked true…

今天的考核题目: 你知道React和Vue的区别吗? skr,skr

React 和 Vue 的区别 博主面了几家公司&#xff0c;看简历上写着使用Vue.js框架&#xff0c;就会问&#xff0c;你能说一说 vue 和 react的区别吗 &#xff1f;react 听过&#xff0c;没用过&#xff0c;所以就只能尴尬的说不怎么了解react。这不&#xff0c;最近刚学了react …

Play和Grails Java框架的优缺点

框架通过为程序员提供一些有用的功能来简化应用程序开发过程。 由于开发人员的普遍使用&#xff0c;Java框架经常被开发人员使用。 您可以在市场上找到各种Java开发框架。 新手开发人员经常在论坛上发布一个常见问题&#xff1a;“哪种Java框架是最好的&#xff1f;” 首先&am…

argb888与rgb888转换程序_一文了解各平台RGB565和RGB888区别

原标题&#xff1a;一文了解各平台RGB565和RGB888区别用过AM335x平台的小伙伴应该知道&#xff0c;OK335xS开发平台的LCD接口是RGB888模式的&#xff0c;而OK335xD开发平台的LCD接口是RGB565模式的。如果把xS的镜像烧写到xD平台上&#xff0c;那么LCD会显示颜色异常。这是为什么…

d4d#9 玩Docker只要浏览器就够了,PWD是个神奇的网站

本文是d4d系列的第9篇&#xff0c;在这一篇中给大家介绍一个学习Docker最为快捷高效的方式&#xff0c;你不需要自己搭建环境&#xff0c;也不用担心把自己的开发环境搞乱&#xff0c;你需要的只是一个浏览器&#xff0c;就可以立即开始学习Docker的常用命令&#xff1b;你甚至…

基于 Docker 打造前端持续集成开发环境

知乎: https://zhuanlan.zhihu.com/p/37961402本文将以一个标准的 Vue 项目为例&#xff0c;完全抛弃传统的前端项目开发部署方式&#xff0c;基于 Docker 容器技术打造一个精简的前端持续集成的开发环境。 前置知识&#xff1a;1. CI&#xff08;持续集成&#xff09;&#xf…

哪个内存更快?Heap或ByteBuffer或Direct?

Java正在成为新的C / C &#xff0c;它被广泛用于开发高性能系统。 对像我这样的数百万Java开发人员来说非常好&#xff01; 在这个博客中&#xff0c;我将分享我可以用Java完成的不同类型的内存分配实验以及您从中获得的好处。 Java中的内存分配 Java提供哪种类型的内存分配…

java没有打印mysql日志_0216 aop和打印数据库执行日志

需求maven依赖p6spyp6spy3.8.7com.google.guavaguava28.2-jreorg.springframework.bootspring-boot-starter-data-jpaorg.springframework.bootspring-boot-starter-webmysqlmysql-connector-javaruntimeorg.projectlomboklomboktrue打印sql配置要点&#xff1a;驱动配置 appli…

php数组基础

php中&#xff0c;数组的下标可以是整数&#xff0c;或字符串。 php中&#xff0c;数组的元素顺序不是由下标决定&#xff0c;而是由其“加入”的顺序决定。 定义&#xff1a; $arr1 array(元素1&#xff0c;元素2&#xff0c;。。。。。 ); array(1, 5, 1.1, “abc”, tr…

1.格式化输入输出

1.格式化输入input() input()函数&#xff0c;通常只能返回一个数据类型&#xff0c;那么怎么可以进行多个变量的复制呢&#xff1f;看下面这段代码。 1 str1, str2 eval(input("请输入两个字符串&#xff1a;")) 2 print(str1, str2) 3 4 num1, num2 eval(input(…

canvas像素点操作 —— 视频绿幕抠图

原文地址 主要内容 上篇文章学习了canvas像素点的获取 —— 传送门&#xff0c; 今天学一下canvas像素点操作。 一个方法&#xff1a;putImageData putImageData 用法&#xff1a; context.putImageData(imgData, x, y, dX, dY, dWidth, dHeight);参数描述imgData规定要放…

并发编程(一):基础概述

本篇博客主要讲述并发编程中的一些基础内容&#xff0c;并了解一下基本概念。 首先我们了解一下什么是并发&#xff1f; 同时拥有两个或者多个线程&#xff0c;如果程序在单核处理器上运行&#xff0c;多个线程将交替的换入或者换出内存&#xff0c;这些线程是同时“存在”的&a…

python哲学翻译_Python

正在学习Python开发语言的用户&#xff0c;可能会在学习过程中听说过讲师说过Python有一段有关于Python的哲学理念机设计思想&#xff0c;在Python里输入“import this”命令就会出现一段英文格言&#xff0c;这里我们把Python的这段格言的双语版分享出来&#xff0c;帮助正在学…

如何创建线程?

Java并发编程&#xff1a;如何创建线程&#xff1f; 在前面一篇文章中已经讲述了在进程和线程的由来&#xff0c;今天就来讲一下在Java中如何创建线程&#xff0c;让线程去执行一个子任务。下面先讲述一下Java中的应用程序和进程相关的概念知识&#xff0c;然后再阐述如何创建线…

经典MapReduce作业和Yarn上MapReduce作业运行机制

一、经典MapReduce的作业运行机制 如下图是经典MapReduce作业的工作原理&#xff1a; 1.1 经典MapReduce作业的实体 经典MapReduce作业运行过程包含的实体&#xff1a; 客户端&#xff0c;提交MapReduce作业。JobTracker&#xff0c;协调作业的运行。JobTracker是一个Java应用程…

根据Linux2.6.26源码分析进程模型

1.关于进程 1.1进程的概念 进程是正在运行的程序实体&#xff0c;并且包括这个运行的程序中占据的所有系统资源&#xff0c;比如说CPU(寄存器)&#xff0c;IO,内存&#xff0c;网络资源等。很多人在回答进程的概念的时候&#xff0c;往往只会说它是一个运行的实体&#xff0c;而…