第1步:定义线程容器收纳HttpHeaders和HttpStatus
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;public class ResponseUtils {private static ThreadLocal<HttpHeaders> ThreadLocalHeaders = new InheritableThreadLocal<>();private static ThreadLocal<HttpStatus> ThreadLocalStatus = new InheritableThreadLocal<>();public static void addHeaders(String key, String value) {if (ThreadLocalHeaders.get() == null) {ThreadLocalHeaders.set(new HttpHeaders());}ThreadLocalHeaders.get().add(key, value);}public static void setResponseCode(HttpStatus httpStatus) {ThreadLocalStatus.set(httpStatus);}public static HttpHeaders getHeaders() {return ThreadLocalHeaders.get();}public static HttpStatus getResponseCode() {return ThreadLocalStatus.get();}public static void clear() {if (ThreadLocalHeaders.get() != null) {ThreadLocalHeaders.remove();}if (ThreadLocalStatus.get() != null) {ThreadLocalStatus.remove();}}
}
第2步:分页信息 转储到 线程容器 方法的封装
import com.github.pagehelper.PageInfo;
import com.zhangziwa.practisesvr.utils.response.ResponseUtils;public class PageHeaderUtils {private static final String PAGE_NUM = "page_num"; // 当前第几页private static final String PAGE_SIZE = "page_size"; // 每页显示的条数private static final String PREV_PAGE = "prev_page"; // 上一页页码private static final String NEXT_PAGE = "next_page"; // 下一页页码private static final String TOTAL_COUNT = "total_count"; // 总条数private static final String TOTAL_PAGE = "total_page"; // 总页数public static <E> void setPageHeader(PageInfo<E> page) {if (page == null) {return;}ResponseUtils.addHeaders(PAGE_NUM, String.valueOf(page.getPageNum()));ResponseUtils.addHeaders(PAGE_SIZE, String.valueOf(page.getPageSize()));ResponseUtils.addHeaders(TOTAL_COUNT, String.valueOf(page.getTotal()));ResponseUtils.addHeaders(TOTAL_PAGE, String.valueOf(page.getPages() == 0 ? 1 : page.getPages()));// page.getPages()=1表示就1页,前后页都不存在,故也算特殊场景.也为了page.getPages()+1和page.getPages()-1不会对[1,page.getPages()]越界if (page.getPages() == 0 || page.getPages() == 1) {ResponseUtils.addHeaders(PREV_PAGE, "");ResponseUtils.addHeaders(NEXT_PAGE, "");} else if (page.getPageNum() == 1) {ResponseUtils.addHeaders(PREV_PAGE, "");ResponseUtils.addHeaders(NEXT_PAGE, String.valueOf(page.getPages() + 1));} else if (page.getPageNum() == page.getPages()) {ResponseUtils.addHeaders(PREV_PAGE, String.valueOf(page.getPages() - 1));ResponseUtils.addHeaders(NEXT_PAGE, "");} else {ResponseUtils.addHeaders(PREV_PAGE, String.valueOf(page.getPages() - 1));ResponseUtils.addHeaders(NEXT_PAGE, String.valueOf(page.getPages() + 1));}}
}
第3步:分页查询,HttpHeaders和HttpStatus收集到线程容器中
public List<Student> listStudents(Integer pageNum, Integer PageSize) {PageHelper.startPage(PageUtils.getPageNum(pageNum), PageUtils.getPageSize(PageSize), PageUtils.isQueryTotalCount());PageHelper.orderBy("age asc");List<Student> students = userMapper.listStudents();PageInfo<Student> studentPageInfo = PageInfo.of(students);// 收集分页信息到 ThreadLocalPageHeaderUtils.setPageHeader(studentPageInfo);// 收集HttpStatus到 ThreadLocal// ResponseUtils.setResponseCode(num2HttpStatus("200")); // 为了使用一下num2HttpStatus方法ResponseUtils.setResponseCode(HttpStatus.OK);return students;
}
public class HttpStatusUtils {public static HttpStatus num2HttpStatus(String num) {HttpStatus httpStatus = HttpStatus.NOT_FOUND;for (HttpStatus status : HttpStatus.values()) {if (Integer.parseInt(num) == status.value()) {return status;}}return httpStatus;}
}
第4步:controller层需为@RestController Restful接口
@RestController
@Slf4j
public class SearchController {@AutowiredUserService userService;@RequestMapping(value = "/getAllStudents", method = RequestMethod.GET)public List<Student> login() {List<Student> students = userService.listStudents(1, 10);students.forEach(System.out::println);return students;}
}
第5步:线程容器收纳HttpHeaders和HttpStatus添加到ServerHttpResponse
@ControllerAdvice
public class HttpResponseBodyAdvice implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class clazz,ServerHttpRequest request, ServerHttpResponse response) {HttpHeaders headers = response.getHeaders();// 分页信息添加到ServerHttpResponseHttpHeaders headersContext = ResponseUtils.getHeaders();if (nonNull(headersContext) && !headersContext.isEmpty()) {headers.addAll(headersContext);}// 状态码添加到ServerHttpResponseif (nonNull(ResponseUtils.getResponseCode())) {response.setStatusCode(ResponseUtils.getResponseCode());}return body;}
}
第6步:测试结果