zoukankan      html  css  js  c++  java
  • java学习day69-JT项目07-(商品/详情一对一操作//文件上传)

    商品上架/下架

    业务分析

    当用户点击商品上架下架操作时,应该修改数据库中的状态信息status

    分析:

    1. 下架操作 /item/instock status=2
    2. 上架操作 /item/reshelf status=1

    restFul优化:

    1. 下架操作 /item/updateStatus/2
    2. 上架操作 /item/updateStatus/1

    页面URL分析

    1596590030625

    页面JS

    1596698691970

    实现RestFul调用

    重构页面url地址

    1596698805250

    编辑ItemController

    //商品上下架操作,使用restful风格
    @RequestMapping("/updateStatus/{status}")
    public SysResult updateStatus(Long[] ids,@PathVariable("status") Integer status){
        itemService.updatStatus(ids,status);
        return  SysResult.success();
    }
    

    编辑ItemService

    //利用手写sql实现状态修改
    @Override
    public void updatStatus(Long[] ids, Integer status) {
        itemMapper.updown(ids,status);
    
    }
    
    //利用MP实现状态修改(上下架操作)
    //	@Override
    //	public void updatStatus(Long[] ids, Integer status) {
    //		List<Long> idsList = Arrays.asList(ids);//数组转化为集合
    //		UpdateWrapper<Item> updateWrapper = new UpdateWrapper<>();
    //
    //		updateWrapper.in("id",idsList);
    //		Item item = new Item();
    //		item.setStatus(status);
    //		itemMapper.update(item,updateWrapper);
    //
    //	}
    

    编辑Mapper接口/xml映射文件

    1596699019669

    <update id="updown">
        update  tb_item set status =#{status},updated=now()
        where id in(
        <foreach collection="ids" item="id" separator=",">
            #{id}
        </foreach>
        )
    </update>
    

    富文本编辑器

    富文本编辑器介绍

    ​ KindEditor是一套开源的HTML可视化编辑器,主要用于让用户在网站上获得所见即所得编辑效果,兼容IE、Firefox、Chrome、Safari、Opera等主流浏览器。

    富文本编辑器入门案例

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">
    <script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script>
    <script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script>
    <script type="text/javascript" charset="utf-8" src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>
    
    <script type="text/javascript">
    	$(function(){
    	    //在指定的为止初始化富文本.
    		KindEditor.ready(function(){
    			KindEditor.create("#editor")
    		})
    	})
    </script>
    </head>
    <body>
    <h1>富文本编辑器</h1>
    
    <textarea style="700px;height:350px" id="editor"></textarea>
    </body>
    </html>
    

    商品表/商品详情表关系

    说明:由于用户查询商品时,首先查询的是商品的主要信息.如果用户对某个商品感兴趣,才会查询商品详情信息.所以采用2张表的形式 展现商品/商品详情.
    思考: 商品信息由商品/详情2部分构成.所有CRUD操作应该同时操作商品详情表.应该实现关联的操作.

    1596699239639

    编辑ItemDesc POJO对象

    package com.jt.pojo;
    /**
     * 构建商品详情的POJO对象
     *
     */
    @TableName("tb_item_desc")
    @Data
    @Accessors(chain = true)
    public class ItemDesc extends BasePojo{
    
        @TableId                //只标识主键即可
        private Long itemId;    //要求与商品表Id保持一致.
        private String itemDesc;    //商品详情信息
    }
    
    
    

    编辑ItemDescMapper

    package com.jt.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.jt.pojo.ItemDesc;
    //继承接口并且要指定对应的表
    public interface ItemDescMapper extends BaseMapper<ItemDesc> {//对象与表进行绑定
        //如果自己不写sql,则可以省略mapper映射文件的编写
    }
    

    重构后台商品CRUD操作

    重构商品入库操作

    页面参数提交

    说明:在原有的商品新增的基础之上,完成商品详情新增操作.

    1596699383588

    编辑ItemController

    动态接受参数信息 Item/ItemDesc.完成入库修改删除操作

    //需要完成两张表的入库操作
    @RequestMapping("/save")
    public SysResult saveItem(Item item, ItemDesc itemDesc){
        itemService.saveItem(item,itemDesc);
        return  SysResult.success();
    }
    

    编辑ItemService

    //保存商品 完成两张表的入库操作,保证商品的id与商品详情id一致
    //注意事项: 完成数据库数据更新操作时,需要注意数据库事务问题
    @Transactional
    @Override
    public void saveItem(Item item , ItemDesc itemDesc) {
        //保存信息时要记录更改时间
        //		item.setStatus(1).setCreated(new Date()).setUpdated(item.getCreated());
        item.setStatus(1);
        //典型一对一的插入
        itemMapper.insert(item);
        //分析问题: item表的 主键是自增数据库入库之后才会有 主键生成.
        //解决方案:让数据库完成入库之后自动的实现主键的回显。改操作由MP机制动态完成
        //<insert id="xxx" keyProperty="id" useGeneratedKeys="true"></insert>
        itemDesc.setItemId(item.getId());
        itemDescMapper.insert(itemDesc);
    
    }
    

    实现商品详情信息回显

    页面url分析

    说明:检查商品详情展现的url地址路径.

    1596699780262

    页面JS分析

    1596699871372

    编辑ItemController

    说明:根据restFul风格实现商品详情查询.

    /**
    * 	根据商品id查询商品详情信息
    http://localhost:8091/item/query/item/desc/1474391987
    参数:  包含在url中,利用restFul方式动态获取
    * 返回值:  SysResult对象
    *
    */
    @RequestMapping("/query/item/desc/{itemId}")
    public SysResult findItemDescById(@PathVariable("itemId") Long itemId){
    ItemDesc itemDesc= itemService.findItemDescById(itemId);
    //将服务器数据返回页面
    return  SysResult.success(itemDesc);
    }
    

    编辑ItemService

    //根据指定的ID查询商品详情信息
    @Override
    public ItemDesc findItemDescById(Long itemId) {
        ItemDesc itemDesc = itemDescMapper.selectById(itemId);
        return itemDesc;
    }
    

    重构商品修改以及删除操作

    编辑ItemController

    //商品修改操作
    /**
    	 * 完成商品信息修改
    	 * url:http://localhost:8091/item/update
    	 * 参数: 整个商品表单
    	 * 返回值: SysResult对象
    	 */
    @RequestMapping("/update")
    public SysResult updateItem(Item item, ItemDesc itemDesc){
        itemService.updateItem(item,itemDesc);
        return   SysResult.success();
    }
    //删除商品信息 批量删除 (单个删除)
    //springmvc知识点: 可以根据指定的类型动态的实现参数类型的转化 规则: 如果字符串使用","分割,则可以使用数组的形式传参
    /**
    	 * 业务需求: 完成商品删除操作
    	 * url请求地址: /item/delete
    	 * 参数: ids=  id1,id2 串
    	 * 返回值结果:  SysResult对象
    	 * SpringMVC知识点: 可以根据制定的类型动态的实现参数类型的转化.
    	 * 					如果字符串使用","号分隔,则可以使用数组的方式接参.
    	 */
    @RequestMapping("/delete")
    public SysResult deleteItems(Long[] ids){
        itemService.deleteItemsByIds(ids);
        return   SysResult.success();
    }
    

    编辑ItemService

    //修改商品信息
    @Transactional
    @Override
    public void updateItem(Item item , ItemDesc itemDesc) {
        item.setStatus(1);
        //		item.setStatus(1).setCreated(new Date()).setUpdated(item.getCreated());
        itemMapper.updateById(item);//设定主键
        itemDesc.setItemId(item.getId());
        //实现商品详情的更新
        itemDescMapper.updateById(itemDesc);
    }
    //删除商品信息
    @Transactional
    @Override
    public void deleteItemsByIds(Long[] ids) {
        //将数组转化为集合
        //		List<Long> idsList = Arrays.asList(ids);
        //		itemMapper.deleteBatchIds(idsList);
        itemMapper.deleteItems(ids);
        //根据商品id删除商品的详情信息
        itemDescMapper.deleteItemDescByIds(ids);
    }
    

    编辑ItemDescMapper接口

    package com.jt.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.jt.pojo.ItemDesc;
    //继承接口并且要指定对应的表
    public interface ItemDescMapper extends BaseMapper<ItemDesc> {//对象与表进行绑定
        //如果自己不写sql,则可以省略mapper映射文件的编写
        void deleteItemDescByIds(Long[] ids);
    
    }
    

    编辑ItemDescMapper.xml文件

    <delete id="deleteItemDescByIds">
        delete  from tb_item_desc
        <where>
            item_id in
            <foreach collection="array" item="id" open="(" close=")" separator=",">
                #{id}
            </foreach>
        </where>
    </delete>
    

    商品详情展示

    1596700454135

    文件上传

    文件上传入门案例

    编辑HTML页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    	<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>
    </body>
    </html>
    

    编辑FileController

    package com.jt.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    
    @RestController
    public class FileController {
    
        /**
         * 完成文件上传的入门案例
         * url地址: http://localhost:8091/file
         * 请求参数: fileImage
         * 返回值:   文件上传成功
         *
         * 利用SpringMVC中提供的工具API,实现文件上传的简化.
         * 记住类型:MultipartFile
         * 实现步骤:
         *      1.接收资源文件
         *      2.准备文件上传目录
         *      3.准备文件上传的全路径   目录/文件名称
         常识: 
    	 * 		1.必须指定文件上传的路径信息   D:JT-SOFTimages文件名称.jpg
    	 * 		2.将字节信息利用outPutStream进行输出操作
    	 * 
    	 * 说明:文件上传默认大小1M=1024*1024   
    	 * 具体参见CommonsFileUploadSupport类
         */
        @RequestMapping("/file")
        public String  file(MultipartFile fileImage){
    
           //2.文件文件上传的目录
            String fileDirPath = "D:/JT-SOFT/images";
            File dirFile = new File(fileDirPath);
            //判断文件目录是否存在
            if(!dirFile.exists()){
                //如果文化间目录没有,则应该新建目录
                dirFile.mkdirs(); //创建多级目录
            }
    
            //3.准备文件上传的全路径.  路径+文件名称
            String fileName = fileImage.getOriginalFilename();  //文件名称.后缀   123.jgp
            File realFile = new File(fileDirPath+"/"+fileName);
            //将字节信息输出到文件中.
            try {
                fileImage.transferTo(realFile); //实现文件上传
                return "文件上传成功!!!";
            } catch (IOException e) {
                e.printStackTrace();
                return "文件上传失败!!!";
            }
    
        }
    }
    

    商品文件上传实现

    富文本编辑器返回值说明

    {“error”:0,“url”:“图片的保存路径”,“width”:图片的宽度,“height”:图片的高度}
    属性1: error 如果在文件上传的过程中出现问题 则标识为1 ,如果没有错误 标识为0.
    属性2: url 代表图片的虚拟访问地址. 磁盘地址
    属性3: width/height 获取图片的宽高 可以省略.

    封装文件上传的返回值VO-ImageVO

    package com.jt.vo;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Accessors(chain = true)
    public class ImageVO implements Serializable {
    
        private static final long serialVersionUID = -5302337766946721739L;
        private  Integer error;//确认图片是否有误 0 正常  1 错误
        private String url;  //图片访问的虚拟地址
        private  Integer width; //宽度
        private  Integer height; //高度
    
        //通过工具API
        public static ImageVO fail(){
            return  new ImageVO(1,null,null,null);
        }
        public static ImageVO success(String url){
            return  new ImageVO(0,url,null,null);
        }
        public static ImageVO success(String url,Integer width,Integer height){
            return  new ImageVO(0,url,width,height);
        }
    
    }
    

    文件上传的参数说明

    请求的url分析

    1596701033980

    文件上传JS属性配置:

    1596701054469

    编辑FileController

    说明: 文件上传时,需要注意富文本编辑器中传递的url参数.

    	/**
    	 * 业务分析:实现文件上传.
    	 * 1.url地址: http://localhost:8091/pic/upload
    	 * 2.参数:   uploadFile  文件上传对象
    	 * 3.返回值:  ImageVO对象
    	 */
    	@RequestMapping("/pic/upload")
    	public ImageVO uploadFile(MultipartFile uploadFile) {
    		//直接交给业务层处理	
    		return fileService.uploadFile(uploadFile);
    	}
    
    

    编辑FileService

    package com.jt.service;
    
    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;
    
    @Service
    public class FileServiceImpl implements FileService {
        //创建根目录
        private String localDirPath ="D:/JT-SOFT/images";
        private  static Set<String> imageTypeSet = new HashSet<>();
        static {
            imageTypeSet.add(".jpg");
            imageTypeSet.add(".png");
            imageTypeSet.add(".gif");
            //.....可以动态的添加
        }
    
        /**
         *
         * 1.校验文件有效性. jpg/. png|. gif......
         * 2.校验文件是否为恶意程序 (木马. exe).jpg
         * 3.提高用户检索图片的效率  分目录存储.
         * 4.为了防止重名图片的提交自定义文件名称.
         * 5.实现图片的物理上传 本地磁盘中.
         * 6.准备一个访问图片的虚拟路径
         *  @param uploadFile
         * @return
         */
    
        @Override
        public ImageVO upload(MultipartFile uploadFile) {
            //1 校验图片类型 1) 利用正则表达式进行校验 2)指定一个集合进行校验
            //1.1获取文件名称
            String fileName= uploadFile.getOriginalFilename();
            fileName = fileName.toLowerCase();
            //1.2获取文件名称后缀,然后将获取的后缀转为小写
            String fileType = fileName.substring(fileName.lastIndexOf("."));
    
            //进行校验
            if (!imageTypeSet.contains(fileType)){
                //如果类型不匹配,应该告诉用户上传图片有误
                //
                return ImageVO.fail();
            }
            //.校验文件是否为恶意程序 (木马. exe).jpg 方法:通过图片的特有属性进行校验
            try {
               //2.1  将上传的图片利用图片API进行转化,如果不能成功转化则一定不是图片
                BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
                //校验图片的特有属性 宽度和高度
                int width = bufferedImage.getWidth();
                int height = bufferedImage.getHeight();
                if (width==0 || height == 0){
                    //如果获取的宽或者高为0 则不是图片
                    return  ImageVO.fail();
                }
    
            } catch (IOException e) {
                e.printStackTrace();
                return  ImageVO.fail();
            }
            //实现分目录存储 方案1 利用hash 之后每隔2-3位进行
            //方案2 通过时间来划分目录
            //获取格式化时间 利用工具API
            String datePath = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
            //创建文件目录 2部分 根目录+时间目录
            String localDir = localDirPath+datePath;
            File dirFile = new File(localDir);
            if (!dirFile.exists()){
                dirFile.mkdirs();
            }
            //4防止文件重名,需要自定义名称 UUID
            //4.1 生成uuid
            String uuid = UUID.randomUUID().toString().replace("-","");
            //4.2 动态生成文件名称
            String uuidName = uuid+fileType;
            //5 实现文件上传 准备文件全路径
            String realFilePath = localDir+uuidName;
            //5.1 封装文件真实对象
            File imageFile = new File(realFilePath);
            //5.2 实现文件上传
            try {
                uploadFile.transferTo(imageFile);
    
            } catch (IOException e) {
                e.printStackTrace();
                return  ImageVO.fail();
            }
            //6.暂时使用虚拟路径
            String url ="https://s1.ax1x.com/2020/08/02/atSA6U.png";
            return ImageVO.success(url);
        }
    }
    
    
    
  • 相关阅读:
    开始学习编写用于 Windows SideShow 设备的小工具【转】
    Windows Mobile 6.5 Developer Tool Kit 下载
    Microsoft Security Essentials 微软免费杀毒软件下载
    SQL Server 2008 空间数据存储摘抄(SRID 点 MultiPoint LineString MultiLineString 多边形 MultiPolygon GeometryCollection)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (2)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (4)
    负载测试、压力测试和性能测试的异同
    Windows Server 2008 Vista Sidebar Gadget (侧边栏小工具) 入门开发实例
    Silverlight Tools 安装失败 解决办法
    SQL Server 2008 空间数据库 空间索引概念及创建(取自帮助)
  • 原文地址:https://www.cnblogs.com/liqbk/p/13447199.html
Copyright © 2011-2022 走看看