【抽奖系统开发实战】Spring Boot 项目的奖品模块开发:文件上传、时序设计与奖品创建

发布时间:2026/7/28 21:35:44

【抽奖系统开发实战】Spring Boot 项目的奖品模块开发:文件上传、时序设计与奖品创建 文章目录一、图片功能二、创建奖品2.1 时序图2.2 约定前后端交互接口2.3 前端实现2.4 使用RequestPart注解出现的错误三、奖品列表展示3.1 时序图3.2 约定前后端交互接口3.3 奖品列表页面前端实现一、图片功能application.properties 配置上传文件路径配置图片本地存储路径和静态资源映射。## 图片服务 ##pic.local-pathD:/PIC# spring boot3 升级配置名spring.web.resources.static-locationsclasspath:/static/,file:${pic.local-path}注意如果访问的本地路径需要添加配置项spring.web.resources.static-locationsspring boot 3升级过配置名原本为spring.resources.static-locations访问静态资源不做拦截AppConfig类中excludes新增/*.jpg图片服务PictureService接口定义定义保存图片的接口接收MultipartFile文件返回保存后的文件名。接口实现实现保存图片的逻辑检查本地目录是否存在不存在则创建。获取原始文件名和后缀。使用UUID生成新的文件名防止重名。调用MultipartFile的transferTo方法将文件保存到指定路径。返回新文件名。接口实现示例/** * 保存图片 */ServicepublicclassPictureServiceImplimplementsPictureService{Value(${pic.local-path})privateStringlocalPath;OverridepublicStringsavePicture(MultipartFilemultipartFile){// 创建目录FiledirnewFile(localPath);if(!dir.exists()){dir.mkdirs();}// 创建索引// 1. 获取文件全名称StringfilenamemultipartFile.getOriginalFilename();assertfilename!null;// 2. 拿到文件后缀Stringsuffixfilename.substring(filename.lastIndexOf(.));// 3. 生成索引filenameUUID.randomUUID()suffix;// 图片保存try{multipartFile.transferTo(newFile(localPath/filename));}catch(IOExceptione){thrownewServiceException(ServiceErrorCodeConstants.PIC_UPLOAD_ERROR);}returnfilename;}}二、创建奖品2.1 时序图2.2 约定前后端交互接口请求接口地址/prize/create请求方式POST请求参数param{prizeName:吹风机,description:吹风机,price:100}prizePicObj-C.jpg文件类型响应{code:200,data:17,msg:}Controller层接口设计使用RequestPart分别接收JSON参数CreatePrizeParam和图片文件MultipartFile。调用PrizeService的createPrize方法并返回结果。CreatePrizeParam定义接收参数的实体类包含奖品名称、描述和价值并使用了参数校验注解。Service层接口设计定义PrizeService接口包含创建奖品的方法。接口实现实现createPrize方法。将参数封装为PrizeDO对象。调用PictureService保存图片获取文件名。将图片URL设置到PrizeDO中。调用PrizeMapper的insert方法将奖品信息存入数据库。返回新生成的奖品ID。接口实现示例ServicepublicclassPrizeServiceImplimplementsPrizeService{AutowiredprivatePrizeMapperprizeMapper;AutowiredprivatePictureServicepictureService;/** * 创建奖品 * * param param 奖品属性 * param picFile 奖品图片 * return 返回奖品ID */OverridepublicLongcreatePrize(CreatePrizeParamparam,MultipartFilepicFile){// 上传图片StringfileNamepictureService.savePicture(picFile);// 存储库中PrizeDOprizeDOnewPrizeDO();prizeDO.setName(param.getPrizeName());prizeDO.setDescription(param.getDescription());prizeDO.setImageUrl(fileName);prizeDO.setPrice(param.getPrice());prizeMapper.insert(prizeDO);returnprizeDO.getId();}}Dao层接口设计使用Mapper定义PrizeMapper接口。提供Insert方法插入PrizeDO并使用Options获取自增主键。2.3 前端实现前端页面使用jQuery和AJAX实现创建奖品的流程获取用户token。创建FormData对象添加奖品参数JSON字符串和图片文件。发送POST请求到/prize/create设置请求头user_token。成功或失败时给出相应提示。2.4 使用RequestPart注解出现的错误问题描述前端请求创建奖品时后端解析MultipartFile报错Content type application/octet-stream not supported但Postman测试正常。原因分析请求的content-type可能为null被默认设置为application/octet-stream而Spring没有定义该类型的messageConverter。解决方案自定义一个MultipartJackson2HttpMessageConverter继承AbstractJackson2HttpMessageConverter并指定其支持MediaType.APPLICATION_OCTET_STREAM同时覆盖canWrite方法返回false使其只用于读取。三、奖品列表展示3.1 时序图3.2 约定前后端交互接口请求接口地址/prize/find-list请求方式GET请求参数currentPage1当前页码pageSize10每页记录数响应{code:200,data:{total:3,records:[{prizeId:17,prizeName:吹风机,description:吹风机,price:100,imageUrl:d11fa79c-9cfb-46b9-8fb6-3226ba1ff6d6.jpg}]},msg:}Controller层接口设计接收PageListParam参数包含currentPage和pageSize。调用PrizeService的findPrizeList方法返回PageListDTO。将PageListDTO转换为FindPrizeListResult对象返回给前端。Service层接口设计在PrizeService中新增翻页查询奖品列表的方法。接口实现实现findPrizeList方法。调用PrizeMapper的count方法获取总记录数。调用PrizeMapper的queryPrizeByPage方法传入offset和pageSize获取当前页的PrizeDO列表。将PrizeDO列表转换为PrizeDTO列表。封装成PageListDTO对象返回。接口实现示例/** * 返回奖品当前页列表和奖品总量 * * param param * return */OverridepublicPageListDTOPrizeDTOfindPrizeList(PageParamparam){// 设置总量inttotalprizeMapper.selectPrizeCount();// 查询列表ListPrizeDTOprizeDTOListnewArrayList();ListPrizeDOprizeDOListprizeMapper.selectPrizeList(param.offset(),param.getPageSize());for(PrizeDOprizeDO:prizeDOList){PrizeDTOprizeDTOnewPrizeDTO();prizeDTO.setPrizeId(prizeDO.getId());prizeDTO.setDescription(prizeDO.getDescription());prizeDTO.setName(prizeDO.getName());prizeDTO.setPrice(prizeDO.getPrice());prizeDTO.setImageUrl(prizeDO.getImageUrl());prizeDTOList.add(prizeDTO);}returnnewPageListDTO(total,prizeDTOList);}Dao层接口设计在PrizeMapper中新增翻页查询所需的方法int count();获取总记录数。ListPrizeDO queryPrizesByPage();根据偏移量和页大小查询奖品列表。3.3 奖品列表页面前端实现前端页面使用jQuery和AJAX实现翻页展示奖品列表的流程定义全局变量currentPage、pageSize、totalPages。创建fetchPrizes(page)函数发送GET请求到/prize/find-list。成功时清空表格遍历result.data.records生成表格行并更新分页信息。实现上一页previousPage、下一页nextPage和输入框回车跳转功能。

相关新闻