4. 上传音乐模块设计
4.1 上传音乐的接口设计
请求和响应设计:
新建music实体类:
java
@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类
java
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的代码
javaint insert(String title,String singer,String time,String url,int userid);
java<?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>
代码如下:
java
//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());
//调用insert
try{
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文件;
java
@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();
}
代码解释:
Files.readAllBytes(String path) : 读取⽂件中的所有字节,读⼊内存,参数path是⽂件的路径
ResponseEntity
ResponseEntity对象是Spring对请求响应的封装。它继承了HttpEntity对象,包含了Http的响应码 (httpstatus)、响应头(header)、响应体(body)三个部分。 ResponseEntity类继承⾃HttpEntity类,被⽤于Controller层⽅法。
ResponseEntity.ok⽅法有2个⽅ 法,分别是有参数和没有参数。
//这个⽅法若被调⽤的话,返回OK状态
javapublic static ResponseEntity.BodyBuilder ok(){ return status(HttpStatus.OK); }
// 这个⽅法若被调⽤的话,返回 body 内容和 OK 状态
javapublic 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标签,故此不能进行播放;