项目经验_之_常用规范类
前言
Github:https://github.com/HealerJean
1、异常相关
1.1、异常类
1.1.1、业务异常类:BusinessException
package com.healerjean.proj.exception;
import com.healerjean.proj.enums.ResponseEnum;
public class BusinessException extends RuntimeException {
private int code;
public BusinessException(int code) {
this.code = code;
}
public BusinessException(String message) {
super(message);
this.code = ResponseEnum.逻辑错误.code;
}
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
public BusinessException(ResponseEnum responseEnum) {
super(responseEnum.msg);
this.code = responseEnum.code ;
}
public BusinessException(ResponseEnum responseEnum,String message) {
super(message);
this.code = responseEnum.code ;
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
this.code = ResponseEnum.逻辑错误.code;
}
public BusinessException(int code ,Throwable e) {
super(e);
this.code = code;
}
public BusinessException(ResponseEnum responseEnum, Throwable t) {
super(responseEnum.msg, t);
this.code = responseEnum.code;
}
public void setCode(int code) {
this.code = code;
}
public int getCode() {
return code;
}
}
1.1.2、参数异常类:ParameterErrorException
package com.healerjean.proj.exception;
import com.healerjean.proj.enums.ResponseEnum;
public class ParameterErrorException extends com.healerjean.proj.exception.BusinessException {
public ParameterErrorException() {
super(ResponseEnum.参数错误);
}
public ParameterErrorException(ResponseEnum responseEnum) {
super(ResponseEnum.参数错误, responseEnum.msg);
}
public ParameterErrorException(String msg) {
super(ResponseEnum.参数错误, msg);
}
}
1.1.3、接口异常类:HaoDanKuApiException
package com.healerjean.proj.exception;
import com.healerjean.proj.enums.ResponseEnum;
public class HaoDanKuApiException extends BusinessException {
public HaoDanKuApiException(String msg) {
super(ResponseEnum.好单库接口返回报错, msg);
}
public HaoDanKuApiException(Throwable e) {
super(ResponseEnum.好单库接口请求异常, e);
}
}
1.1.4、NotFoundException、ExistException
public class ExistException extends BusinessException {
public ExistException(ResponseEnum responseEnum) {
super(responseEnum);
}
}
public class NotFoundException extends BusinessException {
public NotFoundException(ResponseEnum responseEnum) {
super(responseEnum);
}
}
1.2、异常全局处理
1.2.1、ControllerHandleConfig
package com.healerjean.proj.config;
import com.healerjean.proj.dto.ResponseBean;
import com.healerjean.proj.enums.ResponseEnum;
import com.healerjean.proj.exception.BusinessException;
import com.healerjean.proj.exception.ParameterErrorException;
import com.healerjean.proj.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.servlet.http.HttpServletResponse;
import javax.validation.UnexpectedTypeException;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@ControllerAdvice
public class ControllerHandleConfig {
/**
* 不支持的请求方始
*/
@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
@ResponseStatus(value = HttpStatus.METHOD_NOT_ALLOWED)
public ResponseBean methodNotSupportExceptionHandler(HttpRequestMethodNotSupportedException e) {
log.error("不支持的请求方式", e);
return ResponseBean.buildFailure(ResponseEnum.不支持的请求方式.code, e.getMessage());
}
/**
* 参数类型错误
* 1、(BindException : 比如 Integer 传入String )
* Field error in object 'demoDTO' on field 'age': rejected value [fasdf]; codes [typeMismatch.demoDTO.age,typeMismatch.age,typeMismatch.java.lang.Integer,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [demoDTO.age,age]; arguments []; default message [age]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' for property 'age'; nested exception is java.lang.NumberFormatException: For input string: "fasdf"]
*/
@ExceptionHandler(value = {BindException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ResponseBean bindExceptionHandler(BindException e) {
log.error("====参数类型错误===", e);
return ResponseBean.buildFailure(ResponseEnum.参数类型错误.code, e.getMessage());
}
/**
* 参数格式问题
*/
@ExceptionHandler(value = {MethodArgumentTypeMismatchException.class, HttpMessageConversionException.class, UnexpectedTypeException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ResponseBean httpMessageConversionExceptionHandler(Exception e) {
log.error("====参数格式异常===", e);
return ResponseBean.buildFailure(ResponseEnum.参数格式异常.code, e.getMessage());
}
/**
* 参数错误
*/
@ExceptionHandler(value = ParameterErrorException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ResponseBean parameterErrorExceptionHandler(ParameterErrorException e) {
log.error("参数异常------------参数错误:code:{},message:{}", e.getCode(), e.getMessage());
return ResponseBean.buildFailure(e.getCode(), e.getMessage());
}
/**
* 业务异常,给前台返回异常数据
*/
@ExceptionHandler(value = BusinessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ResponseBean businessExceptionHandler(BusinessException e) {
log.error("业务异常------------异常信息:code:{},message{}" ,e.getCode(), e.getMessage());
return ResponseBean.buildFailure(e.getCode(),e.getMessage());
}
/**
* 所有异常报错
*/
@ExceptionHandler
@ResponseBody
public HttpEntity<ResponseBean> allExceptionHandler(HttpServletResponse response, Exception e) {
log.error("====系统错误===", e);
response.setStatus(ResponseEnum.系统错误.code);
return returnMessage(ResponseBean.buildFailure(ResponseEnum.系统错误));
}
private HttpEntity<ResponseBean> returnMessage(ResponseBean responseBean) {
HttpHeaders header = new HttpHeaders();
header.add("Content-Type", "application/json");
header.add("Charset", "UTF-8");
return new HttpEntity<>(responseBean, header);
}
/**
* 参数非法
* 1、(BindException : 比如 Integer 传入abc )
*/
// @ExceptionHandler(value = {MethodArgumentTypeMismatchException.class, HttpRequestMethodNotSupportedException.class, HttpMessageConversionException.class, BindException.class, UnexpectedTypeException.class})
// @ResponseBody
// public HttpEntity<ResponseBean> httpMessageConversionExceptionHandler(HttpServletResponse response, Exception e) {
// log.error("====参数格式异常===", e);
// // 等同于 @ResponseStatus(HttpStatus.BAD_REQUEST)
// // 但是setStatus 不能比随便设置,最好一般情况下不要和HttpStatus 有重复的,这样有可能会造成没有输出Response body
// response.setStatus(ResponseEnum.参数格式异常.code);
// return returnMessage(ResponseBean.buildFailure(ResponseEnum.参数格式异常));
// }
// @ExceptionHandler(value ={HttpMessageConversionException.class, BindException.class} )
// @ResponseBody
// public HttpEntity<ResponseBean> httpMessageConversionExceptionHandler(Exception e) {
// log.error("====参数格式异常===", e);
// return new ResponseEntity<>(ResponseBean.buildFailure(ResponseEnum.参数格式异常),HttpStatus.BAD_REQUEST);
// }
}
2、枚举
2.1、响应枚举
package com.healerjean.proj.enums;
import java.util.Arrays;
import java.util.List;
public enum ResponseEnum {
正常(200, "访问正常"),
参数错误(301, "参数错误"),
参数格式异常(302, "参数格式异常"),
不支持的请求方式(303, "不支持的请求方式"),
参数类型错误(304, "参数类型错误"),
逻辑错误(305, "逻辑错误"),
未登陆(306, "未登陆"),
登陆成功(307, "登陆成功"),
重复操作(308, "重复操作"),
非法操作(309, "非法操作"),
请求无法被服务器理解(400, "请求无法被服务器理解"),
未授权(401, "未授权"),
访问禁止(403, "访问禁止"),
页面丢失(404, "页面丢失"),
系统错误(500, "系统错误"),
未知错误(999, "未知错误"),
用户已经存在(1000, "用户已经存在"),
用户不存在(1001, "用户不存在"),
微信接口请求异常(2001,"微信接口请求异常"),
淘宝接口请求异常(2002,"淘宝接口请求异常"),
淘宝接口数据异常(2003,"淘宝接口数据异常"),
好单库口请求异常(2004,"好单库口请求异常"),
好单库接口数据异常(2005,"好单库接口数据异常"),
;
public int code;
public String msg;
ResponseEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public static boolean checkExist( Integer code){
for (ResponseEnum value : ResponseEnum.values()){
if (value.code == code){
return true;
}
}
return false;
}
public static ResponseEnum toEnum(int code){
for (ResponseEnum value : ResponseEnum.values()){
if (value.code == code){
return value;
}
}
return ResponseEnum.未知错误;
}
public static String getMsg(int code){
for (ResponseEnum value : ResponseEnum.values()){
if (value.code == code){
return value.msg;
}
}
return ResponseEnum.未知错误.msg;
}
public ResponseEnum value(String enumName){
return valueOf( enumName ) ;
}
public static List<ResponseEnum> getList(){
return Arrays.asList(values());
}
}
2.2、业务枚举
package com.healerjean.proj.enums;
public interface BusinessEnum {
/**
* 验证码枚举
*/
enum VerifyCodeTypeEnum {
图片验证码("captcha", "图片验证码"),
注册邮箱验证码("RegistEmail", "注册邮箱验证码"),
找回密码邮箱验证码("RetrievePasswordEmail", "找回密码邮箱验证码"),
;
VerifyCodeTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String code;
public String desc;
public static VerifyCodeTypeEnum toEnum(String code) {
for (VerifyCodeTypeEnum item : VerifyCodeTypeEnum.values()) {
if (item.code.equals(code)) {
return item;
}
}
return null;
}
}
/**
* 模板类型
*/
enum TemplateTypeEnum {
邮件("Email", "邮件"),
;
public String code;
public String desc;
TemplateTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
}
/**
* 模板名字
*/
enum TempleNameEnum {
邮箱验证("VerifyEmail", "邮箱验证"),
找回密码邮箱验证("PasswordVerifyEmail", "找回密码邮箱验证"),
手机号验证("VerifyPhone", "手机号验证"),
;
TempleNameEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String code;
public String desc;
public static TempleNameEnum toEnum(String code) {
for (TempleNameEnum item : TempleNameEnum.values()) {
if (item.code.equals(code)) {
return item;
}
}
return null;
}
}
/**
* 菜单类型
*/
enum MenuTypeEnum {
后端菜单("0", "后端菜单"),
前端菜单("1", "前端菜单");
MenuTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String code;
public String desc;
public static MenuTypeEnum toEnum(String code) {
for (MenuTypeEnum value : MenuTypeEnum.values()) {
if (value.code .equals( code)) {
return value;
}
}
return null;
}
}
/**
* 用户类型
*/
enum UserTypeEnum {
管理人员("manager", "管理人员"),
网站用户("webuser", "网站用户");
UserTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String code;
public String desc;
public static MenuTypeEnum toEnum(String code) {
for (MenuTypeEnum value : MenuTypeEnum.values()) {
if (value.code .equals( code)) {
return value;
}
}
return null;
}
}
}
2.3、状态枚举
package com.healerjean.proj.enums;
/**
* @Description
* @Author HealerJean
* @Date 2019-06-16 01:58.
*/
public enum StatusEnum {
生效("10", "生效"),
废弃("99", "废弃");
StatusEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String code;
public String desc;
}
2.4、下拉菜单枚举
package com.duodian.admore.data;
import java.io.Serializable;
/**
* 下拉列表用
*/
public class LabelValueBean implements Serializable{
private static final long serialVersionUID = -1211726511402154326L;
private String label;
private String value;
private Boolean checked = false;
public LabelValueBean() {
}
public LabelValueBean(String label, String value) {
this.label = label;
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public Boolean getChecked() {
return checked;
}
public void setChecked(Boolean checked) {
this.checked = checked;
}
}
3、响应Bean
package com.healerjean.proj.dto;
import com.healerjean.proj.enums.ResponseEnum;
import com.healerjean.proj.utils.JsonUtils;
/**
* 返回对象
*/
public class ResponseBean {
private ResponseBean() {
}
public static ResponseBean buildSuccess() {
ResponseBean responseBean = new ResponseBean();
responseBean.setSuccess(true);
responseBean.setCode(ResponseEnum.正常.code);
responseBean.setDate(System.currentTimeMillis() + "");
return responseBean;
}
public static ResponseBean buildSuccess(String msg) {
ResponseBean responseBean = new ResponseBean();
responseBean.setSuccess(true);
responseBean.setCode(ResponseEnum.正常.code);
responseBean.setResult(msg);
responseBean.setDate(System.currentTimeMillis() + "");
return responseBean;
}
public static ResponseBean buildSuccess(Object result) {
ResponseBean responseBean = new ResponseBean();
responseBean.setSuccess(true);
responseBean.setCode(ResponseEnum.正常.code);
responseBean.setResult(result);
responseBean.setDate(System.currentTimeMillis() + "");
return responseBean;
}
public static ResponseBean buildSuccess(String msg, Object result) {
ResponseBean responseBean = new ResponseBean();
responseBean.setSuccess(true);
responseBean.setCode(ResponseEnum.正常.code);
responseBean.setMsg(msg);
responseBean.setResult(result);
responseBean.setDate(System.currentTimeMillis() + "");
return responseBean;
}
public static String buildSensitivitySuccess(String msg, Object result) {
return JsonUtils.toJsonStringWithSensitivity(buildSuccess(msg, result));
}
public static String buildSensitivitySuccess(Object result) {
return JsonUtils.toJsonStringWithSensitivity(buildSuccess(result));
}
public static ResponseBean buildFailure() {
ResponseBean responseBean = new ResponseBean();
responseBean.setSuccess(false);
responseBean.setCode(ResponseEnum.系统错误.code);
responseBean.setDate(System.currentTimeMillis() + "");
return responseBean;
}
public static ResponseBean buildFailure(String msg) {
ResponseBean responseBean = new ResponseBean();
responseBean.setSuccess(false);
responseBean.setCode(ResponseEnum.系统错误.code);
responseBean.setMsg(msg);
responseBean.setDate(System.currentTimeMillis() + "");
return responseBean;
}
public static ResponseBean buildFailure(ResponseEnum responseEnum) {
ResponseBean responseBean = new ResponseBean();
responseBean.setSuccess(false);
responseBean.setCode(responseEnum.code);
responseBean.setMsg(responseEnum.msg);
responseBean.setDate(System.currentTimeMillis() + "");
return responseBean;
}
public static ResponseBean buildFailure(int code, String msg) {
ResponseBean responseBean = new ResponseBean();
responseBean.setSuccess(false);
responseBean.setCode(code);
responseBean.setMsg(msg);
responseBean.setDate(System.currentTimeMillis() + "");
return responseBean;
}
public static ResponseBean buildFailure(ResponseEnum responseEnum, String msg) {
ResponseBean responseBean = new ResponseBean();
responseBean.setSuccess(false);
responseBean.setCode(responseEnum.code);
responseBean.setMsg(msg);
responseBean.setDate(System.currentTimeMillis() + "");
return responseBean;
}
private boolean success;
private Object result = "{}";
private String msg = "";
private int code;
private String date;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
4、POJO(BO、DTO、VO、AO)、Query
POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO。
VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
DO(Data Object):此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
BO(Business Object):业务对象,由 Service 层输出的封装业务逻辑的对象。
AO(Application Object):应用对象,在 Web 层与 Service 层之间抽象的复用对象模型,极为贴 近展示层,复用度不高。
Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类 来传输。
数据对象:xxxDO,xxx即为数据表名。
数据传输对象:xxxDTO,xxx为业务领域相关的名称。
展示对象:xxxVO,xxx一般为网页名称。
4.1、VO( View Object)
显示层对象,通常是Web向模板渲染引擎层传输的对象
public List<UserVO> getUserVOs(UserQuery userQuery){
//DTO转VO
BeanUils.dtoToUserVO(userservice.getUserDTOs());
}
4.2、DTO (Data Transfer Object)
数据传输对象,Service或Manager向外传输的对象。
List<UserDTO> getUserDTOs(UserQuery userQuery){
//BO转DTO,也可能DO转DTO
BeanUils.boToUserDTO(userservice.getUserBOs());
}
4.3、BO( Business Object):
业务对象。 由Service层输出的封装业务逻辑的对象。
Service内部的私有代码
List<UserBO> getUserBOs(UserQuery userQuery){
//DO转VO
BeanUils.doToUserBO(userdao.getUserDOs());
}
4.4、DO ( Data Object)
与数据库表结构一一对应,通过DAO层向上传输数据源对象。**
List<UserDO> getUsers(UserQuery userQuery);