SpringBoot中常用数据处理方式详解

 更新时间:2025年07月17日 09:39:25   作者:字节跳跃者  
这篇文章主要为大家详细介绍了SpringBoot中常用数据处理方式的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

统一结果响应

为了与前端进行数据交互时,能有一个统一的数据结构,一般我们都需要一个统一响应结果类

以下直接上代码,粘贴可用

package com.kjyfx.response;

import java.io.Serializable;

/**
 * 微信公众号:云说Java、Java栈记
 * @Created by 墨云
 * @Description 统一响应数据
 * @Date 2020/8/29 12:33
 */
public class BaseResponse<T> implements Serializable {
    private static final long serialVersionUID = 3997124446365032582L;

    /**
     * 返回消息
     */
    private String message;

    /**
     * 返回对象
     */
    private T data;

    /**
     * 是否成功
     */
    private Boolean state;

    /**
     * 自定义错误码
     */
    private Integer code;


    /**
     * 错误,系统异常
     *
     * @return result
     */
    public static BaseResponse renderError() {
        BaseResponse response = new BaseResponse();
        response.setState(Boolean.FALSE);
        response.setCode(500);
        return response;
    }

    /**
     * 错误数据(带消息)
     *
     * @param msg 需要返回的消息
     * @return result
     */
    public static BaseResponse renderError(String msg) {
        BaseResponse response = BaseResponse.renderError();
        response.setMessage(msg);
        return response;
    }
    /**
     * 错误数据(带消息)
     *
     * @param msg 需要返回的消息
     * @return result
     */
    public static BaseResponse renderError(String msg, Integer code) {
        BaseResponse response = BaseResponse.renderError();
        response.setMessage(msg);
        response.setCode(code);
        return response;
    }
    /**
     * 成功数据
     *
     * @return result
     */
    public static BaseResponse renderSuccess() {
        BaseResponse response = new BaseResponse();
        response.setState(Boolean.TRUE);
        response.setCode(200);
        return response;
    }

    /**
     * 成功数据(带信息)
     *
     * @param msg 需要返回的信息
     * @return result
     */
    public static BaseResponse renderSuccess(String msg) {
        BaseResponse response = BaseResponse.renderSuccess();
        response.setMessage(msg);
        return response;
    }

    /**
     * 成功数据(带数据)
     *
     * @param obj 需要返回的对象
     * @return result
     */
    public static BaseResponse renderSuccess(Object obj) {
        BaseResponse response = BaseResponse.renderSuccess();
        response.setData(obj);
        return response;
    }

    /**
     * 成功数据(带数据,带信息)
     *
     * @param msg 需要返回的信息
     * @param obj 需要返回的对象
     * @return result
     */
    public static BaseResponse renderSuccess(String msg, Object obj) {
        BaseResponse response = BaseResponse.renderSuccess();
        response.setMessage(msg);
        response.setData(obj);
        return response;
    }

    /**
     * 失败数据
     *
     * @return result
     */
    public static BaseResponse renderFail() {
        BaseResponse response = new BaseResponse();
        response.setState(Boolean.FALSE);
        response.setCode(500);
        return response;
    }

    /**
     * 失败数据(带消息)
     *
     * @param msg 需要返回的消息
     * @return result
     */
    public static BaseResponse renderFail(String msg) {
        BaseResponse response = BaseResponse.renderFail();
        response.setMessage(msg);
        return response;
    }
    /**
     * 失败数据(带消息)
     *
     * @param msg 需要返回的消息
     * @param code 自定义错误码
     * @return result
     */
    public static BaseResponse renderFail(String msg, Integer code) {
        BaseResponse response = BaseResponse.renderFail();
        response.setMessage(msg);
        response.setCode(code);
        return response;
    }

    /**
     * 失败数据(带数据,带信息)
     *
     * @param msg 需要返回的信息
     * @param obj 需要返回的对象
     * @return result
     */
    public static BaseResponse renderFail(String msg, Object obj) {
        BaseResponse response = BaseResponse.renderFail();
        response.setMessage(msg);
        response.setData(obj);
        return response;
    }
    /**
     * 失败数据(带数据,带信息)
     *
     * @param msg 需要返回的信息
     * @param obj 需要返回的对象
     * @param code 自定义错误码
     * @return result
     */
    public static BaseResponse renderFail(String msg, Object obj, Integer code) {
        BaseResponse response = BaseResponse.renderFail();
        response.setMessage(msg);
        response.setData(obj);
        response.setCode(code);
        return response;
    }


    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

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

    public Boolean getState() {
        return state;
    }

