SpringBoot 项目中 标准化 Json 的返回

在项目中我们往往会规定后台向前端传输数据的格式,比如下面这个

{
  "code": 0,
  "msg": "成功",
  "data": {
    "***": "****"
    ...
  }
}

最外层有三个字段,code,msg,和data,全部主要数据都放进data里,这样更加的规范可控

1.创建一个用于返回的类  ResultVO

/**
 * http请求返回的最外层对象
 * @author: 林之谦
 * @date: 2018/7/27
 * @description:
 */
@Data
//@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResultVO<T> implements Serializable {


    private static final long serialVersionUID = 1451589387303987463L;

    /** 错误码 */
    private Integer code;

    /** 提示信息 */
    private String msg;

    /** 返回的具体内容 */
    private T data;
}

2.创建一个枚举类,用于规定返回的结果的类型 ResultEnum

/**
 * @author: 林之谦
 * @date: 2018/7/27
 * @description:
 */

@Getter
public enum  ResultEnum {
    SUCCESS(0,"成功"),

    PARAM_ERROR(1,"参数不正确"),

    PRODUCT_NOT_EXIST(10,"商品不存在"),

    PRODUCT_STOCK_ERROR(11,"商品库存不正确"),

    ORDER_NOT_EXIST(12,"订单不存在"),

    ORDERDETAIL_NOT_EXIST(13,"订单详情不存在"),

    ORDER_STATUS_ERROR(14,"订单状态不正确"),

    ORDER_UPDATE_FAIL(15,"订单更新失败"),

    ORDER_DETAIL_EMPTY(16,"订单详情为空"),

    ORDER_PAY_STATUS_ERROR(17,"订单支付状态不正确"),

    CAR_EMPTY(18,"购物车为空"),

    ORDER_OWNER_ERROR(19,"该订单不属于当前用户"),

    WECHAT_MP_ERROR(20,"微信公众账号方面错误"),

    WXPAY_NOTIFY_MONEY_VERIFY_ERROR(21,"微信支付异步通知金额校验不通过"),

    ORDER_CANCEL_SUCCESS(22,"订单取消成功"),

    ORDER_FINISH_SUCCESS(23,"订单完结成功"),

    PRODUCT_STATUS_ERROR(24,"商品状态不正确"),

    PRODUCT_ON_SALE_SUCCESS(25,"商品上架成功"),

    PRODUCT_OFF_SALE_SUCCESS(26,"商品下架成功"),

    LOGIN_FAIL(27,"登录失败,登陆信息不正确"),

    LOGOUT_SUCCESS(28,"登出成功"),
    ;
    private Integer code;

    private String msg;

    ResultEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

3.创建一个用于生成返回对象的工具类 ResultVOUtil

成功的返回就只有 0,成功 这个选择,但是失败的种类多种多样

/**
 * @author: 林之谦
 * @date: 2018/7/27
 * @description:
 */

public class ResultVOUtil {

    public static ResultVO success(Object object){
        ResultVO resultVO = new ResultVO();
        resultVO.setData(object);
        resultVO.setCode(0);
        resultVO.setMsg("成功");
        return resultVO;
    }

    public static ResultVO success(){
        return success(null);
    }

    public static ResultVO error(Integer code,String msg){
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(code);
        resultVO.setMsg(msg);
        return resultVO;
    }
}

4.创建一个ResultVO 中 data 的使用类,例如我们的data要放入产品信息的话,就创建一个 ProductInfoVO

这种VO里面的属性只填前端需要的,用@JsonProperty注解声明在Json中该属性的名字

/**
 * 商品详情
 * @author: 林之谦
 * @date: 2018/7/27
 * @description:
 */
@Data
public class ProductInfoVO implements Serializable {

    private static final long serialVersionUID = 8929804736625426112L;

    @JsonProperty("id")
    private String productId;

    @JsonProperty("name")
    private String productName;

    @JsonProperty("price")
    private BigDecimal productPrice;

    @JsonProperty("description")
    private String productDescription;

