SpringMVC(三十四):统一响应消息体

star2017 1年前 ⋅ 245 阅读

Spring MVC API 接口响应的消息体最好统一结构,便于前端识别和规范。

方式一

ResponseVO

public class ResponseVO<T> {

    private int status;     // 返回状态
    private String message; // 描述信息
    private T data;         // 数据

    public ResponseVO() {}

    public ResponseVO(HttpStatusEnum httpStatus) {
        this.status = httpStatus.status();
        this.message = httpStatus.message();
    }
    public ResponseVO(HttpStatusEnum httpStatus, T data) {
        this.status = httpStatus.status();
        this.message = httpStatus.message();
        this.data = data;
    }

    public ResponseVO(int status, String message) {
        this.status = status;
        this.message = message;
    }
    public ResponseVO(int status, String message, T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }
    public ResponseVO(T data) {
        this.status = HttpStatusEnum.SUCCESS.status();
        this.message = HttpStatusEnum.SUCCESS.message();
        this.data = data;
    }

    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }
}

ResponseEntity

Spring Http 也提供了响应体类 ResponseEntity,在响应给前端时也可直接使用返回 ResponseEntity 对象,传入数据。

ResponseEntity 扩展自 HttpEntity,增加了 HttpStatus 状态码。可在 RestTemplate 或 @Controller 注解类中的方法中使用。

RestTemplate 的 getForEntity()exchange() 方法返回的就是 ResponseEntity 实例。如下示例

ResponseEntity<String> entity = template.getForEntity("http://example.com", String.class);
String body = entity.getBody();
MediaType contentType = entity.getHeaders().getContentType();
HttpStatus statusCode = entity.getStatusCode();

还可以在 Spring MVC 中使用,作为 @Controller 方法的返回值:

@RequestMapping("/handle")
public ResponseEntity<String> handle() {
    URI location = ...;
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setLocation(location);
    responseHeaders.set("MyResponseHeader", "MyValue");
    return new ResponseEntity&lt;String&gt;("Hello World", responseHeaders, HttpStatus.CREATED);
}

或通过静态方法调用构建器来访问:

@RequestMapping("/handle")
public ResponseEntity<String> handle() {
    URI location = ...;
    return ResponseEntity.created(location).header("MyResponseHeader", "MyValue").body("Hello World");
}

ResponseHelper

public class ResponseHelper {

    public final static void execption(HttpStatusEnum httpStatus) {
        throw new RestException(httpStatus);
    }
    public final static void execption(HttpStatusEnum httpStatus, Object data) {
        throw new RestException(httpStatus, data);
    }

    public final static void execption(int status, String message) {
        throw new RestException(status, message);
    }
    public final static void execption(int status, String message, Object data) {
        throw new RestException(status, message, data);
    }

    /**
     * 服务端处理成功
     *
     * @param <T>
     * @return ResponseVO
     */
    public final static <T> ResponseVO<T> success(T data) {
        return new ResponseVO<T>(data);
    }

    /**
     * 服务端校验失败(请求数据语义有误)
     *
     * @param <T>
     * @return ResponseVO
     */
    public final static <T> ResponseVO<T> badRequest(T data) {
        return new ResponseVO<T>(HttpStatusEnum.BAD_REQUEST, data);
    }

    /**
     * 服务端校验失败(请求数据语义有误)
     *
     * @param message
     * @return ResponseVO
     */
    public final static <T> ResponseVO<T> badRequest(String message) {
        return new ResponseVO<T>(HttpStatusEnum.BAD_REQUEST.status(), message);
    }

    /**
     * 服务端校验数据冲突(数据重复...)
     *
     * @param <T>
     * @return ResponseVO
     */
    public final static <T> ResponseVO<T> conflict(T data) {
        return new ResponseVO<T>(HttpStatusEnum.CONFLICT, data);
    }

    /**
     * 服务端校验数据冲突(数据重复...)
     *
     * @param message
     * @return ResponseVO
     */
    public final static <T> ResponseVO<T> conflict(String message) {
        return new ResponseVO<T>(HttpStatusEnum.CONFLICT.status(), message);
    }

    /**
     * 服务端内部错误
     *
     * @param <T>
     * @return ResponseVO
     */
    public final static <T> ResponseVO<T> error(T data) {
        return new ResponseVO<T>(HttpStatusEnum.INTERNAL_SERVER_ERROR, data);
    }

    /**
     * 服务端内部错误
     *
     * @param message
     * @return ResponseVO
     */
    public final static <T> ResponseVO<T> error(String message) {
        return new ResponseVO<T>(HttpStatusEnum.INTERNAL_SERVER_ERROR.status(), message);
    }

    /**
     * 无权限
     *
     * @param <T>
     * @return ResponseVO
     */
    public final static <T> ResponseVO<T> unauthorized(T data) {
        return new ResponseVO<T>(HttpStatusEnum.UNAUTHORIZED, data);
    }

    /**
     * 无权限
     *
     * @param message
     * @return ResponseVO
     */
    public final static <T> ResponseVO<T> unauthorized(String message) {
        return new ResponseVO<T>(HttpStatusEnum.UNAUTHORIZED.status(), message);
    }
}

HttpStatusEnum

Http 状态码 及 Spring Http 状态码枚举

统一响应消息体

在使用时,可返回 new ResponseVO(data),也可使用 ResponseHelper 调用静态方法,传入数据。

方式二

ResponseModel

@Data
public class ResponseModel<T> {

    @JsonIgnore
    public static final int SUCCESS_CODE = 200;

    private int code = SUCCESS_CODE;

    private String message = "success";

