个人使用SpringMVC框架项目的心得

4月19日更新 : 已在Github中上传了精简的SpringMVC框架的MAVEN工程包。可以在进行简单配置后使用。

链接: springMVC

本文仅作SpringMVC框架使用过程中的一些个人总结。

项目结构

项目大致分为公共包(common-utils)、核心(core)、前端(web)三个工程。
大致目录:
Worksapce
|-common-utils
|-core
|-web

公共包

common-utils

全系统(包括其它模块)公用的部分:
common-utils
|-exception
|-utils
|-Generic
  |-GenericDao
  |-GenericService

  • 异常处理

    根据业务逻辑分成:系统异常SystemException、业务异常BusinessException两大类。

    1. 业务异常
      通常指业务处理中可能出现的异常情况,通常是违反业务正常进行规则出现的异常,而不是系统错误。
      应该给前台反馈适当的异常信息。而不是单纯的错误代码。且一般是业务逻辑判断后主动抛出的异常,而不是程序错误抛出的异常。

    2. 系统异常
      一般是程序错误,或者违规操作造成程序无法继续运行的状况。为了提高用户体验,通常捕捉到程序异常Exception后记录日志系统,
      然后将其包装成系统异常BusinessException抛给前台。这样反馈给用户的时异常的概述,而不是冗长的异常代码。
      同时也不影响查询日志获得更详细的错误信息。

  • 工具库

    可以从网络上获取:引入MAVEN依赖,或者导入java。并可以适当的进行继承与扩展。对于提高编程效率很有帮助。尽量用T、E等,扩大适用范围。

  • 公共接口

    1. 数据层 GenericDao, GenericDaoImpl
      所有项目的公共实现,如:增、删、改、查…。

    2。 服务层 GenericService, `GenericServiceImpl
    所有项目的业务实现。

核心

core

具体模块的核心工程:

core
|-commons
  |-utils
  |-comstatic
  |-config
|-Module_1
  |-Dao
  |-Domain
  |-Service
|-Module_2
  |-Dao
  |-Domain
  |-Service
。。。。

  • 公共库

    包括工具库、静态参数类、配置类

    1. 工具库
      可以从网络上获取:引入MAVEN依赖,或者导入java。并可以适当的进行继承与扩展。对于提高编程效率很有帮助。

    2. 静态参数类
      避免在代码中直接写入参数,而是将参数提取出来放进参数类中。

    3. 配置类config
      将一些允许在项目发布后进行设置的参数暴露出来,以.property或者.xml方式保存。

  • 数据层 Dao Extends GenericDao

    common-utilsGenericDao基础上添加个性化的方法。

    比如:

    清空整张表、从JSON文件导入数据、针对该表个性化数据查询、处理等。

    1. 接口 Dao
      针对某个表Entity实现对其数据基本的处理。

    2. 实现 DaoImpl
      针对某个表Entity实现对其数据基本的处理。

  • 业务逻辑层 Service Extends GenericService

    1. 接口 Service
      针对某一项业务的接口,可能涉及多个表Entity,因此在Service层可以调用多个Dao。

    2. 实现 ServiceImpl
      针对某一项业务的具体实现。
      为实现数据库的事务处理,在Service的实现上,应加上事务标签@Transactional

前端

web

前端工程:
web
|-controller
  |-Module_1
    |-ModuleController
|-webapp
  |-WEB-INF
  |-resource

  • 控制器 Controller

用来控制页面跳转 1. 返回页面与数据 `ModelAndView`。 使用 `RequestMapping` 标签。 2. 返回数据实体 使用 `ResponseBody`+`RequestMapping` 标签。 一般Mapping时候在路径上加上`/api/`比较好。这样有利于明显标志数据与页面的分离。 3. 在`Controller`上方也可以加入统一的`Mapping`路径. 这样可以用于在有用户认证拦截的框架中(如:`Shiro`)实现统一的免密连接。多用于`api`或者后台调试页面。

  • 资源 webapp

用于一般资源文件的放置。
一般`resource`可以放置`images`,`css`,`javascript`等文件。`WEB-INF`中放置`html`文件。

Controller - Service - Dao 的三层结构

阐述

  • Controller用于与用户直接交互,浏览器,HTTP请求等。

  • Service用于业务逻辑处理。注意接口输入输出的规范,这样有利于接口复用。

  • Dao用于直接与数据实体交互,实现数据的简单提取与处理。避免在Dao层出现跨表操作现象.

结构

结构示意图如下:
个人使用SpringMVC框架项目的心得_第1张图片

  • 一般Controller只与Service交互。 Service只与Dao交互。

异常处理

抛出与捕获

  • Controller-Service-Dao 三层架构

* `Dao` 中不涉及业务,一般错误都是系统异常,不做处理,直接抛出`Exception`, 在`Service`中做进一步处理。 “`java public void doSomething() throws Exception { try{ someFunction(); } catch(Exception e){ throw e; } } “` * `Service` 中涉及复杂业务,一般错误处理在这里处理完成后抛出。 “`java public void doSomething() throws Exception { logger.debug(); try{ someFunction(); if(BusinessError){ logger.info(); throw new BusinessException(); } } catch (Exception e){ logger.error(); throw new SystemException(); } } “` * `Controller`中捕获系统抛出的异常,并交予用户处理。 “`java public void doSomething() throws Exception { /*为保证系统正常运行,一般进行try-catch操作,不管正常与否均能返回结果*/ boolean statusFlag; String ErrMsg; try{ service.doSomething(); statusFlag = true; } catch (SystemException e) { statusFlag = false; ErrMsg = e.getMessage(); } catch (BusinessException e) { statusFlag = false; ErrMsg = e.getMessage(); } catch (Exception e) { statusFlag = false; //系统内未捕获的错误,应该记录日志 logger.error(); ErrMsg = e.toString(); } //最终判断是否成功执行 if(statusFlag) { return success; } else { return ErrMsg; } } “`

日志系统

埋点

埋点工作最好在项目进行中时就留意进行。初期可以先写个日志工具logger,并加上空方法,甚至简单的System.out.println()都行。

避免在日志点直接写入日志实现方法,这样对于后期统一的修改有好处。

不同级别的日志

如上文的异常处理为例,代码中可以看到日志埋点中可以使用debug,info,error三个级别的日志处理。这样就可以方便地区分日志类别。同时不同的日志级别区分,可以为以后实现控制日志记录级别,减少日志量打下基础。

可配置的统一调度

  • 为日志专门创建一个logger,其中加入个性化的设置,日志器log4jLogger,customLogger等等。通过统一的方法调用各个logger

  • 通过config在外部.property文件中实现不同logger的调度开关。

  • 通过config在外部实现日志级别的处理

设置日志级别 DEBUG(3) > INFO(2) > ERROR(1) > NONE(0)

则当设置logLevel = 3时,会记录所有日志; 当logLevel = 1时,就只会记录系统错误日志了。

伪代码如下:


    public void error(String className, String functionName, String logInfo) {
        try {
            if(onfig.getLOG_LEVEL() >= Static.LOG_LEVEL_ERROR) {
                if(config.isUSE_LOGGER()) {
                    logger.errorLog(className, functionName, logInfo);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • 最终效果如下

个人使用SpringMVC框架项目的心得_第2张图片

你可能感兴趣的:(Web后端开发)