java 接口返回json数据封装

前言

首先,采用的是springboot,在controller中使用了@RestController或者@ResponseBody注解,返回的数据本身就是json格式。但是这样的json串在前后端分离使用中并不满足实际的效果,因此需要进行相应的封装,以满足前端能够正确处理获取的数据。

一、准备

1.1 使用的是fastjson,因此需要pom文件引入包

版本随你

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.58</version>
</dependency>

1.2 统一的返回规范必不可少

一般情况下,状态、信息、数据这三项已经满足大部分需要。如果需求特殊可以自己修改。
序列化
值得说一下的是重写tostring时就将其转换为json串JSON.toJSONString(this);。本文所用的返回类进行了实例化,因此采用JSON.方法,也可以通过JSONObject(已经实现序列化,返回类不需要再次序列化)的方发进行转换。
在这里插入图片描述
为空处理
利用fastjson自带的注解来处理返回时无值得情况,统一显示为null。@JSONField(serialzeFeatures = {SerializerFeature.WriteMapNullValue})

import java.io.Serializable;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * 
 * @Description: 统一API响应结果封装
 * @author ZhiPengyu
 * @date: 2020年4月29日 下午2:48:18
 */
public class ResponseBody implements Serializable {
 
    /**
	 * 
	 */
	private static final long serialVersionUID = 1886106011131539131L;
	
	private String code;
    private String message;
    @JSONField(serialzeFeatures = {SerializerFeature.WriteMapNullValue})
    private Object data;
    
	/* set and get */
    public String getCode() {
        return code;
    }
 
    public void setCode(String code) {
        this.code = code;
    }
 
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
 
    public Object getData() {
        return data;
    }
 
    public void setData(Object data) {
        this.data = data;
    }
    
	/* 构造 */
    public ResponseBody() {
		super();
		// TODO Auto-generated constructor stub
	}

    public ResponseBody(String code, String message, Object data) {
		super();
		this.code = code;
		this.message = message;
		this.data = data;
	}

	/**
     * 默认成功或者失败,无数据
     * @param resultCode
     */
	public ResponseBody(ResultCode resultCode) {
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
    }
	
	/**
	 * 枚举结果以及获取数据
	 * @param resultCode
	 * @param data
	 */
	public ResponseBody(ResultCode resultCode,String message) {
        this.code = resultCode.getCode();
        this.message = message;
    }
	
	/**
	 * 枚举结果以及获取数据
	 * @param resultCode
	 * @param data
	 */
	public ResponseBody(ResultCode resultCode,Object data) {
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
        this.data = data;
    }
	
	@Override
	public String toString() {
		return JSON.toJSONString(this);
	}

}

二、封装

为了更好的进行操作,将操作细节隐藏封装。

2.1枚举

就是状态码的统一操作,这样是更加规范的,对前端也一样。

/**
 * 
 * @Description: 响应码枚举,参考HTTP状态码的语义
 * @author ZhiPengyu
 * @date: 2020年4月29日 上午9:27:40
 */
public enum ResultCode {
    /* 成功 */
    SUCCESS("200", "Success!"),
    /* 失败 */
    FAIL("400", "Failure!"),
    
	/* 参考HTTP状态码 */
    NO_PERMISSION("403", "Need Authorities!"),//没有权限
    LOGIN_NO("402", "Need Login!"),//未登录
    LOGIN_FAIL("401", "Login Failure!"),//登录失败
    LOGIN_SUCCESS("200", "Login Success!"),//登录成功
    LOGOUT_SUCCESS("200", "Logout Success!"),//退出登录
    SESSION_EXPIRES("101", "Session Expires!"),//会话到期
    SESSION_EXPIRES_OTHER_LOGIN("101", "Session Expires!Other users login!"),//会话到期,其他用户登录
    
    
    private String code;
    private String message;
    
    public String getCode() {
        return code;
    }

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

    public String getMessage() {
        return message;
    }

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

	/**
	 * 
	 * @param code
	 * @param message
	 */
    ResultCode(String code, String message) {
        this.code = code;
        this.message = message;
    }

}

2.2封装

利用**@Component**注解简化用户在返回数据是复杂复制操作,同时减少自定义的使用,以枚举为主,可以不断添加。

