在我们的服务器中,我们有一个通用的servlet映射
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
问题是并非每个* .do url都在控制器中配置,因此调用以* .do结尾但不存在的url会产生500错误,而同样不存在的url以* .do结尾会返回正确的404
所以我想做的是配置DispatcherServlet在这些情况下返回404,或者至少捕获所有这些异常并返回404。
答案 0 :(得分:1)
在控制器类中添加上述方法。每次抛出的异常,甚至是RuntimeExceptions,都会从这个方法中捕获它们。
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex) {
Logger.getLogger(GuestNavController.class).error(ex);
ModelAndView modelAndView = initializeModelAndView("guest/error500");
return modelAndView;
}
很明显,如果更改@ExceptionHandler异常参数和方法参数(它们必须相同),您将能够捕获特定的异常。
如果您有多个控制器类,则应创建控制器建议。您可以在源代码中添加上述类。
@ControllerAdvice
public class ExceptionManager {
private final Logger logger = Logger.getLogger(ExceptionManager.class);
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoHandlerFoundException.class)
public ModelAndView handleError404(Exception ex) {
logger.error("ERROR 404: " + ex.getMessage());
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("guest/error404");
return modelAndView;
}
}
您可以在此类中添加多个方法。此方法将捕获抛出的每个异常 小心,以防您同时包含上述两种解决方案。如果在包含带有@ExceptionHandler批注的方法的控制器中抛出异常,则异常将仅由此方法捕获,而不是从外部类捕获。外部类(解决方案2)将捕获未被内部方法捕获的异常(解决方案1)。
答案 1 :(得分:0)
除了在部署描述符中配置<error-page/>
元素以专门捕获404
错误,或者您没有任何其他选项。如果您使用完整的Web应用程序容器(如glassfish),则可以选择在容器级别覆盖404
页面。根据配置查看here选项(servlet 3.0有一个新选项)
请注意,JavaEE堆栈中没有ViewNotFoundException
这样的东西(我检查过绝对肯定),因为容器跳入并在第一个提示中控制某些东西可能从根本上是错误的提供所请求的资源
4XX
系列状态代码作为开发人员通常无法控制,因为它们描述了您可能无法处理的错误情况(401-forbidden
,404-Not found
等)或不应该处理,有点像java的运行时异常。