SpringBoot实战(九):标准化json返回值

简介: SpringBoot实战(九):标准化json返回值

强烈推荐一个大神的人工智能的教程:http://www.captainai.net/zhanghan


【前言】


      前后端分离是现在系统开发主流模式,上篇博文《SpringBoot集成Swagger》介绍了利器Swagger;这篇接着定义返回Json格式的规范;无规矩,不成方圆;有了好的规范前后端的开发效率将大大提高;


【返回Json结果规范化】


        一、规范化的必要性


              1、未规范化痛点:


                    返回格式杂乱,前后端不能用统一的工具类去处理,极大拖延联调进度;


              2、规范化爽点:


                    返回格式统一,前后端都可以用统一的工具类去处理,极大推进了联调进度;


        二、如何改造:


              1、项目中增加Wrapper


/*
 * Copyright (c) 2019. zhanghan_java@163.com All Rights Reserved.
 * 项目名称:实战SpringBoot
 * 类名称:Wrapper.java
 * 创建人:张晗
 * 联系方式:zhanghan_java@163.com
 * 开源地址: https://github.com/dangnianchuntian/springboot
 * 博客地址: https://blog.csdn.net/zhanghan18333611647
 */
package com.zhanghan.zhboot.util.wrapper;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
import java.io.Serializable;
/**
 * The class Wrapper.
 *
 * @param <T> the type parameter @author https://blog.csdn.net/zhanghan18333611647
 */
@Data
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class Wrapper<T> implements Serializable {
  /**
  * 序列化标识
  */
  private static final long serialVersionUID = 3782350118017398556L;
  /**
  * 成功码.
  */
  public static final int SUCCESS_CODE = 0;
  /**
  * 成功信息.
  */
  public static final String SUCCESS_MESSAGE = "操作成功";
  /**
  * 错误码.
  */
  public static final int ERROR_CODE = 1;
  /**
  * 错误信息.
  */
  public static final String ERROR_MESSAGE = "内部异常";
  /**
  * 编号.
  */
  private int code;
  /**
  * 信息.
  */
  private String message;
  /**
  * 结果数据
  */
  private T result;
  /**
  * Instantiates a new wrapper. default code=0
  */
  Wrapper() {
  this(SUCCESS_CODE, SUCCESS_MESSAGE);
  }
  /**
  * Instantiates a new wrapper.
  *
  * @param code    the code
  * @param message the message
  */
  Wrapper(int code, String message) {
  this(code, message, null);
  }
  /**
  * Instantiates a new wrapper.
  *
  * @param code    the code
  * @param message the message
  * @param result  the result
  */
  Wrapper(int code, String message, T result) {
  super();
  this.code(code).message(message).result(result);
  }
  /**
  * Sets the 编号 , 返回自身的引用.
  *
  * @param code the new 编号
  *
  * @return the wrapper
  */
  private Wrapper<T> code(int code) {
  this.setCode(code);
  return this;
  }
  /**
  * Sets the 信息 , 返回自身的引用.
  *
  * @param message the new 信息
  *
  * @return the wrapper
  */
  private Wrapper<T> message(String message) {
  this.setMessage(message);
  return this;
  }
  /**
  * Sets the 结果数据 , 返回自身的引用.
  *
  * @param result the new 结果数据
  *
  * @return the wrapper
  */
  public Wrapper<T> result(T result) {
  this.setResult(result);
  return this;
  }
  /**
  * 判断是否成功: 依据 Wrapper.SUCCESS_CODE == this.code
  *
  * @return code =0,true;否则 false.
  */
  @JsonIgnore
  public boolean success() {
  return Wrapper.SUCCESS_CODE == this.code;
  }
  /**
  * 判断是否成功: 依据 Wrapper.SUCCESS_CODE != this.code
  *
  * @return code !=0,true;否则 false.
  */
  @JsonIgnore
  public boolean error() {
  return !success();
  }
}


              2、项目中增加WrapMapper


/*
 * Copyright (c) 2019. zhanghan_java@163.com All Rights Reserved.
 * 项目名称:实战SpringBoot
 * 类名称:WrapMapper.java
 * 创建人:张晗
 * 联系方式:zhanghan_java@163.com
 * 开源地址: https://github.com/dangnianchuntian/springboot
 * 博客地址: https://blog.csdn.net/zhanghan18333611647
 */
package com.zhanghan.zhboot.util.wrapper;
import io.micrometer.core.instrument.util.StringUtils;
/**
 * The class Wrap mapper.
 *
 * @author https://blog.csdn.net/zhanghan18333611647
 */
