学习完整课程请移步 互联网 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);