实战分析:Spring boot &&Freemarker统一异常处理FreeMarker template error

参考了 设置一个FreemarkerExceptionHandler捕获freemarker页面上的异常

在Freemarker页面中如果使用${userName},

并且userName为空,那么Freemarker页面就会崩掉 需要设置默认值${userName!}来避免对象为空的错误。

同理 ${user.userName}也应该写成这样${(user.userName)!""}

现在有一个需求,就是万一我用了${userName},但是我又不想页面崩掉,怎么办呢?

文中使用的是配置springMVC-servlet.xml的方式

在Spring boot中呢,就properties或者yml文件中添加

spring.freemarker.settings.template_exception_handler=com.***.FreemarkerExceptionHandler

指明一下,这类异常哪个类来处理一下

然后类的内容就是

package com.***.exception;

import freemarker.core.Environment;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.io.IOException;
import java.io.Writer;

public class FreemarkerExceptionHandler implements TemplateExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(FreemarkerExceptionHandler.class);
    @Override
    public void handleTemplateException(TemplateException te, Environment env, Writer out) throws TemplateException {
	    	log.warn("[Freemarker Error: " + te.getMessage() + "]");
	        String missingVariable = "undefined";
	        try {
	            String[] tmp = te.getMessageWithoutStackTop().split("\n");
	            if (tmp.length > 1)
	                tmp = tmp[1].split(" ");
	            if (tmp.length > 1)
	                missingVariable = tmp[1];
	            out.write("");
	            log.error("[出错了,请联系网站管理员]", te);
	        } catch (IOException e) {
	            throw new TemplateException(
	                    "Failed to print error message. Cause: " + e, env);
	        }

    }
}

到这里,只能说抛出了异常,但是该报错还是报错,只能说在前台渲染的过程中,这个错误可以拦截到了

然后该处理的地步:

Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面

用来展示异常内容。

画重点--->>>>>该请求有一个全局的错误页面

所以我们要动手脚,就要从这个路径调用的类下手

Spring Boot 实现ErrorController接口处理404、500等错误页面

我们需要实现ErrorController接口,重写handleError方法。

所以你的自定义统一异常处理类的结构就是 

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping(value = "error")
public class CustomErrorController implements ErrorController {

	@Override
	public String getErrorPath() {
		return "error40x";//这是个我自己写的404的页面的fileName,在template根目录下
	}
	
	@RequestMapping
	public String error() {
		return getErrorPath();
	}

}

猜你喜欢

转载自blog.csdn.net/qq_16513911/article/details/82192467
今日推荐