实现 RESTful 风格的 API

学习完整课程请移步 互联网 Java 全栈工程师

本节视频

  • 【视频】Spring Cloud Alibaba-MyShop-实现 RESTful 风格 API

注意:本节视频时间较长,但包含了很多基础性的操作,有兴趣的同学不要错过 (๑´ㅂ`๑́)و✧

本节关键代码

POM

主要在 myshop-commons 项目增加了如下依赖:


    com.fasterxml.jackson.core
    jackson-databind


    com.github.ben-manes.caffeine
    guava


    org.apache.commons
    commons-lang3

相关工具类

主要在 myshop-commons 项目中增加了如下工具类:

AbstractBaseResult

package com.funtl.myshop.commons.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

import java.io.Serializable;

/**
 * 通用的响应结果
 * 

Title: AbstractBaseResult

*

Description:

* * @author Lusifer * @version 1.0.0 * @date 2019/1/23 15:10 */ @Data public abstract class AbstractBaseResult implements Serializable { @Data @JsonInclude(JsonInclude.Include.NON_NULL) protected static class Links { private String self; private String next; private String last; } @Data @JsonInclude(JsonInclude.Include.NON_NULL) protected static class DataBean { private String type; private Long id; private T attributes; private T relationships; private Links links; } }

AbstractBaseDomain

package com.funtl.myshop.commons.dto;

import lombok.Data;

import java.io.Serializable;

/**
 * 通用的领域模型
 * 

Title: AbstractBaseDomain

*

Description:

* * @author Lusifer * @version 1.0.0 * @date 2019/1/23 15:50 */ @Data public abstract class AbstractBaseDomain implements Serializable { private Long id; }

SuccessResult

package com.funtl.myshop.commons.dto;

import com.google.common.collect.Lists;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
 * 请求成功
 * 

Title: SuccessResult

*

Description:

* * @author Lusifer * @version 1.0.0 * @date 2019/1/23 15:07 */ @Data @EqualsAndHashCode(callSuper = false) public class SuccessResult extends AbstractBaseResult { private Links links; private List data; public SuccessResult(String self, T attributes) { links = new Links(); links.setSelf(self); createDataBean(null, attributes); } public SuccessResult(String self, int next, int last, List attributes) { links = new Links(); links.setSelf(self); links.setNext(self + "?page=" + next); links.setLast(self + "?page=" + last); attributes.forEach(attribute -> createDataBean(self, attribute)); } private void createDataBean(String self, T attributes) { if (data == null) { data = Lists.newArrayList(); } DataBean dataBean = new DataBean(); dataBean.setId(attributes.getId()); dataBean.setType(attributes.getClass().getSimpleName()); dataBean.setAttributes(attributes); if (StringUtils.isNotBlank(self)) { Links links = new Links(); links.setSelf(self + "/" + attributes.getId()); dataBean.setLinks(links); } data.add(dataBean); } }

ErrorResult

package com.funtl.myshop.commons.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 请求失败
 * 

Title: ErrorResult

*

Description:

* * @author Lusifer * @version 1.0.0 * @date 2019/1/23 15:07 */ @Data @AllArgsConstructor @EqualsAndHashCode(callSuper = false) @JsonInclude(JsonInclude.Include.NON_NULL) public class ErrorResult extends AbstractBaseResult { private int code; private String title; private String detail; }

BaseResultFactory

package com.funtl.myshop.commons.dto;

import java.util.List;

/**
 * 通用响应结构工厂
 * 

Title: BaseResultFactory

*

Description:

* * @author Lusifer * @version 1.0.0 * @date 2019/1/23 15:16 */ public class BaseResultFactory { private static final String LOGGER_LEVEL_DEBUG = "DEBUG"; private static BaseResultFactory baseResultFactory; private BaseResultFactory() { } public static BaseResultFactory getInstance() { if (baseResultFactory == null) { synchronized (BaseResultFactory.class) { if (baseResultFactory == null) { baseResultFactory = new BaseResultFactory(); } } } return baseResultFactory; } /** * 构建单笔数据结果集 * * @param self * @return */ public AbstractBaseResult build(String self, T attributes) { return new SuccessResult(self, attributes); } /** * 构建多笔数据结果集 * * @param self * @param next * @param last * @return */ public AbstractBaseResult build(String self, int next, int last, List attributes) { return new SuccessResult(self, next, last, attributes); } /** * 构建请求错误的响应结构 * * @param code * @param title * @param detail * @param level 日志级别,只有 DEBUG 时才显示详情 * @return */ public AbstractBaseResult build(int code, String title, String detail, String level) { if (LOGGER_LEVEL_DEBUG.equals(level)) { return new ErrorResult(code, title, detail); } else { return new ErrorResult(code, title, null); } } }

TestController

package com.funtl.myshop.service.reg.controller;

import com.funtl.myshop.commons.domain.TbUser;
import com.funtl.myshop.commons.dto.AbstractBaseResult;
import com.funtl.myshop.commons.dto.BaseResultFactory;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
@RequestMapping(value = "test")
public class TestController {

    @Autowired
    private ConfigurableApplicationContext applicationContext;

    @GetMapping(value = "records/{id}")
    public AbstractBaseResult getById(HttpServletRequest request, @PathVariable long id) {
        TbUser tbUser = new TbUser();
        tbUser.setId(1L);
        tbUser.setUsername("和谷桐人");

        if (id == 1) {
            return BaseResultFactory.getInstance().build(request.getRequestURI(), tbUser);
        } else {
            return BaseResultFactory.build(HttpStatus.UNAUTHORIZED.value(), "参数类型错误", "ID 只能为 1", applicationContext.getEnvironment().getProperty("logging.level.com.funtl.myshop"));
        }
    }

    @GetMapping(value = "records")
    public AbstractBaseResult getList(HttpServletRequest request) {
        TbUser tbUser1 = new TbUser();
        tbUser1.setId(1L);
        tbUser1.setUsername("和谷桐人");

        TbUser tbUser2 = new TbUser();
        tbUser2.setId(2L);
        tbUser2.setUsername("亚丝娜");

        List tbUsers = Lists.newArrayList();
        tbUsers.add(tbUser1);
        tbUsers.add(tbUser2);

        return BaseResultFactory.getInstance().build(request.getRequestURI(), 2, 10, tbUsers);
    }
}

设置 Json 不返回 null 字段

@JsonInclude(JsonInclude.Include.NON_NULL)

附:SpringMVC 返回状态码

response.setHeader("Content-Type", "application/vnd.api+json");
response.setStatus(500);

你可能感兴趣的:(实现 RESTful 风格的 API)