首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用来自Spring的自定义错误响应

使用来自Spring的自定义错误响应
EN

Stack Overflow用户
提问于 2020-04-13 06:38:11
回答 1查看 676关注 0票数 0

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

自定义例外:

代码语言:javascript
运行
复制
 public class TicketNotFoundException extends RuntimeException
{
    public TicketNotFoundException(Long id)
    {
        super("Ticket not found with id: "+id);
    }
}

自定义响应:

代码语言:javascript
运行
复制
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
 }

自定义异常处理程序:

代码语言:javascript
运行
复制
@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);
    }
}

反应本身是有效的:

{时间戳:"2020-04-13 09:33:52",状态: 404,错误:“未找到id: 1的票证”}

后端终端:

代码语言:javascript
运行
复制
 Resolved [com.eggorko.ebt.ticket.TicketNotFoundException: Ticket not found with id: 1] 

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

客户端控制器如下所示:

代码语言:javascript
运行
复制
@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";
    }

我做了一点客户端,但不起作用:

代码语言:javascript
运行
复制
@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";
    }
}

这就是我在终端客户端得到的信息:

代码语言:javascript
运行
复制
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。但我不知道该怎么办。

更新

所以我做了这个:

代码语言:javascript
运行
复制
 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没有开火,而且基本过时了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-13 07:21:06

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

更新

现在我知道您想要实现什么,它提供了500个,因为您没有在客户端控制器中处理异常,当您进行rest模板调用时,您说我想要一个票证类型的响应,但是您正在得到CustomErrorResponse的响应,确定它是通过控制台日志抛出的还是捕获异常,然后处理它并进行处理。

代码语言:javascript
运行
复制
@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";
    }

您可以包装您的票证,并且CustomErrorResponse是一个父类,然后可以使用实例来确定您收到的响应。

代码语言:javascript
运行
复制
ResponseEntity<Parent> parent= restTemplate.getForEntity( url+ id, 
        Parent.class);
if(parent.getBody() instanceof Ticket)
{
//normal flow
}
else
{
//error
}

UPDATE2

ErrorController过时了,因为

代码语言:javascript
运行
复制
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";

是用模型返回视图error.jsp(或.html),它不是重定向到URL /error,可以通过使用重定向看见来实现,但我建议不要这样做,您的ErrorController是指处理应用程序中发生的错误,而不是在您的应用程序调用时发生的错误,在这种情况下实现一个正确的响应页面。

编码愉快!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61182679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档