    public void setState(Boolean state) {
        this.state = state;
    }

    public Integer getCode() {
        return code;
    }

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

接下来我们就可以用统一结果响应类进行数据交互

@RequestMapping("/getUser")
public BaseResponse getUser(){
    SysUser sysUser = new SysUser()
            .setId(1000L)
            .setAccount("moyun")
            .setUserName("墨云");
    return BaseResponse.renderSuccess("成功!",sysUser);
}

访问接口:http://localhost:9000/base/sysUser/getUser,得到如下数据,统一的数据结构,也方便前端请求接口之后的统一响应拦截处理

从code状态码跟state查看数据信息就很清晰

{
    "message": "成功!",
    "data": {
        "id": 1000,
        "account": "moyun",
        "password": null,
        "userName": "墨云",
        "tel": null,
        "status": null,
        "createUser": null,
        "createType": null,
        "createTime": null,
        "updateTime": null
    },
    "state": true,
    "code": 200
}

一般在实际项目中,见得最多的就是BaseResponse和JsonResult这两个统一响应结果类,命名看个人习惯,内部结构都大同小异

成功结果,常用以下四个静态方法

BaseResponse.renderSuccess();
BaseResponse.renderSuccess(String msg);
BaseResponse.renderSuccess(Object obj);
BaseResponse.renderSuccess(String msg, Object obj);

业务级错误结果,常用以下五个静态方法

BaseResponse.renderFail();
BaseResponse.renderFail(String msg);
BaseResponse.renderFail(String msg, Integer code);
BaseResponse.renderFail(String msg, Object obj);
BaseResponse.renderFail(String msg, Object obj, Integer code);

系统级错误结果,可用以下三个静态方法(不常用,只是与业务级错误进行区分)

BaseResponse.renderError();
BaseResponse renderError(String msg);
BaseResponse renderError(String msg, Integer code);

全局异常处理

全局异常处理类主要用于,当服务器出现异常时,将捕获到的异常信息以json数据返给前端。

先自定义一个异常类,继承RuntimeException

package com.kjyfx.exception;

/**
 * 微信公众号:云说Java、Java栈记
 * @author moyun
 * @date 2020/12/01
 */
public class MsgException extends RuntimeException{
    public MsgException() {
    }

    public MsgException(String message) {
        super(message);
    }

    public MsgException(String message, Throwable cause) {
        super(message, cause);
    }

    public MsgException(Throwable cause) {
        super(cause);
    }

    protected MsgException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

再定义一个全局异常处理器,可以自行添加其他异常处理

package com.kjyfx.exception;


import com.kjyfx.response.BaseResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;

/**
 * 微信公众号:云说Java、Java栈记
 * @author moyun
 * @date 2020/12/01
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);


    @ExceptionHandler(value = MsgException.class)
    public BaseResponse msgExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
        logger.error(e.getMessage());
        e.printStackTrace();
        return BaseResponse.renderFail(e.getMessage());
    }

    @ExceptionHandler(value = NullPointerException.class)
    public BaseResponse nullExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
        logger.error(e.getMessage());
        e.printStackTrace();
        return BaseResponse.renderFail("出现了空指针!");
    }

    @ExceptionHandler(value = org.springframework.web.servlet.NoHandlerFoundException.class)
    public BaseResponse noHandlerFoundExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
        logger.error(e.getMessage());
        return BaseResponse.renderFail("404,未找到请求地址");
    }



    @ExceptionHandler(value = IllegalArgumentException.class)
    public BaseResponse illegalArgumentExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
        logger.error(e.getMessage());
        e.printStackTrace();
        return BaseResponse.renderFail(e.getMessage());
    }

    @ExceptionHandler(value = SQLException.class)
    public BaseResponse sQLExceptionExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
        logger.error(e.getMessage());
        return BaseResponse.renderFail("数据库查询异常");
    }

}

当我们访问以下接口时,sysUser对象恒为空,此时就会抛出一个MsgException

@RequestMapping("/getUser")
public SysUser getUser(){
    SysUser sysUser = null;
    if(null == sysUser){
        throw new MsgException("服务器报了一个错");
    }
    return new SysUser();
}

此时我们访问接口:http://localhost:9000/base/sysUser/getUser

就会得到以下数据,便是全局异常处理器为我们处理的

{
    "message": "服务器报了一个错",
    "data": null,
    "state": false,
    "code": 500
}

全局异常处理器最主要的两个注解,

@RestControllerAdvice:作用于类上,相当于Controller的切面,对异常统一处理,定制,之后再以json格式返给前端

@ExceptionHandler:统一处理某一类异常,作用于方法上,捕捉到相应异常后,会执行其修饰的方法

例如:执行到第四行的时候肯定会报空指针异常

@RequestMapping("/getUser")
public SysUser getUser(){
    SysUser sysUser = null;
    sysUser.setId(1000L);
    return new SysUser();
}

访问接口后,将会得到全局异常处理器返回的数据

{
    "message": "出现了空指针!",
    "data": null,
    "state": false,
    "code": 500
}

JSON数据处理

对于以上得到的json数据,如果对象属性没有赋值,则会显示为null值,对前端来说这是很不友好的,一不小心整个页面就会瘫痪,接下来我们用SpringBoot自带的Jackson对数据进行转换,将null处理为""空串

创建JacksonConfig配置类:

package com.kjyfx.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.io.IOException;

/**
 * @Description TODO
 * 微信公众号:云说Java、Java栈记
 * @Date 2020/12/10 22:20
 * @Created by moyun
 */
@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        SerializerProvider serializerProvider = objectMapper.getSerializerProvider();
        serializerProvider.setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
                jsonGenerator.writeString("");
            }
        });
        return objectMapper;
    }

}

