相关疑难解决方法(0)

如何使用Spring MVC/Spring Boot编写正确的全局错误处理程序

我正在编写一个使用Spring 4.0.4和Spring Boot 1.0.2的Web应用程序,使用Tomcat作为嵌入式Web容器,我想实现一个全局异常处理,它拦截所有异常并以特定方式记录它们.我的简单要求是:

  • 我想全局处理尚未在其他地方处理的所有异常(例如在控制器异常处理程序中).我想记录消息,我想向用户显示自定义错误消息.
  • 我不希望Spring或Web容器自己记录任何错误,因为我想自己这样做.

到目前为止,我的解决方案看起来像这样(简化,没有日志记录,也没有重定向到错误视图):

@Controller
@RequestMapping("/errors")
public class ErrorHandler implements EmbeddedServletContainerCustomizer
{
    @Override
    public void customize(final ConfigurableEmbeddedServletContainer factory)
    {
        factory.addErrorPages(new ErrorPage("/errors/unexpected"));
        factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/errors/notfound"));
    }

    @RequestMapping("unexpected")
    @ResponseBody
    public String unexpectedError(final HttpServletRequest request)
    {
        return "Exception: " + request.getAttribute("javax.servlet.error.exception");
    }

    @RequestMapping("notfound")
    @ResponseBody
    public String notFound()
    {
        return "Error 404";
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是该unexpectedError方法正确处理控制器中抛出的异常,并且该方法处理404状态代码notFound.到目前为止很好,但我有以下问题:

  • Tomcat或Spring(不确定谁负责)仍在记录错误消息.我不希望这样,因为我想自己记录(附加信息),我不希望日志中出现重复的错误消息.如何防止此默认日志记录?
  • 我访问异常对象的方式似乎不对.我从request属性中获取if javax.servlet.error.exception.这甚至不是抛出的异常,它是一个实例,org.springframework.web.util.NestedServletException我必须深入到这个嵌套异常中来获取真实异常.我很确定有一种更简单的方法,但我找不到它.

那么我该如何解决这些问题呢?或者我实现这个全局异常处理程序的方式是完全错误的,还有更好的选择吗?

java spring tomcat spring-mvc spring-boot

39
推荐指数
1
解决办法
5万
查看次数

Spring Boot - 自定义404页面,带有独立的tomcat

我在一个独立的tomcat实例中运行一个Spring启动应用程序,我试图覆盖错误页面.根据我的理解,Spring提供了一个过滤器ErrorPageFilter,它允许我像Spring一样正常设置错误页面EmbeddedServletContainerCustomizer 来完全处理这种情况.

所以我在一个类中有我的标准自动配置/ servlet初始化程序:

@Configuration
@ComponentScan
@EnableAutoConfiguration(exclude = [ GroovyTemplateAutoConfiguration, SecurityAutoConfiguration, ErrorMvcAutoConfiguration, JmxAutoConfiguration ] )
class Application extends SpringBootServletInitializer {

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        application.sources( Application )
    }
Run Code Online (Sandbox Code Playgroud)

(我使用相同的类进行自动配置和servlet初始化,这就是为什么我只是Application在configure方法中传递我的类)

查看SpringBootServletInitializer的源代码,看起来ErrorPageFilter只是通过在这里扩展该类来添加类.我已经关闭了ErrorMvcAutoConfiguration- 但是再一次,查看源代码,它看起来只是设置默认错误页面而不是实际设置任何东西ErrorPageFilter.

然后我有我的错误配置文件:

@Configuration
class ErrorConfiguration implements EmbeddedServletContainerCustomizer {

    @Override public void customize( ConfigurableEmbeddedServletContainer container ) {
        container.addErrorPages(new ErrorPage( HttpStatus.NOT_FOUND, "/errors/404" ))
    }
Run Code Online (Sandbox Code Playgroud)

但是,如果我只是访问一个无效的网址,而我DispatcherServlet找不到匹配,那么我只是得到tomcats /404.html - 而不是我的视图链接到" /errors/404"(我将此路径映射到百里香视图模板,工作正常 - 如果我导航到/ errors/404则显示ok) …

spring tomcat spring-mvc spring-boot

8
推荐指数
1
解决办法
2万
查看次数

Spring Boot 获取浏览器请求 URL

我有一个简单的休息控制器,可以捕获错误。我想获得浏览器发送到服务器的实际 URL,但 servlet 给了我一个不同的 URL。

如果我导航到127.0.0.1/abc404 错误被触发,它被路由到/error定义的处理程序。但是,输出给了我结果127.0.0.1/error而不是127.0.0.1/abc. 如何获取原始网址?

@RestController
public class IndexController implements ErrorController {

    @RequestMapping("/")
    public String index() {
        return "OK";
    }

    @RequestMapping("/error")
    public String error(HttpServletRequest request) {
        System.out.println("ERR: " + request.getRequestURL() + " : " + request.getRequestURI());
        return "ERR";
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }
}
Run Code Online (Sandbox Code Playgroud)

java spring spring-boot

2
推荐指数
1
解决办法
7528
查看次数

标签 统计

spring ×3

spring-boot ×3

java ×2

spring-mvc ×2

tomcat ×2