Spring Boot 自定义返回对象以及统一封装

友好的返回统一的标准格式,方便记录

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中,相关配置位置图例:

测试结果:

可以看到直接返回字符串的时候,已经做了封装:

普通的请求测试,能返回统一的格式:

发现一个大佬,对于这些有更详细的描述,可以直接使用,链接如下:

https://www.cnblogs.com/konglxblog/p/15888012.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值