top.zenyoung.controller.BaseController Maven / Gradle / Ivy
package top.zenyoung.controller;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoSink;
import top.zenyoung.common.model.*;
import top.zenyoung.common.paging.PagingQuery;
import top.zenyoung.common.paging.PagingResult;
import top.zenyoung.controller.listener.*;
import top.zenyoung.controller.model.ExceptHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* 控制器-基类
*
* @author yangyong
* @version 1.0
* 2020/2/7 12:28 下午
**/
@Slf4j
public abstract class BaseController {
/**
* 获取异常处理器集合
*
* @return 异常处理器集合
*/
@Nonnull
protected List getExceptHandlers() {
return Lists.newLinkedList();
}
private boolean handlerNotExcept(
@Nonnull final RespResult> respResult,
@Nullable final Throwable e,
@Nonnull final ExceptHandlerListener listener
) {
//获取异常处理器集合
final List exceptHandlers = getExceptHandlers();
if (exceptHandlers.size() > 0) {
//添加异常处理集合
listener.getExceptHandlers(exceptHandlers);
}
if (e != null && exceptHandlers.size() > 0) {
final Map, ExceptHandler> handlerMap = exceptHandlers.stream()
.collect(Collectors.toMap(ExceptHandler::getEClass, handler -> handler, (n, o) -> n));
if (handlerMap.size() > 0) {
return handlerNotExceptCause(respResult, e, handlerMap);
}
}
return true;
}
private boolean handlerNotExceptCause(
@Nonnull final RespResult> respResult,
@Nonnull final Throwable e,
@Nonnull final Map, ExceptHandler> handlerMap
) {
final ExceptHandler handler = handlerMap.getOrDefault(e.getClass(), null);
if (handler != null) {
respResult.setCode(handler.getCode());
respResult.setMsg(e.getMessage());
return false;
}
final Throwable cause = e.getCause();
if (cause != null) {
return handlerNotExceptCause(respResult, cause, handlerMap);
}
return true;
}
/**
* 业务处理
*
* @param sink Mono处理器
* @param reqData 请求数据
* @param resp 响应数据
* @param listener 前置业务处理器
* @param process 业务处理器
* @param 请求数据类型
* @param 前置处理器类型
* @param 响应数据类型
*/
private & ExceptHandlerListener, Resp extends RespResult>> void handler(
@Nullable final MonoSink sink,
@Nullable final ReqData reqData,
@Nonnull final Resp resp,
@Nonnull final P listener,
@Nonnull final Consumer process
) {
try {
//前置业务处理
listener.preHandler(reqData);
//业务处理
process.accept(resp);
} catch (Throwable e) {
log.warn("handler-exp:", e);
if (handlerNotExcept(resp, e, listener)) {
resp.buildRespFail(e.getMessage());
}
} finally {
if (sink != null) {
sink.success(resp);
}
}
}
/**
* 查询数据
*
* @param listener 查询处理器
* @param - 查询数据类型
* @param
结果数据类型
* @return 查询结果
*/
protected - Mono
> buildQuery(
@Nonnull final QueryListener- listener
) {
return Mono.create(sink -> handler(sink, null, RespDataResult.
ofSuccess(null), listener,
resp -> {
//查询数据
final List- items = listener.query();
//结果处理
resp.setData(DataResult.
builder()
//数据总数
.total(items == null ? 0L : (long) items.size())
//数据集合转换
.rows(items == null || items.size() == 0 ? Lists.newLinkedList() :
items.stream()
.filter(Objects::nonNull)
.map(listener)
.filter(Objects::nonNull)
.collect(Collectors.toList())
)
.build()
);
})
);
}
/**
* 查询数据
*
* @param queryHandler 查询处理器
* @param convertHandler 查询结果转换处理器
* @param - 查询数据类型
* @param
结果数据类型
* @return 查询结果
*/
protected - Mono
> buildQuery(
@Nonnull final Supplier> queryHandler,
@Nonnull final Function- convertHandler
) {
return buildQuery(new QueryListener
- () {
@Override
public List
- query() {
return queryHandler.get();
}
@Override
public Ret apply(final Item data) {
return convertHandler.apply(data);
}
});
}
/**
* 分页查询数据
*
* @param reqQuery 分页查询条件
* @param listener 查询处理器
* @param
请求查询条件类型
* @param 转换后查询条件类型
* @param - 查询数据类型
* @param
结果数据类型
* @return 查询结果
*/
protected Mono> buildQuery(
@Nonnull final PagingQuery reqQuery,
@Nonnull final PagingQueryListener listener
) {
return Mono.create(sink -> handler(sink, reqQuery.getQuery(), RespDataResult.ofSuccess(null), listener,
resp -> {
//查询数据处理
final PagingResult- queryResult = listener.query(new PagingQuery
() {
@Override
public Integer getIndex() {
return reqQuery.getIndex();
}
@Override
public Integer getRows() {
return reqQuery.getRows();
}
@Override
public Qry getQuery() {
return listener.convert(reqQuery.getQuery());
}
});
if (queryResult == null || CollectionUtils.isEmpty(queryResult.getRows())) {
resp.setData(DataResult.builder()
.total(0L)
.rows(Lists.newLinkedList())
.build()
);
return;
}
//查询结果处理
final Long totals = queryResult.getTotal();
final List- items = queryResult.getRows();
resp.setData(DataResult.
builder()
//总数据
.total(totals == null ? 0L : totals)
//数据处理
.rows(items == null || items.size() == 0 ? Lists.newLinkedList() :
items.stream()
.filter(Objects::nonNull)
.map(listener)
.filter(Objects::nonNull)
.collect(Collectors.toList())
)
.build()
);
}
));
}
/**
* 分页查询数据
*
* @param reqQuery 分页查询条件
* @param queryConvertHandler 查询条件转换处理
* @param pagingQueryHandler 分页查询处理
* @param resultConvertHandler 查询结果转换处理
* @param 请求查询条件类型
* @param 转换后查询条件类型
* @param - 查询数据类型
* @param
结果数据类型
* @return 查询结果
*/
protected Mono> buildQuery(
@Nonnull final PagingQuery reqQuery,
@Nonnull final Function queryConvertHandler,
@Nonnull final Function, PagingResult- > pagingQueryHandler,
@Nonnull final Function
- resultConvertHandler
) {
return buildQuery(reqQuery, new PagingQueryListener
() {
@Override
public Qry convert(@Nullable ReqQry reqQry) {
return queryConvertHandler.apply(reqQry);
}
@Override
public PagingResult- query(@Nonnull final PagingQuery
query) {
return pagingQueryHandler.apply(query);
}
@Override
public Ret apply(final Item data) {
return resultConvertHandler.apply(data);
}
});
}
/**
* 业务处理-无入参验证
*
* @param resp 响应对象
* @param listener 业务处理器
* @param 返回数据类型
* @param 响应数据类型
* @return 响应数据
*/
private > Mono action(@Nonnull final Resp resp, @Nonnull final ProccessListener listener) {
return Mono.create(sink -> handler(sink, null, resp, listener,
respRet -> {
final R data = listener.apply(null);
if (data != null) {
respRet.setData(data);
}
}
));
}
/**
* 业务处理-无入参验证
*
* @param listener 处理器
* @param 返回数据类型
* @return 处理结果
*/
protected Mono> action(@Nonnull final ProccessListener listener) {
return action(new RespResult().buildRespSuccess(null), listener);
}
/**
* 业务异常消息处理
*
* @param throwable 异常
* @return 异常消息
*/
private String actionExceptionHandler(@Nullable final Throwable throwable) {
if (throwable != null) {
if (throwable instanceof BindingResult) {
final String error = ((BindingResult) throwable).getFieldErrors().stream()
.map(fe -> {
String err = fe.getDefaultMessage();
if (Strings.isNullOrEmpty(err)) {
err = fe.toString();
}
return err;
})
.filter(err -> !Strings.isNullOrEmpty(err))
.collect(Collectors.joining());
if (!Strings.isNullOrEmpty(error)) {
return error;
}
}
return throwable.getMessage();
}
return null;
}
/**
* 业务处理-有入参验证
*
* @param req 入参数据
* @param respSuccessHandler 响应成功数据
* @param respFailHandler 响应失败处理
* @param listener 业务处理器
* @param 入参数据类型
* @param 出参数据类型
* @param 响应数据
* @return 处理结果
*/
private > Mono action(
@Nonnull final Mono req,
@Nonnull final Supplier respSuccessHandler,
@Nonnull final Function respFailHandler,
@Nonnull final ProccessListener listener
) {
return Mono.create(sink -> req.doOnError(Throwable.class, e -> sink.success(respFailHandler.apply(actionExceptionHandler(e))))
.doOnNext(data -> handler(sink, data, respSuccessHandler.get(), listener,
respRet -> {
//业务处理
final R ret = listener.apply(data);
if (ret != null) {
respRet.setData(ret);
}
}
)).subscribe()
);
}
/**
* 业务处理
*
* @param req 请求数据
* @param process 处理器
* @param 请求数据类型
* @param 响应数据类型
* @return 处理结果
*/
protected Mono> action(@Nonnull final Mono req, @Nonnull final ProccessListener process) {
return action(req, () -> RespResult.ofSuccess(null), RespResult::ofFail, process);
}
/**
* 业务处理-新增
*
* @param req 请求数据
* @param process 处理器
* @param 请求数据类型
* @return 处理结果
*/
protected Mono actionAdd(@Nonnull final Mono req, @Nonnull final ProccessListener process) {
return action(req, () -> RespAddResult.ofSuccess(null), err -> RespAddResult.of(ResultCode.Fail, err, null),
new ProccessListener() {
@Override
public void getExceptHandlers(@Nonnull final List handlers) {
process.getExceptHandlers(handlers);
}
@Override
public void preHandler(@Nullable final T reqData) {
process.preHandler(reqData);
}
@Override
public RespAddResult.AddResult apply(final T data) {
return new RespAddResult.AddResult(process.apply(data));
}
}
);
}
/**
* 业务处理-修改
*
* @param req 请求数据
* @param process 处理器
* @param 请求数据类型
* @return 处理结果
*/
protected Mono actionModify(@Nonnull final Mono req, @Nonnull final ProccessModifyListener process) {
return action(req, RespModifyResult::ofFinish, err -> RespModifyResult.of(ResultCode.Fail, err),
new ProccessListener() {
@Override
public void getExceptHandlers(@Nonnull final List handlers) {
process.getExceptHandlers(handlers);
}
@Override
public void preHandler(@Nullable final T reqData) {
process.preHandler(reqData);
}
@Override
public Serializable apply(final T data) {
process.accept(data);
return null;
}
}
);
}
/**
* 业务处理-删除
*
* @param req 请求数据
* @param process 业务处理器
* @param 请求数据类型
* @return 处理结果
*/
protected Mono actionDelete(@Nonnull final Mono req, @Nonnull final ProccessModifyListener process) {
return action(req, RespDeleteResult::ofFinish, err -> RespDeleteResult.of(ResultCode.Fail, err),
new ProccessListener() {
@Override
public void getExceptHandlers(@Nonnull final List handlers) {
process.getExceptHandlers(handlers);
}
@Override
public void preHandler(@Nullable final T reqData) {
process.preHandler(reqData);
}
@Override
public Serializable apply(final T data) {
process.accept(data);
return null;
}
}
);
}
/**
* 业务处理-删除
*
* @param process 删除处理器
* @return 处理结果
*/
protected Mono actionDelete(@Nonnull final ProccessDeleteListener process) {
return action(RespDeleteResult.ofFinish(),
new ProccessListener() {
@Override
public void getExceptHandlers(@Nonnull final List handlers) {
process.getExceptHandlers(handlers);
}
@Override
public void preHandler(@Nullable final Void reqData) {
process.preHandler(reqData);
}
@Override
public Serializable apply(final Void aVoid) {
//删除处理器
process.accept(aVoid);
return null;
}
}
);
}
protected interface ProccessModifyListener extends Consumer, PreHandlerListener, ExceptHandlerListener {
}
protected interface ProccessDeleteListener extends ProccessModifyListener {
}
@Data
protected static class ReqPagingQuery implements PagingQuery {
/**
* 页码
*/
private Integer index;
/**
* 当前页数量
*/
private Integer rows;
/**
* 查询条件
*/
private T query;
}
}