1

我有问题。每次发生异常时,我的 spring 错误控制器都会绕过我的 sitemash-freemarker 装饰器,只显示错误转储。或者它包含装饰器但没有放入用户会话,因此装饰器中的个性化消失了。

如何使用 freemarker 在 Spring 中正确集成异常处理?

从 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>

错误控制器.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();
}
}

错误.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>
4

1 回答 1

3

像这样的东西:

<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配置。您可以为特定异常类指定自定义视图或回退到默认视图。您也可以覆盖其中一个标准解析器以使用其他数据填充模型,例如,将堆栈跟踪转储到字符串中并将其显示在扰流器块下的异常页面上。

于 2011-06-21T17:51:06.657 回答