AOP实战案例—分页拦截器

场景

拦截所有rest请求,设置分页信息,并将分页结果写入返回信息中。

实现

1、分页信息对象

import java.io.Serializable;
import java.util.List;

public class Page implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    /**
     * 当前页索引
     */
    private int page = 1;

    /**
     * 每页显示的数据条数
     */
    private int pageSize = 20;

    /**
     * 总条数
     */
    private int total = 0;

    /**
     * 总页数
     */
    private int totalPage = 1;

    /**
     * 排序字段
     */
    private String sort;

    /**
     * 排序方式 ASC DESC
     */
    private String order;

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public String getSort() {
        return sort;
    }

    public void setSort(String sort) {
        this.sort = sort;
    }

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    public void paging(){}

    public void order(){}

    public void setPagingResult(int total, int totalPage){};
    public void setPagingResult(List list){};

    public <T> List<T> packResult(List<T> list, int total) {return null;};
}

2、PageThreadLocal(业务类—操作当前线程中的分页信息)

import com.xxx.ajax.Page;

class PageThreadLocal {

    private static final ThreadLocal<Page> pageThreadLocal = new ThreadLocal<Page>();

    private static final ThreadLocal<Boolean> ifReturnThreadLocal = new ThreadLocal<Boolean>();

    public static void setPage(Page pageInfo) {
        pageThreadLocal.set(pageInfo);
    }
    
    public static Page getPage() {
        return pageThreadLocal.get();
    }

    public static void clearPage() {
        pageThreadLocal.remove();
    }

    public static void setIfReturn(Boolean ifReturn) {
        ifReturnThreadLocal.set(ifReturn);
    }

    public static Boolean getIfReturn() {
        return ifReturnThreadLocal.get();
    }

    public static void clearIfReturn() {
        ifReturnThreadLocal.remove();
    }

}

3、分页信息对象方法实现类

import com.github.pagehelper.PageHelper;
import com.xxx.ajax.Page;

import java.util.List;

class ProxyPageInfo extends Page {

    private Page getPageInfo() {
        if(PageThreadLocal.getPage() == null) {
            PageThreadLocal.setPage(new Page());
        }
        return PageThreadLocal.getPage();
    }

    @Override
    public int getPage() {
        return getPageInfo().getPage();
    }

    @Override
    public void setPage(int page) {
        super.setPage(page);
        getPageInfo().setPage(page);
    }

    @Override
    public int getPageSize() {
        return getPageInfo().getPageSize();
    }

    @Override
    public void setPageSize(int pageSize) {
        super.setPageSize(pageSize);
        getPageInfo().setPageSize(pageSize);
    }

    @Override
    public int getTotal() {
        return getPageInfo().getTotal();
    }

    @Override
    public void setTotal(int total) {
        super.setTotal(total);
        getPageInfo().setTotal(total);
    }

    @Override
    public int getTotalPage() {
        return getPageInfo().getTotalPage();
    }

    @Override
    public void setTotalPage(int totalPage) {
        super.setTotalPage(totalPage);
        getPageInfo().setTotalPage(totalPage);
    }

    @Override
    public String getSort() {
        return getPageInfo().getSort();
    }

    @Override
    public void setSort(String sort) {
        super.setSort(sort);
        getPageInfo().setSort(sort);
    }

    @Override
    public String getOrder() {
        return getPageInfo().getOrder();
    }

    @Override
    public void setOrder(String order) {
        super.setOrder(order);
        getPageInfo().setOrder(order);
    }

    @Override
    public void paging(){
        PageThreadLocal.setIfReturn(false);
        //分页
        PageHelper.startPage(getPageInfo().getPage(), getPageInfo().getPageSize());
    }

    @Override
    public void order() {
        //排序
        if(getSort() != null) {
            if(getOrder() != null) {
                PageHelper.orderBy(getSort() + " " + getOrder());
            } else {
                PageHelper.orderBy(getSort());
            }
        }
    }

    @Override
    public void setPagingResult(int total, int totalPage) {
        setTotal(total);
        setTotalPage(totalPage);
        PageThreadLocal.setIfReturn(false);
    }

    @Override
    public void setPagingResult(List list) {
        if(list instanceof com.github.pagehelper.Page) {
            com.github.pagehelper.Page page = (com.github.pagehelper.Page) list;
            setTotal((int) page.getTotal());
            setTotalPage(page.getPages());
            PageThreadLocal.setIfReturn(false);
        }
    }

