请教如何有效的使用 ResponseEntity? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Vimax
V2EX    Java

请教如何有效的使用 ResponseEntity?

  •  
  •   Vimax 2020-06-24 10:57:35 +08:00 4063 次点击
    这是一个创建于 2018 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ResponseEntity 标识整个 http 相应:状态码、头部信息以及相应体内容。因此我们可以使用其对 http 响应实现完整配置。

    目前打算使用 ResponseEntity 替代自定义实体响应对象。请教下如何有效的使用 ResponseEntity,比如@ResponseEntity如何自定义返回业务的错误码?以及推荐使用 ResponseEntity 作为返回对象吗?

    之前都是通过自定义code,msg,data属性对象,通过@ResponseBody返回给前端。

    spring 封装了很多好用的东西,所以打算尝试下@ResponseEntity

     @GetMapping("{id}") public ResponseEntity<UserInfo> getUserById(@PathVariable("id") Long id) { UserInfo user = userInfoService.getById(id); boolean flag = ObjectUtils.isEmpty(user); if (flag) { return ResponseEntity.notFound().build(); } return ResponseEntity.ok(user); } 

    上面的根据 id 查询用户,查询到内容就返回 200 状态码,查询不到就返回 404 。

    但是有些业务有多个错误类型,这时用 ResponseEntity,只能返回 http 状态码就显得有些不足。

    如果再封装个返回类型,ResponseResult 对象,里面存msg,code,data

    @Data @NoArgsConstructor public class ResponseResult<T> { @NonNull private Integer code; @NonNull private String msg; private T data; } 

    然后再用ResponseEntity<ResponseResult>封装返回给前端。

     @GetMapping("{id}") public ResponseEntity<ResponseResult<UserInfo>> getUserById(@PathVariable("id") Long id) { UserInfo user = userInfoService.getById(id); boolean flag = ObjectUtils.isEmpty(user); if (flag) { return ResponseEntity.notFound().build(); } ResponseResult<UserInfo> userResult = new ResponseResult(); userResult.setData(user); return ResponseEntity.ok(userResult); } 

    这样会不会多此一举,不如直接用@ResponseBody返回ResponseResult就可以了。

    当然,ResponseEntity 好处是可以返回 404 这些浏览器状态码。

    第 1 条附言    2020-06-24 13:12:33 +08:00
    采纳 3L 的回答。
    4 条回复    2020-06-24 13:11:35 +08:00
    hantsy
        1
    hantsy  
       2020-06-24 11:06:20 +08:00
    这种封装 ResponseResult 是脱了裤子放屁。
    Oktfolio
        2
    Oktfolio  
       2020-06-24 11:11:45 +08:00   1
    package com.oktfolio.tero.common;

    import com.fasterxml.jackson.annotation.JsonFormat;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.google.common.base.Strings;
    import com.oktfolio.tero.common.enums.ResultCode;
    import com.oktfolio.tero.common.enums.ResultCodeEnum;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;

    import javax.annotation.Nonnull;
    import javax.annotation.Nullable;
    import java.time.LocalDateTime;
    import java.util.Objects;

    /**
    * @author oktfolio [email protected]
    * @date 2020/06/08
    */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class ResultEntity<T> {
    protected String code;
    protected String message;
    protected T data;
    protected HttpStatus status;
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
    protected LocalDateTime datetime;

    public String getCode() {
    return code;
    }

    public String getMessage() {
    return message;
    }

    public T getData() {
    return data;
    }

    public HttpStatus getStatus() {
    return status;
    }

    public LocalDateTime getDatetime() {
    return datetime;
    }

    private ResultEntity() {
    }

    public ResultEntity(String code, String message, T data, HttpStatus status, LocalDateTime datetime) {
    this.code = code;
    this.message = message;
    this.data = data;
    this.status = status;
    this.datetime = datetime;
    }

    public static Builder builder() {
    return new Builder();
    }

    public static class Builder {

    protected String code;
    protected String message;
    protected HttpStatus status;
    protected LocalDateTime datetime;

    public Builder code(String code) {
    this.code = code;
    return this;
    }

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

    public Builder datetime(LocalDateTime datetime) {
    this.datetime = datetime;
    return this;
    }

    public Builder status(@Nonnull HttpStatus status) {
    this.status = status;
    return this;
    }

    public <T> ResultEntity<T> data(@Nullable T data) {
    return new ResultEntity<>(code, message, data, status, datetime);
    }

    public <T> ResultEntity<T> build() {
    return this.data(null);
    }

    }

    public static <T> ResultEntity<T> ok() {
    return ResultEntity.builder()
    .status(HttpStatus.OK)
    .build();
    }

    public static <T> ResultEntity<T> created() {
    return ResultEntity.builder()
    .status(HttpStatus.CREATED)
    .build();
    }

    public static <T> ResultEntity<T> noContent() {
    return ResultEntity.builder()
    .status(HttpStatus.NO_CONTENT)
    .build();
    }

    public static <T> ResultEntity<T> ok(T data) {
    return ResultEntity.builder()
    .status(HttpStatus.OK)
    .datetime(LocalDateTime.now())
    .data(data);
    }

    public static <T> ResultEntity<T> created(T data) {
    return ResultEntity.builder()
    .status(HttpStatus.CREATED)
    .data(data);
    }

    public static <T> ResultEntity<T> of(@Nonnull ResultCode resultCode) {
    return ResultEntity.builder()
    .status(resultCode.status())
    .code(resultCode.value())
    .message(resultCode.message())
    .datetime(LocalDateTime.now())
    .build();
    }

    public static <T> ResultEntity<T> error() {
    return ResultEntity.builder()
    .status(ResultCodeEnum.ERROR.status())
    .code(ResultCodeEnum.ERROR.value())
    .message(ResultCodeEnum.ERROR.message())
    .datetime(LocalDateTime.now())
    .build();
    }

    public static <T> ResultEntity<T> error(@Nonnull HttpStatus status, @Nonnull String message) {
    return ResultEntity.builder()
    .status(status)
    .code(ResultCodeEnum.ERROR.value())
    .message(message)
    .datetime(LocalDateTime.now())
    .build();
    }

    public static <T> ResultEntity<T> notFound(@Nonnull ResultCode resultCode) {
    return ResultEntity.builder()
    .status(HttpStatus.NOT_FOUND)
    .code(resultCode.value())
    .message(resultCode.message())
    .datetime(LocalDateTime.now())
    .build();
    }

    public static <T> ResultEntity<T> badRequest(@Nonnull ResultCode resultCode) {
    return ResultEntity.builder()
    .status(HttpStatus.BAD_REQUEST)
    .code(resultCode.value())
    .message(resultCode.message())
    .build();
    }

    public static <T> ResultEntity<T> unauthorized(@Nonnull ResultCode resultCode) {
    return ResultEntity.builder()
    .status(HttpStatus.UNAUTHORIZED)
    .code(resultCode.value())
    .message(resultCode.message())
    .datetime(LocalDateTime.now())
    .build();
    }

    public static <T> ResultEntity<T> unauthorized(String message) {
    return ResultEntity.builder()
    .status(HttpStatus.UNAUTHORIZED)
    .code(ResultCodeEnum.ERROR.value())
    .message(message)
    .datetime(LocalDateTime.now())
    .build();
    }

    public static <T> ResultEntity<T> forbidden(@Nonnull ResultCode resultCode) {
    return ResultEntity.builder()
    .status(HttpStatus.FORBIDDEN)
    .code(resultCode.value())
    .message(resultCode.message())
    .datetime(LocalDateTime.now())
    .build();
    }

    public static <T> ResultEntity<T> created(@Nonnull ResultCode resultCode) {
    return ResultEntity.builder()
    .status(HttpStatus.CREATED)
    .code(resultCode.value())
    .message(resultCode.message())
    .build();
    }

    public static <T> ResultEntity<T> internalServerError() {
    return ResultEntity.builder()
    .status(ResultCodeEnum.INTERNAL_SERVER_ERROR.status())
    .code(ResultCodeEnum.INTERNAL_SERVER_ERROR.value())
    .message(ResultCodeEnum.INTERNAL_SERVER_ERROR.message())
    .datetime(LocalDateTime.now())
    .build();
    }

    public static <T> ResultEntity<T> internalServerError(@Nonnull ResultCode resultCode) {
    return ResultEntity.builder()
    .status(HttpStatus.INTERNAL_SERVER_ERROR)
    .code(resultCode.value())
    .message(resultCode.message())
    .datetime(LocalDateTime.now())
    .build();
    }

    public ResponseEntity<Object> responseEntity() {
    if (Objects.isNull(this.data)
    && Strings.isNullOrEmpty(this.code)
    && Strings.isNullOrEmpty(this.message)
    && !Objects.isNull(this.status)) {
    return new ResponseEntity<>(this.getStatus());
    } else {
    return new ResponseEntity<>(this, this.getStatus());
    }
    }
    }

    我是这么玩的。
    hantsy
        3
    hantsy  
       2020-06-24 11:15:12 +08:00   2
    业务中所有正常路径直接返回,全部需要 Http Status 标志。如 200,201,204 。

    使用 Spring 时,所有的异常路径可以封装成 Exception,集成处理。

    Exception 处理除了要反应正确的 Http Status (常见的,除了一些安全框架 401,403 外,如 404,400,409,422 等),还可以带常见的辅助信息。如果非常要一个所谓的业务异常代码,在异常处理中加入。

    https://github.com/hantsy/spring-microservice-sample/blob/master/post-service/src/main/java/com/hantsylabs/sample/springmicroservice/post/PostExceptionHandler.java#L31
    Vimax
        4
    Vimax  
    OP
       2020-06-24 13:11:35 +08:00
    @hantsy 采纳并学习。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2465 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 07:10 PVG 15:10 LAX 23:10 JFK 02:10
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86