强烈推荐一个大神的人工智能的教程:http://www.captainbed.net/zhanghan
【前言】
前后端分离是现在系统开发主流模式,上篇博文《SpringBoot集成Swagger》介绍了利器Swagger;这篇接着定义返回Json格式的规范;无规矩,不成方圆;有了好的规范前后端的开发效率将大大提高;
【返回Json结果规范化】
一、规范化的必要性
1、未规范化痛点:
返回格式杂乱,前后端不能用统一的工具类去处理,极大拖延联调进度;
2、规范化爽点:
返回格式统一,前后端都可以用统一的工具类去处理,极大推进了联调进度;
二、如何改造:
1、项目中增加Wrapper
/*
* Copyright (c) 2019. [email protected] All Rights Reserved.
* 项目名称:实战SpringBoot
* 类名称:Wrapper.java
* 创建人:张晗
* 联系方式:[email protected]
* 开源地址: 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. [email protected] All Rights Reserved.
* 项目名称:实战SpringBoot
* 类名称:WrapMapper.java
* 创建人:张晗
* 联系方式:[email protected]
* 开源地址: 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. [email protected] All Rights Reserved.
* 项目名称:实战SpringBoot
* 类名称:CheckMobileController.java
* 创建人:张晗
* 联系方式:[email protected]
* 开源地址: 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、观察在工作中最耗时的工作,不断优化,提高工作效率。