spring Boot手把手教学(8): 封装统一返回实体类

·  阅读 7049

1、前言

前情回顾:

目前为止,已经写了七篇关于 Spring boot 的文章,大多是都一些基础配置服务,工欲善其事,必先利其器。

在实际项目中,很多同事,总是忽略基础项目建设,觉得基础项目建设不重要,没有写业务代码重要。

个人觉得,基础服务也是很重要的,这是个人整体从上而下的知识积累,业务代码CRUD,写完也没有多大的能力提升,贵在总结吧。

文章写得或许有些许粗糙,望来往同学,切莫在意,不喜勿喷哈哈,欢迎多多指导。

废话不多说,

返回实体类的封装,今天就简单的介绍一下吧。

2、返回实体类

统一API响应结果封装:com.scaffold.test.base.Result

package com.scaffold.test.base;

import lombok.Data;

/**
 * 统一API响应结果封装
 */

@Data
public class Result {

    private int code;

    private String message = "success";

    private Object data;

    // 后面result生成器需要以下方法
    public Result setCode(ResultCode resultCode){
        this.code = resultCode.code;
        return this;
    }

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

    public Result setData(Object data){
        this.data = data;
        return this;
    }

}
复制代码

这里我们是用 lombok, @Data 注解,简化了实体类的GetterSetter

<!-- lombok 简化代码-->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <optional>true</optional>
</dependency>
复制代码

在实际项目中:

一般 Response 包含三个 KEY : code、message 和 data,固定的数据结构约定,方便和其他同事联调测试。

1. code

HTTP状态码(500 Server Error, 404 Not Fund 等等 1XX,2XX,3XX,4XX,5XX的各类错误 )

也有业务系统自定义的一些非标准状态码比如000000,999999,比较乱,建议还是以标准为好;

HTTP 状态码大全


1 消息
▪ 100 Continue
▪ 101 Switching Protocols
▪ 102 Processing


2 成功
▪ 200 OK
▪ 201 Created
▪ 202 Accepted
▪ 203 Non-Authoritative Information
▪ 204 No Content
▪ 205 Reset Content
▪ 206 Partial Content
▪ 207 Multi-Status




3 重定向
▪ 300 Multiple Choices
▪ 301 Moved Permanently
▪ 302 Move Temporarily
▪ 303 See Other
▪ 304 Not Modified
▪ 305 Use Proxy
▪ 306 Switch Proxy
▪ 307 Temporary Redirect




4 请求错误
▪ 400 Bad Request401 Unauthorized
▪ 402 Payment Required
▪ 403 Forbidden
▪ 404 Not Found
▪ 405 Method Not Allowed
▪ 406 Not Acceptable
▪ 407 Proxy Authentication Required
▪ 408 Request Timeout
▪ 409 Conflict
▪ 410 Gone
▪ 411 Length Required
▪ 412 Precondition Failed
▪ 413 Request Entity Too Large
▪ 414 Request-URI Too Long
▪ 415 Unsupported Media Type
▪ 416 Requested Range Not Satisfiable
▪ 417 Expectation Failed
▪ 418 I'm a teapot421 Misdirected Request422 Unprocessable Entity
▪ 423 Locked
▪ 424 Failed Dependency
▪ 425 Too Early
▪ 426 Upgrade Required
▪ 449 Retry With451 Unavailable For Legal Reasons




5 服务器错误
▪ 500 Internal Server Error501 Not Implemented
▪ 502 Bad Gateway
▪ 503 Service Unavailable
▪ 504 Gateway Timeout
▪ 505 HTTP Version Not Supported
▪ 506 Variant Also Negotiates
▪ 507 Insufficient Storage
▪ 509 Bandwidth Limit Exceeded
▪ 510 Not Extended
▪ 600 Unparseable Response Headers
复制代码

5 服务器错误 ▪ 500 Internal Server Error ▪ 501 Not Implemented ▪ 502 Bad Gateway ▪ 503 Service Unavailable ▪ 504 Gateway Timeout ▪ 505 HTTP Version Not Supported ▪ 506 Variant Also Negotiates ▪ 507 Insufficient Storage ▪ 509 Bandwidth Limit Exceeded ▪ 510 Not Extended ▪ 600 Unparseable Response Headers

2. data

data 返回的就是我们所需的数据,无论是 List 还是 Map, 都在这里返回;

// 查询所有
@GetMapping("/list")
public Result getList() {
   Result result;
   List<Job> jobList = jobService.findAll();
   result = ResultResponse.getSuccessResult(jobList);
   return result;
}
复制代码

3. message

message 返回的就是提示语,以便于作出友好提示

3、自定义响应码枚举

com.scaffold.test.base.ResultCode