public class WrapMapper {
    /**
     * Instantiates a new wrap mapper.
     */
    private WrapMapper() {
    }
    /**
     * Wrap.
     *
     * @param <E>     the element type
     * @param code    the code
     * @param message the message
     * @param o       the o
     * @return the wrapper
     */
    public static <E> Wrapper<E> wrap(int code, String message, E o) {
        return new Wrapper<>(code, message, o);
    }
    /**
     * Wrap.
     *
     * @param <E>     the element type
     * @param code    the code
     * @param message the message
     * @return the wrapper
     */
    public static <E> Wrapper<E> wrap(int code, String message) {
        return wrap(code, message, null);
    }
    /**
     * Wrap.
     *
     * @param <E>  the element type
     * @param code the code
     * @return the wrapper
     */
    public static <E> Wrapper<E> wrap(int code) {
        return wrap(code, null);
    }
    /**
     * Wrap.
     *
     * @param <E> the element type
     * @param e   the e
     * @return the wrapper
     */
    public static <E> Wrapper<E> wrap(Exception e) {
        return new Wrapper<>(Wrapper.ERROR_CODE, e.getMessage(), null);
    }
    /**
     * Un wrapper.
     *
     * @param <E>     the element type
     * @param wrapper the wrapper
     * @return the e
     */
    public static <E> E unWrap(Wrapper<E> wrapper) {
        return wrapper.getResult();
    }
    /**
     * Wrap ERROR. code=1
     *
     * @param <E> the element type
     * @return the wrapper
     */
    public static <E> Wrapper<E> error() {
        return wrap(Wrapper.ERROR_CODE, Wrapper.ERROR_MESSAGE, null);
    }
    /**
     * Error wrapper.
     *
     * @param <E>     the type parameter
     * @param message the message
     * @return the wrapper
     */
    public static <E> Wrapper<E> error(String message) {
        return wrap(Wrapper.ERROR_CODE, StringUtils.isBlank(message) ? Wrapper.ERROR_MESSAGE : message, null);
    }
    /**
     * Wrap SUCCESS. code=0
     *
     * @param <E> the element type
     * @return the wrapper
     */
    public static <E> Wrapper<E> ok() {
        return new Wrapper<>();
    }
    /**
     * Ok wrapper.
     *
     * @param <E> the type parameter
     * @param o   the o
     * @return the wrapper
     */
    public static <E> Wrapper<E> ok(E o) {
        return new Wrapper<>(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, o);
    }
}


              3、修改Controller的返回值(以CheckMobileController为例)


/*
 * Copyright (c) 2019. zhanghan_java@163.com All Rights Reserved.
 * 项目名称:实战SpringBoot
 * 类名称:CheckMobileController.java
 * 创建人:张晗
 * 联系方式:zhanghan_java@163.com
 * 开源地址: https://github.com/dangnianchuntian/springboot
 * 博客地址: https://blog.csdn.net/zhanghan18333611647
 */
package com.zhanghan.zhboot.controller;
import com.mysql.jdbc.StringUtils;
import com.zhanghan.zhboot.controller.request.MobileCheckRequest;
import com.zhanghan.zhboot.properties.MobilePreFixProperties;
import com.zhanghan.zhboot.util.wrapper.WrapMapper;
import com.zhanghan.zhboot.util.wrapper.Wrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@Api(value = "校验手机号控制器",tags = {"校验手机号控制器"})
public class CheckMobileController {
    @Autowired
    private MobilePreFixProperties mobilePreFixProperties;
    @ApiOperation(value="优雅校验手机号格式方式",tags = {"校验手机号控制器"})
    @RequestMapping(value = "/good/check/mobile", method = RequestMethod.POST)
    public Wrapper goodCheckMobile(@RequestBody @Validated MobileCheckRequest mobileCheckRequest) {
        String countryCode = mobileCheckRequest.getCountryCode();
        String proFix = mobilePreFixProperties.getPrefixs().get(countryCode);
        if (StringUtils.isNullOrEmpty(proFix)) {
            return WrapMapper.error("参数错误");
        }
        String mobile = mobileCheckRequest.getMobile();
        Boolean isLegal = false;
        if (mobile.startsWith(proFix)) {
            isLegal = true;
        }
        Map map = new HashMap();
        map.put("mobile", mobile);
        map.put("isLegal", isLegal);
        map.put("proFix", proFix);
        return WrapMapper.ok(map);
    }
    @ApiOperation(value="扩展性差校验手机号格式方式",tags = {"校验手机号控制器"})
    @RequestMapping(value = "/bad/check/mobile", method = RequestMethod.POST)
    public Wrapper badCheckMobile(@RequestBody MobileCheckRequest mobileCheckRequest) {
        String countryCode = mobileCheckRequest.getCountryCode();
        String proFix;
        if (countryCode.equals("CN")) {
            proFix = "86";
        } else if (countryCode.equals("US")) {
            proFix = "1";
        } else {
            return WrapMapper.error("参数错误");
        }
        String mobile = mobileCheckRequest.getMobile();
        Boolean isLegal = false;
        if (mobile.startsWith(proFix)) {
            isLegal = true;
        }
        Map map = new HashMap();
        map.put("mobile", mobile);
        map.put("isLegal", isLegal);
        map.put("proFix", proFix);
        return  WrapMapper.ok(map);
    }
}


        三、效果展示:


              1、启动项目访问 http://localhost:8080/swagger-ui.html


              2、在swagger中访问 校验手机号控制器 中的方法


