Spring如何定义一个统一返回类呢?
下文笔者讲述Spring定义一个统一返回类的方法及示例分享
定义统一返回类的实现思路: 1.定义一个泛型类 用于返回类对象 2.使用ResponseUtil封装 返回类 3.使用@RestControllerAdvice拦截返回内容
统一返回类
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @ApiModel(value = "response", description = "响应") public class Response<T> { @JsonProperty("rsp_code") @JSONField(name = "rsp_code") @ApiModelProperty(value = "响应码(0:成功)", position = 1) private int rspCode = 0; @JsonProperty("rsp_desc") @JSONField(name = "rsp_desc") @ApiModelProperty(value = "响应码描述 ", position = 2) private String rspDesc = "successful"; @ApiModelProperty(value = "数据", position = 5) private T data; public int getRspCode() { return rspCode; } public void setRspCode(int rspCode) { this.rspCode = rspCode; } public String getRspDesc() { return rspDesc; } public void setRspDesc(String rspDesc) { this.rspDesc = rspDesc; } public T getData() { return data; } public void setData(T data) { this.data = data; } @Override public String toString() { return JSON.toJSONString(this); } }
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @ApiModel(value = "pagingResponse", description = "分页响应") public class PagingResponse<T> extends Response<T> { @ApiModelProperty(value = "总条数", position = 3) private long total; @ApiModelProperty(value = "总页数", position = 4) private int pages; public long getTotal() { return total; } public void setTotal(long total) { this.total = total; } public int getPages() { return pages; } public void setPages(int pages) { this.pages = pages; } }
统一返回工具类
import com.github.pagehelper.PageInfo; import com.java265.common.DataEntity.Model.Response.Common.PagingResponse; import com.java265.common.DataEntity.Model.Response.Common.Response; import org.springframework.data.domain.Page; import java.util.list; public class ResponseUtil { public static <T> Response<T> out(T t) { Response<T> res = new Response<>(); res.setData(t); return res; } public static <T> Response<T> outSuccess() { Response<T> res = new Response<>(); return res; } public static <T> Response<T> outFail() { Response<T> res = new Response<>(); res.setRspCode(-1); res.setRspDesc("操作失败"); return res; } public static <T> PagingResponse<T> outNull() { PagingResponse<T> res = new PagingResponse<>(); res.setData(null); return res; } public static <T> Response<T> outError(String desc) { Response<T> res = new Response<>(); res.setRspCode(-1); res.setRspDesc(desc); return res; } public static <T> PagingResponse<List<T>> out(List<T> t, long total, int pages) { PagingResponse<List<T>> res = new PagingResponse<>(); res.setData(t); res.setPages(pages); res.setTotal(total); return res; } public static <T> PagingResponse<List<T>> out(Page<T> page) { PagingResponse<List<T>> res = new PagingResponse<>(); if (page == null) { return res; } res.setData(page.getContent()); res.setPages(page.getTotalPages()); res.setTotal(page.getTotalElements()); return res; } public static <T> PagingResponse<List<T>> out(PageInfo<T> page) { PagingResponse<List<T>> res = new PagingResponse<>(); if (page == null) { return res; } res.setData(page.getList()); res.setPages(page.getPages()); res.setTotal(page.getTotal()); return res; } public static <T> PagingResponse<List<T>> outPageError(String desc) { PagingResponse<List<T>> res = new PagingResponse<>(); res.setRspCode(-1); res.setRspDesc(desc); return res; } }
controller二次封装
import com.github.pagehelper.PageInfo; import com.java265.common.DataEntity.Model.Response.Common.Response; import com.java265.core.DataApi.Common.Util.ResponseUtil; import org.springframework.core.MethodParameter; import org.springframework.data.domain.Page; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @RestControllerAdvice public class ResponseHandler implements ResponseBodyAdvice<Object> { /** * 只处理有RestResponse注解的方法,防止处理其他不需要封装的,或者swaggwer等 * * @param returnType * @param converterType * @return */ @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { //直接返回true就是拦截所有的controller,也会拦截swagger的controller导致swagger不可用 return returnType.hasMethodAnnotation(RestResponse.class); } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { Response respVo = null; if (body instanceof Response) { respVo = (Response) body; } else if (body instanceof Page) { Page page = (Page) body; respVo = ResponseUtil.out(page); } else if (body instanceof PageInfo) { PageInfo pageInfo = (PageInfo) body; respVo = ResponseUtil.out(pageInfo); } else { respVo = ResponseUtil.out(body); } //如果返回的字符串类型,会先判断HttpMessageConverter能否支持对应的返回类型再使用ResponseBodyAdvice进行封装 //那么此时在进来就不是String类型,所以会报无法转换成ResponseVO对象,那么这里有两种方法,一种是直接返回json字符串,另一种是 //一种是自己的WebConfig进行额外的配置 // if (body instanceof String){ // return JSONUtil.toJsonStr(respVo); // } return respVo; } }定义加入此注解的内容会被转换
package com.java265.core.DataApi.Common.Response; import java.lang.annotation.*; /** * * @Desc 忽略统一返回封装的注解 * @date 2023/2/17 14:45 */ @Documented @Inherited @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.Runtime) public @interface RestResponse { }
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。