在日常的开发过程中,我经常会写一些接口,有的可能是处理前端录入的数据,有的可能是别调用,为了代码的健壮,接口中我都会对数据的有效性进行校验的,包括去空格之类的操作,才会进入到我的逻辑代码,不管理是前端或者调用者有没有进行校验,我都会进行校验,返回不同的状态码回去。
或者封装一个Result对象代替JSONObject,效果是一样的,这样产生了一个问题,大量的判断语句,重复的代码过多,经过改良后:
1:首先建一个枚举类来管理所有的状态码和状态消息:
2.封装一个Result类:
如果需要扩展,可以在扩展类里继承该类,例如:
4.封装数据校验工具类:
5.controller统一捕获异常处理:
做完这些后,其实以后的新项目直接将这些代码拷一份过去就行了,以后的代码就可以这样写了:
假如现在有这样的一个注册需求,前端传入用户名和密码,昵称如果未填写就默认生成一个昵称,后端进行保存,以前我可能会这们做:
public JSONObject register(String username, String password, String nickname) {
JSONObject result = new JSONObject();
if (username == null || username == "") {
result.put("status", "1");
result.put("message", "用户名不能这空");
return result;
}
if (password == null || password == "") {
result.put("status", "2");
result.put("message", "密码不能这空");
return result;
}
if (nickname == null || nickname == "") {
nickname = "默认";
} else {
nickname = nickname.trim();
}
username = username.trim();
password = password.trim();
if (!username.matches("正则表达式")) {
result.put("status", "3");
result.put("message", "用户名必须xxx位");
return result;
}
if (!password.matches("正则表达式")) {
result.put("status", "4");
result.put("message", "密码名必须xxx位");
return result;
}
if (!nickname.matches("正则表达式")) {
result.put("status", "5");
result.put("message", "昵称必须xxx位");
return result;
}
User userDb = userDao.getByUsername(username);
if (userDb != null) {
result.put("status", "6");
result.put("message", "用户名已存在");
return result;
}
User user = new User();
user.setUsername(username);
user.setPassword(password);
user.setNickname(nickname);
try {
userDao.save(user);
} catch (Exception e) {
result.put("status", "7");
result.put("message", "发生了异常");
return result;
}
result.put("status", "0");
result.put("message", "保存成功");
return result;
}
或者封装一个Result对象代替JSONObject,效果是一样的,这样产生了一个问题,大量的判断语句,重复的代码过多,经过改良后:
1:首先建一个枚举类来管理所有的状态码和状态消息:
public enum ErrorCode {
SUCCESS(0, "成功"),
ERROR(1, "异常"),
PARAM_EMPTY(11, "参数不能为空"),
REG_NULL(12, "正则参数为NULL"),
ID_EMPTY(101, "ID不能为空"),
ID_ERROR(102, "ID不正确"),
ST_EMPTY(103, "状态不能为空"),
ST_ERROR(104, "状态不正确"),
USERNAME_EMPTY(201, "用户名不能为空"),
USERNAME_ERROR(202, "用户名必须xxx位"),
PASSWORD_EMPTY(203, "密码不能为空"),
PASSWORD_ERROR(204, "密码必须xxx位"),
NICKNAME_ERROR(205, "昵称必须xxx位"),
USER_EXISTENCE(206, "用户已存在"),
;
private int code;
private String msg;
private ErrorCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
public static String getMdg(int code) {
for (ErrorCode ec : ErrorCode.values()) {
if (Objects.equals(ec.code, code)) {
return ec.msg;
}
}
return null;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
2.封装一个Result类:
public class Result implements Serializable {
private static final long serialVersionUID = 1381695547116163922L;
private int code;// 状态码
private String msg;// 消息
public Result() {
super();
}
public Result(Result result) {
super();
this.code = result.getCode();
this.msg = result.getMsg();
}
public Result(int code) {
super();
this.code = code;
}
public Result(int code, String msg) {
super();
this.code = code;
this.msg = msg;
}
public Result(ErrorCode errorCode) {
super();
this.code = errorCode.getCode();
this.msg = errorCode.getMsg();
}
public boolean isSuccess() {
return Objects.equals(code, 0) ? true : false;
}
public boolean isError() {
return Objects.equals(code, 0) ? false : true;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "Result [code=" + code + ", msg=" + msg + "]";
}
}
如果需要扩展,可以在扩展类里继承该类,例如:
public class AjaxResult extends Result {
private static final long serialVersionUID = -5052761507270848804L;
private Object data;
public AjaxResult() {
super();
}
public AjaxResult(Result result) {
super(result);
}
public AjaxResult(int code) {
super(code);
}
public AjaxResult(int code, String msg) {
super(code, msg);
}
public AjaxResult(int code, String msg, Object data) {
super(code, msg);
this.data = data;
}
public AjaxResult(ErrorCode errorCode) {
super(errorCode);
}
public AjaxResult(ErrorCode errorCode, Object data) {
super(errorCode);
this.data = data;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "AlipayResult [super=" + super.toString() + "data=" + data + "]";
}
}
3.自定义一个异常类:
public class ResultException extends RuntimeException {
private static final long serialVersionUID = 3054458026076308895L;
private Result result;
public ResultException(Result result) {
this.result = result;
}
public ResultException(int code) {
this.result = new Result(code);
}
public ResultException(int code, String msg) {
this.result = new Result(code, msg);
}
public ResultException(ErrorCode code) {
this.result = new Result(code);
}
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
@Override
public String toString() {
return "ResultException [result=" + result + "]";
}
}
4.封装数据校验工具类:
public class CheckUtils {
public static final String NUMBER_PATTERN = "[+-]?\\d+";
public static final String INT_PATTERN = "[+-]?\\d{1,8}";
public static final String LONG_PATTERN = "[+-]?\\d{1,18}";
public static final String STATUS_PATTERN = "[01]";
public static boolean isNull(Object object) {
return object == null;
}
public static boolean isNotNull(Object object) {
return !isNull(object);
}
public static <T> T ifNull(T arg1, T arg2) {
return isNotNull(arg1) ? arg1 : arg2;
}
public static void checkNull(Object object, ErrorCode errorCode) throws ResultException {
if (isNotNull(object))
throw new ResultException(errorCode);
}
public static <T> T checkNotNull(T t, ErrorCode errorCode) throws ResultException {
if (isNull(t))
throw new ResultException(errorCode);
return t;
}
public static boolean isEmpty(Collection<?> collection) {
return isNull(collection) || collection.isEmpty();
}
public static boolean isNotEmpty(Collection<?> collection) {
return !isEmpty(collection);
}
public static <T> Collection<T> ifEmpty(Collection<T> arg1, Collection<T> arg2) {
return isNotEmpty(arg1) ? arg1 : arg2;
}
public static void checkEmpty(Collection<?> collection, ErrorCode errorCode) throws ResultException {
if (isNotEmpty(collection))
throw new ResultException(errorCode);
}
public static <T> Collection<T> checkNotEmpty(Collection<T> collection, ErrorCode errorCode) throws ResultException {
if (isEmpty(collection))
throw new ResultException(errorCode);
return collection;
}
public static boolean isEmpty(Object[] array) {
return isNull(array) || array.length == 0;
}
public static boolean isNotEmpty(Object[] array) {
return !isEmpty(array);
}
public static <T> T[] ifEmpty(T[] arg1, T[] arg2) {
return isNotEmpty(arg1) ? arg1 : arg2;
}
public static void checkEmpty(Object[] array, ErrorCode errorCode) throws ResultException {
if (isNotEmpty(array))
throw new ResultException(errorCode);
}
public static <T> T[] checkNotEmpty(T[] array, ErrorCode errorCode) throws ResultException {
if (isEmpty(array))
throw new ResultException(errorCode);
return array;
}
public static boolean isEmpty(Map<?, ?> map) {
return isNull(map) || map.isEmpty();
}
public static boolean isNotEmpty(Map<?, ?> map) {
return !isEmpty(map);
}
public static <K, V> Map<K, V> ifEmpty(Map<K, V> arg1, Map<K, V> arg2) {
return isNotEmpty(arg1) ? arg1 : arg2;
}
public static void checkEmpty(Map<?, ?> map, ErrorCode errorCode) throws ResultException {
if (isNotEmpty(map))
throw new ResultException(errorCode);
}
public static <T, V> Map<T, V> checkNotEmpty(Map<T, V> map, ErrorCode errorCode) throws ResultException {
if (isEmpty(map))
throw new ResultException(errorCode);
return map;
}
public static boolean isEmpty(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if (Character.isWhitespace(str.charAt(i)) == false) {
return false;
}
}
return true;
}
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
public static String ifEmpty(String arg1, String arg2) {
return isNotEmpty(arg1) ? arg1 : arg2;
}
public static void checkEmpty(String str, ErrorCode errorCode) throws ResultException {
if (isNotEmpty(str))
throw new ResultException(errorCode);
}
public static String checkNotEmpty(String str, ErrorCode errorCode) throws ResultException {
if (isEmpty(str))
throw new ResultException(errorCode);
return str.trim();
}
public static boolean isReg(String str, String reg) {
return isNotNull(reg) && isNotNull(str) && str.matches(reg);
}
public static boolean isNotReg(String str, String reg) {
return !isReg(str, reg);
}
public static String ifNotReg(String arg1, String reg, String arg2) {
return isReg(arg1, reg) ? arg1 : arg2;
}
public static String checkReg(String str, String reg, ErrorCode errorCode) throws ResultException {
if (isNull(reg))
throw new ResultException(ErrorCode.REG_NULL);
if (isNotReg(str, reg)) {
throw new ResultException(errorCode);
}
return str;
}
public static void checkNotReg(String str, String reg, ErrorCode errorCode) throws ResultException {
if (isNull(reg))
throw new ResultException(ErrorCode.REG_NULL);
if (isReg(str, reg)) {
throw new ResultException(errorCode);
}
}
public static boolean isEquals(Object arg1, Object arg2) {
return Objects.equals(arg1, arg2);
}
public static boolean isNotEquals(Object arg1, Object arg2) {
return !isEquals(arg1, arg2);
}
public static void checkEquals(Object arg1, Object arg2, ErrorCode errorCode) throws ResultException {
if (isNotEquals(arg1, arg2))
throw new ResultException(errorCode);
}
public static void checkNotEquals(Object arg1, Object arg2, ErrorCode errorCode) throws ResultException {
if (isEquals(arg1, arg2))
throw new ResultException(errorCode);
}
public static boolean isEqualsIgnoreCase(String arg1, String arg2) {
return arg1 == arg2 || (isNotNull(arg1) && arg1.equalsIgnoreCase(arg2));
}
public static boolean isNotEqualsIgnoreCase(String arg1, String arg2) {
return !isEqualsIgnoreCase(arg1, arg2);
}
public static void checkEqualsIgnoreCase(String arg1, String arg2, ErrorCode errorCode) throws ResultException {
if (isNotEqualsIgnoreCase(arg1, arg2))
throw new ResultException(errorCode);
}
public static void checkNotEqualsIgnoreCase(String arg1, String arg2, ErrorCode errorCode) throws ResultException {
if (isEqualsIgnoreCase(arg1, arg2))
throw new ResultException(errorCode);
}
public static boolean checkTrue(boolean arg, ErrorCode errorCode) throws ResultException {
if (!arg)
throw new ResultException(errorCode);
return arg;
}
public static boolean checkFalse(boolean arg, ErrorCode errorCode) throws ResultException {
if (arg)
throw new ResultException(errorCode);
return arg;
}
public static boolean isLong(String str) {
return isNotEmpty(str) && isReg(str.trim(), LONG_PATTERN);
}
public static boolean isNotLong(String str) {
return !isLong(str);
}
public static long checkLong(String str, ErrorCode errorCode) {
if (isNotLong(str)) {
throw new ResultException(errorCode);
}
return Long.parseLong(str);
}
public static boolean isInt(String str) {
return isNotEmpty(str) && isReg(str.trim(), INT_PATTERN);
}
public static boolean isNotInt(String str) {
return !isInt(str);
}
public static int checkInt(String str, ErrorCode errorCode) {
if (isNotInt(str)) {
throw new ResultException(errorCode);
}
return Integer.parseInt(str);
}
public static boolean isId(String id) {
return isLong(id);
}
public static boolean isNotId(String id) {
return !isId(id);
}
public static long checkId(String id) throws ResultException {
if (isNotId(id)) {
throw new ResultException(ErrorCode.ID_ERROR);
}
return Long.parseLong(id);
}
public static boolean isStatus(String status) {
return isReg(status, STATUS_PATTERN);
}
public static boolean isNotStatus(String status) {
return !isStatus(status);
}
public static boolean checkStatus(String status) throws ResultException {
if (isNotStatus(status)) {
throw new ResultException(ErrorCode.ST_ERROR);
}
return isEqualsIgnoreCase("0", status.trim()) ? false : true;
}
}
5.controller统一捕获异常处理:
@ControllerAdvice
public class ControllerExceptionHandler {
private static final Logger logger = Logger.getLogger(ControllerExceptionHandler.class);
@ExceptionHandler(value = ResultException.class)
@ResponseBody
public Result resultExceptionHandler(ResultException resultException) {
return resultException.getResult();
}
@ExceptionHandler(value = Exception.class)
public void exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) {
try {
logger.error("发生了异常", ex);
if (HttpUtils.isAjax(request)) {
HttpUtils.sendData(response, ErrorCode.ERROR);
} else {
response.sendRedirect(request.getContextPath() + "/500");
}
} catch (Exception e) {
logger.error("处理Exception发生了异常", e);
}
}
}
做完这些后,其实以后的新项目直接将这些代码拷一份过去就行了,以后的代码就可以这样写了:
public Result register(String username, String password, String nickname) {
username = CheckUtils.checkReg(CheckUtils.checkNotEmpty(username, ErrorCode.USERNAME_EMPTY),
"正则表达式", ErrorCode.USERNAME_ERROR);
password = CheckUtils.checkReg(CheckUtils.checkNotEmpty(password, ErrorCode.PASSWORD_EMPTY),
"正则表达式", ErrorCode.PASSWORD_ERROR);
nickname = CheckUtils.checkReg(CheckUtils.ifEmpty(nickname, "默认"),
"正则表达式", ErrorCode.NICKNAME_ERROR);
CheckUtils.checkNull(userDao.getByUsername(username), ErrorCode.USER_EXISTENCE);
User user = new User();
user.setUsername(username);
user.setPassword(password);
user.setNickname(nickname);
userDao.save(user);
return new Result(ErrorCode.SUCCESS);
}
这样就简洁了很多了,而且不同的错误能返回不同的状态码和消息,方法出错还能触发事务回滚,代码也比较键壮