友好的返回统一的标准格式,方便记录
Spring Boot还提供了一些方法,可以统一返回对象,不用每个返回类都自己用返回类包装
1.基础的返回类:
package com.test.ft.common.wrapper;
import cn.hutool.http.HttpStatus;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* @author aaa
* @description 基础返回类
*/
@Data
@AllArgsConstructor
public class ResultBean<T> {
private int code;
private String msg;
private T data;
private long timestamp;
protected ResultBean() {
this.timestamp = System.currentTimeMillis();
}
private static <T> ResultBean<T> of(int code, String msg, T data) {
ResultBean<T> result = new ResultBean<>();
result.code = code;
result.msg = msg;
result.data = data;
result.timestamp=System.currentTimeMillis();
return result;
}
public static <T> ResultBean<T> success() {
return success("处理成功");
}
public static <T> ResultBean<T> success(String msg) {
return of(HttpStatus.HTTP_OK, msg, null);
}
public static <T> ResultBean<T> success(String msg, T data) {
return of(HttpStatus.HTTP_OK, msg, data);
}
public static <T> ResultBean<T> success(T data) {
return of(HttpStatus.HTTP_OK, "处理成功", data);
}
public static <T> ResultBean<T> success(int code, String msg) {
return of(code, msg, null);
}
public static <T> ResultBean<T> error(int code, String msg) {
return of(code, msg, null);
}
public static <T> ResultBean<T> error(String msg) {
return error(HttpStatus.HTTP_INTERNAL_ERROR, msg);
}
public static <T> ResultBean<T> error(String msg, T data) {
return error(HttpStatus.HTTP_INTERNAL_ERROR, msg, data);
}
public static <T> ResultBean<T> error(int code, String msg, T data) {
return of(code, msg, data);
}
}
分页返回类,继承基础的ResultBean:
package com.test.ft.common.wrapper;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author aaa
* @description
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class PageResult<T> extends ResultBean<T> {
//总记录数
private long counts;
//当前页码
private long page;
//每页记录数
private long pageSize;
private PageResult() {
}
private static <T> PageResult<T> of( String msg, T data, long counts, long page, long pageSize) {
PageResult<T> result = new PageResult<>();
result.page=page;
result.pageSize=pageSize;
result.counts=counts;
result.setCode(HttpStatus.HTTP_OK);
result.setData(data);
result.setMsg(msg);
return result;
}
private static <T> PageResult<T> of(int code, String msg) {
PageResult<T> result = new PageResult<>();
result.setCode(code);
result.setMsg(msg);
return result;
}
/**
* 该分页默认使用mybatis plus分页,其他的分页参数可以自行设置
* @param page 分页参数信息
* @param msg 提示信息
* @return 分页查询结果
* @param <T> t
*/
public static <T> PageResult<T> success(Page<?> page,String msg){
return of(msg, (T)page.getRecords(), page.getTotal(), page.getPages(),page.getSize());
}
public static <T> PageResult<T> success(Page<?> page){
return success(page,"查询成功");
}
public static <T> PageResult<T> error(String msg){
return error(HttpStatus.HTTP_INTERNAL_ERROR,msg);
}
public static <T> PageResult<T> error(int code,String msg){
return of(code,msg);
}
}
2.自定义响应处理拦截器
由于demo里面web通过Feign来调用Server的服务,所以在Server和web里面都有请求返回,所以将拦截器放在Web模块中
package com.example.ftweb.config;
import cn.hutool.json.JSONUtil;
import com.test.ft.common.wrapper.ResultBean;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.springframework.core.MethodParameter;
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;
/**
* @author aaa
* @description
*/
@RestControllerAdvice
public class MyResponseHandle implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(@NotNull MethodParameter returnType, @NotNull Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@SneakyThrows
@Override
public Object beforeBodyWrite(Object body, @NotNull MethodParameter returnType, @NotNull MediaType selectedContentType, @NotNull Class<? extends HttpMessageConverter<?>> selectedConverterType, @NotNull ServerHttpRequest request, ServerHttpResponse response) {
if (body instanceof ResultBean) {
return body;
}
// 使用HuTool工具类的JSON转换器,可以换成ObjectMapper等其他JSON格式转换
return body instanceof String ? JSONUtil.toJsonStr(ResultBean.success(body)) : ResultBean.success(body);
}
}
其他事项:
在测试中,发现直接返回一个字符串的时候,用处理器封装后,返回的中文变成了问号:???,经过查询,有2种处理方式:
1.第一种处理方式:
在请求上加上:
@RequestMapping(value = "/test",produces = "application/json;charset=UTF-8")
2.第二种方式,继承WebMvcConfigurationSupport后重写相关方法,全局处理
package com.example.ftweb.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* @author aaa
* @description 解决页面返回的中文乱码。
* 自定义消息转换器:自定义WebConfiguration继承WebMvcConfigurationSupport类
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 解决中文乱码
* @return {@link HttpMessageConverter}<{@link String}>
*/
@Bean
public HttpMessageConverter<String> httpMessageConverter(){
return new StringHttpMessageConverter(StandardCharsets.UTF_8);
}
/**
* 解决中文乱码后,返回json时可能会出现No converter found for return value of type: xxxx 或 Could not find acceptable representation
* @return {@link ObjectMapper}
*/
public ObjectMapper getObjectMapper(){
return new ObjectMapper();
}
public MappingJackson2HttpMessageConverter messageConverter(){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(getObjectMapper());
return converter;
}
@Override
protected void configureMessageConverters(@NotNull List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
// 解决中文乱码
converters.add(httpMessageConverter());
// 添加解决中文乱码后的配置之后,返回json数据直接报错 500:no convertter for return value of type 或这个:Could not find acceptable representation
converters.add(messageConverter());
}
}
demo中,相关配置位置图例:
测试结果:
可以看到直接返回字符串的时候,已经做了封装:
普通的请求测试,能返回统一的格式:
发现一个大佬,对于这些有更详细的描述,可以直接使用,链接如下: