SSM实战项目——哈哈音乐(三)文件服务器模块开发

1、创建模块

创建一个子模块(hami-fie),里面不写任何代码,专门用于文件上传的服务器

在hami-file的webapp下创建上传文件资源的文件夹,并引入资源(图片、音频)

2、pom.xml主配置文件中引入文件上传的依赖

            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons-io.version}</version>
            </dependency>
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>${commons-fileupload.version}</version>
            </dependency>

 3、在springmvc配置文件中加入文件上传的配置

 <!--文件上传-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10024000"></property>
    </bean>

4、在hami-core中创建sys.properties属性文件

filePath=http://localhost:8082/ecps-file

5、在hami-core中创建属性文件读取工具类

package com.qcby.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class PropReader {
    public static String read(String key){
        String result = null;
        Properties prop = new Properties();
        InputStream stream = PropReader.class.getClassLoader().getResourceAsStream("sys.properties");
        try {
            prop.load(stream);
            result = prop.getProperty(key);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }
}

6、复制一份tomcat作为文件服务器

修改web.xml的配置,让其变成非只读

<servlet>

        <servlet-name>default</servlet-name>

        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>

        <init-param>

            <param-name>debug</param-name>

            <param-value>0</param-value>

        </init-param>

        <init-param>

            <param-name>readonly</param-name>

            <param-value>false</param-value>

        </init-param>

        <init-param>

            <param-name>listings</param-name>

            <param-value>false</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

    </servlet>

7、创建文件上传的Controller

package com.qcby.controller;

import com.alibaba.fastjson.JSONObject;
import com.qcby.util.PropReader;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

/**
 * 文件上传
 */
@Controller
@RequestMapping("/upload")
public class UploadController {
    /**
     * @param picfile  要上传的图片信息
     * @param fileType 文件类型
     * @param request  请求对象
     * @param response 响应对象
     * @param lastImg  用于确定最后一张上传的图片
     * @throws IOException
     */
    @RequestMapping("/uploadFile")
    public void uploadFile(MultipartFile picfile, String fileType, String lastImg, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //1、通过请求对象获取所有有关文件上传的信息
        //2、拿到要上传的文件名称做处理(UUID)
        String originalFilename = picfile.getOriginalFilename();
        String fileName = UUID.randomUUID().toString();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        fileName = fileName + suffix;
        //3、上传位置 上传路径
        String filepath = "http://localhost:8082";
        //绝对路径,用于前端访问
        String realpath = filepath + "/" + fileType + "/" + fileName;
        //相对路径,用于存储到数据库
        String relativepath = "/" + fileType + "/" + fileName;
        //4、获取上传文件的字节流(图片、音频文件等)   字符流(文件文本)
        byte[] bytes = picfile.getBytes();
        //5、利用提供好的类进行文件上传
        //创建jersy的客户端
        Client client = Client.create();
        //获取web资源
        WebResource resource = client.resource(realpath);
        //判断是否为最后一张需要上传的图片,删除老图片
        if (lastImg != null && !"".equals(lastImg)) {
            WebResource resource1 = client.resource(lastImg);
            // 尝试执行HEAD请求以检查资源是否存在
            ClientResponse response1 = resource1.head();
            if (response1.getStatus() == 200) {
                // 资源存在,可以安全地删除
                System.out.println("正在删除资源...");
                response1.close();  // 关闭HEAD请求的响应
                resource1.delete();
            } else {
                // 资源不存在,不需要删除
                System.out.println("资源不存在,无需删除");
            }
        }
        //文件上传
        resource.put(bytes);
        //创建json对象
        JSONObject jo = new JSONObject();
        jo.put("realPath", realpath);
        jo.put("relativePath", relativepath);

        response.getWriter().write(jo.toString());


//        //把Request做强制转换
//        MultipartHttpServletRequest mr = (MultipartHttpServletRequest) request;
//        //获取文件上传相关的所有前端传递信息
//        Map<String, MultipartFile> fileMap = mr.getFileMap();
//        //获取前端传递的文件
//        //MultipartFile file = fileMap.get("picfile");
//        //获取文件名字
//        //String filename = file.getOriginalFilename();
//        Set<String> keySet = fileMap.keySet();
//        Iterator<String> iterator = keySet.iterator();
//        String key = iterator.next();
//        //获得到上传的文件
//        MultipartFile multipartFile = fileMap.get(key);
//        byte[] bytes = multipartFile.getBytes();
//
//        //获得文件的原始文件名
//        String originalFilename = multipartFile.getOriginalFilename();
//        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
//        String fileName = UUID.randomUUID().toString();
//        fileName = fileName + suffix;
//
//        //创建jersy的客户端
//        Client client = Client.create();
//
//        //删除老图片
//        if(StringUtils.isNotBlank(lastImage)){
//            WebResource resource1 = client.resource(lastImage);
//            resource1.delete();
//        }
//
//        //resource的参数文件服务器上的文件的绝对路径
//        WebResource resource = client.resource(PropReader.read("filePath")+"/"+type+"/"+fileName);
//        resource.put(bytes);
//        //创建json对象
//        JSONObject jo = new JSONObject();
//        jo.put("realPath", PropReader.read("filePath")+"/"+type+"/"+fileName);
//        jo.put("relativePath", "/"+type+"/"+fileName);
//
//        response.getWriter().write(jo.toString());
    }

    /**
     * 上传mp3
     * @param mp3file
     * @param fileType
     * @param lastMp3
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping("/uploadFileMp3")
    public void uploadFileMp3(MultipartFile mp3file, String fileType, String lastMp3, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //1、通过请求对象获取所有有关文件上传的信息
        //2、拿到要上传的文件名称做处理(UUID)
        String originalFilename = mp3file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        fileName = fileName + suffix;
        //3、上传位置 上传路径
        String filepath = "http://localhost:8082";
        //绝对路径,用于前端访问
        String realpath = filepath + "/" + fileType + "/" + fileName;
        //相对路径,用于存储到数据库
        String relativepath = "/" + fileType + "/" + fileName;
        //4、获取上传文件的字节流(图片、音频文件等)   字符流(文件文本)
        byte[] bytes = mp3file.getBytes();
        //5、利用提供好的类进行文件上传
        //创建jersy的客户端
        Client client = Client.create();
        //获取web资源
        WebResource resource = client.resource(realpath);
        //判断是否为最后一张需要上传的MP3,删除老mp3
        if (lastMp3 != null && !"".equals(lastMp3)) {
            WebResource resource1 = client.resource(lastMp3);
            // 尝试执行HEAD请求以检查资源是否存在
            ClientResponse response1 = resource1.head();
            if (response1.getStatus() == 200) {
                // 资源存在,可以安全地删除
                System.out.println("正在删除资源...");
                response1.close();  // 关闭HEAD请求的响应
                resource1.delete();
            } else {
                // 资源不存在,不需要删除
                System.out.println("资源不存在,无需删除");
            }
        }
        //文件上传
        resource.put(bytes);
        //创建json对象
        JSONObject jo = new JSONObject();
        jo.put("realPath", realpath);
        jo.put("relativePath", relativepath);

        response.getWriter().write(jo.toString());

    }
}

8、前端ajax的调用和返回

上传图片

function  submitFile(){
            $("#location").val($("#i-file").val());
            $("#songerForm").ajaxSubmit({
                url:"/upload/uploadFile",
                data:{
                    fileType:"pic"
                },
                dataType:"json",
                success:function (json) {
                    $("#songerImg").attr("src",json.realPath);
                    $(".example-image-link").attr("href",json.realPath);
                    $("#lastImg").val(json.realPath);
                    $("#pic").val(json.relativePath);
                }
            })
        }

上传MP3

function  submitFile(){
            $("#mp3loc").val($("#i1-file").val());
            $("#song-form").ajaxSubmit({
                url:"/upload/uploadFileMp3",
                data:{
                    fileType:"mp3"
                },
                dataType:"json",
                success:function (json) {
                    $("#lastMp3").val(json.realPath);
                    $("#mp3").val(json.relativePath);
                    $("audio").attr("src",json.realPath)
                }
            })
        }

数据库存入文件路径形式

9、前端文件上传代码

<div class="controls form-group">
    <div class="col-sm-4 col-md-2">
        <div class="image-row">
            <div class="image-set">
                <a class="example-image-link" href="../../img/gallery-photo/image-3.jpg" data-lightbox="example-set" title="Click on the right side of the image to move forward.">
                <img id="songerImg" class="example-image" src="../../img/gallery-photo/thumb-3.jpg" alt="Plants: image 1 0f 4 thumb" width="150" height="150" />
                </a>
             </div>
         </div>
     </div>
</div>
<label for="i-file" class="control-label">选择文件 <span class="required">*</span></label>
    <div id="examples" class="section examples-section">
         <div class="col-sm-6">
              <div class="input-group">
                   <input id='location' class="form-control" onclick="$('#i-file').click();">
                   <label class="input-group-btn">
                   <input type="button" id="i-check" value="选择封面" class="btn btn-primary" onclick="$('#i-file').click();">
                   </label>
               </div>
          </div>
    <input type="hidden" id="pic" name="pic" lay-verify="pic">
    <input type="hidden" id="lastImg" name="lastImg">
    <input type="file" name="picfile" id='i-file'  accept=".jpg, .png" onchange="submitFile()" style="display: none">
</div>

a标签class="example-image-link"用于对图片的放大缩小显示,值为绝对路径

img标签id="songerImg"用于显示上传到服务器的图片,值为绝对路径

input输入框中id="pic" 用于存储存入数据库的图片路径,值为相对路径

input输入框中id="lastImg"用于存储上一次上传图片的路径,值为绝对路径,如果图片上传多次,但是没有提交到数据库,那么前几次上传到服务器中的图片将被删除,只保留最后提交的一次图片,并将图片的相对存入数据库

MP3文件上传的逻辑与图片文件上传相似

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/519252.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

提升提测质量之研测共建

提升提测质量之研测共建 简介 你是否也有同样的困惑&#xff1f;跟进的需求&#xff0c;就在提测前一秒&#xff0c;被告知不能如期提测了&#xff0c;研测计划被打乱&#xff1b;提测的功能&#xff0c;犹如遇到不好的购物体验&#xff0c;缺斤短两&#xff0c;与prd预期不符…

Elasticsearch:我们如何演化处理二进制文档格式

作者&#xff1a;来自 Elastic Sean Story 从二进制文件中提取内容是一个常见的用例。一些 PDF 文件可能非常庞大 — 考虑到几 GB 甚至更多。Elastic 在处理此类文档方面已经取得了长足的进步&#xff0c;今天&#xff0c;我们很高兴地介绍我们的新工具 —— 数据提取服务&…

AopContext.currentProxy() 的代理对象错误(未被更新)问题

背景&#xff1a; 原来在springAOP的用法中&#xff0c;只有代理的类才会被切入&#xff0c;我们在controller层调用service的方法的时候&#xff0c;是可以被切入的&#xff0c;但是如果我们在service层 A方法中&#xff0c;调用B方法&#xff0c;切点切的是B方法&#xff0c;…

猫头虎技术分享 || 断网了,还能ping127.0.0.1吗?

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

开源大语言模型(LLM)汇总(持续更新中)

随着ChatGPT的火爆&#xff0c;越来越多人希望在本地运行一个大语言模型。为此我维护了这个开源大语言模型汇总&#xff0c;跟踪每天不发的大语言模型和精调语言模型。 我将根据个模型采用的基础大模型进行分类&#xff0c;每个大模型下列出各派生模型。 Alpaca (Stanford) 斯…

Java毕业设计 基于SSM jsp商城系统 美妆系统

Java毕业设计 基于SSM jsp商城系统 美妆系统 SSM jsp 商城系统 美妆系统 功能介绍 首页 分类展示商品 搜索商品 登录 注册 邮箱激活 购物车 结算 支付 我的订单 个人信息设置 后台管理 登录 商品管理 添加修改下架商品 商品类型管理 添加修改删除分类 订单管理 确认发货 取消…

SAP HCM 多成本中心薪酬过账标准程序解读

SAP HCM薪酬过账会涉及到CO对象&#xff0c;CO对象主要是成本中心、WBS、内部订单、订单等&#xff0c;成本中心有多个维护地方0001信息类型0027信息类型等&#xff0c;那么成本中心多个地方维护&#xff0c;优先级是如何&#xff0c;0027>1018>0001,也就是说人身上的优先…

微电网优化:基于​海象优化算法(Walrus Optimization Algorithm,WOA)​的微电网优化(提供MATLAB代码)

一、微电网优化模型 微电网是一个相对独立的本地化电力单元&#xff0c;用户现场的分布式发电可以支持用电需求。为此&#xff0c;您的微电网将接入、监控、预测和控制您本地的分布式能源系统&#xff0c;同时强化供电系统的弹性&#xff0c;保障您的用电更经济。您可以在连接…

隐语SecretFlow实训营-第8讲:快速上手隐语SCQL的开发实践

SCQL使用/集成实践 目前SCQL只开放API供用户使用/集成 使用SCDBClient上手体验可以基于SCQL API开发封装白屏产品&#xff0c;或集成到业务链路中 使用流程&#xff1a; 部署系统 环境配置&#xff1a; 机器配置&#xff1a;CPU/MEM最低8C16G机构之间的网络互通 镜像&…

雪球acw_sc__v2 加密参数构造解析

打开雪球网站:https://xueqiu.com/today 首先打开Edge浏览器,清除应用程序里面的cookie 接着,跳转到源代码,刷新网页,进行调试,首先进入debugger模式,需要反debug调试。 输入相关代码,解除subug模式 点击保留日志,这里显示有两次请求,分别分析下。 第一个today返…

重读Java设计模式: 适配器模式解析

引言 在软件开发中&#xff0c;经常会遇到不同接口之间的兼容性问题。当需要使用一个已有的类&#xff0c;但其接口与我们所需的不兼容时&#xff0c;我们可以通过适配器模式来解决这一问题。适配器模式是一种结构型设计模式&#xff0c;它允许接口不兼容的类之间进行合作。本…

AI绘画:使用ComfyUI结合LCM进行实时绘图:开启AI艺术创作新篇章

在数字艺术的世界里&#xff0c;ComfyUI和LCM&#xff08;Latent Contextual Modulation&#xff09;的结合为艺术家和设计师们提供了一个强大的实时绘图工具。LCM是一种先进的技术&#xff0c;它能够实时地将用户的输入和反馈融入到图像生成过程中&#xff0c;从而创造出动态变…

Vue3从入门到实战:掌握状态管理库pinia(上部分)

1.新的状态管理工具pinia Pinia 是一个状态管理库&#xff0c;通俗点讲&#xff0c;它的主要作用就是帮助我们在 Vue 3 应用中更好地管理和维护组件的状态。 举例子解释&#xff1a; 新建一个Count.vue文件&#xff0c;功能用来计数求和。 <template><div class&q…

【MATLAB】哈里斯鹰优化(HHO)

发表在中科院二区Future Generation Computer Systems期刊上的论文“Harris hawks optimization: Algorithm and applications" 01.引言 本文提出了一种基于种群的、受自然启发的优化范式&#xff0c;称为Harris Hawks Optimizer (HHO)。HHO的主要灵感来源于自然界中哈里…

day64 单调栈part03

柱状图中最大的矩形 困难 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 看了一圈 最后还是别的题解几句话看明白了 明确一点&#xff0c;遍历每个高…

004 CSS介绍2

文章目录 css最常用属性link元素进制css颜色表示浏览器的渲染流程(不含js) css最常用属性 font-size 文字大小 color:前景色(文字颜色) background-color:背景色 width:宽度 height:高度 link元素 也可以用来创建站点图标 link元素常见属性 href:指定被链接资源的URL rel:指…

Proxifier监控流量转发Charles

Charles开启 SOCKS Proxy 在Proxifier的Proxy Servers选项中点击add添加如下规则&#xff1a;127.0.0.1:8889&#xff0c; 端口号8889对应Charles开放的端口号&#xff0c; 选择SOCKS5&#xff0c;支持监控http和https 配置好之后点击Check进行验证, 点击Test Settings选项&…

二.音视频编辑-媒体组合-播放

引言 当涉及到音视频编辑时&#xff0c;媒体资源的提取和组合是至关重要的环节。在iOS平台上&#xff0c;AVFoundation框架提供了丰富而强大的功能&#xff0c;使得媒体资源的操作变得轻松而高效。从原始的媒体中提取片段&#xff0c;然后将它们巧妙地组合成一个完整的作品&am…

SV学习笔记(二)

接口 什么是接口&#xff1f; 接口 主要用作验证 &#xff0c;国外有些团队会使用sv进行设计&#xff0c;那么接口就会用作设计。验证环境中&#xff0c;接口可以 使连接变得简洁而不易出错 。interface和module的使用性质很像&#xff0c; 可以定义端口&#xff0c;也可以定…

文心一言 VS 讯飞星火 VS chatgpt (230)-- 算法导论17.1 1题

一、如果栈操作包括 MULTIPUSH 操作&#xff0c;它将 k 个数据项压入栈中&#xff0c;那么栈操作的摊还代价的界还是 O(1) 吗? 文心一言&#xff1a; 在栈的基本操作中&#xff0c;我们通常考虑的是单个元素的压入&#xff08;push&#xff09;和弹出&#xff08;pop&#x…