- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
在本教程中,我们将如何在 Spring Boot REST Applications 中自定义 Exceptions 以满足我们的需求。
异常处理是开发应用程序和服务的关键要素。 Spring Boot 提供了良好的默认异常处理机制。
要了解Spring Boot 提供的默认异常处理是如何工作的,让我们开始请求一个不存在的 URL:
curl -s http://localhost:8080/unknown | jq
{
"timestamp": "2020-04-01T13:12:00.327+0000",
"status": 404,
“error": "Not Found",
"message”: "No message available",
"path": "/unknown"
}
需要注意的关键事项如下:
让我们创建一个引发异常的资源,并向其发送 GET 请求,以了解应用程序如何对运行时异常做出反应。
检查以下代码片段:
@RequestMapping("/list") public List < Customer > findAll() {
throw new RuntimeException("Some Exception Occured");
}
让我们在 http://localhost:8080/list/ 向前面的服务发出 GET 请求
响应如下代码所示:
curl -s http://localhost:8080/list | jq
{
"timestamp": "2020-04-01T13:15:11.091+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Some Exception Occured",
"path": "/list"
}
需要注意的一些重要事项如下:
让我们看一个使用自定义异常类的更复杂的示例
@RequestMapping("/find/{id}") public Customer findOne(@PathVariable int id) {
Customer c = repository.findCustomer(id);
if (c != null) return c;
else throw new CustomerNotFoundException(id);
}
如您所见,在这种情况下,如果您的搜索没有返回数据,我们将抛出 CustomerNotFoundException。
在这种情况下,如果我们返回一个 500 Internal Server Error 它对客户端来说就没有那么有意义了,客户端无法猜测如何修复这个错误。另一方面,如果我们返回一个状态码为 404 的错误,那就更合适了。
我们可以使用带有 @ExceptionHandler 的 ControllerAdvice 来处理自定义异常,它将处理自定义异常,填充并返回自定义响应,如下所示。
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@ControllerAdvice
public class MyExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(CustomerNotFoundException.class)
public void springHandleNotFound(HttpServletResponse response) throws IOException {
response.sendError(HttpStatus.NOT_FOUND.value());
}
}
这是 CustomerNotFoundException 类:
package com.example.testrest;
public class CustomerNotFoundException extends RuntimeException {
public CustomerNotFoundException(int id) {
super("Customer id not found : " + id);
}
}
因此,现在如果您请求未找到的客户,您将收到带有 CustomerNotFoundException 错误消息和状态 404 的 JSON 作为响应,而不是一般的 500 错误:
curl -s http://localhost:8080/find/9 | jq
{
"timestamp": "2020-04-01T14:01:47.637+0000",
"status": 404,
"error": "Not Found",
"message": "Customer id not found : 9",
"path": "/one/9"
}
要覆盖所有异常的默认 JSON 错误响应,只需创建一个扩展 DefaultErrorAttributes 的类。让我们看看如何在错误属性列表中添加应用程序版本:
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
@Component public class MyErrorAttributes extends DefaultErrorAttributes {
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
@Override public Map < String, Object > getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map < String, Object > errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
Object timestamp = errorAttributes.get("timestamp");
if (timestamp == null) {
errorAttributes.put("timestamp", dateFormat.format(new Date()));
} else {
errorAttributes.put("timestamp", dateFormat.format((Date) timestamp));
}
// Custom Attribute
errorAttributes.put("app.version", "2.2");
return errorAttributes;
}
}
在这种情况下,返回的 JSON 将是:
curl -s http://localhost:8080/query/9 | jq
{
"timestamp": "2020/04/01 16:25:29",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/query/9",
"app.version": "2.2"
}
本教程的源代码:https://github.com/fmarchioni/masterspringboot/tree/master/exception
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!