    @Override
    public <T> List<T> packResult(List<T> list, int total) {
        com.github.pagehelper.Page<T> result = new com.github.pagehelper.Page<T>();
        for(T t : list) {
            result.add(t);
        }
        result.setPageSize(getPageSize());
        result.setTotal(total);
        return result;
    }
}

4、返回对象

public class AjaxResult {

    private Integer success = Integer.valueOf(0);
    private String code = "200";
    private String msg = "";
    private Object data;
    private Page page;
    private String token;

    public AjaxResult() {
    }

    public void setSuccess(Integer success) {
        this.success = success;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public static AjaxResult success() {
        AjaxResult result = new AjaxResult();
        result.setSuccess(Integer.valueOf(1));
        result.setMsg("success");
        return result;
    }

    public static AjaxResult success(String msg) {
        AjaxResult result = new AjaxResult();
        result.setSuccess(Integer.valueOf(1));
        result.setMsg(msg);
        return result;
    }

    public static AjaxResult success(String msg, Object data) {
        AjaxResult result = new AjaxResult();
        result.setSuccess(Integer.valueOf(1));
        result.setData(data);
        result.setMsg(msg);
        return result;
    }

    public static AjaxResult success(Object data) {
        AjaxResult result = new AjaxResult();
        result.setSuccess(Integer.valueOf(1));
        result.setData(data);
        result.setMsg("success");
        return result;
    }

    public static AjaxResult failure() {
        AjaxResult result = new AjaxResult();
        result.setSuccess(Integer.valueOf(0));
        result.setMsg("failure");
        return result;
    }

    public static AjaxResult failure(String msg) {
        AjaxResult result = new AjaxResult();
        result.setSuccess(Integer.valueOf(0));
        result.setMsg(msg);
        return result;
    }

    public static AjaxResult failure(String code, String msg) {
        AjaxResult result = new AjaxResult();
        result.setSuccess(Integer.valueOf(0));
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

    public static AjaxResult failure(String msg, Object data) {
        AjaxResult result = new AjaxResult();
        result.setSuccess(Integer.valueOf(0));
        result.setMsg(msg);
        result.setData(data);
        return result;
    }

    public static AjaxResult failure(String code, String msg, Object data) {
        AjaxResult result = new AjaxResult();
        result.setSuccess(Integer.valueOf(0));
        result.setMsg(msg);
        result.setData(data);
        result.setCode(code);
        return result;
    }

    public static AjaxResult getResult(Page page, Object data) throws Exception {
        AjaxResult result = new AjaxResult();
        Page newPage = new Page();
        newPage.setPage(page.getPage());
        newPage.setPageSize(page.getPageSize());
        newPage.setTotal(page.getTotal());
        newPage.setTotalPage(page.getTotalPage());
        result.setPage(newPage);
        result.setData(data);
        result.setSuccess(Integer.valueOf(1));
        return result;
    }

    public Page getPage() {
        return this.page;
    }

    public void setPage(Page page) {
        this.page = page;
    }

    public Integer getSuccess() {
        return this.success;
    }

    public String getMsg() {
        return this.msg;
    }

    public Object getData() {
        return this.data;
    }

    public String getCode() {
        return this.code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }
}

5、拦截器

import com.xxx.ajax.AjaxResult;
import com.xxx.ajax.Page;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Configuration
@ConditionalOnProperty(name = "framework.page.started", havingValue = "true")
class PageHandle {

    @Autowired
    private HttpServletRequest request;

    private static final Logger log = LoggerFactory.getLogger(PageHandle.class);

    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    private void requestMapping(){}

    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
    private void getMapping(){}

    @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
    private void postMapping(){}

    @Pointcut("@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
    private void deleteMapping(){}

    @Pointcut("@annotation(org.springframework.web.bind.annotation.PutMapping)")
    private void putMapping(){}

    @Around("requestMapping()")
    public Object requestMappingAround(ProceedingJoinPoint pjp) throws Throwable {
        return around(pjp);
    }

    @Around("getMapping()")
    public Object getMappingAround(ProceedingJoinPoint pjp) throws Throwable {
        return around(pjp);
    }

    @Around("postMapping()")
    public Object postMappingAround(ProceedingJoinPoint pjp) throws Throwable {
        return around(pjp);
    }

    @Around("deleteMapping()")
    public Object deleteMappingAround(ProceedingJoinPoint pjp) throws Throwable {
        return around(pjp);
    }

    @Around("putMapping()")
    public Object putMappingAround(ProceedingJoinPoint pjp) throws Throwable {
        return around(pjp);
    }

    private Object around(ProceedingJoinPoint pjp) throws Throwable {
        PageThreadLocal.clearIfReturn();
        PageThreadLocal.clearPage();
        long start = System.currentTimeMillis();
        Object result = null;
        try {
//            if(request.getMethod().equals("GET")) {
                Page page = getPageInfo();
                PageThreadLocal.setPage(page);
//            }
        } finally {
            try {
                result = pjp.proceed();
            } finally {
                if(result instanceof AjaxResult) {
                    AjaxResult ajaxResult = (AjaxResult) result;
                    Object data = ajaxResult.getData();
                    if(data instanceof com.github.pagehelper.Page) {
                        Page page = PageThreadLocal.getPage();
                        if(page == null) {
                            page = new Page();
                        }
                        page.setTotal((int) ((com.github.pagehelper.Page) data).getTotal());
                        page.setTotalPage((int) ((com.github.pagehelper.Page) data).getPages());
                        PageThreadLocal.setPage(page);
                        PageThreadLocal.setIfReturn(true);
                        ajaxResult.setPage(PageThreadLocal.getPage());
                    } else {
                        if(PageThreadLocal.getIfReturn() != null && !PageThreadLocal.getIfReturn()) {
                            Page page = PageThreadLocal.getPage();
                            PageThreadLocal.setIfReturn(true);
                            ajaxResult.setPage(page);
                        }
                    }
                }
                //TODO 非Ajax时,page要放到response里,具体结构要与陈强协商后再写
                PageThreadLocal.clearIfReturn();
                PageThreadLocal.clearPage();
            }
        }
        long end = System.currentTimeMillis();
        log.debug("page参数处理 + 方法运行 = {}ms", end - start);
        return result;
    }

    private Page getPageInfo() {
        Page page = new Page();
        if(request != null) {
            Object pageNum = request.getParameter("page");
            if (pageNum != null) {
                page.setPage(Integer.valueOf((String) pageNum));
            }

            Object pageSize = request.getParameter("pageSize");
            if (pageSize != null) {
                page.setPageSize(Integer.valueOf((String) pageSize));
            }

            Object total = request.getParameter("total");
            if (total != null) {
                page.setTotal(Integer.valueOf((String) total));
            }

            Object totalPage = request.getParameter("totalPage");
            if (totalPage != null) {
                page.setTotalPage(Integer.valueOf((String) totalPage));
            }

            Object sort = request.getParameter("sort");
            if (sort != null) {
                page.setSort((String) sort);
            }

            Object order = request.getParameter("order");
            if (order != null) {
                page.setOrder((String) order);
            }

        }
        return page;
    }

    /**
     * 拦截dubbo,清除分页信息
     */
    @Pointcut("execution(* com.**.service.**.*(..))")
    private void adviceService(){}

    @Around("adviceService()")
    public Object aroundService(ProceedingJoinPoint pjp) throws Throwable {
        Object result = null;
        try {
            result = pjp.proceed();
        } finally {
            PageThreadLocal.clearIfReturn();
            PageThreadLocal.clearPage();
        }
        return result;
    }

//    /**
//     * 拦截MQ,清除分页信息
//     */
//    @Pointcut("execution(* com.lfmf.**.mq.**.*.process(Object,*))")
//    private void adviceMQ(){}
//
//    @Around("adviceMQ()")
//    public Object aroundMQ(ProceedingJoinPoint pjp) throws Throwable {
//        Object result = null;
//        try {
//            result = pjp.proceed();
//        } finally {
//            PageThreadLocal.clearIfReturn();
//            PageThreadLocal.clearPage();
//        }
//        return result;
//    }

    @Bean
    public ProxyPageInfo proxyPageInfo() {
        return new ProxyPageInfo();
    }
}

6、业务类中启用分页查询

import com.xxx.ajax.Page;
import com.xxx.api.dto.resp.Api;
import com.xxx.api.mapper.ApiMapper;
import com.xxx.api.service.IApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ApiServiceImpl implements IApiService {

    @Autowired
    private ApiMapper apiMapper;

    @Autowired
    private Page page;

    /**
     * 获取接口列表
     * @param name 接口名称
     * @param address 接口地址
     * @return
     */
    @Override
    public List<Api> getApiList(String name, String address) {
        page.paging();
        return apiMapper.getList(name, address);
    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容