当前位置: 首页 > news >正文

本地音乐服务器(二)

 4. 上传音乐模块设计

4.1 上传音乐的接口设计

请求和响应设计:

新建music实体类:

@Data
public class Music {private int id;private String title;private String singer;private String time;private String url;private int userid;
}

4.2 创建MusicController类

package com.example.spring_musicserver_1113.controller;import com.example.spring_musicserver_1113.tools.Constant;
import com.example.spring_musicserver_1113.tools.ResponseBodyMessage;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;/*** @version 1.0* @Author 作者名* @Date 2024/11/14 13:19* @注释*/
@RestController
@RequestMapping("/music")
public class MusicController {private String SAVE_PATH="D:/music/";@RequestMapping("/upload")public ResponseBodyMessage<Boolean> insertMusic(@RequestParam String singer,@RequestParam("filename") MultipartFile file, HttpServletRequest request){//1、判断登录情况HttpSession httpSession = request.getSession(false);if(httpSession == null || httpSession.getAttribute(Constant.USERINFO_SESSION_KEY) == null){System.out.println("没有登录!");return new ResponseBodyMessage<>(-1,"请登录后上传",false);}//2、上传到服务器String fileNameAndType = file.getOriginalFilename();System.out.println("fileNameAndType"+fileNameAndType);String path = SAVE_PATH + fileNameAndType;File dest = new File(path);if(!dest.exists()){dest.mkdir();}try {file.transferTo(dest);return new ResponseBodyMessage<>(0,"上传成功",true);} catch (IOException e) {e.printStackTrace();}return new ResponseBodyMessage<>(-1,"上传失败",false);}
}

使用postman进行测试:

首先登录,其次在上传音乐:

        但是我们在目标路径下面得到上传的文件:

优化一下上传路径细节:

首先在properties文件里面进行配置:

其次通过@value注入上传文件的路径:

重新部署,进行测试,无误;

4.3 如何判断上传的⽂件是mp3

        每一种文件都有自己的格式,不能通过后缀名判断mp3⽂件格式,如果一个文件的id3v1部分的前三个字节,这三个字节是标签标志,如果该标签存在且正确的话(包含tag字符),该文件就是音频文件或mp3文件;

        MP3文件结构:

        MP3 文件大体分为三部分:TAG_V2(ID3V2),Frame, TAG_V1(ID3V1)

        由上图结构可知,每个Frame都由帧头和数据部分组成 

参考链接: https://blog.csdn.net/ffjffjffjffjffj/article/details/99691239 https://www.cnblogs.com/ranson7zop/p/7655474.html https://blog.csdn.net/sunshine1314/article/details/2514322

        我们此时的上传逻辑是,在客户端(postman通过form表单进行音乐上传请求,服务器接受文件到某一路径,服务器根据文件的路径和请求的会话信息获取网数据库上传的数据,最后通过mybaties操作数据层进行数据库添加)

4.4 实现数据库上传

        上述实现只是实现了简单的本地上传⽂件,还未将数据插⼊到数据库当中,接下来我们实现数据库中数据的写⼊。

1、准备数据

2、调用insert

        完善musicmapper和musicmappe.xml的代码

 int insert(String title,String singer,String time,String url,int userid);
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.spring_musicserver_1113.mapper.MusicMapper"><insert id="insert">insert into music(title,singer,time,url,userid)values(#{title},#{singer},#{time},#{url},#{userid});</insert>
</mapper>

代码如下:

//3、进行数据库的上传//准备数据int index = fileNameAndType.lastIndexOf(".");//对于文件名,从后往前扫描,找到第一个。String title = fileNameAndType.substring(0,index);User user = (User) httpSession.getAttribute(Constant.USERINFO_SESSION_KEY);int userid = user.getId();//播放音乐的时候就会发出一个http请求String url = "/music/get?path="+title;SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");String time = sf.format(new Date());//调用inserttry{int ret = 0;ret = musicMapper.insert(title,singer,time,url,userid);if (ret == 1){return new ResponseBodyMessage<>(0,"数据库上传成功",true);}else {return new ResponseBodyMessage<>(-1,"数据库上传失败",false);}}catch (BindingException e){dest.delete();return new ResponseBodyMessage<>(-1,"数据库上传失败",false);}

测试结果如下:

 5. 播放音乐模块设计

