最近开发的java web项目(struts+freemarker),页面各种报404,500,抛各种异常,而且这些错误直接显示在页面上,对用户很不友好。最后通过以下三个步骤优化项目的容错
一、修改web.xml,重定向404页面
web.xml的功能很强大,如果页面返回错误码,如404,500,可以将页面重定向新的页面,如下配置,将所有404页面重定向到自定义的404.html
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
二、修改struts.xml,捕获代码中未catch的异常,并重定向至专门处理错误的action,返回用户友好的界面
上面提到的web.xml,也可以配置捕获异常,但如果捕获异常后,想做进一步处理,例如通知项目开发人员页面报错,就不太方便了。为满足异常处理的个性化需求,可以配置struts.xml
配置struts.xml,找到package节点,
定义捕获所有未捕获的异常,并交给errorHandle这个action处理
<global-results>
<result name="allException" type="chain">errorHandle</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="allException" exception="java.lang.Exception"></exception-mapping>
</global-exception-mappings>
新增errorHandle action配置
<action name="errorHandle" class="com.test.action.ErrorHandleAction">
<result name="success" type="freemarker">/WEB-INF/error.html</result>
</action>
当然,还需要你自己写com.test.action.ErrorHandleAction代码逻辑,这个acion中,要特别注意,要自己捕获异常,不然,如果这个acion也抛出异常,逻辑就陷入死循环了
最后,我的struts.xml大致是这样的
<struts>
<package name="default" namespace="/" extends="json-default">
<result-types>
<result-type name="chart"
class="org.apache.struts2.dispatcher.ChartResult" />
</result-types>
<global-results>
<result name="allException" type="chain">errorHandle</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="allException" exception="java.lang.Exception"></exception-mapping>
</global-exception-mappings>
<action name="errorHandle" class="com.test.action.ErrorHandleAction">
<result name="success" type="freemarker">/WEB-INF/error.html</result>
</action>
//以下省略其他的
</struts>
三、配置freemarker.properties,可以在填充freemarker时,自动将null值填为empty值
freemarker是一种优秀的页面模版框架,但它有一个很恶心的地方,如果填入模版中的值中,有null值,页面会报错,并且会将出错信息直接抛给用户
有两个优化配置:
1、首先在classpath(一般就是src目录)下新增freemarker.properties,文件名是固定的,freemarker会自动读取这个配置。在这个文件如下配置
2、classic_compatible=true
效果:将null值填为empty值,但这个配置有一个缺陷,对于子嵌套字段值是无效的,例如dog.food值如果是null,那它能自动将这个值改为空值,但如果dog.food.sunday中,dog值就是null值,这个配置就无能为力了
3、template_exception_handler=ignore
效果:不会捕获异常。如果freemarker生成模版时出错,不会将错误信息抛到前端页面,用户看到的,是一个没有填充任何值的页面模版。
最后我们只配置了classic_compatible=true,这个配置已经能解决我们很大部分的问题。没有使用template_exception_handler这个配置,一是因为这样配置后,本文第二节的方法,就不能捕获该类异常了,二来觉得给用户没有填充值的页面模版,其实也不太好