Spring Boot常用数据处理方式

  • A+
所属分类:Java片段

一、统一结果响应

为了与前端进行数据交互时,能有一个统一的数据结构,也方便告知前端请求结果正确与否,一般我们都需要一个统一响应结果类

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

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
}

PDF文档下载
链接:https://pan.baidu.com/s/1WuJPmF28OT3t-oRhQVU4TQ
提取码:cxxb

  • 云说Java
  • 关注公众号获取更多资源
  • weinxin
  • Java栈记
  • 关注公众号获取更多资源
  • weinxin
墨云

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: