zoukankan      html  css  js  c++  java
  • SpringMVC的项目架构思想

    SpringMVC的项目架构思想

    一、DO和Model的区别

    DO是对数据库表的映射。Model是处理业务逻辑的模型(领域模型)。例如:用户信息表和用户密码表分别是两个DO,但是对于实体用户来说,密码表的字段也属于用户,所以需要在Service层使用Model来处理业务逻辑,Model包含了两张表的字段的并集。在Mapper层使用DO,在Service层使用Model。

    public class UserDO {
        private Integer id;
        private String name;
        private Boolean gender;
        private Integer age;
        private String telphone;
        private String registerType;
        private String thirdPartyId;
        //getter、setter
    public class UserPasswordDO {
        private Integer id;
        private String encrptPassword;
        private Integer userId;
        //getter、setter

    二、VO和Model的区别

    VO(View Object视图对象),用于前端展示。Model中包含了用户的密码数据,不应该通过Controller层返回给前端,这是不安全的操作。在Controller层通过VO返回部分可以展示到前端的数据即可。

    public class UserModel {
        private Integer id;
        private String name;
        private Boolean gender;
        private Integer age;
        private String telphone;
        private String registerMode;
        private String thirdPartyId;
        private String encrptPassword;
        //getter、setter
    public class UserVO {
        private Integer id;
        private String name;
        private Boolean gender;
        private Integer age;
        private String telphone;
        //getter、setter

    三、层次结构

    1. dao层:定义XXXMapper接口、对应的XXXMapper.xml在resource目录下的mapper文件夹里,使用数据模型DO(Data Object)

    2. service层:定义XXXService接口、实现类XXXServiceImpl、领域模型Model

      @Service
      public class UserServiceImpl implements UserService {
      ​
          @Autowired
          private UserDOMapper userDOMapper;
          @Autowired
          private UserPasswordDOMapper userPasswordDOMapper;
      ​
          @Override
          public UserModel getUserById(Integer id) {
              UserDO userDO = userDOMapper.selectByPrimaryKey(id);
              if (userDO == null) {
                  return null;
              }
              UserPasswordDO userPasswordDO = userPasswordDOMapper.selectByUid(userDO.getId());
              return covertFromDataObject(userDO, userPasswordDO);
          }
      ​
          private UserModel covertFromDataObject(UserDO userDO, UserPasswordDO userPasswordDO) {
              if (userDO == null) {
                  return null;
              }
              UserModel userModel = new UserModel();
              BeanUtils.copyProperties(userDO, userModel);
              if (userPasswordDO != null) {
                  userModel.setEncrptPassword(userPasswordDO.getEncrptPassword());
              }
              return userModel;
          }
      }
    3. controller层:定义XXXController类、视图模型VO(View Object)

      @RestController("user")
      @RequestMapping("/user")
      public class UserController {
          @Autowired
          private UserService userService;
      ​
          @RequestMapping("/get")
          public UserVO getUser(@RequestParam(name = "id") Integer id){
              UserModel userModel = userService.getUserById(id);
              //将核心的领域模型对象转化为可供UI使用的VO
              return convertFromModel(userModel);
          }
      ​
          private UserVO convertFromModel(UserModel userModel){
              if(userModel == null){
                  return null;
              }
              UserVO userVO = new UserVO();
              BeanUtils.copyProperties(userModel, userVO);
              return userVO;
          }
      }

    四、归一化Controller层的响应信息

    1. 定义一个公共的返回值类型

      public class CommonReturnType {
          //处理结果 success/fail
          //fail 返回通用的错误码格式
          //success 返回数据
          private String status;
          private Object data;
      ​
          public static CommonReturnType create(Object result, String status) {
              CommonReturnType returnType = new CommonReturnType();
              returnType.setStatus(status);
              returnType.setData(result);
              return returnType;
          }
      ​
          public static CommonReturnType create(Object result) {
              return CommonReturnType.create(result, "success");
          }
      ​
          public String getStatus() {
              return status;
          }
      ​
          public void setStatus(String status) {
              this.status = status;
          }
      ​
          public Object getData() {
              return data;
          }
      ​
          public void setData(Object data) {
              this.data = data;
          }
      }
    2. 在Controller层返回CommonResultType

      @RequestMapping("/get")
      public CommonReturnType getUser(@RequestParam(name = "id") Integer id){
          UserModel userModel = userService.getUserById(id);
          //将核心的领域模型对象转化为可供UI使用的VO
          UserVO userVO =  convertFromModel(userModel);
          //返回通用对象
          return CommonReturnType.create(userVO);
      }
    3. 前端得到的返回正确的结果

      {
          "status":"success",
          "data":{
              "id":1,
              "name":"张三",
              "gender":false,
              "age":12,
              "telphone":"123456"
          }
      }
    4. 异常结果的处理(见下一Part)

    五、 包装器业务异常类的实现

    1. 定义一个公共错误接口/error

      public interface CommonError {
          public int getErrCode();
          public String getErrMsg();
          public CommonError setErrMsg(String errMsg);
      }
    2. 定义一个枚举错误类/error

      public enum EmBusinessError implements CommonError {
          //通用错误类型 00001
          PARAMETER_VALIDATION_ERROR(00001,"参数不合法"),
          //用户信息相关 1000X
          USER_NOT_EXIST(10001,"用户不存在")
          //
          ;
          private EmBusinessError(int errCode, String errMsg){
              this.errCode = errCode;
              this.errMsg = errMsg;
          }
          private int errCode;
          private String errMsg;
          @Override
          public int getErrCode() {
              return this.errCode;
          }
      ​
          @Override
          public String getErrMsg() {
              return this.errMsg;
          }
      ​
          @Override
          public CommonError setErrMsg(String errMsg) {
              this.errMsg = errMsg;
              return this;
          }
      }
    3. 定义异常包装类/exception

      //包装器业务异常类的实现
      public class BusinessException extends Exception implements CommonError {
          private CommonError commonError;
      ​
          //直接接收EmBusinessError的传参用于构造业务异常
          public BusinessException(CommonError commonError){
              super();
              this.commonError = commonError;
          }
      ​
          //接收自定义errMsg的方式构造业务异常
          public BusinessException(CommonError commonError, String errMsg){
              super();
              this.commonError = commonError;
              this.commonError.setErrMsg(errMsg);
          }
          @Override
          public int getErrCode() {
              return this.commonError.getErrCode();
          }
      ​
          @Override
          public String getErrMsg() {
              return this.commonError.getErrMsg();
          }
      ​
          @Override
          public CommonError setErrMsg(String errMsg) {
              this.commonError.setErrMsg(errMsg);
              return this;
          }
      }
    4. 在Controller层抛出异常

      @RequestMapping("/get")
      public CommonReturnType getUser(@RequestParam(name = "id") Integer id) throws BusinessException {
          UserModel userModel = userService.getUserById(id);
          if(userModel == null){
              throw new BusinessException(EmBusinessError.USER_NOT_EXIST);
          }
          //将核心的领域模型对象转化为可供UI使用的VO
          UserVO userVO =  convertFromModel(userModel);
          //返回通用对象
          return CommonReturnType.create(userVO);
      }

    六、异常的处理

    1. 定义exceptionHandler解决未被Controller层吸收的exception

      @ExceptionHandler(Exception.class)
      @ResponseStatus(HttpStatus.OK)
      public Object handlerException(HttpServletRequest request, Exception ex){
          BusinessException businessException = (BusinessException) ex;
          CommonReturnType commonReturnType = new CommonReturnType();
          commonReturnType.setStatus("fail");
          Map<String, Object> responseData = new HashMap<>();
          responseData.put("errCode",businessException.getErrCode());
          responseData.put("errMsg",businessException.getErrMsg());
          commonReturnType.setData(responseData);
          return commonReturnType;
      }
    2. 前端得到的JSON数据

      {"status":"fail",
       "data":{
           "errCode":10001,
           "errMsg":"用户不存在"
       }
      }
    3. 优化异常处理,定义BaseController,其余Controller继承基类。

      @RestController
      public class BaseController {
          @ExceptionHandler(Exception.class)
          @ResponseStatus(HttpStatus.OK)
          public Object handlerException(HttpServletRequest request, Exception ex){
              Map<String, Object> responseData = new HashMap<>();
              if(ex instanceof BusinessException){
                  BusinessException businessException = (BusinessException) ex;
                  CommonReturnType commonReturnType = new CommonReturnType();
                  commonReturnType.setStatus("fail");
                  responseData.put("errCode",businessException.getErrCode());
                  responseData.put("errMsg",businessException.getErrMsg());
              }
              else{
                  responseData.put("errCode", EmBusinessError.UNKNOWN_ERROR.getErrCode());
                  responseData.put("errMsg",EmBusinessError.UNKNOWN_ERROR.getErrMsg());
              }
              return CommonReturnType.create(responseData,"fail");
          }
      }
  • 相关阅读:
    如何在数据库某一列数据的前面或者后面增加字符
    jmeter分布式测试教程和远程的代理机无法连接网络的问题解决方法
    jmeter和jdk的安装教程
    第十周总结
    第九周总结
    第八周总结
    企业应用架构模式-阅读笔记01
    需求征集系统进度08
    需求征集系统进度07
    第七周总结
  • 原文地址:https://www.cnblogs.com/xdcat/p/13228446.html
Copyright © 2011-2022 走看看