3672dc1b8ae866d46ca7565f1d6605c9_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTI4MjkxMjQ=,size_16,color_FFFFFF,t_70.png


        四、项目地址及代码版本:


              1、地址:https://github.com/dangnianchuntian/springboot


              2、代码版本:1.2.0-Release


【总结】


        1、约定重要性;


        2、观察在工作中最耗时的工作,不断优化,提高工作效率。


相关文章
|
14天前
|
JSON Java 数据格式
springboot中表字段映射中设置JSON格式字段映射
springboot中表字段映射中设置JSON格式字段映射
33 1
|
3月前
|
JSON Java API
解码Spring Boot与JSON的完美融合:提升你的Web开发效率,实战技巧大公开!
【8月更文挑战第29天】Spring Boot作为Java开发的轻量级框架,通过`jackson`库提供了强大的JSON处理功能,简化了Web服务和数据交互的实现。本文通过代码示例介绍如何在Spring Boot中进行JSON序列化和反序列化操作,并展示了处理复杂JSON数据及创建RESTful API的方法,帮助开发者提高效率和应用性能。
154 0
|
3月前
|
JSON Java API
Jackson:SpringBoot中的JSON王者,优雅掌控数据之道
【8月更文挑战第29天】在Java的广阔生态中,SpringBoot以其“约定优于配置”的理念,极大地简化了企业级应用的开发流程。而在SpringBoot处理HTTP请求与响应的过程中,JSON数据的序列化和反序列化是不可或缺的一环。在众多JSON处理库中,Jackson凭借其高效、灵活和强大的特性,成为了SpringBoot中处理JSON数据的首选。今天,就让我们一起深入探讨Jackson如何在SpringBoot中优雅地控制JSON数据。
124 0
|
4月前
|
文字识别 Java
文本,文字识别07,SpringBoot服务开发-入参和返回值,编写接口的时候,要注意识别的文字返回的是多行,因此必须是List集合,Bean层,及实体类的搭建
文本,文字识别07,SpringBoot服务开发-入参和返回值,编写接口的时候,要注意识别的文字返回的是多行,因此必须是List集合,Bean层,及实体类的搭建
|
4月前
|
JSON Java fastjson
Spring Boot返回Json数据及数据封装
本文详细介绍了如何在Spring Boot项目中处理JSON数据的传输 Spring Boot默认使用Jackson作为JSON处理器,并通过`spring-boot-starter-web`依赖自动包含相关组件。文章还展示了如何配置Jackson处理null值,使其转换为空字符串。此外,文章比较了Jackson和FastJson的特点,并提供了FastJson的配置示例,展示了如何处理null值以适应不同应用场景。
|
5月前
|
JSON 缓存 Java
Spring Boot中的JSON解析优化
Spring Boot中的JSON解析优化
|
6月前
|
JSON JavaScript 前端开发
Golang深入浅出之-Go语言JSON处理:编码与解码实战
【4月更文挑战第26天】本文探讨了Go语言中处理JSON的常见问题及解决策略。通过`json.Marshal`和`json.Unmarshal`进行编码和解码,同时指出结构体标签、时间处理、omitempty使用及数组/切片区别等易错点。建议正确使用结构体标签,自定义处理`time.Time`,明智选择omitempty,并理解数组与切片差异。文中提供基础示例及时间类型处理的实战代码,帮助读者掌握JSON操作。
172 1
Golang深入浅出之-Go语言JSON处理:编码与解码实战
|
6月前
|
JSON Java 数据格式
nbcio-boot升级springboot、mybatis-plus和JSQLParser后的LocalDateTime日期json问题
nbcio-boot升级springboot、mybatis-plus和JSQLParser后的LocalDateTime日期json问题
74 0
|
6月前
|
JSON JavaScript Java
从前端Vue到后端Spring Boot:接收JSON数据的正确姿势
从前端Vue到后端Spring Boot:接收JSON数据的正确姿势
293 0
|
6月前
|
JSON Java 数据处理
Spring Boot与Jsonson对象:灵活的JSON操作实战
【4月更文挑战第28天】在现代Web应用开发中,JSON数据格式的处理至关重要。假设 "Jsonson" 代表一个类似于Jackson的库,这样的工具在Spring Boot中用于处理JSON。本篇博客将介绍Spring Boot中处理JSON数据的基本概念,并通过实际例子展示如何使用类似Jackson的工具进行数据处理。
244 0