IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 在线音乐服务器 -> 正文阅读

[Java知识库]在线音乐服务器

基于HTTP、Servlet、Maven
实现的核心功能:
1.登录、注册
2.上传音乐
3.删除某一个音乐信息
4.删除选中音乐信息
5.查询音乐(包含查找指定\模糊匹配的音乐)
6.添加音乐到“喜欢列表”
7.查询喜欢的音乐(包含查找指定\模糊匹配的音乐)

重要的知识点:

  1. 简单的Web服务器设计能力
  2. Java 操作 MySQL 数据库
  3. 数据库设计
  4. JSON 的使用
  5. 强化 HTTP 协议的理解
  6. Servlet 的使用
  7. Java集合的使用
  8. 前端知识的简单使用如:HTML+CSS+JS

面试问题:一次HTTP 请求过程?
TCP三次握手四次挥手,五层协议体系(应用层、传输层、网络层、数据链路层、物理层)
每一层的协议。

整体架构:
项目整体基于HTTP协议,前端使用HTML+CSS+JS构建页面整体布局,后端采用分层结构,分为Servlet层,Service(业务层)层,Dao层的设计,以达到在设计上的高内聚低耦合。

数据库设计:

三张表:

music、user、lovemusic(一个用户可以喜欢多个音乐,一个音乐可以被多个用户喜欢,所以是多对多的关系)

– 数据库
drop database if exists onlinemusic;
create database if not exists onlinemusic character set utf8;
– 使用数据库

use `onlinemusic`;
DROP TABLE IF EXISTS `music`;
CREATE TABLE `music` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`title` varchar(50) NOT NULL,
`singer` varchar(30) NOT NULL,
`time` varchar(13) NOT NULL,
`url` varchar(100) NOT NULL,
`userid` int(11) NOT NULL
);
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`password` varchar(32) NOT NULL,
`age` INT NOT NULL,
`gender` varchar(2) NOT NULL,
`email` varchar(50) NOT NULL
);
DROP TABLE IF EXISTS `lovemusic`;
CREATE TABLE `lovemusic` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`music_id` int(11) NOT NULL
);
INSERT INTO user(username,password,age,gender,email)
VALUES("chensiyou","12345","21","男","1746112818@qq.com");

maven管理,Tomcat服务器配置

创建entity(实体包)

创建user、music类

服务器API设计:

  1. JSON:将对象转换成字符串,JSON相比XML,文件更小。序列化与反序列化。

  2. 登录:

    请求:POST /loginServlet data:{username,password} JSON组织数据

    响应:{msg:true}

    3.上传音乐:上传音乐到服务器目录

? POST /uploadServlet (不仅是给数据库写一条数据,还要给服务器目录下上传一条真正的文件)

? data:filename

? 4.删除某一条音乐信息

? POST /deleteServlet

? data:{“id”:id}

? 响应:

? {msg:true}

? 5.删除选中的音乐

? POST /deleteSelMusicServlet
? data:{“id”:id}//id为数组
? 响应:
? {msg: true}

? 6.查询音乐(指定查找/模糊匹配)

? 请求:

? GET /findMusicServlet
? data:{musicName:musicName}

? 7.添加音乐到喜欢列表

? 请求:

? POST /loveMusicServlet
? data: {“id”: obj}
? 响应:
? {msg: true}

? 8.查询喜欢的音乐(查找指定/模糊匹配)

? 请求:
? GET /findLoveMusicServlet
? data:{musicName:musicName}

? 9.移除某个喜欢的音乐

? 请求:

? POST /removeLoveServlet
? data: {“id”: obj}

封装数据库操作

创建一个util包

创建JDBCUtils类:获取数据源(单例模式),数据库连接、关闭。

创建dao包(通过dao层来操纵MySQL)

创建UserDao类(对数据库中的user表进行操作):

? 1.实现UserDao.login功能:

? PreparedStatement和Statement 的关系和区别:

