CartAddDTO,代码如下
DTO:前端收集到数据发送给后端的实体
VO:后端从数据库查询出来要发送给前端的实体
@Data // 定义knife4j在线文档解释文本的注解 @ApiModel("新增购物车商品信息的DTO") public class CartAddDTO implements Serializable { @ApiModelProperty(value = "商品编号", name="commodityCode",example = "PC100") private String commodityCode; // 商品编号 @ApiModelProperty(value = "商品单价", name="price",example = "136") private Integer price; // 商品单价 @ApiModelProperty(value = "商品数量", name="count",example = "3") private Integer count; // 商品数量 @ApiModelProperty(value = "用户ID", name="userId",example = "UU100") private String userId; // 用户ID }
创建包
pojo.cart.model
包中创建类Cart
@Data public class Cart implements Serializable { private Integer id; // 商品编号 private String commodityCode; // 价格 private Integer price; // 数量 private Integer count; // 用户id private Integer userId; }
下面创建订单模块需要的类
pojo.order.dto.OrderAddDTO
@ApiModel("新增订单的DTO") @Data public class OrderAddDTO implements Serializable { @ApiModelProperty(value = "用户id",name="userId",example = "UU100") private String userId; @ApiModelProperty(value = "商品编号",name="commodityCode",example = "PC100") private String commodityCode; @ApiModelProperty(value = "商品数量",name="count",example = "5") private Integer count; @ApiModelProperty(value = "总金额",name="money",example = "50") private Integer money; }
pojo.order.model.Order
@Data public class Order implements Serializable { private Integer id; private String userId; private String commodityCode; private Integer count; private Integer money; }
最后是库存相关的类
pojo.stock.dto.StockReduceCountDTO
@ApiModel("商品减少库存DTO") @Data public class StockReduceCountDTO implements Serializable { @ApiModelProperty(value = "商品编号",name="commodityCode",example = "PC100") private String commodityCode; @ApiModelProperty(value = "减库存数",name="reduceCount",example = "5") private Integer reduceCount; }
pojo.stock.model.Stock
@Data public class Stock implements Serializable { private Integer id; private String commodityCode; private Integer reduceCount; }
创建包com.taobao.mall.commons.exception
包中创建类MallServiceException
/** * 业务异常 */ @Data @EqualsAndHashCode(callSuper = false) public class MallServiceException extends RuntimeException { private ResponseCode responseCode; public MallServiceException(ResponseCode responseCode, String message) { super(message); setResponseCode(responseCode); } }
将restful包中用于控制器返回的JsonResult类复制
/** * 通用响应对象 */ @Data public class JsonResultimplements Serializable { /** * 状态码 */ @ApiModelProperty(value = "业务状态码", position = 1, example = "200, 400, 401, 403, 404, 409, 500") private Integer state; /** * 消息 */ @ApiModelProperty(value = "业务消息", position = 2, example = "登录失败!密码错误!") private String message; /** * 数据 */ @ApiModelProperty(value = "业务数据", position = 3) private T data; /** * 创建响应结果对象,表示"成功",不封装其它任何数据 * @return 响应结果对象 */ public static JsonResult ok() { return ok("OK"); } public static JsonResult ok(String message){ JsonResult jsonResult=new JsonResult(); jsonResult.setState(ResponseCode.OK.getValue()); jsonResult.setMessage(message); jsonResult.setData(null); return jsonResult; } /** * 创建响应结果对象,表示"成功",且封装客户端期望响应的数据 * @param data 客户端期望响应的数据 * @return 响应结果对象 */ public static JsonResult ok(String message,T data) { JsonResult jsonResult = new JsonResult<>(); jsonResult.setState(ResponseCode.OK.getValue()); jsonResult.setData(data); return jsonResult; } /** * 创建响应结果对象,表示"失败",且封装"失败"的描述 * * @param e MallServiceException异常对象 * @return 响应结果对象 */ public static JsonResult failed(CoolSharkServiceException e) { return failed(e.getResponseCode(), e); } /** * 创建响应结果对象,表示"失败",且封装"失败"的描述 * * @param responseCode "失败"的状态码 * @param e "失败"时抛出的异常对象 * @return 响应结果对象 */ public static JsonResult failed(ResponseCode responseCode, Throwable e) { return failed(responseCode, e.getMessage()); } /** * 创建响应结果对象,表示"失败",且封装"失败"的描述 * * @param responseCode "失败"的状态码 * @param message "失败"的描述文本 * @return 响应结果对象 */ public static JsonResult failed(ResponseCode responseCode, String message) { JsonResult jsonResult = new JsonResult<>(); jsonResult.setState(responseCode.getValue()); jsonResult.setMessage(message); return jsonResult; } }
我们编写的所有模块控制层发送异常时,也都由SpringMvc的统一异常处理类来处理
所以commons模块编写统一异常处理类也是常规操作
/** * 全局异常处理器 */ @RestControllerAdvice @Slf4j public class GlobalControllerExceptionHandler { /** * 处理业务异常 */ @ExceptionHandler({MallServiceException.class}) public JsonResulthandleMallServiceException(MallServiceException e) { log.debug("出现业务异常,业务错误码={},描述文本={}", e.getResponseCode().getValue(), e.getMessage()); e.printStackTrace(); JsonResult result = JsonResult.failed(e); log.debug("即将返回:{}", result); return result; } /** * 处理绑定异常(通过Validation框架验证请求参数时的异常) */ @ExceptionHandler(BindException.class) public JsonResult handleBindException(BindException e) { log.debug("验证请求数据时出现异常:{}", e.getClass().getName()); e.printStackTrace(); String message = e.getBindingResult().getFieldError().getDefaultMessage(); JsonResult result = JsonResult.failed(ResponseCode.BAD_REQUEST, message); log.debug("即将返回:{}", result); return result; } /** * 处理系统(其它)异常 */ @ExceptionHandler({Throwable.class}) public JsonResult handleSystemError(Throwable e) { log.debug("出现系统异常,异常类型={},描述文本={}", e.getClass().getName(), e.getMessage()); e.printStackTrace(); JsonResult result = JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR, e); log.debug("即将返回:{}", result); return result; } }
commons模块内容编写暂时告一段落
business:商业\生意\业务的意思
这个模块创建出来是为了触发订单业务的
创建子项目mall-business
父子相认
子项目pom文件
4.0.0 com.mall mall 0.0.1-SNAPSHOT com.mall mall-business 0.0.1-SNAPSHOT mall-business Demo project for Spring Boot org.springframework.boot spring-boot-starter-web com.github.xiaoymin knife4j-spring-boot-starter com.taobao mall-commons 0.0.1-SNAPSHOT
yml文件配置数据源
spring: datasource: url: jdbc:mysql://localhost:3306/csmall_db?useSSL=false&useUnicode=true&characterEncoding=utf-8 username: root password: root
配置business模块application.yml文件
yml文件内容如下
server: port: 20000 #公共配置 mybatis: configuration: cache-enabled: false # 不启用mybatis缓存 map-underscore-to-camel-case: true # 映射支持驼峰命名法 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 将运行的sql输出到控制台 knife4j: # 开启增强配置 enable: true # 生产环境屏蔽,开启将禁止访问在线API文档 production: false # Basic认证功能,即是否需要通过用户名、密码验证后才可以访问在线API文档 basic: # 是否开启Basic认证 enable: false # 用户名,如果开启Basic认证却未配置用户名与密码,默认是:admin/123321 username: root # 密码 password: root spring: profiles: active: dev
我们在配置末尾看到了
spring: profiles: active: dev
上面的配置含义是让SpringBoot读取额外配置文件
我们参数值编写的是dev,那么springBoot会读取application-dev.yml
dev是可以随意修改的名字,没有任何固定要求
创建config包,编写一些必要配置
首先创建CommonsConfiguration
// 只有添加了@Configuration才能配置当前Spring环境 @Configuration // 扫描commons模块的统一异常处理类,使其在项目中生效 @ComponentScan("cn.tedu.csmall.commons.exception") public class CommonsConfiguration { }
因为business模块是业务的触发者,所以不需要数据库操作,直接编写业务逻辑层即可
创建service包,包中创建IBusinessService接口
代码如下
public interface IBusinessService { // 定义触发新增订单模块功能的方法 void buy(); }
新建service.impl包
包中创建BusinessServiceImpl类
代码如下
@Service @Slf4j public class BusinessServiceImpl implements IBusinessService { @Override public void buy() { // 模拟购买业务 // 创建用于新增订单的DTO实体OrderAddDTO OrderAddDTO orderAddDTO=new OrderAddDTO(); // 为orderAddDTO赋值 orderAddDTO.setUserId("UU100"); orderAddDTO.setCommodityCode("PC100"); orderAddDTO.setCount(5); orderAddDTO.setMoney(500); // 因为是模拟购买,现在还不能调用order模块,所以只是输出 log.info("新增订单的信息为:{}",orderAddDTO); } }
创建控制层controller
创建类BusinessController代码如下
@RestController @RequestMapping("/base/business") // knife4j控制器描述 @Api(tags = "新增订单业务触发") public class BusinessController { @Autowired private IBusinessService businessService; @PostMapping("/buy") // localhost:20000/base/business/buy(必须是post请求,浏览器输入地址无效) @ApiOperation("执行触发的方法") public JsonResult buy(){ // 调用业务逻辑层的方法 businessService.buy(); return JsonResult.ok("购买完成!"); } }
启动当前business项目
访问
http://localhost:20000/doc.html