简体   繁体   English

在404和500 Http Error Spring MVC上发送电子邮件或记录错误

[英]Send Email or Logged Error on 404 and 500 Http Error Spring MVC

I have been thinking, how is it possible for me to send an email when a particular HTTP Error code happens in my Spring MVC Web app. 我一直在想,当我的Spring MVC Web应用程序中发生特定的HTTP错误代码时,我怎么可能发送电子邮件。 Please take a look at my web.xml configuration. 请看一下我的web.xml配置。 It works fine and redirects me to the particular error page. 它工作正常,并将我重定向到特定的错误页面。

<web-app ...>
  <servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
  </servlet-mapping>

  <error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/pages/404.jsp</location>
  </error-page>

  <error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/pages/500.jsp</location>
  </error-page>

</web-app>

But what I want is, I want to send email or logged the occurence of this particular error. 但我想要的是,我想发送电子邮件或记录此特定错误的发生。 I was told in my earlier question that this type of error does not get handled by my controller hierarchy. 在我之前的问题中,我被告知我的控制器层次结构不会处理这种类型的错误。

Any thoughts please? 有什么想法吗?

For some reason, I did something like this. 出于某种原因,我做了类似的事情。 It works as for my case. 它适用于我的情况。 Can you comment on what I did? 你能评论我做了什么吗? In my web.xml, I edited my location tag to forward it to my controller. 在我的web.xml中,我编辑了我的位置标记以将其转发到我的控制器。

 <!-- Error Pages -->
    <error-page>
        <error-code>404</error-code>
        <location>/errorEncountered.htm</location>
    </error-page>

    <error-page>
        <error-code>500</error-code>
        <location>/errorEncountered.htm</location>
    </error-page>

In My controller, this is where I send an email. 在我的控制器中,这是我发送电子邮件的地方。

@Controller
@RequestMapping("/errorEncountered.htm")
public class ErrorHandlerController {
    private MailService mailService;

    @RequestMapping(method = RequestMethod.GET)
    public String handleGet(HttpServletRequest request) {
            // The Servlet spec guarantees this attribute will be available
            Throwable exception = (Throwable) request
                    .getAttribute("javax.servlet.error.exception");

            .
            .
            .
            mailService.sendMail();
        }
    }
}

Any criticism? 任何批评?

For 4nn (client side) errors, your best bet is to configure the access logs at servletcontainer level. 对于4nn (客户端)错误,最好的办法是在servletcontainer级别配置访问日志。 In case of Tomcat, you can do this in flavor of a Valve . 在Tomcat的情况下,你可以在Valve的味道中做到这一点。 It's more or less a kind of Filter which is to be plugged at servletcontainer level rather than at webapp level. 它或多或少是一种Filter ,它可以在servletcontainer级而不是webapp级别插入。 You can find more detail in the Apache Tomcat Configuration Reference . 您可以在Apache Tomcat配置参考中找到更多详细信息。 You'll need to turn on and configure the Access Log Valve . 您需要打开并配置Access Log Valve This will only write to a logfile, but you can just extend org.apache.catalina.valves.AccessLogValve and add some code which sends a mail in case of a 404 . 这只会写入日志文件,但您可以只扩展org.apache.catalina.valves.AccessLogValve并添加一些代码,以便在404情况下发送邮件。 To get it to run, just put that class in Tomcat's classpath and specify it as className in Valve configuration. 要使它运行,只需将该类放在Tomcat的类路径中,并在Valve配置中将其指定为className

For 5nn (server side) errors, you can create and put a Filter on an url-pattern of /* which does basically the following in doFilter() method. 对于5nn (服务器端)错误,您可以在/*url-pattern上创建并放置一个Filter ,它在doFilter()方法中基本上执行以下操作。

try {
    chain.doFilter(request, response);
}
catch (ServletException | IOException e) {
    mail(e);
    throw e;
}

Sending email on Http Error Code might be too late in the process to find why the error happened. 在Http错误代码上发送电子邮件可能为时已晚,无法找到错误发生的原因。 A better thing to do for us was sending emails on exceptions. 为我们做的更好的事情是发送关于异常的电子邮件。 We might not want to do that for every exception, as that would be overwhelming. 我们可能不希望为每个例外都这样做,因为这将是压倒性的。

To do this we extend SimpleMappingExceptionResolver. 为此,我们扩展SimpleMappingExceptionResolver。 This Resolver is then required to be initialized with the context. 然后需要使用上下文初始化此解析器。

MyExceptionResolver extends SimpleMappingExceptionResolver
{
    @Autowire
    MailService mailService;

    protected ModelAndView getModelAndView(String viewName, Exception ex, HttpServletRequest request)
    {
       //Depending on exception resolve to view name, either 404 or server crash report

       //Also send emails for specific exception types.
    } 
}

 Spring wiring:
 <bean class="x.y.z.MyExceptionResolver"/>

Also, we can do exception handling with aspects. 此外,我们可以使用方面进行异常处理。 You can look up the aspects documentation for this. 您可以查看方面文档。

When using the web.xml , Spring will not be first in line for a request (also depending on your <url-pattern> s). 使用web.xml ,Spring不会首先web.xml请求(也取决于您的<url-pattern> )。

What you can do is write a custom servlet that extends HTTPServlet . 你可以做的是编写一个扩展HTTPServlet的自定义servlet。

In that servlet you can write the code for sending the email in the doGet() method that you over-ride from HttpServlet . 在该servlet中,您可以编写用于通过HttpServlet覆盖的doGet()方法发送电子邮件的代码。

Edit your web.xml <url-pattern> to go to that servlet when the error occurs. 编辑web.xml <url-pattern>以在发生错误时转到该servlet。

If its a error code 404, you know already that the problem relates to a page not found. 如果它是错误代码404,您已经知道问题与找不到的页面有关。

Cool. 凉。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM