乐趣区

关于java:第四阶段笔记-Jingtaoday06

day 06 商品图片上传

此文档是依据上课流程编写,更多细节及图片请参见刘老师的专栏

江哥的专栏

《cgb2008- 京淘 day06》

一. 实现商品 CRUD 操作
  1. 商品高低架操作

    i. 编辑 ItemController

    /* 业务: 商品的高低架
       url: http://localhost:8091/item/[instock|reself]
       参数: 1/2
       返回值: SysResult
       SpringMVC 参数接管阐明: 以, 宰割则主动转化为数组类型
       */
    @RequestMapping("/{op}")
    @ResponseBody
    public SysResult opStock(@PathVariable String op,Long[] ids){if(op.equals("instock")){System.out.println("=== Instock ===");
          itemService.opStock(ids,2);
       }else if(op.equals("reshelf")){System.out.println("=== Reshelf ===");
          itemService.opStock(ids,1);
       }
       return SysResult.success();}

    ii. 编辑 ItemServiceImpl

    @Override
    public void opStock(Long[] ids,int status) {
       //1. 以 MP 的办法操作数据库 只批改状态码 /updated 工夫
       Item item = new Item();
       QueryWrapper queryWrapper = new QueryWrapper();
       queryWrapper.in("id",ids);
       item.setStatus(status);
       itemMapper.update(item,queryWrapper);
    
       //2. 手写 SQL
       itemMapper.updateStatus(ids,status);
    }

    iii. 编辑 ItemMapper.xml

    void updateStatus(@Param("ids") Long[] ids, @Param("status") int status);
    <update id="updateStatus">
       UPDATE tb_item SET status=#{status},updated=now()
       WHERE id IN(
       <foreach collection="ids" item="id" separator=",">
          #{id}
       </foreach>
       )
    </update>
二. 实现商品详情信息的展示
  1. 业务阐明

    ​ 个别用户查问商品时,只须要展示展现商品相干信息即可,如果用户点击某个商品时才会展示商品详情,因为商品详情信息是大字段,检索绝对较慢节约性能。

    ​ 1) tb_item;2) tb_item_desc 一对一

    i. 编辑 ItemDesc pojo 对象

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Accessors(chain = true)
    @TableName("tb_item_desc")
    public class ItemDesc extends BasePojo{
    
        @TableId
        private Long itemId; // 与 item 表中的数据统一
        private String itemDesc;
    }

    ii. 编辑 ItemDescMapper

    @Mapper
    public interface ItemDescMapper extends BaseMapper<ItemDesc> {}
  2. 富文本编辑器介绍

    <script type="text/javascript">
       $(function(){KindEditor.ready(function(){KindEditor.create("#editor")
          })
       })
    </script>
    <textarea style="width:700px;height:350px" id="editor"></textarea>
  3. 重构商品新增

    ​ 因为商品的新增是将 Item/ItemDesc 对象一起新增,所以要实现两张表的入库。

    i. 编辑 ItemController

    @RequestMapping("/save")
    @ResponseBody
    public SysResult saveItem(Item item, ItemDesc itemDesc){itemService.saveItem(item,itemDesc);
       return SysResult.success();}

    ii. 编辑 ItemServiceImpl

    // Item 表主键自增
    @Override
    @Transactional
    public void saveItem(Item item, ItemDesc itemDesc) {item.setStatus(1);
       itemMapper.insert(item);
       //MP 用法: 如果实现了主键自增, 主动实现了主键回显
       // 获取主键信息
       itemDesc.setItemId(item.getId());
       itemDescMapper.insert(itemDesc);
    }
  4. 重构商品编辑

    ​ 查问到商品的详情信息,返回给用户,而后将批改后的内容执行两次入库操作。

    i. 编辑 ItemController

    /* 业务: 依据商品 id 号, 检索商品详情
       url: http://localhost:8091/item/desc/1233
       参数: rest 格调
       返回值: SysResult
       SpringMVC 参数接管阐明: 以, 宰割则主动转化为数组类型
       */
    @RequestMapping("/query/item/desc/{itemId}")
    @ResponseBody
    public SysResult findItemDescById(@PathVariable Long itemId){ItemDesc itemDesc = itemService.findItemDescById(itemId);
       return SysResult.success(itemDesc);
    }

    ii. 编辑 ItemServiceImpl

    @Override
    public ItemDesc findItemDescById(Long itemId) {return itemDescMapper.selectById(itemId);
    }
  5. 重构商品更新

    ​ 用户在更新商品时,要更新两张表的数据 Item/ItemDesc

    i. 编辑 ItemController

    @RequestMapping("/update")
    @ResponseBody
    public SysResult updateItem(Item item,ItemDesc itemDesc){itemService.updateItem(item,itemDesc);
       return SysResult.success();}

    ii. 编辑 ItemServiceImpl

    public void updateItem(Item item, ItemDesc itemDesc) {itemMapper.updateById(item);
       // 补全数据
       itemDesc.setItemId(item.getId());
       itemDescMapper.updateById(itemDesc);
    }
  6. 重构商品删除

    i. 编写 ItemServiceImpl

    public void deleteItems(Integer[] ids) {//itemMapper.deleteBatchIds(Arrays.asList(ids));  //MP
       itemMapper.deleteItems(Arrays.asList(ids));  // 手写 SQL
       itemDescMapper.deleteBatchIds(Arrays.asList(ids)));
    }