    @JsonProperty("icon")
    private String productIcon;

}

5.使用实例

/**
 * @author: 林之谦
 * @date: 2018/7/27
 * @description:
 */

@RestController
@RequestMapping("/buyer/product")
@CacheConfig(cacheNames = "product")
public class BuyerProductController {

    @Autowired
    private ProductInfoService productService;

    @Autowired
    private ProductCategoryService categoryService;

    @GetMapping("/list")
    @Cacheable(key = "123",unless = "#result.getCode() != 0")
    public ResultVO list(){

        System.out.println("【进入数据库查询商品信息】");
        // 1.查询所有的上架商品
        List<ProductInfo> productInfoList = productService.findUpAll();

        // 2.查询类目(一次性查询)
        //传统方法
//        for (ProductInfo productInfo : productInfoList){
//            categoryTypeList.add(productInfo.getCategoryType());
//        }
        //精简的做法 (java8,lambda)
        List<Integer> categoryTypeList = productInfoList.stream()
                .map(e->e.getCategoryType())
                .collect(Collectors.toList());

        List<ProductCategory> productCategoryList = categoryService.findByCategoryTypeIn(categoryTypeList);


        // 3.数据拼装
        List<ProductVO> productVOList = new ArrayList<>();

        for (ProductCategory productCategory : productCategoryList){
            ProductVO productVO = new ProductVO();
            productVO.setCategoryType(productCategory.getCategoryType());
            productVO.setCategoryName(productCategory.getCategoryName());

            List<ProductInfoVO> productInfoVOList = new ArrayList<>();
            for(ProductInfo productInfo : productInfoList){
                if(productInfo.getCategoryType().equals(productCategory.getCategoryType())){
                    ProductInfoVO productInfoVO = new ProductInfoVO();
                    BeanUtils.copyProperties(productInfo,productInfoVO);
                    productInfoVOList.add(productInfoVO);
                }
            }
            productVO.setProductInfoVOList(productInfoVOList);

            productVOList.add(productVO);
        }

        return ResultVOUtil.success(productVOList);
    }
}

 

### 解决方案 为了确保 `LocalDateTime` 在 JSON 响应中作为标准日期时间字符串而不是时间戳返回,在 Spring Boot 中可以通过多种方式来实现这一目标。 #### 方法一:使用 Jackson 注解自定义序列化格式 当实体类中的字段为 `LocalDateTime` 类型时,可以在字段上添加 `@JsonFormat` 注解指定期望的日期时间格式: ```java import com.fasterxml.jackson.annotation.JsonFormat; import java.time.LocalDateTime; public class Event { @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime eventTime; // getter and setter methods... } ``` 此方法适用于特定字段定制化的场景[^1]。 #### 方法二:全局配置Jackson ObjectMapper 如果希望整个应用程序统一处理所有的 `LocalDateTime` 字段,则可在应用启动时通过配置文件或编码的方式调整默认的 `ObjectMapper` 行为。具体做法是在项目的配置类中注册一个新的 `HttpMessageConverters` 实例,并设置其使用的 `ObjectMapper` 的序列化特性: ```java import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class WebConfig { @Bean public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { return builder.modules(new JavaTimeModule()) .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) .build(); } } ``` 上述代码片段禁用了将日期写入为时间戳的功能(`WRITE_DATES_AS_TIMESTAMPS`)并启用了对Java 8 时间API的支持模块 (`JavaTimeModule`). 这样做之后,所有被转换成JSON的对象里的 `LocalDateTime`, `ZonedDateTime` 和其他新的时间类型都会按照ISO-8601的标准格式输出[^2]. #### 方法三:利用 application.properties 或者 yml 文件进行简单配置 最简便的方法之一就是在 `application.properties` (或 `.yml`) 配置文件里加入如下配置项: ```properties spring.jackson.serialization.write_dates_as_timestamps=false ``` 这同样达到了关闭时间戳模式的效果,使得 `LocalDateTime` 对象能够以更易读的形式呈现给客户端[^3].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值