package com.scaffold.test.base;

/**
 * 响应码枚举,对应HTTP状态码
 */

public enum ResultCode {
    SUCCESS(200),//成功
    FAIL(400),//失败
    UNAUTHORIZED(401),//未认证(签名错误)
    NOT_FOUND(404),//接口不存在
    INTERNAL_SERVER_ERROR(500);//服务器内部错误

    public int code;

    ResultCode(int code) {
        this.code = code;
    }

}

复制代码

4、响应结果生成类

package com.scaffold.test.base;

/**
 * 响应结果封装
 */

public class ResultResponse {
    private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";

    // 只返回状态
    public static Result getSuccessResult() {
        return new Result()
                .setCode(ResultCode.SUCCESS)
                .setMessage(DEFAULT_SUCCESS_MESSAGE);
    }

    // 成功返回数据
    public static Result getSuccessResult(Object data) {
        return new Result()
                .setCode(ResultCode.SUCCESS)
                .setMessage(DEFAULT_SUCCESS_MESSAGE)
                .setData(data);
    }

    // 失败
    public static Result getFailResult(String message) {
        return new Result()
                .setCode(ResultCode.FAIL)
                .setMessage(message);
    }
}

复制代码

这里有三种状态的方法,大抵是够用了;

第一种,是无需返回data, 比如只查询状态

// 无需data
@GetMapping("/status")
public Result status() {
  // 模拟无需data
  return ResultResponse.getSuccessResult();
}
复制代码

第二种是,请求获取数据成功

// 查询所有
@GetMapping("/list")
public Result getList() {
  Result result;
  List<Job> jobList = jobService.findAll();
  result = ResultResponse.getSuccessResult(jobList);
  return result;
}
复制代码

第三种是,请求获取失败信息

// 错误
@GetMapping("/err")
public Result err() {
  // 模拟错误
  return ResultResponse.getFailResult("模拟错误");
}
复制代码

5、完整代码

com.scaffold.test.base.Result: 统一API响应结果封装

package com.scaffold.test.base;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;

/**
 * 统一API响应结果封装
 */

@Data
// 非空返回
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class Result {

    private int code;

    private String message = "success";

    private Object data;

    public Result setCode(ResultCode resultCode){
        this.code = resultCode.code;
        return this;
    }

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

    public Result setData(Object data){
        this.data = data;
        return this;
    }

}

复制代码

com.scaffold.test.base.ResultCode: 响应码枚举

package com.scaffold.test.base;

/**
 * 响应码枚举,参考HTTP状态码的语义
 */

public enum ResultCode {
    SUCCESS(200),//成功
    FAIL(400),//失败
    UNAUTHORIZED(401),//未认证(签名错误)
    NOT_FOUND(404),//接口不存在
    INTERNAL_SERVER_ERROR(500);//服务器内部错误

    public int code;

    ResultCode(int code) {
        this.code = code;
    }

}

复制代码

com.scaffold.test.base.ResultResponse

package com.scaffold.test.base;

/**
 * 响应结果生成工具
 */

public class ResultResponse {
    private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";

    // 只返回状态
    public static Result getSuccessResult() {
        return new Result()
                .setCode(ResultCode.SUCCESS)
                .setMessage(DEFAULT_SUCCESS_MESSAGE);
    }

    // 成功返回数据
    public static Result getSuccessResult(Object data) {
        return new Result()
                .setCode(ResultCode.SUCCESS)
                .setMessage(DEFAULT_SUCCESS_MESSAGE)
                .setData(data);
    }

    // 失败
    public static Result getFailResult(String message) {
        return new Result()
                .setCode(ResultCode.FAIL)
                .setMessage(message);
    }
}

复制代码

com.scaffold.test.controller.JobController

package com.scaffold.test.controller;


import com.scaffold.test.base.Result;
import com.scaffold.test.base.ResultResponse;
import com.scaffold.test.base.ServiceException;
import com.scaffold.test.entity.Job;
import com.scaffold.test.service.JobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author alex wong
 * @since 2020-06-14
 */
@RestController
@RequestMapping("/job")
public class JobController {

    @Autowired
    private JobService jobService;

    // 查询所有
    @GetMapping("/list")
    public Result getList() {
        Result result;
        List<Job> jobList = jobService.findAll();
        result = ResultResponse.getSuccessResult(jobList);
        return result;
    }

    // 错误
    @GetMapping("/err")
    public Result err() {
        // 模拟错误
        return ResultResponse.getFailResult("模拟错误");
    }
    
    // 无需data
    @GetMapping("/status")
    public Result status() {
        // 模拟无需data
        return ResultResponse.getSuccessResult();
    }

}

复制代码

本文使用 mdnice 排版

分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改