三. 实现商品图片上传
  1. 文件上传入门案例

    i. 页面标识

    <h1> 实现文件长传 </h1>
    <!--enctype="开启多媒体标签"  -->
    <form action="http://localhost:8091/file" method="post" 
    enctype="multipart/form-data">
       <input name="fileImage" type="file" />
       <input type="submit" value="提交"/>
    </form>

    ii. 编辑 FileController

    @RestController
    public class FileController {@RequestMapping("/file")
        public String file(MultipartFile fileImage) throws IOException {
            //1. 获取图片的名称
            String name = fileImage.getOriginalFilename();
            //2. 定义文件目录
            String fileDirPath = "E:/jt_img";
            //3. 创立目录
            File fileDir = new File(fileDirPath);
            if(!fileDir.exists()){fileDir.mkdirs();
            }
            //4. 生成文件全门路
            String filePath = fileDirPath+"/"+name;
            File imageFile = new File(filePath);
            //5. 实现文件上传
            fileImage.transferTo(imageFile);
            return "FILE UPLOAD OK";
        }
    }
  2. 业务实现

    i. 形容

    ​ url:localhost:8091/pic/upload?dir=image

    ​ 参数类型:uploadFile

    ​ 返回值 JSON 构造:{“error”:0,”url”:” 图片保留门路 ”,”width”: 宽度,”height”: 高度}

    ii. 编辑 ImageVO

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Accessors(chain = true)
    public class ImageVO {//{"error":0,"url":"图片保留门路","width": 宽度,"height": 高度}
        private Integer error;
        private String url;
        private Integer width;
        private Integer height;
        public static ImageVO fail(){return new ImageVO(1,null,null,null);
        }
        public static ImageVO success(String url,Integer width,Integer height){return new ImageVO(0, url, width, height);
        }
    }

    iii. 编辑 FileController

    @Autowired
    private FileService fileService;
    /* 业务需要: 实现文件上传操作
        url: localhost:8091/pic/upload?dir=image
        参数: uploadFile
        返回值: ImageVO
    */
    @RequestMapping("/pic/upload")
    public ImageVO upload(MultipartFile uploadFile){return fileService.upload(uploadFile);
    }

    iv. 编辑 FileServiceImpl

    @Service
    public class FileServiceImpl implements FileService{private static Set<String> typeSet = new HashSet<>();
        // 动态代码块为动态成员赋值
        static {typeSet.add(".jpg");
            typeSet.add(".png");
            typeSet.add(".gif");
        }
    
        /* 业务逻辑: 实现文件上传
            1. 校验图片的类型 jpg png gif
            2. 校验文件是否为恶意程序
            3. 采纳分目录的构造进行存储
            4. 防止文件重名 UUID
         */
        @Override
        public ImageVO upload(MultipartFile uploadFile) {
            //1. 利用汇合校验 / 利用正则表达式
            String fileName = uploadFile.getOriginalFilename().toLowerCase();
            int index = fileName.lastIndexOf(".");
            String fileType = fileName.substring(index);  //.jpg
            //List Map Set []
            if(!typeSet.contains(fileType))
                return ImageVO.fail();
    
            //2. 如果是图片 高度 宽度
            try {BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
                int width = bufferedImage.getWidth();
                int height = bufferedImage.getHeight();
                if(width==0||height==0)
                    return ImageVO.fail();
    
                //3. 依照 年 - 月 - 日 的形式进行目录的划分
                String fileDir = "E:/jt_img";
                String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
                        .format(new Date());
                //E:/jt_img/2020/12/1/
                String fileDirPath = fileDir+dateDir;
                File dirFile = new File(fileDirPath);
                if(!dirFile.exists())
                    dirFile.mkdirs();
    
                //4.UUID 32 位 16 进制数 --> 2^128
                //  hashCode 8 为 16 进制数 --> 2^32
                String uuid = java.util.UUID.randomUUID().toString()
                        .replace("-", "");
                String uuidName = uuid+fileType;
                File realFile = new File(fileDirPath+uuidName);
                uploadFile.transferTo(realFile);
                String url = "";
                return ImageVO.success(url, width, height);
            } catch (IOException e) {e.printStackTrace();
                return ImageVO.fail();  // 报错返回}
        }
    }
作业:理解反向代理 / 正向代理;磁盘地址优化
退出移动版