CGB2004-京淘项目Day07

   日期:2020-08-08     浏览:88    评论:0    
核心提示:文件上传案例

1.商品上架/下架操作

1.1 业务分析

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

1.2 页面URL分析

1.3 页面JS分析

1.4 实现RestFul调用

1.4.1 重构页面url地址

1.4.2 编辑ItemController


	@RequestMapping("/{status}")
	public SysResult updateStatus(@PathVariable Integer status,Long[] ids){

		itemService.updateStatus(ids,status);
		return SysResult.success();
	}

1.4.3 编辑ItemService


	@Override
	public void updateStatus(Long[] ids, Integer status) {

		itemMapper.updateStatus(ids,status);

		

	}

1.4.4 编辑Mapper接口/xml映射文件

<!--更新商品的状态信息-->
	<update id="updateStatus">
		update tb_item set status = #{status},updated=now() where id in (
			<foreach collection="ids" item="id" separator=",">
				#{id}
			</foreach>
		)
	</update>

2.富文本编辑器

2.1富文本编辑器介绍

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

2.1富文本编辑器入门案例

<%@ 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="width:700px;height:350px" id="editor"></textarea>
</body>
</html>

2.2商品表/商品分类表关系

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

2.3编辑ItemDesc POJO对象

package com.jt.pojo;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;


@TableName("tb_item_desc")
@Data
@Accessors(chain = true)
public class ItemDesc extends BasePojo{

    @TableId                //只标识主键即可
    private Long itemId;    //要求与商品表Id保持一致.
    private String itemDesc;    //商品详情信息
}

2.4编辑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映射文件

}

3.重构后台商品CRUD操作

3.1重构商品入库操作

3.1.1 页面参数提交

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

3.1.2 编辑ItemController

动态接受参数信息 Item/ItemDesc.

3.1.3 编辑ItemService


	@Override
	@Transactional
	public void saveItem(Item item,ItemDesc itemDesc) {
		//保证入库的时间一致
		item.setStatus(1);
		itemMapper.insert(item);
		//分析问题: item表的主键是自增 数据库入库之后才会有主键生成.
		//解决方案: 让数据库完成入库之后自动的实现主键的回显. 该操作由MP方式动态完成
		itemDesc.setItemId(item.getId()); //必然有值
		itemDescMapper.insert(itemDesc);
	}

3.2实现商品详情信息回显

3.2.1 页面url分析

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

3.2.2 页面JS分析

3.2.3 编辑ItemController

说明:根据restFul风格实现商品分类查询.


	@RequestMapping("/query/item/desc/{itemId}")
	public SysResult findItemDescById(@PathVariable  Long itemId){

		ItemDesc itemDesc = itemService.findItemDescById(itemId);
		//将服务器数据返回页面
		return SysResult.success(itemDesc);
	}

3.2.4 编辑ItemService

//根据指定的ID查询商品详情信息
	@Override
	public ItemDesc findItemDescById(Long itemId) {

		return itemDescMapper.selectById(itemId);
	}

3.2.5 页面效果展现

4 文件上传

4.1文件上传入门案例

4.1.1 编辑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>

4.1.2 编辑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 {

    
    @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 "文件上传失败!!!";
        }

    }
}

4.2商品文件上传实现

4.2.1 富文本编辑器返回值说明

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

4.2.2 封装文件上传的返回值VO

package com.jt.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVO implements Serializable {

    private Integer error;  //确认是否有错误 0正常 1错误
    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){

        return new ImageVO(0, url, null, null);
    }

    public static ImageVO success(String url,Integer width,Integer height){

        return new ImageVO(0, url, width, height);
    }

}

4.2.4 文件上传的参数说明


文件上传JS属性配置:

4.2.3 编辑FileController

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


    @RequestMapping("/pic/upload")
    public ImageVO  upload(MultipartFile uploadFile){

        return fileService.upload(uploadFile);
    }

4.2.3编辑FileService

package com.jt.service;

import com.jt.vo.ImageVO;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Service
public class FileServiceImpl implements FileService{

    //定义图片的类型集合.
    private static Set<String> imageTypeSet = new HashSet<>();
    private String localDirPath = "D:/JT-SOFT/images"; //定义本地磁盘目录

    static {
        imageTypeSet.add(".jpg"); //字母小写类型
        imageTypeSet.add(".png");
        imageTypeSet.add(".gif");
        //其他的省略.....
    }

    
    @Override
    public ImageVO upload(MultipartFile uploadFile) {
        //1.校验图片类型 1.利用正则表达式进行校验 2.利用集合进行校验 Set 数据是否存在即可.
        //1.1 获取图片名称 abc.jpg ABC.JPG
        String fileName = uploadFile.getOriginalFilename();
        fileName = fileName.toLowerCase(); //将所有的字母都小写
        //1.2 获取图片的类型
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);    //.jpg
        if(!imageTypeSet.contains(fileType)){ //如果类型不匹配

            return ImageVO.fail();  //图片上传失败.
        }

        //2.如何判断文件是否为恶意程序? 文件是否有图片的特有属性!!!!
        //2.1将上传的文件类型利用图片的API进行转化 如果转化不成功则一定不是图片.
        try {
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            //2.2校验是否有图片的特有属性 高度/宽度
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            //2.3校验宽度和高度是否有值.
            if(width == 0 || height == 0){

                return ImageVO.fail();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVO.fail(); //返回失败即可
        }

        //3.实现分目录存储
        // 方案1: 利用hash之后每隔2-3位截取之后拼接
        // 方案2: 以时间为单位进行分隔 /yyyy/MM/dd/
        //3.1 利用工具API将时间转化为指定的格式
        String datePath = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
        //3.2 动态生成文件目录 2部分=根目录+时间目录
        String localDir = localDirPath + datePath;

        //3.3判断目录是否存在, 如果不存在则新建目录
        File dirFile = new File(localDir);
        if(!dirFile.exists()){

            dirFile.mkdirs();   //如果不存在,则新建目录
        }

        //4. 防止文件重名,需要自定义文件名称 UUID
        //4.1生成uuid
        String  uuid =
                UUID.randomUUID().toString().replace("-", "");
        //4.2动态生成文件名称 uuid +.jpg
        String uuidFileName = uuid + fileType;

        //5.实现文件上传 准备文件全路径 目录+文件名称
        String realFilePath = localDir + uuidFileName;
        //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://img14.360buyimg.com/n1/s546x546_jfs/t1/122216/5/8769/316276/5f2a160eE30a3fbfd/f742fb30fdea6239.jpg";
        return ImageVO.success(url);
    }
}

作业

1.仿照京东商品路径 以 http://image.jt.com/ 路径拼接 形成虚拟记录. 思考路径拼接注意事项
2.能否利用动态赋值的方式 修改属性值.
3.了解什么是方向代理/正向代理/nginx

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服