在线音乐播放器 --- 图片上传

本文档详细介绍了如何在后端和前端实现图片上传功能,并解决浏览器因安全限制无法直接访问本地文件的问题。通过配置虚拟路径映射本地路径,使得前端能够安全地访问服务器上的图片资源。同时,提供了前端HTML和CSS代码,以及后端处理图片上传的Java代码,包括文件类型的检查和防止文件名冲突的UUID处理。

1. 图片上传功能

由于之前的上传功能, 上传的只有固定的图片, 并没有实现图片的上传功能. 这里就来完善上传功能.

这里使用固定的地址上传, 要想前端再去访问该地址, 启动的项目去直接访问本地的静态地址会有报错 (Not allowed to load local resource)

原因: 浏览器出于安全方面的考虑,禁止网页访问本地文件,因为图片是存在项目目录下的,所以无法通过本地的 url 进行访问。

在linux服务器上, 上传到服务器上的地址里, 想要去直接访问服务上的文件夹, 也是不可能的.

解决办法: 配置 虚拟路径 映射 本地路径

1.1 配置虚拟路径

这里将 本地路径 映射到了 虚拟路径, 这里就可以通过虚拟路径来访问本地路径里的内容了

@Configuration
public class AppConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 这里 "/prodecut/**" 是虚拟路径
        // 这里 "file:E/images/" 是本地路径  
	    registry.addResourceHandler("/product/**").addResourceLocations("file:E:/images/");
    }
}

1.2 前端代码

这里对前端上传功能进行完善
在这里插入图片描述
在这里插入图片描述

1.2.1 upload.html

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
    <title>上传音乐</title>
    <link rel="stylesheet" href="css/upload.css">
</head>
<body>
<!--enctype="multipart/form-data"-->
<form  enctype="multipart/form-data" id="form1">
    <div class="one">
        <span class="message">文件上传: </span>
        <input type="file" name="filename" id="file" />
    </div>
    <div class="one">
        <span class="message">歌手姓名: </span>
        <label><input type="text" name="singer" placeholder="请输入歌手名" id="singer" /> </label>
    </div>
    <div class="one">
        <span class="message">封面选择: </span>
        <input type="file" id="file2" name="imgname" onchange="upCh(this)"/>
    </div>

    <div class="one">
        <span class="message">图片样式: </span>
        <img id="fileimg" src="" />
    </div>
    <div class="one">
        <input type="button" value="上传" id="submit" onclick="login()"/>
    </div>
</form>

<script src="js/jquery-3.3.1.min.js"></script>
<script>

    function upCh(file) {
        let img = document.getElementById('fileimg');
        let formData = new FormData();
        let imgUrl = file.files[0];
        console.log(imgUrl);
        if (imgUrl) {
            console.log(1);
            formData.append('file',imgUrl);
            img.src = window.URL.createObjectURL(imgUrl);
        }
    }
    function login(){
        // 获取到这里的文件信息
        let filename = $('#file')[0].files[0];
        if (filename == undefined) {
            alert("请选择文件!");
            return;
        }
        // 获取到这里的歌手信息
        let singer = document.querySelector('#singer');
        if (singer.value.trim() == ""){
            alert("请添加歌手!");
            return;
        }
        // 获取到图片信息
        let imgname = $('#file2')[0].files[0];
        if (imgname == undefined) {
            alert("请选择图片!");
            return;
        }
        let isJPG = imgname.type === "image/jpeg";
        if (!isJPG){
            alert("上传图片格式部是jpg的!");
            return;
        }
        // 使用formData来返回
        let formData = new FormData($("#form1")[0]);
        formData.append("filename",filename);
        formData.append("singer",singer.value.trim());
        formData.append("imgname",imgname);
        $.ajax({
            type: "POST",
            url: "music/upload",
            data: formData,
            processData: false,
            contentType: false,
            success: function(data) {
                if(data.status == -1){
                    alert(data.message);
                    location.assign("upload.html");
                }else{
                    alert(data.message);
                    location.assign("index.html");
                }
            },
            error:function() {
                alert("出现异常");
                location.assign("upload.html");
            }
        });
    }
</script>
</body>
</html>

1.2.2 upload.css

#form1{
    display: flex;
    flex-direction: column;
    align-items: center;
}
.one{
    display: flex;
    justify-content: center;
    align-items: center;
}
.one .message{
    width: 110px;
    height: 50px;
    line-height: 50px;
    font-weight: 600;
}

