Guns框架学习记录-5-全局异常拦截器+代码生成器

9.全局异常拦截器

全局异常拦截器可以拦截程序中出现的已知异常(主动声明的异常)和未知异常。关于异常拦截,建立一个全局异常拦截器,对程序中所有异常进行分类拦截,并友好的返回异常信息,有利于提高程序的健壮性。

构建全局异常拦截器:Throwable异常的顶级父类
1. 添加@ControllerAdvice注解,拦截所有的含有@RequestMapping注解的方法。
2. @ExceptionHandler(XxxException.class) 声明拦截的异常类型。
3. @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 声明遇到此异常时响应的状态码。
例:拦截业务异常
@ExceptionHandler(BussinessException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ErrorTip notFount(BussinessException e) {
    LogManager.me().executeLog(LogTaskFactory.exceptionLog(ShiroKit.getUser().getId(), e));
    getRequest().setAttribute("tip", e.getMessage());
    log.error("业务异常:", e);
    //这里的ErrorTip类为 code + message 形式的自定义响应体结构。
    return new ErrorTip(e.getCode(), e.getMessage());
}
当拦截未知异常的时候,可以将@ExceptionHandler(Throwable.class)中的异常类型设置为Throwable。

10.代码生成器

业务场景:开发新业务的时候,减少重复代码的编写,利用代码生成器构建业务框架模板。

Guns框架中的代码生成器是如何实现的?

原理:模板 + 变量 = 代码
设计方面分三块:config + engine + template
config:配置方面,定义全局配置,针对不同模板类型进行相关配置。
    ContextConfig:全局基础配置
    ControllerConfig:Controller模板配置
    ServiceConfig:Service模板配置
    DaoConfig:DAO模板配置
    PageConfig:页面模板配置
engine:模板引擎,初始化config的相关配置,结合template进行代码生成。
    AbstractTemplateEngine:抽象模板引擎父类
    GunsTemplateEngine:Guns模板引擎
    SimpleTemplateEngine:模板引擎具体实现类 -- 通用
template:采用beetl模板引擎进行模板页面的构造。
    XxxController.java.btl
标记一点:模板设计模式,在GunsTemplateEngine中定义逻辑骨架,将实现步骤推迟到子类SimpleTemplateEngine中去完成。

骨架实现:这里只说明GunsTemplateEngine模板引擎中的重要方法。

protected GroupTemplate groupTemplate; //引入Beetl的组模板生成对象

//config的配置加入模板引擎 binding表明将config绑定模板页面中的变量,类比model.addAttribute()。
public void configTemplate(Template template){
    template.binding("controller", super.getControllerConfig());
    template.binding("context", super.getContextConfig());
    template.binding("dao", super.getDaoConfig());
    template.binding("service", super.getServiceConfig());
}

//重点:生成文件方法 template是模板页面路径,filePath是生成文件路径 -- 自定义
public void generateFile(String template,String filePath){
    Template pageTemplate = groupTemplate.getTemplate(template);
    configTemplate(pageTemplate);
    //路径分隔符配置 基于不同平台系统
    if(PlatformUtil.isWindows()){
        filePath = filePath.replaceAll("/+|\\\\+","\\\\");
    }else{
        filePath = filePath.replaceAll("/+|\\\\+","/");
    }
    //生成文件目录
    File file = new File(filePath);
    File parentFile = file.getParentFile();
    if(!parentFile.exists()){
        parentFile.mkdirs();
    }
    try {
        //渲染出生成文件
        pageTemplate.renderTo(new FileOutputStream(file));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
} 

//上述提到的模板设计模式,在此处得以应用,实现交给子类SimpleTemplateEngine去完成。
protected abstract void generatePageEditHtml();
protected abstract void generatePageAddHtml();
protected abstract void generatePageInfoJs();
protected abstract void generatePageJs();
protected abstract void generatePageHtml();
protected abstract void generateController();
protected abstract void generateDao();
protected abstract void generateService();

具体实现:SimpleTemplateEngine具体模板引擎实现类。

public class SimpleTemplateEngine extends GunsTemplateEngine {

    @Override
    protected void generatePageEditHtml() {
        String path = ToolUtil.format(super.getContextConfig().getProjectPath() + getPageConfig().getPageEditPathTemplate(),
                super.getContextConfig().getBizEnName(),super.getContextConfig().getBizEnName());
        //核心代码:template为模板页面路径,path为自定义文件生成路径。
        generateFile("gunsTemplate/page_edit.html.btl", path);
        System.out.println("生成编辑页面成功!");
    }
}

这里需要说明path的处理方式:

1. ToolUtil.format 格式化文本
    public static String format(String template, Object... values) {
        return StrKit.format(template, values);
    }
    调用了StrKit.format的静态方法,template为预设路径,values为需要替换预设路径中占位符的字符串集合。
    例:StrKit.format("aaa {} ccc","bbb") 格式化后为:"aaa bbb ccc" 
    进入super.getContextConfig().getProjectPath() + getPageConfig().getPageEditPathTemplate()模板预设路径中:
    pageEditPathTemplate = "\\src\\main\\webapp\\WEB-INF\\view\\" + contextConfig.getModuleName() + "\\{}\\{}_edit.html";
    可以看到模板预设路径中含有{}占位符,因此,方法的第二个参数就是自定义的填充占位符的字符集。
    经过填充占位符之后,拼接成自定义的文件生成路径作为generateFile的path。
2.  ContextConfig 设置自定义的填充占位符字符集,即对全局配置ContextConfig成员变量进行赋值。
    这部分可以自定义,字符集中主要包括:模块名 + 业务名 + ...

开启模板引擎,进行代码生成:

GunsTemplateEngine gunsTemplateEngine = new SimpleTemplateEngine();
//导入全局配置信息
gunsTemplateEngine.setContextConfig(contextConfig);
//代码生成器启动
gunsTemplateEngine.start();

start()方法:开启生成器进行代码生成。

//生成器开始方法
public void start() {
    //配置之间的相互依赖
    super.initConfig();

    //生成模板 -- 判断各项配置开关是否开启,开启后进行生成 -- 实现交给子类去完成
    if(super.contextConfig.getControllerSwitch()){
        generateController();
    }
    if(super.contextConfig.getIndexPageSwitch()){
        generatePageHtml();
    }
    if(super.contextConfig.getAddPageSwitch()){
        generatePageAddHtml();
    }
    if(super.contextConfig.getEditPageSwitch()){
        generatePageEditHtml();
    }
    if(super.contextConfig.getJsSwitch()){
        generatePageJs();
    }
    if(super.contextConfig.getInfoJsSwitch()){
        generatePageInfoJs();
    }
    if(super.contextConfig.getDaoSwitch()){
        generateDao();
    }
    if(super.contextConfig.getServiceSwitch()){
        generateService();
    }

}

猜你喜欢

转载自blog.csdn.net/Nerver_77/article/details/81564174