        请求响应设计

        新增⽅法get获取mp3文件;

@RequestMapping("/get")public ResponseEntity<byte[]> get(String path){File file = new File(SAVE_PATH+"/"+path);byte[] a= null;try {a = Files.readAllBytes(file.toPath());if(a == null){return ResponseEntity.badRequest().build();}return ResponseEntity.ok(a);} catch (IOException e) {e.printStackTrace();}return ResponseEntity.badRequest().build();}

        代码解释:

        1. Files.readAllBytes(String path) : 读取⽂件中的所有字节,读⼊内存,参数path是⽂件的路径

        2. ResponseEntity

        ResponseEntity对象是Spring对请求响应的封装。它继承了HttpEntity对象,包含了Http的响应码 (httpstatus)、响应头(header)、响应体(body)三个部分。 ResponseEntity类继承⾃HttpEntity类,被⽤于Controller层⽅法。

        ResponseEntity.ok⽅法有2个⽅ 法,分别是有参数和没有参数。

        //这个⽅法若被调⽤的话,返回OK状态

public static ResponseEntity.BodyBuilder ok(){return status(HttpStatus.OK);}

        // 这个⽅法若被调⽤的话,返回 body 内容和 OK 状态

 public static <T> ResponseEntity<T> ok(T body) {ResponseEntity.BodyBuilder builder = ok();//ResponseEntity可以通过这个builder返回任意类型的body内容return builder.body(body);
}

        使用postman测试mp3文件能否上传成功:

        如图所示,我们的文件是mp3文件; 