@Primary:

当Spring容器扫描到某个接口的多个 bean 时,如果某个bean上加了@Primary 注解 ,则这个bean会被优先选用

@ConditionalOnMissingBean:

它是修饰bean的一个注解,主要实现的是,当你的bean被注册之后,如果而注册相同类型的bean,就不会成功,

它会保证你的bean只有一个,即你的实例只有一个

之后我们重启项目,再访问接口,会得到以下数据,null成功被转成了""空串

{
    "message": "成功!",
    "data": {
        "id": 1000,
        "account": "moyun",
        "password": "",
        "userName": "墨云",
        "tel": "",
        "status": "",
        "createUser": "",
        "createType": "",
        "createTime": "",
        "updateTime": ""
    },
    "state": true,
    "code": 200
}

到此这篇关于SpringBoot中常用数据处理方式详解的文章就介绍到这了,更多相关SpringBoot数据处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现限定时间CountDownLatch并行场景

    Java实现限定时间CountDownLatch并行场景

    本文将结合实例代码,介绍Java实现限定时间CountDownLatch并行场景,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2021-07-07
  • Apache log4j2-RCE 漏洞复现及修复建议(CVE-2021-44228)

    Apache log4j2-RCE 漏洞复现及修复建议(CVE-2021-44228)

    Apache Log4j2是一款Java日志框架,大量应用于业务系统开发。2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞(CVE-2021-44228),本文给大家介绍Apache log4j2-RCE 漏洞复现(CVE-2021-44228)的相关知识,感兴趣的朋友一起看看吧
    2021-12-12
  • Java函数式编程(十):收集器

    Java函数式编程(十):收集器

    这篇文章主要介绍了Java函数式编程(十):收集器,本文是系列文章的第10篇,其它文章请参阅本文底部的相关文章,需要的朋友可以参考下
    2014-09-09
  • java编译后的文件出现xx$1.class的原因及解决方式

    java编译后的文件出现xx$1.class的原因及解决方式

    这篇文章主要介绍了java编译后的文件出现xx$1.class的原因及解决方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 解决mybatis批量更新(update foreach)失败的问题

    解决mybatis批量更新(update foreach)失败的问题

    这篇文章主要介绍了解决mybatis批量更新(update foreach)失败的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • SpringBoot结合mockito测试实战

    SpringBoot结合mockito测试实战

    与集成测试将系统作为一个整体测试不同,单元测试更应该专注于某个类。所以当被测试类与外部类有依赖的时候,尤其是与数据库相关的这种费时且有状态的类,很难做单元测试。但好在可以通过“Mockito”这种仿真框架来模拟这些比较费时的类,从而专注于测试某个类内部的逻辑
    2022-11-11
  • springboot项目关闭swagger如何防止漏洞扫描

    springboot项目关闭swagger如何防止漏洞扫描

    这篇文章主要介绍了springboot项目关闭swagger如何防止漏洞扫描,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • 详解MyBatis-Puls中saveBatch批量添加慢的问题

    详解MyBatis-Puls中saveBatch批量添加慢的问题

    本文主要介绍了详解MyBatis-Puls中saveBatch批量添加慢的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • java实现简单的验证码功能

    java实现简单的验证码功能

    这篇文章主要为大家详细介绍了java实现简单的验证码功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • Mybatis如何实现关联属性懒加载

    Mybatis如何实现关联属性懒加载

    这篇文章主要介绍了Mybatis如何实现关联属性懒加载的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07

最新评论