    private T result;

    @JsonIgnore
    public static ResponseModel<?> success() {
        return new ResponseModel<>();
    }

    @JsonIgnore
    public static ResponseModel<?> success(String message) {
        return new ResponseModel<>(message);
    }

    @JsonIgnore
    public static <T> ResponseModel<T> success(T result) {
        return new ResponseModel<>(result);
    }

    @JsonIgnore
    public static <T> ResponseModel<T> success(String message, T result) {
        return new ResponseModel<>(message, result);
    }

    @JsonIgnore
    public static ResponseModel<?> fail() {
        return new ResponseModel<>(SystemErrorCode.SYS_INTERNAL_ERROR);
    }

    @JsonIgnore
    public static ResponseModel<?> fail(ErrorCode errorCode) {
        return new ResponseModel<>(errorCode.getCode(), errorCode.getMessage());
    }

    @JsonIgnore
    public static <T> ResponseModel<T> fail(ErrorCode errorCode, T result) {
        return new ResponseModel<>(errorCode, result);
    }

    @JsonIgnore
    public static <T> ResponseModel<T> fail(T result) {
        return new ResponseModel<>(SystemErrorCode.SYS_INTERNAL_ERROR, result);
    }

    @JsonIgnore
    public static ResponseModel<?> fail(String message) {
        return new ResponseModel<>(SystemErrorCode.SYS_INTERNAL_ERROR.getCode(), message);
    }

    public static ResponseModel<?> duplicateKey() {
        return duplicateKey(SystemErrorCode.REQ_PARAM_DUPLICATE_KEY.getMessage());
    }

    public static ResponseModel<?> duplicateKey(String message) {
        return new ResponseModel<>(SystemErrorCode.REQ_PARAM_DUPLICATE_KEY.getCode(), message);
    }


    public ResponseModel() {
    }

    public ResponseModel(T result) {
        this.result = result;
    }

    public ResponseModel(String message, T result) {
        this.message = message;
        this.result = result;
    }

    public ResponseModel(ErrorCode errorCode) {
        this.code = errorCode.getCode();
        this.message = errorCode.getMessage();
    }

    public ResponseModel(ErrorCode errorCode, T result) {
        this.code = errorCode.getCode();
        this.message = errorCode.getMessage();
        this.result = result;
    }

    public ResponseModel(BusinessException ex) {
        this.code = ex.getCode();
        this.message = ex.getMessage();
    }

    public ResponseModel(String message) {
        this.message = message;
    }

    public ResponseModel(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public ResponseModel(int code, String message, T result) {
        this.code = code;
        this.message = message;
        this.result = result;
    }

    @JsonIgnore
    public boolean isSuccess() {
        return this.code == SUCCESS_CODE;
    }
}

SystemErrorCode

/**
 * Copyright © 2018 深圳市巨鼎医疗设备有限公司
 */
package com.clearofchina.core.model;

/**
 * 系统错误码
 *
 * @author Zhouych
 * @date 2020年4月1日 上午10:03:51 <br/>
 * @since V1.0.0
 */
public enum SystemErrorCode implements ErrorCode {

    SYS_INTERNAL_ERROR(500, "系统异常"),

    SYS_REQUEST_PARAM_ERROR(400, "请求参数有误"),

    SYS_UNAUTHORIZED(401, "系统未授权"),

    SYS_FORBIDDEN(403, "权限不足"),

    SYS_UNSUPPORTED_METHOD(405, "不支持的请求方法"),

    REQ_URI_NOT_FOUND(404, "请求路径不存在"),

    REQ_METHOD_NOT_SUPPORT(405, "请求类型不支持"),

    REQ_PARAM_DUPLICATE_KEY(406, "请求参数已存在"),

    REQ_PARAM_CANT_BE_EMPTY(407, "必传参数不能为空"),

    REQ_PARAM_TYPE_ERROR(408, "请求参数类型错误或必传为空"),

    REQ_PARAM_LENGTH_OUT_OF_RANGE(409, "参数长度超出限制"),

    REQ_MSG_NOT_READABLE(410, "请求数据不可读(为空或格式异常)"),

    REQ_PARAM_ID_CANT_BE_NULL(411, "请求参数 id 不能为空"),

    UPLOAD_FILE_SIZE_OUT_OF_MAX_LIMIT(412, "上传文件大小超出最大限制"),

    UPLOAD_FILE_FAIL(414, "上传文件失败"),

    REQ_BODY_SIZE_OUT_OF_MAX_LIMIT(413, "请求报文大小超出最大限制"),

    UPDATE_DATA_NOT_FOUND(430, "要更新的数据不存在"),

    DELETE_DATA_NOT_FOUND(431, "要删除的数据不存在");

    private int code;

    private String message;

    private SystemErrorCode(int code, String message) {
        this.code = code;
        this.message = message;
    }

    @Override
    public int getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return message;
    }

    @Override
    public SystemErrorCode parse(int code) {
        SystemErrorCode[] values = SystemErrorCode.values();
        for (SystemErrorCode value : values) {
            if (value.getCode() == code) {
                return value;
            }
        }
        return null;
    }
}

ErrorCode

public interface ErrorCode {

    /**
     * 获取错误码
     * 
     * @return
     */
    int getCode();

    /**
     * 获取错误信息
     * 
     * @return
     */
    String getMessage();

    /**
     * 根据错误码反推错误信息
     * 
     * @param code
     * @return
     */
    ErrorCode parse(int code);
}
更多内容请访问:IT源点

相关文章推荐
  • 该目录下还没有内容!

全部评论: 0

    我有话说: