【问题标题】:How I create an error handler (404, 500...) in Spring Boot/MVC我如何在 Spring Boot/MVC 中创建错误处理程序(404、500...)
【发布时间】:2016-12-11 04:33:15
【问题描述】:

几个小时以来,我试图在 Spring Boot/MVC 中创建一个 custom 全局错误处理程序。看了很多文章,一无所获。

这是我的错误类:

我尝试创建一个这样的类

@Controller
public class ErrorPagesController {

    @RequestMapping("/404")
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String notFound() {
        return "/error/404";
    }

    @RequestMapping("/403")
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public String forbidden() {
        return "/error/403";
    }

    @RequestMapping("/500")
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String internalServerError() {
        return "/error/500";
    }

}

【问题讨论】:

  • 您好,您的问题太宽泛了,您需要向人们展示一个具体的问题来帮助您解决问题,例如:向我们展示您到目前为止所做的尝试。
  • 我已经编辑了我的问题。
  • @IsmaelEzequiel 为什么不发布您的解决方案作为问题的答案?它会有我的 +1。

标签: java spring spring-mvc spring-boot


【解决方案1】:

你可以试试下面的代码:

@ControllerAdvice
public class ExceptionController {
    @ExceptionHandler(Exception.class)
    public ModelAndView handleError(HttpServletRequest request, Exception e)   {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Request: " + request.getRequestURL() + " raised " + e);
        return new ModelAndView("error");
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public ModelAndView handleError404(HttpServletRequest request, Exception e)   {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Request: " + request.getRequestURL() + " raised " + e);
        return new ModelAndView("404");
    }
}

【讨论】:

  • 这给了我一个Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.servlet.NoHandlerFoundException] 异常。似乎 Spring 无法决定为 NoHandlerFoundException 选择哪种方法,因为两个 ExceptionHandler 注释都匹配......
【解决方案2】:

@Arash 的补充 您可以添加一个可以扩展的新 BaseController 类,用于处理从异常到 http response 的转换。

     import com.alexfrndz.pojo.ErrorResponse;
     import com.alexfrndz.pojo.Error;
     import com.alexfrndz.pojo.exceptions.NotFoundException;
     import org.springframework.http.HttpStatus;
     import org.springframework.http.ResponseEntity;
     import org.springframework.web.bind.annotation.ExceptionHandler;
     import org.springframework.web.bind.annotation.ResponseBody;
     import org.springframework.web.bind.annotation.ResponseStatus;

     import javax.persistence.NoResultException;
     import javax.servlet.http.HttpServletRequest;
     import java.util.List;

     @Slf4j
     public class BaseController {

    @ExceptionHandler(NoResultException.class)
    public ResponseEntity<Exception> handleNoResultException(
            NoResultException nre) {
        log.error("> handleNoResultException");
        log.error("- NoResultException: ", nre);
        log.error("< handleNoResultException");
        return new ResponseEntity<Exception>(HttpStatus.NOT_FOUND);
    }


    @ExceptionHandler(Exception.class)
    public ResponseEntity<Exception> handleException(Exception e) {
        log.error("> handleException");
        log.error("- Exception: ", e);
        log.error("< handleException");
        return new ResponseEntity<Exception>(e,
                HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(NotFoundException.class)
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public ErrorResponse handleNotFoundError(HttpServletRequest req, NotFoundException exception) {
        List<Error> errors = Lists.newArrayList();
        errors.add(new Error(String.valueOf(exception.getCode()), exception.getMessage()));
        return new ErrorResponse(errors);
    }
   }

【讨论】:

    【解决方案3】:

    春季启动更新

    自定义错误页面

    如果要为给定的状态代码显示自定义 HTML 错误页面,请将文件添加到 /error 文件夹。错误页面可以是静态 HTML(即添加到任何静态资源文件夹下)或使用模板构建。文件名应该是准确的状态码或序列掩码。

    例如,要将 404 映射到静态 HTML 文件,您的文件夹结构应如下所示

    src/
     +- main/
         +- java/
         |   + <source code>
         +- resources/
             +- public/
                 +- error/
                 |   +- 404.html
                 +- <other public assets>
    

    Source

    【讨论】:

      【解决方案4】:
      @ControllerAdvice
       public class ErrorHandler {
      
      public RestErrorHandler() {
      }
      
      @ExceptionHandler(YourException.class)
      @ResponseStatus(HttpStatus.BAD_REQUEST)
      public XXX processException(Exception ex){}
      

      你需要这样的课程。为每个异常添加一个方法,并根据需要对其进行注释 - @ResponseBody 等。

      【讨论】:

      • 是否可以返回 ModelAndView 或视图名称?
      【解决方案5】:

      希望这会有所帮助: 创建一个类说:NoProductsFoundException 扩展运行时异常。

          import org.springframework.http.HttpStatus;
          import org.springframework.web.bind.annotation.ResponseStatus;
      
          @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="No products found under this category")
          public class NoProductsFoundException extends RuntimeException{
      
          private static final long serialVersionUID =3935230281455340039L;
          }
      

      然后在你的产品控制器中:

          @RequestMapping("/{category}")
          public String getProductsByCategory(Model
          model,@PathVariable("category") String category) {
      
         List<Product> products = productService.getProductsByCategory(category);
      
         if (products == null || products.isEmpty()) {
         throw new NoProductsFoundException ();
         }
         model.addAttribute("products", products);
         return "products";
      }
      

      【讨论】:

      • 感谢您的回答,但我需要为每种类型的错误(如 404、403、500 等)创建一个自定义和全局错误处理程序,例如:当我去 - localhost:8080 /任何我收到 404 错误或发生某些内部错误时抛出 500 错误。明白了吗?
      • 是的,我知道你想要什么。我的例子只是一个“骨架”。如果你有一些基本的 Java EE 或 Spring mvc 知识,你应该找到你的来弄清楚其余的。
      • 这里是一个很好的例子:stackoverflow.com/questions/27386261/…
      • 谢谢你的一切,我会努力的。
      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 2019-08-20
      • 2016-06-05
      • 1970-01-01
      • 2018-06-26
      • 2011-06-06
      相关资源
      最近更新 更多