强烈推荐一个大神的人工智能的教程: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中访问 校验手机号控制器 中的方法
四、项目地址及代码版本:
1、地址:https://github.com/dangnianchuntian/springboot
2、代码版本:1.2.0-Release
【总结】
1、约定重要性;
2、观察在工作中最耗时的工作,不断优化,提高工作效率。