        测试一个非mp3文件,将一个图片文件格式改为MP3进行上传到服务器和数据库,最后通过get方法进行获取播放,我们发现该mp3文件没有tag标签,故此不能进行播放;

相关文章:

本地音乐服务器(二)

4. 上传音乐模块设计 4.1 上传音乐的接口设计 请求和响应设计&#xff1a; 新建music实体类&#xff1a; Data public class Music {private int id;private String title;private String singer;private String time;private String url;private int userid; } 4.2 创建Mu…...

第三十六篇——伯努利试验:到底如何理解随机性?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 概率论指导着我们对于直觉不靠谱的事情&#xff0c;以及为我们如何更高效…...

【Android、IOS、Flutter、鸿蒙、ReactNative 】屏幕适配

Android Java 屏幕适配 参考 今日头条适配依赖配置 添加设计屏幕尺寸 设置字体大小 通过切换不同屏幕尺寸查看字体大小 设置文本宽高 通过切换不同屏幕尺寸查看文本宽高 Android Compose 屏幕适配 <...

candence : 如何利用EXCEL 绘制复杂、多管脚元件

如何利用EXCEL 绘制复杂、多管脚元件 前面的步骤直接略过 我们以STM32F407VEXX 系列 100pin 芯片为例讲解&#xff1a; 1、新建好一个空元件 2、使用阵列&#xff0c;放置管脚 点击 “ ok ” 3、选中所有管脚 右键 “edit properites” 出现如下页面 4、点击 左上角&…...

项目配置文件选择(Json,xml,Yaml, INI)

选择使用哪种类型的配置文件&#xff08;如 JSON、XML 或其他格式&#xff09;取决于多个因素&#xff0c;包括项目的需求、团队的熟悉程度、数据结构的复杂性以及可读性和可维护性等。以下是对常见配置文件格式的比较&#xff0c;以及在不同情况下的推荐&#xff1a; 1. JSON&…...

Android 使用Retrofit 以纯二进制文件流上传文件

一、背景 一般上传文件都是以表单形式上传文件&#xff0c;最近项目中涉及到非表单形式上传文件流&#xff0c;分为单个文件流上传、大文件分段上传&#xff0c;此种情景资料较少&#xff0c;这里记录下。 二、方案介绍 2.1 需求协议 1. 上传文件 API 端点&#xff1a;/serv…...

Vue3踩坑记录

目录 一、定义常变量 1.1、ref和reactive到底用谁&#xff1f; 二、双向绑定 2.1、直接改变表格该行数据 2.1、在弹窗改变表格该行数据 一、定义常变量 1.1、ref和reactive到底用谁&#xff1f; 已知&#xff1a;使用ref定义基础类型数据&#xff1b;使用reactive定义复…...

大数据-227 离线数仓 - Flume 自定义拦截器(续接上节) 采集启动日志和事件日志

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…...

【热门主题】000054 ECMAScript:现代 Web 开发的核心语言

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…...

【Pytorch】torch.nn.functional模块中的非线性激活函数

在使用torch.nn.functional模块时&#xff0c;需要导入包&#xff1a; from torch.nn import functional 以下是常见激活函数的介绍以及对应的代码示例&#xff1a; tanh (双曲正切) 输出范围&#xff1a;(-1, 1) 特点&#xff1a;中心对称&#xff0c;适合处理归一化后的数据…...

reactflow 中 useNodesState 模块作用

1. 节点状态管理核心功能 useNodesState是一个关键的钩子函数&#xff0c;用于专门管理节点&#xff08;Nodes&#xff09;的状态。节点是流程图的核心元素&#xff0c;它们可以代表各种实体&#xff0c;如流程中的任务、系统中的组件或者数据结构中的元素。 useNodesState提…...

Go语言内存分配源码分析学习笔记

大家好&#xff0c;我是V 哥。GO GO GO&#xff0c;今天来说一说Go语言内存分配问题&#xff0c;Go语言内存分配的源码主要集中在runtime包中&#xff0c;它实现了Go语言的内存管理&#xff0c;包括初始化、分配、回收和释放等。下面来对这些过程详细分析一下&#xff0c;先赞后…...

【jvm】方法区常用参数有哪些

目录 1. -XX:PermSize2. -XX:MaxPermSize3. -XX:MetaspaceSize&#xff08;Java 8及以后&#xff09;4. -XX:MaxMetaspaceSize&#xff08;Java 8及以后&#xff09;5. -Xnoclassgc6. -XX:TraceClassLoading7.-XX:TraceClassUnLoading 1. -XX:PermSize 1.设置JVM初始分配的永久…...

JAVA环境的配置

首先找到JDK环境的官网。 Java Archive Downloads - Java SE 8u211 and laterhttps://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html 我下载的最后一个x64.exe&#xff0c;下载后&#xff0c;直接双击运行&#xff0c;我这里默认安装到…...

LLM文档对话 —— pdf解析关键问题

一、为什么需要进行pdf解析&#xff1f; 最近在探索ChatPDF和ChatDoc等方案的思路&#xff0c;也就是用LLM实现文档助手。在此记录一些难题和解决方案&#xff0c;首先讲解主要思想&#xff0c;其次以问题回答的形式展开。 二、为什么需要对pdf进行解析&#xff1f; 当利用L…...

MySQL单表查询时索引使用情况

本文针对 MySQL 单表查询时索引使用的几种场景情况进行分析。 假设有一个表如下&#xff1a; CREATE TABLE single_table (id INT NOT NULL AUTO_INCREMENT,key1 VARCHAR(100),key2 INT,key3 VARCHAR(100),key_part1 VARCHAR(100),key_part2 VARCHAR(100),key_part3 VARCHAR(1…...

Qt邮箱程序改良版(信号和槽)

上一版代码可以正常使用,但是会报错 上一篇文章 错误信息 "QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread" 指出了一个问题&#xff0c;即在非主线程中尝试启用或禁用套接字通知器&#xff08;QSocketNotifier&#xff09;…...

入门到精通mysql数据(四)

5、运维篇 5.1、日志 5.1.1、错误日志 错误日志是MySQL中最重要的日志之一,它记录了当mysqld启动和停止,以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时,建议首先查看此日志。 该日志是默认开启的,默认存放目录/var/log…...

Java 设计模式 详解

在Java开发中&#xff0c;设计模式是一种常见的、成熟的解决方案&#xff0c;用于应对特定的设计问题和复杂性管理。以下是一些常用的设计模式&#xff0c;它们可以分为三类&#xff1a;创建型模式、结构型模式和行为型模式。 一、创建型模式 创建型模式主要负责对象的创建&a…...

卡尔曼滤波学习资料汇总

卡尔曼滤波学习资料汇总 其实&#xff0c;当初的目的&#xff0c;是为了写 MPU6050 的代码的&#xff0c;然后不知不觉学了那么多&#xff0c;也是因为好奇、感兴趣吧 有些还没看完&#xff0c;之后笔记也会同步更新的 学习原始材料 【卡尔曼滤波器】1_递归算法_Recursive P…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...