我如何在 Spring Boot/MVC 中创建错误处理程序(404、500...)
Posted
技术标签:
【中文标题】我如何在 Spring Boot/MVC 中创建错误处理程序(404、500...)【英文标题】:How I create an error handler (404, 500...) in Spring Boot/MVC 【发布时间】: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。 【参考方案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 知识,你应该找到你的来弄清楚其余的。 或***.com/questions/23580509/… 这里是一个很好的例子:***.com/questions/27386261/… 谢谢你的一切,我会努力的。以上是关于我如何在 Spring Boot/MVC 中创建错误处理程序(404、500...)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Java Spring Boot MVC 中使用 Ajax 删除多个项目
Spring Boot MVC - 如何以编程方式生成实体的 etag 值?
如何在传统的 tomcat webapps 文件夹中部署 Spring Boot MVC 应用程序?