序言
现公司的很多东西,都是一团糟,所以很多东西,都需要重新去规范
对响应结果的统一包装
import com.xingren.common.exceptions.ApiCallException;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Optional;
/**
* API调用结果类
*/
@Data
@ApiModel(value="API调用结果")
public class JsonResult<T> {
/**
* 是否成功
*/
@ApiModelProperty(name = "是否成功")
private boolean success;
/**
* 响应结果
*/
@ApiModelProperty(name = "响应结果")
private Optional<T> data = Optional.empty();
/**
* 错误码
*/
@ApiModelProperty(name = "错误码")
private Optional<Integer> errCode = Optional.empty();
/**
* 错误消息
*/
@ApiModelProperty(name = "错误消息")
private Optional<String> errMessage = Optional.empty();
/**
* 检查传入的调用结果,如果成功并且响应结果不为空,则返回响应结果,否则抛出{@code ApiCallException}。
*
* @param result
* @param <T>
* @return
*/
public static <T> T checkAndExtract(@NotNull JsonResult<T> result) {
if (result.isSuccess() && result.getData().isPresent()) {
return result.getData().get();
}
throw new ApiCallException(result);
}
/**
* 检查传入的调用结果,如果成功,则返回响应结果,否则抛出{@code ApiCallException}。
*
* @param result
* @param <T>
* @return
*/
public static <T> Optional<T> checkAndExtractOptional(@NotNull JsonResult<T> result) {
if (result.isSuccess()) {
return result.getData();
}
throw new ApiCallException(result);
}
/**
* 生成服务调用成功响应
*
* @param <T>
* @return
*/
public static <T> JsonResult<T> ok() {
JsonResult<T> result = new JsonResult<>();
result.setSuccess(true);
return result;
}
/**
* 生成服务调用成功响应
*
* @param data
* @param <T>
* @return
*/
public static <T> JsonResult<T> ok(@NotNull T data) {
JsonResult<T> result = new JsonResult<>();
result.setSuccess(true);
result.setData(Optional.of(data));
return result;
}
/**
* 生成服务调用成功响应--Optional
*
* @param data
* @param <T>
* @return
*/
public static <T> JsonResult<T> ok(@NotNull Optional<T> data) {
JsonResult<T> result = new JsonResult<>();
result.setSuccess(true);
result.setData(data);
return result;
}
/**
* 生成服务调用错误响应
*
* @param <T>
* @return
*/
public static <T> JsonResult<T> error() {
return error(Errors.SERVER_ERROR);
}
/**
* 生成服务调用错误响应
*
* @param errorMessage
* @param <T>
* @return
*/
public static <T> JsonResult<T> error(String errorMessage) {
return error(Errors.SERVER_ERROR.getCode(), errorMessage);
}
/**
* 生成服务调用错误响应
*
* @param error
* @param <T>
* @return
*/
public static <T> JsonResult<T> error(Error error) {
return error(error.getCode(), error.getMessage());
}
/**
* 生成服务调用错误响应
*
* @param errorCode
* @param errorMessage
* @param <T>
* @return
*/
public static <T> JsonResult<T> error(Integer errorCode, String errorMessage) {
JsonResult<T> result = new JsonResult<>();
result.setErrCode(Optional.of(errorCode));
result.setErrMessage(Optional.ofNullable(errorMessage));
return result;
}
}
分页情况的包装类
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collector;
import java.util.stream.Stream;
/**
* 分页查询结果,同时提供Lambda风格的接口。
* <pre>
* Pagination<String> dest = src.stream().map(String::valueOf).collect(Pagination.toPagination(src.getPage(), src.getSize(), src.getTotal()));
* </pre>
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Pagination<T> {
/**
* 查询记录集
*/
private List<T> content = Lists.newArrayList();
/**
* 当前页索引
*/
private Integer page;
/**
* 当前页容量
*/
private Integer size;
/**
* 总记录数
*
* @deprecated 如非必要,否则尽量不要赋值,也即业务无需显示精确页数
*/
@Deprecated
private Optional<Integer> total = Optional.empty();
/**
* 是否可以查询下一页
* <p>
* 实现逻辑:hasNext = content.size() == size,从而避免因查询数据量大导致count慢查询
* 含义:只有当值为true时,才表示当前页"有可能"不是最后一页(缺点:如果最后一页数据的size刚好等于页的size时,会多一次无用的分页查询)
*/
private Optional<Boolean> hasNext = Optional.empty();
/**
* 隐藏构造函数,使用工厂方法。
*/
private Pagination(List<T> content, Integer page, Integer size) {
this.content = content;
this.page = page;
this.size = size;
}
/**
* 构造单页结果(content, 0, content.size())
*/
public static <E> Pagination<E> of(List<E> content) {
return new Pagination<E>(content, 0, content.size());
}
/**
* 构造分页结果(content, page, content.size())
*/
public static <E> Pagination<E> of(List<E> content, Integer page) {
return new Pagination<E>(content, page, content.size());
}
public Stream<T> stream() {
return content.stream();
}
public Stream<T> parallelStream() {
return content.parallelStream();
}
/**
* 实现 Stream -> Pagination 的{@code Collector}。
*/
public static <T> Collector<T, ?, Pagination<T>> toPagination(Integer page, Integer size, Optional<Integer> total) {
return Collector.of(() -> {
Pagination<T> pagination = new Pagination<>();
pagination.setPage(page);
pagination.setSize(size);
pagination.setTotal(total);
return pagination;
}, (pagination, elm) -> pagination.getContent().add(elm),
(left, right) -> {
left.getContent().addAll(right.getContent());
return left;
});
}
/**
* 实现 Stream -> Pagination 的{@code Collector}。
*/
public static <T> Collector<T, ?, Pagination<T>> toPagination(Integer page, Integer size,
Optional<Integer> total, Optional<Boolean> hasNext) {
return Collector.of(() -> {
Pagination<T> pagination = new Pagination<>();
pagination.setPage(page);
pagination.setSize(size);
pagination.setTotal(total);
pagination.setHasNext(hasNext);
return pagination;
}, (pagination, elm) -> pagination.getContent().add(elm),
(left, right) -> {
left.getContent().addAll(right.getContent());
return left;
});
}
}
请求包装类
这一块,如果Controller
使用的是springMVC那一套的东西,可以使用Spring Data JPA
包中的Pageable
类。
用法:
public JsonResult<Pagination<StockCheckVO>> queryCheckList(@Valid StockCheckQuery query,
@PageableDefault(sort = {"created"},
direction = Sort.Direction.DESC)
Pageable pageable) {
}
但是如果Controller
层,公司重写了一套,比如我司,就不好使用Pageable
了。这时就得自定义:
import lombok.Data;
@Data
public class Pageable {
/**
* 页号
*/
private int pageNum;
/**
* 一页条数
*/
private int pageSize;
/**
* 总页数
*/
private int pages;
/**
* 总记录数
*/
private int total;
}
个人总结,仅供参考,山鬼谣me;