企业实战之spring项目《接口响应体格式统一封装》

本文探讨了在Spring项目中如何统一接口响应体格式,通过分析问题、提出实现思路并展示具体代码实现,包括Result接口、PlatformResult通用结果、DefaultErrorResult全局错误格式、GlobalExceptionHandler异常处理器、ResponseResult注解、ResponseResultInterceptor拦截器和ResponseResultHandler响应体处理器,最终实现了接口返回值格式控制功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在之前的文章中我们有介绍过,如何更好、更简单的写好一个接口(接口返回值篇),今天的这篇文章我们主要介绍,怎么统一处理下接口的返回格式问题。

问题分析

我们先来分析下我们所面临的问题在哪里,然后接着给出解决方案。在写一个接口时,我们通常会先统一定义一下接口的返回格式是什么,然后在跟前端去对接,通常的返回格式大体两种(我们以保存用户为例):

1. 成功/失败响应格式不一致(此种方式作为我们默认的接口响应方式)
  • 保存用户成功,响应体
{
   
   
    "id": 10000,
    "pwd": "123456",
    "nickname": "小竹马",
    "img": "http://avatar.youkuaiyun.com/0/E/9/1_aiyaya_.jpg",
    "status": "NORMAL",
    "createTime": 1515075974540
}
  • 失败响应体(下面的格式是spring boot默认的错误响应格式,只不过我们在其基础上增加了一个code字段用于解释更详细的错误码)
{
   
   
    "status": 400,
    "error": "Bad Request",
    "message": "参数无效",
    "code": 10001,
    "path": "/zhuma-demo/users",
    "exception": "org.springframework.web.bind.MethodArgumentNotValidException",
    "errors": [
        {
   
   
            "fieldName": "status",
            "message": "值是无效的"
        }
    ],
    "timestamp": 1515076067369
}
2.成功/失败响应体格式一致
  • 保存用户成功,响应体
{
   
   
    "code": 1,
    "msg": "成功",
    "data": {
   
   
        "id": 10000,
        "pwd": "123456",
        "nickname": "小竹马",
        "img": "http://avatar.youkuaiyun.com/0/E/9/1_aiyaya_.jpg",
        "status": "NORMAL",
        "createTime": 1515076287882
    }
}
  • 失败响应体
{
   
   
    "code": 10001,
    "msg": "参数无效",
    "data": [
        {
   
   
            "fieldName": "status",
            "message": "值是无效的"
        }
    ]
}

那么如果我们想要的响应体格式是第二种,我们该如何写我们的代码呢?你可能想是这样么?

@RestController
@RequestMapping("/users")
public class UserController {
   
   

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public PlatformResult addUser(@Validated @RequestBody User user) {
   
   
        user.setId(10000L);
        user.setCreateTime(new Date());
        return PlatformResult.success(user);
    }

}

PlatformResult.success()这段逻辑显然很多余,每个方法都要这样写一遍,所以上述方式并不是我们想要的,我们要的是

@ResponseResult(PlatformResult.class)
@RestController
@RequestMapping("/users")
public class UserController {
   
   

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User addUser(@Validated @RequestBody User user) {
   
   
        user.setId(10000L);
        user.setCreateTime(new Date());
        return user;
    }

}

我们加了一个自定义的注解@ResponseResult(PlatformResult.class),参数PlatformResult.class告诉这个Controller类下的所有方法都以这个类PlatformResult的格式进行返回,这个注解可以标记在类或方法上,好了,我们的目的明朗了许多,要做的就是标记这个注解让它实现接口返回值格式控制这个功能,下面我们给出具体的实现方式。

实现思路

首先介绍下完成我们这次主要功能的几个类:

  1. Result 是返回格式类的父接口(所有返回格式类都需要继承它)
  2. PlatformResult 通用返回结果格式(我们上面说的第二种返回结果)
  3. DefaultErrorResult 全局错误返回结果(我们上面说的第一种错误时的返回结果)
  4. GlobalExceptionHandler全局异常处理
  5. ResponseResult 注解类(用于在Controller上指定返回值格式类)
  6. ResponseResultInterceptor 拦截器(主要用于将ResponseResult注解类的标记信息传入ResponseResultHandler中)
  7. ResponseResultHandler 响应体格式处理器(主要转换逻辑都在这里)

代码实现

下面将有一大片代码袭来,要顶住!O(∩_∩)O哈哈~

1. Result 接口类
package com.zhuma.demo.comm.result;

import java.io.Serializable;

/**
 * @desc 响应格式父接口
 *
 * @author zhumaer
 * @since 4/1/2018 3:00 PM
 */
public interface Result extends Serializable {
   
   
}

说明
理论上所有的返回格式类都需要实现该接口才能被使用

2. PlatformResult 通用返回结果
package com.zhuma.demo.comm.result;

import com.zhuma.demo.enums.ResultCode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @desc 平台通用返回结果
 * 
 * @author zhumaer
 * @since 10/9/2017 3:00 PM
 */
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class PlatformResult implements Result {
   
   

	private static final long serialVersionUID = 874200365941306385L;

	private Integer code;

	private String msg;

	private Object data;

	public static PlatformResult success() {
   
   
		PlatformResult result = new PlatformResult();
		result.setResultCode(ResultCode.SUCCESS);
		return result;
	}

	public static PlatformResult success(Object data) {
   
   
		PlatformResult result = new PlatformResult();
		result.setResultCode(ResultCode.SUCCESS);
		result.setData(data);
		return result;
	}

	public static PlatformResult failure(ResultCode resultCode) {
   
   
		PlatformResult result = new PlatformResult();
		result.setResultCode(resultCode);
		return result;
	}

	public static PlatformResult failure(ResultCode resultCode, Object data) {
   
   
		PlatformResult result = new PlatformResult();
		result.setResultCode(resultCode);
		result.setData(data);
		return result;
	}

	public static PlatformResult failure(String message) {
   
   
		PlatformResult result = new PlatformResult();
		result.setCode(ResultCode.PARAM_IS_INVALID.code());
		result.setMsg(message);
		return result;
	}

	private void 
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值