Контроллер ошибок Spring Framework с Freemarker - PullRequest
1 голос
/ 25 февраля 2011

У меня проблема. Каждый раз, когда у меня происходит исключение, мой контроллер ошибок Spring либо обходит мой декоратор sitemash-freemarker и просто показывает дамп ошибок. Или он включает в себя декоратор, но не вводит пользовательский сеанс, поэтому персонализация в декораторе исчезла.

Как правильно интегрировать обработку исключений весной с помощью freemarker?

Извлечение из web.xml:

//standard sitemash decorator and freemarker setup
<error-page>
    <error-code>404</error-code>
    <location>/pageNotFound.html?code=404</location>
</error-page>
<error-page>
    <error-code>500</error-code>
    <location>/servletErrorView.html?code=500</location>
</error-page>
<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/error.html</location>
</error-page>

ErrorController.java:

@Controller
public class ErrorController extends AnnotationMethodHandlerAdapter {

private static final Logger log = Logger.getLogger(ErrorController.class);

@Autowired
private ComponentHelper helper;
@Autowired
private MailNotificationService mailNotificationService;

@RequestMapping(value = {"/servletErrorView.html", "/error.html"}, method = RequestMethod.GET)
protected ModelMap showError(HttpServletRequest req) {

    String code = null, message = null, type = null, uri = null;
    Object codeObj, messageObj, typeObj;
    Throwable throwable;

    ModelMap mm = helper.getMM();
    //todo handle org.springframework.web.bind.MissingServletRequestParameterException

    codeObj = req.getAttribute("javax.servlet.error.status_code");
    messageObj = req.getAttribute("javax.servlet.error.message");
    typeObj = req.getAttribute("javax.servlet.error.exception_type");
    throwable = (Throwable) req.getAttribute("javax.servlet.error.exception");
    uri = (String) req.getAttribute("javax.servlet.error.request_uri");

    // Convert the attributes to string values
    if (codeObj != null) code = codeObj.toString();
    if (messageObj != null) message = messageObj.toString();
    if (typeObj != null) type = typeObj.toString();

    // The error reason is either the status code or exception type
    String reason = (code != null ? code : type);
    if (uri == null) {
        uri = req.getRequestURI();
    }
    log.error("ErrorController\n reason:"+reason+"\n message:"+message+"\n uri:"+uri+"\n ",throwable);

    mm.addAttribute("message", "<H4>" + reason + "</H4>" +
            "<H4>" + message + "</H4>" +
            "<P>" + ((throwable != null) ? getStackTrace(throwable) : "") + "</P>" +
            "<I>Error accessing " + uri + "</I>");

    String subject = "Error - "+reason;
    String freemarkerTemplet = "/WEB-INF/freemarker/errorMail.ftl";

    mailNotificationService.sendEmail(subject, "email@domain.com", mm, freemarkerTemplet);

    return mm;
}

public static String getStackTrace(Throwable aThrowable) {
    //add the class name and any message passed to constructor
    final StringBuilder result = new StringBuilder("Trace: ");
    result.append(aThrowable.toString());
    final String NEW_LINE = "<br>";
    result.append(NEW_LINE);

    //add each element of the stack trace
    for (StackTraceElement element : aThrowable.getStackTrace()) {
        result.append(element);
        result.append(NEW_LINE);
    }
    return result.toString();
}
}

error.ftl

<html>
<#import "/spring.ftl" as spring/>
<#import "common.ftl" as common/>
<head>

<title>ITeezy: Error page</title>
    <meta name="description" content="Error"/>
</head>

 <body id="error">

 <div id="main">
  <h1>Error</h1>
<p><a href="<@spring.url "/index.html"/>"> <- Go back to Homepage</a></p><br>
 <div id="logo"> <a href="<@spring.url "/index.html"/>"> <img src="/images/mainlogo.png" alt="[Logo]" width="260" height="140"/> </a> </div>

 <#if message?exists>
     <div class="message">Error: ${message}</div>
 </#if>
  <br>
We're sorry you received an error. Please do us a favor and let us know!
Email: <img src="/images/support-email.png" width="118" height="13"/>
with the error message and a description of what you were doing. Thanks!

<#if exception?exists>
    ${exception}
    <#list exception.stackTrace as st>
        ${st}
    </#list>
<#else>
    <#if javax?exists && javax.servlet?exists && javax.servlet.error?exists && javax.servlet.error.exception?exists>
        Servlet Exception:<p>
        ${javax.servlet.error.exception} <br>
        ${javax.servlet.error.exception.message?default("")} <br>
        <#list javax.servlet.error.exception.stackTrace as st>
            ${st}<br>
        </#list>
    </#if>
</#if>

</div>
</body>
</html>

1 Ответ

3 голосов
/ 21 июня 2011

Примерно так:

<bean id="errorMapping" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="defaultErrorView" value="error/default"/>
    <property name="defaultStatusCode" value="500"/>
    <property name="exceptionMappings">
        <props>
            <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error/uploadsize</prop>
        </props>
    </property>
</bean>

... и вы получите объект с именем exception в вашей модели.Конфигурация web.xml не требуется.Вы можете указать либо пользовательские представления для определенных классов исключений, либо вернуться к представлению по умолчанию.Вы также можете переопределить один из стандартных распознавателей, чтобы заполнить модель дополнительными данными, например, чтобы сбросить трассировку стека в строку и отобразить ее на странице исключений под спойлером.

...