gpt4 book ai didi

java - 使用 Spring REST 的自定义错误响应

转载 作者:行者123 更新时间:2023-12-01 17:27:48 25 4
gpt4 key购买 nike

我想为带有消息的错误代码实现自定义错误页面。到目前为止,按照 baeldung 指南,我在后端得到了这个;

自定义异常:

 public class TicketNotFoundException extends RuntimeException
{
public TicketNotFoundException(Long id)
{
super("Ticket not found with id: "+id);
}
}

自定义响应:

public class CustomErrorResponse
{
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
private LocalDateTime timestamp;
private int status;
private String error;
//getters setters
}

自定义异常处理程序:

@ControllerAdvice
public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler
{

@ExceptionHandler(value = TicketNotFoundException.class)
public ResponseEntity<CustomErrorResponse> customHandleNotFound(Exception ex)
{
CustomErrorResponse errors = new CustomErrorResponse();
errors.setTimestamp(LocalDateTime.now());
errors.setError(ex.getMessage());
errors.setStatus(HttpStatus.NOT_FOUND.value());
return new ResponseEntity<>(errors, HttpStatus.NOT_FOUND);
}
}

响应本身可以工作:

{ timestamp: "2020-04-13 09:33:52", status: 404, error: "Ticket not found with id: 1" }

后端终端:

 Resolved [com.eggorko.ebt.ticket.TicketNotFoundException: Ticket not found with id: 1] 

所以我的问题是我应该在客户端做什么?

客户端 Controller 如下所示:

@GetMapping("/{id}")
public String ticket(@PathVariable Long id, Model model)
{
String url = "http://localhost:8080/api/ticket/";
ResponseEntity<Ticket> ticket = restTemplate.getForEntity( url+ id, Ticket.class);

model.addAttribute("ticket",ticket.getBody());
model.addAttribute("title","Tickets");
return "ticket";
}

我在客户端做了这个,但它不起作用:

@Controller
public class MyErrorController implements ErrorController
{
@RequestMapping("/error")
public String handleError(HttpServletRequest request)
{
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);

if (status != null) {
Integer statusCode = Integer.valueOf(status.toString());

if(statusCode == HttpStatus.NOT_FOUND.value()) {
return "error-404";
}
else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error-500";
}
}
return "error";
}

@Override
public String getErrorPath()
{
return "/error";
}
}

这是我在客户端终端中得到的:

2020-04-13 10:34:40.559 ERROR 12868 --- [nio-8081-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException$NotFound: 404 : [{"timestamp":"2020-04-13 10:34:40","status":404,"error":"Ticket not found with id: 1"}]] with root cause

它会转到 500 错误页面,而不是 404。

我有点明白为什么它不起作用。我在客户端没有任何处理错误的东西,它会出现错误 500。但我不知道该如何处理它。

更新
所以我这样做了:

 String url = "http://localhost:8080/api/ticket/";
try {
ResponseEntity<Ticket> ticket = restTemplate.getForEntity(url + id, Ticket.class);
model.addAttribute("ticket",ticket.getBody());
model.addAttribute("title","Tickets");
}catch (Exception e)
{
String msg = e.getMessage();
model.addAttribute("message",msg);
return "/error";
}
return "ticket";

现在至少我收到了一个错误页面,其中包含来自后端的实际消息。但这个解决方案是围绕 MyErrorController 工作的。 MyErrorController 不会触发并且基本上已过时。

最佳答案

您正在从 MyErrorController 返回 View 名称,您在 View 解析器中指定的位置是否有错误页面 errro.html 或 error.jsp(无论您为 View 解析器使用什么后缀)?此外,您对所有错误代码使用相同的错误页面,您可以为不同的错误代码创建多个错误页面,例如 error-404.jsp 和 error-500.jsp。另一种方法是返回ModelAndView而不是 View 名称,可以引用link .

更新

好吧,现在我明白你想要实现什么,它给出 500 因为你没有在客户端 Controller 中处理异常,当你进行休息模板调用时,你说我想要票证类型的响应,但你得到了CustomErrorResponse 的响应,通过控制台日志或捕获异常来确定它抛出的是哪个异常,然后处理它并进行处理。

@GetMapping("/{id}")
public String ticket(@PathVariable Long id, Model model)
{
String url = "http://localhost:8080/api/ticket/";
try
{
ResponseEntity<Ticket> ticket = restTemplate.getForEntity( url+ id,
Ticket.class);
}
catch(Exception e)
{
// handel exception
}

model.addAttribute("ticket",ticket.getBody());
model.addAttribute("title","Tickets");
return "ticket";
}

或者

您可以包装您的 Ticket,并将 CustomErrorResponse 作为父类,然后可以使用 的实例来确定您收到的响应

ResponseEntity<Parent> parent= restTemplate.getForEntity( url+ id, 
Parent.class);
if(parent.getBody() instanceof Ticket)
{
//normal flow
}
else
{
//error
}

更新2

ErrorController 已过时,因为

String url = "http://localhost:8080/api/ticket/";
try {
ResponseEntity<Ticket> ticket = restTemplate.getForEntity(url + id, Ticket.class);
model.addAttribute("ticket",ticket.getBody());
model.addAttribute("title","Tickets");
}catch (Exception e)
{
String msg = e.getMessage();
model.addAttribute("message",msg);
return "/error";
}
return "ticket";

返回带有模型的 View error.jsp(或 .html),它没有重定向到 URL/error,您可以通过使用重定向 see 来做到这一点,但我建议不要这样做,您的 ErrorController 是为了处理您的应用程序中发生的错误,而不是您的应用程序调用的某些应用程序中发生的错误,针对这种情况实现正确的响应页面。

编码愉快!

关于java - 使用 Spring REST 的自定义错误响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61182679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com