.one input{
    width: 200px;
    height: 30px;
    border-radius: 5px;
    padding: 0;
}
#singer{
    width:192px;
    padding-left: 4px;
}

#submit{
    margin-top: 10px;
}
#submit:active{
    background: #f23a2e;
    color: #fff;
}

#fileimg{
    width: 200px;
    height: 200px;
    border: 1px solid #eee;
}
.Btn{
    width: 100px;
    background: #4BCD61;
    border: 0px;
}

1.3 后端代码

这里的图片上传, 要注意图片名不能出现一致的情况, 所以这里用到 UUID 进行处理

配置文件

upload.path=E:/logs/

uploadImg=E:/images/

具体代码

	@Value("${upload.path}")
    public String SAVE_PATH;

    @Value("${uploadImg}")
    public String IMG_PATH;
    /**
     * 上传音乐
     * @param singer
     * @param file
     * @param request
     * @return
     */
    @RequestMapping("/upload")
    public ResponseBodyMessage<Boolean> insertMusic(@RequestPart("singer") String singer,
                                                    @RequestPart("filename") MultipartFile file,
                                                    @RequestPart("imgname") MultipartFile img,
                                                    HttpServletRequest request,
                                                    HttpServletResponse response) {
        // 检测登录
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute(Constant.USER_SESSION_KEY) == null) {
            System.out.println("当前未登录!");
            return new ResponseBodyMessage<>(-1,"请登录后上传",false);
        }

        // 文件的类型
        String fileNameAndType = file.getOriginalFilename();
        String imgType = img.getOriginalFilename();
        String ext = img.getOriginalFilename().substring(img.getOriginalFilename().lastIndexOf("."));
        String imgNewName = UUID.randomUUID().toString().replaceAll("-","")+ext;
        // 防止出现重复的相同歌曲和相同歌手.可以出现相同歌曲不同歌手
        String title = fileNameAndType.substring(0,fileNameAndType.lastIndexOf('.'));
        // 可能出现多首名称相同的歌曲, 所以用 List
        List<Music> list = musicService.selectByTitle(title);
        if(list != null){
            for(Music music : list) {
                if(music.getAuthor().equals(singer)){
                    return new ResponseBodyMessage<>(-1,"当前歌手的歌曲已经存在!",false);
                }
            }
        }

        // 创建文件
        String path = SAVE_PATH +singer+"-"+fileNameAndType;
        String path2 = IMG_PATH + imgNewName;
        File dest = new File(path);
        if(!dest.exists()) {
            dest.mkdirs();
        }
        File dest2 = new File(path2);
        if(!dest.exists()) {
            dest.mkdirs();
        }

        try {
            file.transferTo(dest);
            //return new ResponseBodyMessage<>(1,"上传成功!",true);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseBodyMessage<>(-1,"服务器上传音乐文件失败!",false);
        }

        try {
            img.transferTo(dest2);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseBodyMessage<>(-1,"服务器上传图片文件失败!",false);
        }

        // 这里对是不是 MP3 文件进行判断. 主要是判断是否存在 TAG 这个字符
        File file1 = new File(path);
        byte[] res = null;
        try {
            res = Files.readAllBytes(file1.toPath());
            if(res == null) {
                return new ResponseBodyMessage<>(-1,"当前文件不存在",false);
            }
            String str = new String(res);
            if(str.indexOf("ID3") != 0 && str.lastIndexOf("TAG") != str.length() - 128) {
                file1.delete();
                return new ResponseBodyMessage<>(-1,"当前不是mp3文件",false);
            }
        }catch (IOException e){
            e.printStackTrace();
            return new ResponseBodyMessage<>(-1,"服务器出现问题", false);
        }

        // 在数据库中上传数据
        User user = (User) session.getAttribute(Constant.USER_SESSION_KEY);
        // 这里传递的 path 没有带 `.MP3` 后期在前端进行设置
        String uploadPath = "/music/play?path="+singer+"-"+title;
        String imgPath = "/product/"+ imgNewName;
        try {
            int ret = musicService.insert(title,singer,uploadPath,imgPath,user.getUserId());
            if(ret == 1) {
                // response.sendRedirect("/index.html");
                return new ResponseBodyMessage<>(1,"上传成功",true);
            }else {
                return new ResponseBodyMessage<>(-1,"数据库上传失败",false);
            }
        }catch (BindingException e) {
            dest.delete();
            return new ResponseBodyMessage<>(-1,"数据库上传失败",false);
        }

    }
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独一无二的哈密瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值