项目完整代码下载地址: https://gitee.com/chuzhuyong/financial-project/tree/master
一、项目准备
模块化开发的好处?
高内聚,低耦合
并行开发,提高开发的效率
如何划分?
业务层次
功能划分
重复使用
(一)、工程创建
构建工具:gradle
(1)下载网址:https://gradle.org/
(2)系统环境变量配置
(3)使用gradle -v命令查看配置是否成功
使用IDEA创建项目流程
创建模块
(二)、数据库设计
管理端
产品表
销售端:
订单表
(三)、创建产品表
create table product( id VARCHAR(50) not null comment '产品编号', name VARCHAR(50) not null comment '产品名称', threshold_amount DECIMAL(15,3) not null comment '起步金额', step_amount DECIMAL(15,3) not null comment '投资步长', lock_term SMALLINT not null comment '锁定期', reward_rate DECIMAL(15,3) not null comment '收益率,0-100 百分比值', status VARCHAR(20) not null comment '状态,AUDINTING:审核中,IN_SELL:销售 中,LOCKED:暂停销售,FINISHED:已结束', memo VARCHAR(200) comment '备注', create_at datetime comment '创建时间', create_user VARCHAR(20) comment '创建者', update_at datetime comment '更新时间', update_user VARCHAR(20) comment '更新者', PRIMARY KEY(id) )ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
(四)、创建订单表
create table order_t( order_id VARCHAR(50) not null comment '订单编号', chan_id VARCHAR(50) not null comment '渠道编号', product_id VARCHAR(50) not null comment '产品编号', chan_user_id VARCHAR(50) not null comment '渠道用户编号', order_type VARCHAR(50) not null comment '类型,APPLY:申购,REDEEM:赎回', order_status VARCHAR(50) not null comment '状态,INIT:初始化,PROCESS:处理 中,SUCCESS:成功,FAIL:失败', outer_order_id VARCHAR(50) not null comment '外部订单编号', amount DECIMAL(15,3) not null comment '金额', memo VARCHAR(200) comment '备注', create_at datetime comment '创建时间', update_at datetime comment '更新时间', PRIMARY KEY(order_id) )ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
(五)、Entity模块
Product类
package com.uos.entity; import java.math.BigDecimal; import java.util.Date; /** * 产品 */ @Entity public class Product { @Id private String id; private String name; private String status; //起投金额 private BigDecimal threshouldAmount; //投资步长 private BigDecimal stepAmount; //锁定期 private Integer lockTerm; //收益率 private BigDecimal rewardRate; private String memo; private Date createAt; private Date updateAt; private String createUser; private String updateUser; @Override public String toString() { return "Order{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", status='" + status + '\'' + ", threshouldAmount=" + threshouldAmount + ", stepAmount=" + stepAmount + ", lockTerm=" + lockTerm + ", rewardRate=" + rewardRate + ", memo='" + memo + '\'' + ", createAt=" + createAt + ", updateAt=" + updateAt + ", createUser='" + createUser + '\'' + ", updateUser='" + updateUser + '\'' + '}'; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public BigDecimal getThreshouldAmount() { return threshouldAmount; } public void setThreshouldAmount(BigDecimal threshouldAmount) { this.threshouldAmount = threshouldAmount; } public BigDecimal getStepAmount() { return stepAmount; } public void setStepAmount(BigDecimal stepAmount) { this.stepAmount = stepAmount; } public Integer getLockTerm() { return lockTerm; } public void setLockTerm(Integer lockTerm) { this.lockTerm = lockTerm; } public BigDecimal getRewardRate() { return rewardRate; } public void setRewardRate(BigDecimal rewardRate) { this.rewardRate = rewardRate; } public String getMemo() { return memo; } public void setMemo(String memo) { this.memo = memo; } public Date getCreateAt() { return createAt; } public void setCreateAt(Date createAt) { this.createAt = createAt; } public Date getUpdateAt() { return updateAt; } public void setUpdateAt(Date updateAt) { this.updateAt = updateAt; } public String getCreateUser() { return createUser; } public void setCreateUser(String createUser) { this.createUser = createUser; } public String getUpdateUser() { return updateUser; } public void setUpdateUser(String updateUser) { this.updateUser = updateUser; } }
Order类
package com.uos.entity; import java.math.BigDecimal; import java.util.Date; /** * 订单 */ @Entity(name = "order_t") public class Order { @Id private String orderId; //渠道id private String chanId; private String chanUserId; private String orderType; private String productId; private BigDecimal amount; private String outerOrderId; private String orderStatus; private String memo; private Date createAt; private Date updateAt; @Override public String toString() { return "Order{" + "orderId='" + orderId + '\'' + ", chanId='" + chanId + '\'' + ", chanUserId='" + chanUserId + '\'' + ", orderType='" + orderType + '\'' + ", productId='" + productId + '\'' + ", amount=" + amount + ", outerOrderId='" + outerOrderId + '\'' + ", orderStatus='" + orderStatus + '\'' + ", memo='" + memo + '\'' + ", createAt=" + createAt + ", updateAt=" + updateAt + '}'; } public String getOrderId() { return orderId; } public void setOrderId(String orderId) { this.orderId = orderId; } public String getChanId() { return chanId; } public void setChanId(String chanId) { this.chanId = chanId; } public String getChanUserId() { return chanUserId; } public void setChanUserId(String chanUserId) { this.chanUserId = chanUserId; } public String getOrderType() { return orderType; } public void setOrderType(String orderType) { this.orderType = orderType; } public String getProductId() { return productId; } public void setProductId(String productId) { this.productId = productId; } public BigDecimal getAmount() { return amount; } public void setAmount(BigDecimal amount) { this.amount = amount; } public String getOuterOrderId() { return outerOrderId; } public void setOuterOrderId(String outerOrderId) { this.outerOrderId = outerOrderId; } public String getOrderStatus() { return orderStatus; } public void setOrderStatus(String orderStatus) { this.orderStatus = orderStatus; } public String getMemo() { return memo; } public void setMemo(String memo) { this.memo = memo; } public Date getCreateAt() { return createAt; } public void setCreateAt(Date createAt) { this.createAt = createAt; } public Date getUpdateAt() { return updateAt; } public void setUpdateAt(Date updateAt) { this.updateAt = updateAt; } }
二、管理端
(一) 、添加产品
1、管理端启动类
package com.uos.manager; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * 管理端启动类 */ @SpringBootApplication public class ManagerApp { public static void main(String[] args) { SpringApplication.run(ManagerApp.class); } }
2、数据库的连接配置application.yml
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/manager?user=root&password=123456&useUnicode=true&characterEncoding=utf-8 jpa: show-sql: true server: context-path: /manager port: 8081
3、ProductRepository接口
package com.uos.manager.repositories; import com.uos.entity.Product; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; /** * 产品管理 */ public interface ProductRepository extends JpaRepository<Product,String>,JpaSpecificationExecutor<Product> { }
4、ProductService产品服务类
package com.uos.manager.service; import com.uos.entity.Product; import com.uos.entity.enums.ProductStatus; import com.uos.manager.repositories.ProductRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import java.math.BigDecimal; import java.util.Date; /* 产品服务类 */ @Service public class ProductService { private static Logger LOG = (Logger) LoggerFactory.getLogger(ProductService.class); @Autowired private ProductRepository repository; public Product addProduct(Product product){ //打印日志信息 LOG.debug("创建产品,参数:{}",product); //数据校验 checkProduct(product); //设置默认值 setDefault(product); //保存值 Product result = repository.save(product); LOG.debug("创建产品,结果:{}",result); return result; } /* 设置默认值: 创建时间、更新时间、投资步长、锁定期 */ private void setDefault(Product product) { if (product.getCreateAt() == null) { product.setCreateAt(new Date()); } if (product.getUpdateAt() == null) { product.setUpdateAt(new Date()); } if (product.getStepAmount() == null) { product.setStepAmount(BigDecimal.ZERO); } if (product.getLockTerm() == null) { product.setLockTerm(0); } if (product.getStatus() == null) { product.setStatus(ProductStatus.AUDITING.name()); } } /* 产品数据的校验: 1.非空数据 2.收益率在0-30%以内 3.投资步长需要为整数 */ private void checkProduct(Product product) { Assert.notNull(product.getId(), "编号不可为空"); //其他非空校验 Assert.isTrue(BigDecimal.ZERO.compareTo(product.getRewardRate()) < 0 && BigDecimal.valueOf(30).compareTo(product.getRewardRate()) >= 0, "收益率范围错误"); Assert.isTrue(BigDecimal.valueOf(product.getStepAmount().longValue()).compareTo(product.getStepAmount()) == 0, "投资步长需为整数"); } }
5、ProductController产品控制类
package com.uos.manager.controller; import com.uos.entity.Product; import com.uos.manager.service.ProductService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * 产品 */ @RestController @RequestMapping("/products") public class ProductController { private static Logger LOG = (Logger) LoggerFactory.getLogger(ProductService.class); @Autowired private ProductService service; @RequestMapping(value = "",method = RequestMethod.POST) public Product addProduct(@RequestBody Product product){ LOG.info("创建产品,参数:{}",product); Product result = service.addProduct(product); LOG.info("创建产品,结果:{}",result); return result; } }
(二)、查询产品
1、查询单个产品
在ProductService中添加
/** * 查询单个产品 */ public Product findOne(String id){ Assert.notNull(id,"需要产品编号参数"); LOG.debug("查询单个产品,id={}",id); Product product = repository.findOne(id); LOG.debug("查询单个产品,结果={}",product); return product; }
在ProductController中添加
/** * 查询单个产品 */ @RequestMapping(value = "/{id}",method = RequestMethod.GET ) public Product findOne(@PathVariable String id){ LOG.info("查询单个产品,id={}",id); Product product = service.findOne(id); LOG.info("查询单个产品,结果={}",product); return product; }
2、分页查询
在ProductService中添加
/** * 分页查询 */ public Page<Product> query(List<String> idList, BigDecimal minRewardRate, BigDecimal maxRewardRate, List<String> statusList, Pageable pageable){ LOG.debug("查询产品,idList={},minRewardRate={},maxRewardRate={},statusList={},pageable={}",idList,minRewardRate,maxRewardRate,statusList,pageable); Specification<Product> specification = new Specification<Product>() { @Override public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) { //获取相关的列 Expression<String> idCol = root.get("id"); Expression<BigDecimal> rewardRateCol = root.get("rewardRate"); Expression<String> statusCol = root.get("status"); //定义断言列表,用来生成断言 List<Predicate> predicates = new ArrayList<>(); //判断产品编号的情况 if (idList != null && idList.size() > 0){ predicates.add(idCol.in(idList)); } if (BigDecimal.ZERO.compareTo(minRewardRate) < 0){ predicates.add(cb.ge(rewardRateCol,minRewardRate)); } if (BigDecimal.ZERO.compareTo(minRewardRate) < 0){ predicates.add(cb.le(rewardRateCol,maxRewardRate)); } //判断产品状态的情况 if (statusList != null && statusList.size() > 0){ predicates.add(statusCol.in(statusList)); } query.where(predicates.toArray(new Predicate[0])); return null; } }; Page<Product> page = repository.findAll(specification,pageable); LOG.debug("查询产品,结果={}",page); return page; }
在ProductController中添加
/** * 分页查询 */ @RequestMapping(value = "",method = RequestMethod.GET) public Page<Product> query(String ids, BigDecimal minRewardRate,BigDecimal maxRewardRate, String status,@RequestParam(defaultValue = "0") int pageNum,@RequestParam(defaultValue = "10") int pageSize){ LOG.info("查询产品,ids={},minRewardRate={},maxRewardRate={},status,pageNum={},pageSize={}"); List<String> idList = null,statusList = null; //判断产品编号 if (!StringUtils.isEmpty(ids)){ idList = Arrays.asList(ids.split(",")); } //判断产品状态 if (!StringUtils.isEmpty(status)){ statusList = Arrays.asList(status.split(",")); } Pageable pageable = new PageRequest(pageNum,pageSize); Page<Product> page = service.query(idList,minRewardRate,maxRewardRate,statusList,pageable); LOG.info("查询产品,结果={}",page); return page; }
在管理端启动类上添加@EntityScan(basePackages = {"com.uos.entity"})
(三)、统一错误处理
用户友好的错误说明
统一处理,简化业务代码
异常标准化
自定义格式化时间,在manager模块下的application.yml中添加
自定义错误页面
定义MyErrorController类
package com.uos.manager.error; import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver; import org.springframework.boot.web.servlet.error.ErrorAttributes; import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.Map; /** * 自定义错误处理controller */ public class MyErrorController extends BasicErrorController { public MyErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties, List<ErrorViewResolver> errorViewResolvers) { super(errorAttributes, errorProperties, errorViewResolvers); } @Override protected Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) { Map<String, Object> attrs = super.getErrorAttributes(request, includeStackTrace); //去除无关的属性 attrs.remove("timestamp"); attrs.remove("status"); attrs.remove("error"); attrs.remove("exception"); attrs.remove("path"); return attrs; } }
定义ErrorConfiguration类 错误处理相关配置
package com.uos.manager.error; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.autoconfigure.web.*; import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver; import org.springframework.boot.web.servlet.error.ErrorAttributes; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; /** * 错误处理相关配置 */ @Configuration public class ErrorConfiguration { @Bean public MyErrorController basicErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties, ObjectProvider<List<ErrorViewResolver>> errorViewResolversProvider) { return new MyErrorController(errorAttributes, serverProperties.getError(), errorViewResolversProvider.getIfAvailable()); } }
定义ErrorEnum类 错误种类
package com.uos.manager.error; /** * 错误种类 */ public enum ErrorEnum { ID_NOT_NULL("F001","编号不能为空",false), UNKNOWN("999","未知异常",false); private String code; private String message; private boolean canRetry; ErrorEnum(String code, String message, boolean canRetry) { this.code = code; this.message = message; this.canRetry = canRetry; } //通过编号获取异常 public static ErrorEnum getByCode(String code){ for (ErrorEnum errorEnum : ErrorEnum.values()) { if (errorEnum.code.equals(code)){ return errorEnum; } } return UNKNOWN; } public String getCode() { return code; } public String getMessage() { return message; } public boolean isCanRetry() { return canRetry; } }
在MyErrorController中添加相关属性
//获取错误种类 ErrorEnum errorEnum = ErrorEnum.getByCode(errorCode); //添加相关属性 attrs.put("message",errorEnum.getMessage()); attrs.put("code",errorEnum.getCode()); attrs.put("canRetry",errorEnum.isCanRetry());
新建ErrorControllerAdvice类
package com.uos.manager.error; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; import java.util.HashMap; import java.util.Map; /** * 统一错误处理 */ @ControllerAdvice(basePackages = {"com.uos.manager.controller"}) public class ErrorControllerAdvice { @ExceptionHandler(Exception.class) @ResponseBody public ResponseEntity handleException(Exception e){ Map<String, Object> attrs = new HashMap<>(); String errorCode = e.getMessage(); ErrorEnum errorEnum = ErrorEnum.getByCode(errorCode); //添加相关属性 attrs.put("message",errorEnum.getMessage()); attrs.put("code",errorEnum.getCode()); attrs.put("canRetry",errorEnum.isCanRetry()); attrs.put("type","advice"); return new ResponseEntity(attrs, HttpStatus.INTERNAL_SERVER_ERROR); } }
说明:ControllerAdvice是Controller的增强
(四)、自动化测试
采用功能测试,使用JUnit框架
在util下创建JsonUtil类
package com.uos.util; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.text.DateFormat; public class JsonUtil { private static final Logger LOG = LoggerFactory.getLogger(JsonUtil.class); private final static ObjectMapper mapper = new ObjectMapper(); static { mapper.enable(SerializationFeature.WRITE_NULL_MAP_VALUES); mapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); // 属性可见度只打印public //mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } public static void setDateFormat(DateFormat dateFormat) { mapper.setDateFormat(dateFormat); } /** * 把Java对象转为JSON字符串 * * @param obj the object need to transfer into json string. * @return json string. */ public static String toJson(Object obj) { try { return mapper.writeValueAsString(obj); } catch (IOException e) { LOG.error("to json exception.", e); throw new JSONException("把对象转换为JSON时出错了", e); } } } final class JSONException extends RuntimeException { public JSONException(final String message) { super(message); } public JSONException(final String message, final Throwable cause) { super(message, cause); } }
在util下创建创建RestUtil类
package com.uos.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; import java.util.Arrays; import java.util.List; import java.util.Map; public class RestUtil { static Logger log = LoggerFactory.getLogger(RestUtil.class); /** * 发送post 请求 * * @param restTemplate * @param url * @param param * @param responseType * @param <T> * @return */ public static <T> T postJSON(RestTemplate restTemplate, String url, Object param, Class<T> responseType) { HttpEntity<String> formEntity = makePostJSONEntiry(param); T result = restTemplate.postForObject(url, formEntity, responseType); log.info("rest-post-json 响应信息:{}", JsonUtil.toJson(result)); return result; } /** * 生成json形式的请求头 * * @param param * @return */ public static HttpEntity<String> makePostJSONEntiry(Object param) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON_UTF8); headers.add("Accept", MediaType.APPLICATION_JSON_VALUE); HttpEntity<String> formEntity = new HttpEntity<String>( JsonUtil.toJson(param), headers); log.info("rest-post-json-请求参数:{}", formEntity.toString()); return formEntity; } public static HttpEntity<String> makePostTextEntiry(Map<String, ? extends Object> param) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.add("Accept", MediaType.APPLICATION_JSON_VALUE); HttpEntity<String> formEntity = new HttpEntity<String>( makeGetParamContent(param), headers); log.info("rest-post-text-请求参数:{}", formEntity.toString()); return formEntity; } /** * 生成Get请求内容 * * @param param * @param excluedes * @return */ public static String makeGetParamContent(Map<String, ? extends Object> param, String... excluedes) { StringBuilder content = new StringBuilder(); List<String> excludeKeys = Arrays.asList(excluedes); param.forEach((key, v) -> { content.append(key).append("=").append(v).append("&"); }); if (content.length() > 0) { content.deleteCharAt(content.length() - 1); } return content.toString(); } }
编写ProductControllerTest类
测试添加产品
package com.uos.manager.controller; import com.uos.entity.Product; import com.uos.entity.enums.ProductStatus; import com.uos.util.RestUtil; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.client.ClientHttpResponse; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.Assert; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestTemplate; import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class ProductControllerTest { private static RestTemplate rest = new RestTemplate(); @Value("http://localhost:${local.server.port}/manager") private String baseUrl; //测试用例 //正常产品数据 private static List<Product> normals = new ArrayList<>(); //异常产品数据 private static List<Product> exceptions = new ArrayList<>(); @BeforeClass public static void init(){ Product p1 = new Product("T001", "灵活宝1号", ProductStatus.AUDITING.name(), BigDecimal.valueOf(10), BigDecimal.valueOf(1), BigDecimal.valueOf(3.42)); Product p2 = new Product("T002", "活期盈-金色人生", ProductStatus.AUDITING.name(), BigDecimal.valueOf(10), BigDecimal.valueOf(0), BigDecimal.valueOf(3.28)); Product p3 = new Product("T003", "朝朝盈-聚财", ProductStatus.AUDITING.name(), BigDecimal.valueOf(100), BigDecimal.valueOf(10), BigDecimal.valueOf(3.86)); normals.add(p1); normals.add(p2); normals.add(p3); Product e1 = new Product(null, "编号不可为空", ProductStatus.AUDITING.name(), BigDecimal.valueOf(10), BigDecimal.valueOf(1), BigDecimal.valueOf(2.34)); Product e2 = new Product("E002", "收益率范围错误", ProductStatus.AUDITING.name(), BigDecimal.ZERO, BigDecimal.valueOf(1), BigDecimal.valueOf(31)); Product e3 = new Product("E003", "投资步长需为整数", ProductStatus.AUDITING.name(), BigDecimal.ZERO, BigDecimal.valueOf(1.01), BigDecimal.valueOf(3.44)); exceptions.add(e1); exceptions.add(e2); exceptions.add(e3); ResponseErrorHandler errorHandler = new ResponseErrorHandler() { @Override public boolean hasError(ClientHttpResponse response) throws IOException { return false; } @Override public void handleError(ClientHttpResponse response) throws IOException { } }; rest.setErrorHandler(errorHandler); } @Test public void create(){ normals.forEach(product -> { Product result = RestUtil.postJSON(rest,baseUrl+"/products",product,Product.class); Assert.notNull(result.getCreateAt(),"创建失败"); } ); } @Test public void createException(){ exceptions.forEach(product -> { Map<String,String> result = RestUtil.postJSON(rest,baseUrl+"/products",product, HashMap.class); Assert.isTrue(result.get("message").equals(product.getName()), "插入成功"); } ); }
}
@Test public void findOne() { normals.forEach(product -> { Product result = rest.getForObject(baseUrl + "/products/" + product.getId(), Product.class); Assert.isTrue(result.getId().equals(product.getId()), "查询失败"); }); exceptions.forEach(product -> { Product result = rest.getForObject(baseUrl + "/products/" + product.getId(), Product.class); Assert.isNull(result, "查询失败"); }); }
数据库结果
1 package com.uos.swagger; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.stereotype.Component; 5 6 /** 7 * swagger配置信息 8 */ 9 @Component 10 @ConfigurationProperties(prefix = "swagger") 11 public class SwaggerInfo { 12 private String groupName = "controller"; 13 private String basePackage; 14 private String antPath; 15 private String title = "HTTP API"; 16 private String description = "管理端接口"; 17 private String license = "Apache License Version 2.0"; 18 19 public String getGroupName() { 20 return groupName; 21 } 22 23 public void setGroupName(String groupName) { 24 this.groupName = groupName; 25 } 26 27 public String getBasePackage() { 28 return basePackage; 29 } 30 31 public void setBasePackage(String basePackage) { 32 this.basePackage = basePackage; 33 } 34 35 public String getAntPath() { 36 return antPath; 37 } 38 39 public void setAntPath(String antPath) { 40 this.antPath = antPath; 41 } 42 43 public String getTitle() { 44 return title; 45 } 46 47 public void setTitle(String title) { 48 this.title = title; 49 } 50 51 public String getDescription() { 52 return description; 53 } 54 55 public void setDescription(String description) { 56 this.description = description; 57 } 58 59 public String getLicense() { 60 return license; 61 } 62 63 public void setLicense(String license) { 64 this.license = license; 65 } 66 }