一、DO和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
三、層次結構
-
dao層:定義XXXMapper介面、對應的XXXMapper.xml在resource目錄下的mapper資料夾裡,使用資料模型DO(Data Object)
-
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; } }
-
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層的響應資訊
-
定義一個公共的返回值型別
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; } }
-
在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); }
-
前端得到的返回正確的結果
{ "status":"success", "data":{ "id":1, "name":"張三", "gender":false, "age":12, "telphone":"123456" } }
-
異常結果的處理(見下一Part)
五、 包裝器業務異常類的實現
-
定義一個公共錯誤介面/error
public interface CommonError { public int getErrCode(); public String getErrMsg(); public CommonError setErrMsg(String errMsg); }
-
定義一個列舉錯誤類/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; } }
-
定義異常包裝類/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; } }
-
在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); }
六、異常的處理
-
定義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; }
-
前端得到的JSON資料
{"status":"fail", "data":{ "errCode":10001, "errMsg":"使用者不存在" } }
-
優化異常處理,定義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"); } }