import org.springframework.stereotype.Component;

@Component
public class ResultGenerator{

	/**
	 * 默认成功,无数据
	 * @return
	 */
	public ResponseBody getSuccessResult() {
        return new ResponseBody(ResultCode.SUCCESS);
    }
	/**
	 * 默认成功,有数据
	 * @param data
	 * @return
	 */
	public ResponseBody getSuccessResult(Object data) {
        return new ResponseBody(ResultCode.SUCCESS,data);
    }
	/**
	 * 默认失败,无数据
	 * @return
	 */
	public ResponseBody getFailResult() {
        return new ResponseBody(ResultCode.FAIL);
    }
	/**
	 * 默认失败
	 * @param message 自定义失败信息
	 * @return
	 */
	public ResponseBody getFailResult(String message) {
        return new ResponseBody(ResultCode.FAIL,message);
    }
	
	/**
	 * 采用枚举中的状态无数据返回
	 * @param resultCode 响应码枚举
	 * @param data
	 * @return
	 */
	public ResponseBody getFreeResult(ResultCode resultCode) {
        return new ResponseBody(resultCode);
    }
	
	/**
	 * 采用枚举中的状态带数据返回
	 * @param resultCode 响应码枚举
	 * @param data
	 * @return
	 */
	public ResponseBody getFreeResult(ResultCode resultCode, Object data) {
        return new ResponseBody(resultCode, data);
    }

	/**
	 * 自定义返回信息
	 * @param code 响应码
	 * @param message 自定义失败信息
	 * @param data
	 * @return
	 */
	public ResponseBody getFreeResult(String code, String message, Object data) {
        return new ResponseBody(code, message, data);
    }

}

三、使用

以往都是在controller进行new操作同时,此时可以通过**@Autowired**注解调用并直接赋值返回。
在这里插入图片描述
如上图所示,通过不同的方式进行对比。

3.1未完全封装

@PreAuthorize("hasRole('ROLE_admin')")
	@RequestMapping(value = "getSysUserAdmin")
	public ResponseBody getSysUserAdmin() {
		ResponseBody responseBody = new ResponseBody();
	    responseBody.setCode("200");
	    responseBody.setMessage("Sccess!");
		List<SysUser> sysUser = sysUserService.select(null, null);
		responseBody.setData(JSON.toJSONString(sysUser));
		
		return responseBody;
	}
{
    "code": "200",
    "message": "Sccess!",
    "data": "[{\"company\":\"科研诚信\",\"createtime\":1586942036000,\"parentName\":\"admin\",\"password\":\"$2a$10$XlftNY9T52IbLlVAT6Nx7ezyYlcSFkVzC.3n3h5jihyzo1g/KtAPa\",\"pwdRole\":1,\"role\":2,\"status\":1,\"uploadAmount\":3,\"uploadResidue\":0,\"userId\":27,\"userIp\":\"89\",\"username\":\"admin1\"}]"
}

3.2完全封装

可以看出差距还是不小的。

@Autowired
	ResultGenerator resultGenerator;

	@RequestMapping(value = "testjson")
	public ResponseBody testjson() {
		List<SysUser> sysUser = sysUserService.selectSysUserByUnameOrCompany(null, null);
		return resultGenerator.getSuccessResult(sysUser);
	}
{
    "code": "200",
    "message": "Success!",
    "data": [
        {
            "userId": 27,
            "username": "admin1",
            "password": "$2a$10$XlftNY9T52IbLlVAT6Nx7ezyYlcSFkVzC.3n3h5jihyzo1g/KtAPa",
            "parentName": "admin",
            "company": "科研诚信",
            "cpyBranch": null,
            "userIp": "89",
            "uploadAmount": 3,
            "uploadResidue": 0,
            "status": 1,
            "role": 2,
            "pwdRole": 1,
            "createtime": "2020-04-15T09:13:56.000+0000",
            "startTime": null,
            "endTime": null,
            "phoneNumber": null,
            "mail": null,
            "remark": null
        }
    ]
}

四、总结

此文是在查看一些文章之后的总结修改,大同小异,方式多种多样。再次仅说了一种,那些地方说不不对,还请留言矫正啊。

  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值