? 关系: PreparedStatement继承自Statement ,都是接口。

? 区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高。

? PreparedStatement可以防止sql注入。

? 先获取数据库连接,将查询sql语句放入PreparedStatement的对象中,将?占位符通过

? PreparedStatement的对象.setString()替换成输入的用户名、密码。

?

? 2.实现UserDao.insertUser功能:

?

创建MusicDao类(对数据库中的music表进行操作):

1.实现MusicDao.upload(音乐上传)功能:

?

2.实现findMusic()(查询全部歌单)功能:

?

? 3.实现findMusicById(int id)(根据id查找音乐)功能:

?

? 4.实现findMusicByKey(String str)(根据关键字查找音乐(模糊查询))功能:

?

? 5.实现deleteMusicById(int musicId)(删除歌曲)功能:

? 在删除音乐时,要检查是否在喜欢列表里有数据记录,如果有两个表里都需要删掉。

?

? 6.实现findLoveMusicById(int musicId)(在喜欢列表查看歌曲是否存在)功能:

? 7.实现DeleteLoveMusicById(int musicId)(在喜欢列表删除)功能:

创建LoveMusicDao类(对数据库中的lovemusic表进行操作):

? 1.实现insertLoveMusic(int userId,int musicId)(添加音乐到喜欢列表)功能:

?

? 2.实现findLoveMusic(int user_id)(当前用户喜欢的音乐)功能:

? 3.实现 findLoveMusicByMusicIdAndUserId(int user_id,int musicID)(预防重复喜欢)功能:

? 4.实现findLoveMusicBykeyAndUID(String str,int user_id)(关键字查找喜欢音乐)功能:

? 5.实现removeLoveMusic(int userId,int musicId)(移除喜欢音乐)功能;

Servlet层实现

servlet是一种处于服务器和浏览器的中间层,是一种可以从前端获取http请求,并且构建一个响应回前端页面,实现生成动态页面的效果,三大周期不会

创建LoginServlet类继承自HttpServlet

1.实现登录业务:从HTTP请求中获取username和password

2.上传音乐

上传音乐分为2步:
第一步将音乐上传到服务器
第二步将音乐信息存放到数据库

知识:本质 上传签到 ——》图片 文档

1.前端 form表单 为了支持上传文件,前端采用enctype=“multipart/form-data”。

