Web应用开发大作业项目记录(2)接口规范的制定与通用类的设计
Reference
这次使用的很多项目搭建方法都参考了这篇文章:一份Spring Boot项目搭建模板,作者真的是太强了,感谢作者的无私奉献。
接口规范:统一返回对象
因为是半前后端分离的项目,页面中几乎所有的数据都是走接口的,所以需要有一个统一的返回格式以便前端进行调用。这里因为后面要做对这个对象的统一创建的工具类,所以没有使用泛型:
package site.wendev.qikebao.common;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author 江文
* @since 2020/10/28 8:52 下午
*/
@Data
@Accessors(chain = true)
public class Response {
/** 错误码,为0则成功 */
private Integer code;
/** 提示信息 */
private String message;
/** 返回数据 */
private Object data;
}
接口规范:统一异常定义
Web应用中少不了异常,对异常也进行统一的处理是很重要的。我们使用枚举定义一些可能发生的异常种类及其所对应的错误码,以便在发生异常的时候可以方便地返回具体的异常信息:
package site.wendev.qikebao.enums;
import lombok.Getter;
/**
* 错误码枚举类
*
* @author 江文
* @since 2020/10/29 8:06 下午
*/
@Getter
public enum ErrorEnum {
// 没有登录
AUTH_FAILURE(-2),
// 参数校验失败
CHECK_FAILURE(-1),
// 添加数据失败
ADD_ERROR(1),
// 更新数据失败
UPDATE_ERROR(2),
// 查找数据失败
GET_ERROR(3),
// 删除失败
DELETE_ERROR(4),
// 未知异常
UNKNOWN_EXCEPTION(99);
private final Integer code;
ErrorEnum(Integer code) {
this.code = code;
}
/**
* 根据错误码拿到对应的枚举对象
*
* @param code 错误码
* @return 错误码对应的枚举对象,找不到则返回null
*/
public static ErrorEnum getByCode(int code){
for (ErrorEnum resultEnum : ErrorEnum.values()) {
if(code == resultEnum.getCode()){
return resultEnum;
}
}
return null;
}
}
抽象VO
总是进行实体类和VO之间的转换实在是麻烦,于是借鉴了参考文章中的方法,写了一个抽象VO。至于这个类该怎么用,在后面编写业务逻辑代码的时候再展开讲:
package site.wendev.qikebao.vo;
import lombok.Data;
/**
* VO基类
*
* @author 江文
* @since 2020/10/29 7:51 下午
*/
@Data
public abstract class BaseVO<T> {
/**
* 根据VO构建实体对象
*
* @return 构建完成的实体对象
*/
public abstract T build();
}
分页
分页在这种只有CRUD的项目中是必不可少的,需要写一个通用的分页查询请求类和一个分页查询返回结果类。
分页查询请求类(所有的具体的分页查询都继承这个类,以便实现不同条件下的分页查询):
package site.wendev.qikebao.vo;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Min;
/**
* 进行分页查询所用的VO基类,实际分页查询的VO继承这个类
*
* @author 江文
* @since 2020/10/29 8:33 下午
*/
@Data
public class BasePageVO<T extends BasePageVO<?>> {
@Min(value = 1, message = "当前页码必须大于1")
private Integer page;
@Range(min = 1, max = 50, message = "每页数据条数必须在1-50条之间")
private Integer size;
public T calcCurrentPage() {
this.page = (this.page - 1) * size;
return (T) this;
}
}
分页查询返回结果类:
package site.wendev.qikebao.vo;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import java.util.List;
/**
* 分页返回对象
*
* @author 江文
* @since 2020/10/29 8:30 下午
*/
@Data
public class PageResponse<T> {
/** 本页的数据 */
private List<T> content;
/** 一共多少数据 */
private Integer total;
/** 一共多少页 */
private Integer totalPages;
/** 当前是第几页 */
private Integer page;
/** 每页多少数据 */
private Integer size;
public PageResponse<T> setPageAndSize(BasePageVO<?> vo) {
BeanUtils.copyProperties(vo, this);
return this;
}
public void setTotal(Integer total) {
this.total = total;
this.setTotalPages(this.total % this.size > 0 ? this.total / this.size + 1 : this.total / this.size);
}
}
统一返回对象的统一创建操作
如果在每个接口里都显式地创建一个Response对象,那样不仅繁琐还容易出错。所以,我们封装一个工具类来进行对统一返回对象的统一创建操作。因为一个操作只有成功和失败两种可能性,所以只需要有两个方法:success和error就可以了:
package site.wendev.qikebao.utils;
import site.wendev.qikebao.common.Response;
import site.wendev.qikebao.enums.ErrorEnum;
/**
* 统一返回对象的统一创建操作
*
* @author 江文
* @since 2020/10/29 8:20 下午
*/
public class ResponseUtil {
public static Response success(Object data) {
// 操作成功,返回的错误码是0并返回对应数据
return new Response().setCode(0).setMessage("操作成功").setData(data);
}
public static Response error(ErrorEnum err, String message) {
// 操作失败,返回对应的错误信息和空数据
return new Response().setCode(err.getCode()).setMessage(message).setData(null);
}
}
统一异常处理
首先我们自定义一个异常:
package site.wendev.qikebao.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 自定异常
*
* @author 江文
* @since 2020/10/29 8:04 下午
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class BusinessException extends RuntimeException {
/** 错误码 */
private final Integer code;
/** 发生异常的方法 */
private final String method;
public BusinessException(Integer code, String message, String method) {
super(message);
this.code = code;
this.method = method;
}
}
然后使用ControllerAdvice进行每种异常对应的配置即可。因为目前还没遇到太多异常,所以就先写一个缺省的异常处理(import太多了就不粘过来了,具体的可以去GitHub上看):
/**
* @author 江文
* @since 2020/10/29 8:44 下午
*/
@Slf4j
@ControllerAdvice
public class ControllerExceptionHandler {
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(Exception.class)
public Response exception(Exception e) {
e.printStackTrace();
return ResponseUtil.error(ErrorEnum.UNKNOWN_EXCEPTION, e.getMessage());
}
}
网友评论