<form method="POST" enctype="multipart/form-data" action="upload">
文件上传:<input type="file" name="filename"/>
歌手名: <label>
<input type="text" name="singer" placeholder="请输入歌手名"/>
</label>
<input type="submit" value="上传"/>
</form>
  1. 后端注解:@MultipartConfig

  2. 后端上传核心代码

    //先上传服务器
    Part part = req.getPart("filename");
    //从content-disposition头中获取源文件名
    String header = part.getHeader("Content-Disposition");
    int start = header.lastIndexOf("=");
    String fileName = header.substring(start + 1)
    .replace("\"", "");
    System.out.println("fileName:"+fileName);
    part.write(SAVEPATH + "/" + fileName);
    

    Part类:

    使用的是Servlet 3.0 新的特征标注(Annotaion)类描述部署,一些低版本的服务器需要使用标准依赖部署描述文件
    (web.xml)来部署,另外Part也是Java EE 6.0新增的类,Part是一个接口继承于javax.servlet.http,代表一部分表单项目接收来自multipart/form-data的POST的请求。

    part.getHeader(“Content-Disposition”):通过此方法获取到源文件名称:
    Content-Disposition: form-data; name=“filename”; filename=“许巍 - 故乡.mp3”
    Content-Type: audio/mpeg

    4.UploadMusicServlet实现

    doPost方法:先要获取登录成功的用户对象,如果没有登录,则无法进行上传音乐(从session中取得user对象)。

    ? 从前端的请求中获取到传输的数据,通过字符串截取获得要上传的文件名称(如果通过postman自己获取文件名会被加密,需要自己通过URLDecoder.decode()方法解密),使用part.write(存储路径+文件名)方法,将from表单中音乐文件上传到服务器中,此时文件上传成功。

    接着要将数据写入数据库中,将数据库表格需要的所有信息都获取出来,通过service层将信息存入数据库。当上传的是同一首歌曲(文件相同)时,不会多次上传(因为使用的Part类的自身特点,但是还是会显示上传成功),因而避免了服务器中有多份相同的文件。

    3.FindMusicServlet实现

    doGet方法:从前端的请求中获取要查询的歌名,去FindMusicService中调用findMusic方法,这时如果请求中获取到的歌名不为空,则进行模糊匹配查询,如果为空,则进行全部音乐查询。将查询的结果放到musiclist中返回给FindMusicServlet,再通过输出流写到前端页面上。

    4.删除音乐信息实现

    4.1删除某个音乐(DeleteMusicServlet)

    doPost方法:首先获取前端参数id,然后在数据库中查找有没有当前id,如果没有当前id的音乐直接返回;如果有就开始删除数据库中的音乐,数据库删除完成后,检查是否删除成功,如果成功,接着删除服务器目录下对应的文件,将删除路径进行拼接,判断文件是否存在,调用delete()方法删除,将删除结果放到hashmap中,最后将map转换为json,传回给前端页面。

    bug:如果先删除数据库中信息,就会获取不到url,所以先需要存一份url的值,以免出现NullPointerException,从而只是删除掉数据库中信息,但无法删除服务器中的文件。

    4.2删除选中音乐(DeleteSelMusicServlet)

    doPost方法:删除选中与删除某个音乐逻辑一样,唯一不同的点是获取的是前端选中的id数组,进行循环遍历删除。

    优化方案:在dao层写一个事务,将id数组放进去进行全部删除,这样如果中间哪个出问题了,操作回滚。(JDBC开启事务,批量删除)

    5.添加喜欢音乐到喜欢列表(LoveMusicServlet)

    doPost方法:首先从前端获取到要添加到喜欢的音乐的id

    6.查找我喜欢的音乐列表(FindLoveMusicServlet)

    doGet方法:

    7.移除我喜欢的音乐(RemoveLoveServlet)

    前端页面的设计

    前端采用HTML+CSS+JS设计,JS使用jQuery,使用的不是原生的JS,而是调用的jQuery中的方法(ajax)

    前端播放使用了audio标签,目前用到这个标签,不好的地方是,需要完整下载好后才能播放。本质上来说,如果可以控制,一边上传,一边播放,这样,实时性比较强,体验感会好。需要达到这样的过程,需要引入协议。而例如音视频传输的协议,一般称为流媒体协议。

    1个G的音乐视频,怎么上传?
    大文件的上传,可能会失败,比如网络原因等。最好的做法是采取分段上传的方式。
    比如:在前端讲这1个G的数据,进行分组,假设分为10组。
    前端做法,参考做法:前端分别获取

    1、每次发送数据的大小
    2、文件总大小(此时就可以知道分为几组了)
    3、每次发送的开始位置和结束位置
    4、一个二进制对象(这个对象就是你发送的区间内组成的对象)
    这个二进制对象,传给后端后,后端每次存储起来。文件名字可以按照-1,-2,-3命名
    5、每次发送成功一段后,后端返回成功后,继续发送下一个区间

    后端做法:
    1、后端可以定义一个数据结构,比如hashmap.来存储每个部分上传的进度。如<部分1,80%>类似这样的。
    2、假设前端,在上传某部分失败了,和服务器进行对比,从上传失败的那个地方开始上传即可。(续传)
    3、全部上传成功后,循环遍历当前目录下的所有文件,进行合并。合并需要注意,顺序不对,文件会受损。所以,这里的处理就是,文件名后面加了1,2,3,4这样顺序就不会乱了

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:32:21  更:2021-09-08 10:37:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/31 7:54:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码