这是一个音乐播放服务器
核心功能
- 登录、注册
- 上传音乐
- 删除某一个音乐信息
- 删除选中多个的音乐信息
- 查询音乐(包含查找指定/模糊匹配的音乐)
- 添加音乐到“喜欢列表”。
- 将英语从喜欢的列表中移除
- 查询喜欢的音乐(包含查找指定/模糊匹配的音乐)
整体框架
项目整体基于HTTP协议,前端使用HTML+CSS+JS构建页面整体布局,后端采用分层结构,分为Servlet层,Dao层的设计,以达到在设计上的高内聚低耦合。
数据库设计
封装数据库
DButils
package util;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DButils {
private static final String URL="jdbc:mysql://127.0.0.1:3306/musicserver?characterEncoding=utf8&useSSL=false";
private static final String USERNAME="root";
private static final String PASSWORD="200121";
private static DataSource dataSource=null;
public static DataSource getDataSource(){
//看一下dataSource 当前是否已经持有一个实例(创建只有一次),如果持有了就不用创建新的,直接返回,如果没有就创建一个新的;
if(dataSource==null){
MysqlDataSource mysqlDataSource=new MysqlDataSource();
mysqlDataSource.setUrl(URL);
mysqlDataSource.setUser(USERNAME);
mysqlDataSource.setPassword(PASSWORD);
dataSource=mysqlDataSource;
}
return dataSource;
}
public static Connection getConnection(){
try {
return getDataSource().getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
public static void close(Connection connection,
PreparedStatement statement,
ResultSet resultSet){
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
操作数据库的SQL语句
-- 数据库
drop database if exists `musicserver`;
create database if not exists `musicserver` character set utf8;
-- 使用数据库
use `musicserver`;
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("刘斯琴","200121","18","女","2711743116@qq.com");
创建一个sql文件,将创建数据库的SQL语句放入,可以用在之后将项目部署在服务器上,在Xshell里面的数据库进行建表。
用户+音乐模块设
创建User类
package entity;
public class User {
private int id;
private String username;
private String password;
private int age;
private String gender;
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Music{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", email='" + email + '\'' +
'}';
}
}
创建Music类
package entity;
public class Music {
private int id;
private String title;
private String singer;
private String time;
private String url;
private int userId;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
@Override
public String toString() {
return "Music{" +
"id=" + id +
", title='" + title + '\'' +
", singer='" + singer + '\'' +
", time='" + time + '\'' +
", url='" + url + '\'' +
", userId=" + userId +
'}';
}
}
实现Dao层
创建UserDao类
用户的登陆,注册功能。
package dao;
import entity.User;
import util.DButils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDao {
public User login(User loginUser) {
Connection connection = null;
//可以语法预防SQL注入与statement
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
connection = DButils.getConnection();
String sql = "select * from user where username=? and password=?";
User user = null;
try {
preparedStatement = connection.prepareStatement(sql);//编译预处理
preparedStatement.setString(1, loginUser.getUsername());
preparedStatement.setString(2, loginUser.getPassword());
resultSet = preparedStatement.executeQuery();//接收结果集
if (resultSet.next()) {
user = new User();
user.setId(resultSet.getInt("id"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
user.setAge(resultSet.getInt("age"));
user.setGender(resultSet.getString("gender"));
user.setEmail(resultSet.getString("email"));
} else {
System.out.println("登录失败!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DButils.close(connection, preparedStatement, resultSet);
}
System.out.println(user);
return user;
}
public void insertUser(User user){
Connection connection=null;
PreparedStatement preparedStatement=null;
connection=DButils.getConnection();
String sql="insert into user (username,password,age,gender,email)values (?,?,?,?,?)";
try {
preparedStatement=connection.prepareStatement(sql);
preparedStatement.setString(1,user.getUsername());
preparedStatement.setString(2,user.getPassword());
preparedStatement.setInt(3,user.getAge());
preparedStatement.setString(4,user.getGender());
preparedStatement.setString(5,user.getEmail());
int ret=preparedStatement.executeUpdate();
if(ret==1){
System.out.println("注册成功!");
}else{
System.out.println("注册失败!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,preparedStatement,null);
}
}
}
创建MusicDao类
实现上传音乐、查询全部音乐、根据id查找音乐、根据关键字模糊查询歌曲、根据musicId删除音乐、在喜欢的音乐这张表里面,根据music-id查找音乐、在喜欢的音乐这张表里面,根据music-id删除音乐功能。
package dao;
import entity.Music;
import util.DButils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class MusicDao {
//上传音乐
public int insert(String title,String singer,String time,String url,int userid){
//上传成功会有返回值
Connection connection=null;
PreparedStatement statement=null;
//ResultSet resultSet=null;
try {
connection=DButils.getConnection();
String sql="insert into music(title,singer,time,url,userid)values (?,?,?,?,?)";
statement=connection.prepareStatement(sql);
statement.setString(1,title);
statement.setString(2,singer);
statement.setString(3,time);
statement.setString(4,url);
statement.setInt(5,userid);
int ret=statement.executeUpdate();
if(ret==1){
return ret;
}
return 0;
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,null);
}
return 0;
}
//显示全部音乐
public List<Music> findMusic(){
Connection connection=null;
PreparedStatement statement=null;
ResultSet resultSet=null;
connection=DButils.getConnection();
String sql="select * from music";
List<Music> musicList=new ArrayList<>();
try {
statement=connection.prepareStatement(sql);
resultSet=statement.executeQuery();
while (resultSet.next()){
Music music=new Music();
music.setId(resultSet.getInt("id"));
music.setTitle(resultSet.getString("title"));
music.setSinger(resultSet.getString("singer"));
music.setTime(resultSet.getString("time"));
music.setUrl(resultSet.getString("url"));
music.setUserId(resultSet.getInt("userid"));
musicList.add(music);
//while循环,因为查询到的不止一条;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,resultSet);
}
return musicList;
}
//根据id查找音乐
public Music findMusicById(int id){
Connection connection=null;
PreparedStatement statement=null;
ResultSet resultSet=null;
connection=DButils.getConnection();
String sql="select * from music where id=?";
try {
statement=connection.prepareStatement(sql);
statement.setInt(1,id);
resultSet= statement.executeQuery();
if(resultSet.next()){
Music music=new Music();
music.setId(resultSet.getInt("id"));
music.setTitle(resultSet.getString("title"));
music.setSinger(resultSet.getString("singer"));
music.setTime(resultSet.getString("time"));
music.setUrl(resultSet.getString("url"));
music.setUserId(resultSet.getInt("userid"));
return music;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,resultSet);
}
return null;
}
//根据关键字模糊查询歌曲
public List<Music> findMusicByKey(String str){
Connection connection=null;
PreparedStatement statement=null;
ResultSet resultSet=null;
connection=DButils.getConnection();
String sql="select * from music where title like ?";
//默认会加上单引号;
List<Music> musicList=new ArrayList<>();
try {
statement=connection.prepareStatement(sql);
str="%"+str+"%";//不能用+=,因为前面就会有空位进行占位了
statement.setString(1,str);
resultSet= statement.executeQuery();
while (resultSet.next()){
Music music=new Music();
music.setId(resultSet.getInt("id"));
music.setTitle(resultSet.getString("title"));
music.setSinger(resultSet.getString("singer"));
music.setTime(resultSet.getString("time"));
music.setUrl(resultSet.getString("url"));
music.setUserId(resultSet.getInt("userid"));
musicList.add(music);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,resultSet);
}
return musicList;
}
//根据musicId删除音乐
public int deleteMusicById(int musicId){
Connection connection=null;
PreparedStatement statement=null;
connection=DButils.getConnection();
String sql="delete from music where id=?";
try {
//从music表中删除音乐要先去lovemucis表里面看看有没有这首音乐,如果有就在lovemusic
//这张表里也把这首歌删除,全部删除(歌都不存在了,喜欢的歌曲里面肯定不能有),因为executeupdate返回值为int类型
//返回1则删除成功,返回0则删除失败
statement=connection.prepareStatement(sql);
statement.setInt(1,musicId);
int ret=statement.executeUpdate();
if(ret==1){
if(findLoveMusicById(musicId)){
int ret2=deleteLoveMusicById(musicId);
if(ret2==1){
System.out.println("删除成功");
return 1;
}
}
return 1;
}else {
return 0;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,null);
}
return 0;
}
//在喜欢的音乐这张表里面,根据music——id查找音乐
public boolean findLoveMusicById(int mucisId){
Connection connection=null;
PreparedStatement statement=null;
ResultSet resultSet=null;
connection=DButils.getConnection();
String sql="select * from lovemusic where music_id=?";
try {
statement=connection.prepareStatement(sql);
statement.setInt(1,mucisId);
resultSet= statement.executeQuery();
if(resultSet.next()){
return true;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,null);
}
return false;
}
//在喜欢的音乐这张表里面,根据music——id删除音乐
public int deleteLoveMusicById(int mucisId){
Connection connection=null;
PreparedStatement statement=null;
ResultSet resultSet=null;
connection=DButils.getConnection();
String sql="delete * from lovemusic where music_id=?";
try {
statement=connection.prepareStatement(sql);
statement.setInt(1,mucisId);
int ret = statement.executeUpdate();
if(ret==1){
return 1;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,null);
}
return 0;
}
}
创建LoveMusic类
实现插入喜欢的音乐、根据user_id查询当前用户喜欢的音乐列表、根据music-id和user-id查找音乐(为了预防一个用户重复喜欢多个音乐)、根据关键字进行模糊查找、移除当前用户喜欢的这首音乐
package dao;
import entity.Music;
import util.DButils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class LoveMusicDao {
//userId因为一个用户可以喜欢多个音乐
//插入喜欢的音乐
public boolean inserLoveMusic(int userId,int musicId){
Connection connection=null;
PreparedStatement statement=null;
ResultSet resultSet=null;
connection= DButils.getConnection();
String sql="insert into lovemusic(user_id,music_id) values (?,?)";
try {
statement=connection.prepareStatement(sql);
statement.setInt(1,userId);
statement.setInt(2,musicId);
int ret=statement.executeUpdate();
if(ret==1){
return true;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,null);
}
return false;
}
//根据user_id查询当前用户喜欢的音乐列表
public List<Music> findLoveMusic(int user_id){
List<Music> musicList=new ArrayList<>();
Connection connection=null;
PreparedStatement statement=null;
ResultSet resultSet=null;
// String sql="select * from lovemusic where user_id=?";
//两张表联合查询
// music表: music-id titlt singer time url user_id
//lovemusic:id user_id music_id
String sql="select m.id as m_id,title,singer,time,url ,userid from lovemusic lm,music m where m.id=lm.music_id and lm.user_id=?";
connection=DButils.getConnection();
try {
statement=connection.prepareStatement(sql);
statement.setInt(1,user_id);
resultSet= statement.executeQuery();
while (resultSet.next()){
Music music=new Music();
music.setId(resultSet.getInt("m_id"));
music.setTitle(resultSet.getString("title"));
music.setSinger(resultSet.getString("singer"));
music.setTime(resultSet.getString("time"));
music.setUrl(resultSet.getString("url"));
music.setUserId(resultSet.getInt("userid"));
musicList.add(music);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,null);
}
return musicList;
}
//预防重复喜欢,使用在添加音乐在喜欢的列表中,需要先检查添加列表中是否有该音乐
public boolean findLoveMusicIdAndUserId(int user_id,int music_id){
Connection connection=null;
PreparedStatement statement=null;
ResultSet resultSet=null;
connection=DButils.getConnection();
String sql="select * from lovermusic where user_id=? ang music_id=?";
try {
statement=connection.prepareStatement(sql);
statement.setInt(1,user_id);
statement.setInt(2,music_id);
resultSet=statement.executeQuery();
if(resultSet.next()){
return true;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,null);
}
return false;
}
//根据关键字进行模糊查找
public List<Music> findLoveMusicBykeyAndUser_id(String str,int user_id){
Connection connection=null;
PreparedStatement statement=null;
ResultSet resultSet=null;
connection=DButils.getConnection();
String sql="select m.id as m_id,title,singer,time,url ,userid from " +
"lovemusic lm,music m where m.id=lm.music_id and lm.user_id=? and title like ?";
List<Music> musicList=new ArrayList<>();
try {
statement=connection.prepareStatement(sql);
statement.setInt(1,user_id);
str = "%"+str+"%";//不能用+=,因为前面就会有空位进行占位了
statement.setString(2,str);
resultSet=statement.executeQuery();
while (resultSet.next()){
Music music=new Music();
music.setId(resultSet.getInt("m_id"));
music.setTitle(resultSet.getString("title"));
music.setSinger(resultSet.getString("singer"));
music.setTime(resultSet.getString("time"));
music.setUrl(resultSet.getString("url"));
music.setUserId(resultSet.getInt("userid"));
musicList.add(music);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DButils.close(connection,statement,resultSet);
}
return musicList;
}
/**
* @param //userId 用户id
* @param// musicId 歌曲id
* @return 返回受影响的行数
* 移除当前用户喜欢的这首音乐,因为同一首音乐可能多个用户喜欢,所以需要传入当前用户的id
*/
public int removeLoveMusic(int user_id,int music_id){
Connection connection=null;
PreparedStatement statement=null;
connection=DButils.getConnection();
String sql="delete from lovemusic where user_id=? and music_id=?";
try {
statement=connection.prepareStatement(sql);
statement.setInt(1,user_id);
statement.setInt(2,music_id);
int ret=statement.executeUpdate();
if(ret==1){
return 1;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return 0;
}
}
实现Servlet层
实现注册功能
注册成功之后,直接跳转到登陆页面。
package Servlet;
import dao.UserDao;
import entity.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/registerServlet")
public class registerServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
//1.先读取用户名提交的用户和密码
String username=req.getParameter("username");
String password=req.getParameter("password");
String age=req.getParameter("age");
String gender=req.getParameter("gender");
String email=req.getParameter("email");
if(username==null||"".equals(username)||
password==null||"".equals(password)||
age==null||"".equals(age)||
gender==null||"".equals(gender)||
email==null||"".equals(email)
){
resp.sendError(404,"提交的资料为空");
return;
}
UserDao userDao=new UserDao();
//需要new一个user
User user=new User();
user.setUsername(username);
user.setPassword(password);
User user1= userDao.login(user);
System.out.println(user.getId());
if (user1!=null){
//用户已经存在提醒注册失败
resp.sendError(404,"用户已经存在,注册失败");
return;
}
User newUser=new User();
newUser.setUsername(username);
newUser.setPassword(password);
int newage=Integer.parseInt(age);
newUser.setAge(newage);
newUser.setGender(gender);
newUser.setEmail(email);
userDao.insertUser(newUser);
resp.sendRedirect("login.html");
}
}
实现登陆功能
package Servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import dao.UserDao;
import entity.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
String username=req.getParameter("username");
String password=req.getParameter("password");
System.out.println("username"+username);
System.out.println("password"+password);
Map<String,Object> return_map=new HashMap<>();
UserDao userDao=new UserDao();
//需要new一个user
User loginUser=new User();
loginUser.setUsername(username);
loginUser.setPassword(password);
//用service层操作数据库
// LoginService loginService=new LoginService();
// User user=loginService.login(loginUser);
//login的返回值是一个user
User user= userDao.login(loginUser);
// System.out.println(user);
// System.out.println(user.getId());
if(user == null) {
//登录失败!
return_map.put("msg",false);
System.out.println(return_map.get("msg"));
}else {
//绑定数据
req.getSession().setAttribute("user", user);
return_map.put("msg",true);
System.out.println(return_map.get("msg"));
}
ObjectMapper mapper=new ObjectMapper();
//利用jackson将map转化为json对象
//write将转化后的json字符串保存到json字符输出流中,最后给客户端
mapper.writeValue(resp.getWriter(),return_map);
}
}
实现查找音乐功能
package Servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import dao.MusicDao;
import entity.Music;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/findMusic")
public class FindMusicServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
String musicName=req.getParameter("musicName");
MusicDao musicDao=new MusicDao();
List<Music> musicList=new ArrayList<>();
if(musicName!=null){
musicList= musicDao.findMusicByKey(musicName);
}else{
musicList= musicDao.findMusic();//什么参数都没有就默认查询全部
}
for (Music music:musicList
) {
System.out.println(music);
}
ObjectMapper objectMapper=new ObjectMapper();
objectMapper.writeValue(resp.getWriter(),musicList);
}
}
实现删除音乐功能
package Servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import dao.MusicDao;
import entity.Music;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/deletemusic")
public class deleteMusicServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
String ID = req.getParameter("id");
int id = Integer.parseInt(ID);
//1.先查询哟没有id,没有这个id就直接返回
MusicDao musicDao = new MusicDao();
Music music = musicDao.findMusicById(id);
Map<String,Object> return_map=new HashMap<>();
if(music==null){
return;
}
//有当前需要删除的音乐,需要进行优化
int ret= musicDao.deleteMusicById(id);
if(ret==1){
//数据库删除成功,那么服务器上的数据也需要发生改变
//删除服务器下对应的目录
// File file=new File("E:\\JAVA代码\\onlinemusic\\src\\main\\webapp\\"+music.getUrl()+".mp3");//括号里面写路径
File file=new File("/root/install/apache-tomcat-8.5.69/webapps/onlinemusic/"+music.getUrl()+".mp3");
if(file.delete()){
//返回值为true or false
return_map.put("msg",true);
}else {
return_map.put("msg",false);
}
}else {
return_map.put("msg",false);
}
ObjectMapper mapper=new ObjectMapper();
//利用jackson将map转化为json对象
//write将转化后的json字符串保存到json字符输出流中,最后给客户端
mapper.writeValue(resp.getWriter(),return_map);
}
}
实现删除多组音乐功能
package Servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import dao.MusicDao;
import entity.Music;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
//批量删除操作
@WebServlet("/deleteselmusic")
public class DeleteSelMusicServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
//选中多个音乐进行删除,传过来的id就是一组数组
String[] ID=req.getParameterValues("id[]");
MusicDao musicDao = new MusicDao();
//要返回给前端删除失败还是成功
Map<String,Object> return_map=new HashMap<>();
int sum=0;
for(int i=0;i<ID.length;i++){
int id=Integer.parseInt(ID[i]);
Music music = musicDao.findMusicById(id);
if(music==null){
continue;
}
//有当前需要删除的音乐,需要进行优化
int ret= musicDao.deleteMusicById(id);
if(ret==1){
//数据库删除成功,那么服务器上的数据也需要发生改变
//删除服务器下对应的目录
File file=new File("/root/install/apache-tomcat-8.5.69/webapps/onlinemusic/"+music.getUrl()+".mp3");
// File file=new File("E:\\JAVA代码\\onlinemusic\\src\\main\\webapp\\"+music.getUrl()+".mp3");//括号里面写路径
if(file.delete()){
//返回值为true or false
sum+=ret;
return_map.put("msg",true);
}else {
System.out.println("删除失败");
return_map.put("msg",false);
}
}else {
System.out.println("删除失败");
return_map.put("msg",false);
}
}
if(sum==ID.length){
System.out.println("删除成功!");
return_map.put("msg",true);
}else{
System.out.println("删除失败了!");
return_map.put("msg",false);
}
ObjectMapper mapper=new ObjectMapper();
//利用jackson将map转化为json对象
//write将转化后的json字符串保存到json字符输出流中,最后给客户端
mapper.writeValue(resp.getWriter(),return_map);
}
}
实现添加喜欢的音乐功能
package Servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import dao.LoveMusicDao;
import entity.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/uploadlovemusic")
public class UploadLoveMusicServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
String musicIds=req.getParameter("id");
int musicId=Integer.parseInt(musicIds);
User user=(User) req.getSession().getAttribute("user");
int userId=user.getId();
Map<String,Object> return_map=new HashMap<>();
LoveMusicDao loveMusicDao=new LoveMusicDao();
//先查看当前用户是否将该音乐添加到喜欢的音乐里面
boolean effect2= loveMusicDao.findLoveMusicIdAndUserId(userId,musicId);
if(effect2){
return_map.put("msg",false);
}else{
boolean effect = loveMusicDao.inserLoveMusic(userId,musicId);
if(effect){
return_map.put("msg",true);
}else{
return_map.put("msg",false);
}
ObjectMapper mapper=new ObjectMapper();
//利用jackson将map转化为json对象
//write将转化后的json字符串保存到json字符输出流中,最后给客户端
mapper.writeValue(resp.getWriter(),return_map);
}
}
}
实现移除喜欢的音乐功能
package Servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import dao.LoveMusicDao;
import entity.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/removelovemusic")
public class RemoveLoveMusicServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
String MusicId=req.getParameter("id");
int musicid=Integer.parseInt(MusicId);
User user =(User)req.getSession().getAttribute("user");
int userid=user.getId();
LoveMusicDao loveMusicDao=new LoveMusicDao();
int ret= loveMusicDao.removeLoveMusic(userid,musicid);
Map<String,Object> return_map=new HashMap<>();
if(ret==1){
return_map.put("msg",true);
}else{
return_map.put("msg",false);
}
ObjectMapper mapper=new ObjectMapper();
//利用jackson将map转化为json对象
//write将转化后的json字符串保存到json字符输出流中,最后给客户端
mapper.writeValue(resp.getWriter(),return_map);
}
}
实现查找喜欢的音乐功能
package Servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import dao.LoveMusicDao;
import dao.MusicDao;
import entity.Music;
import entity.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/findlovemusic")
public class FindLoveMusicServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
String musicname=req.getParameter("musicname");
System.out.println(musicname);
User user=(User)req.getSession().getAttribute("user");
int userid=user.getId();
LoveMusicDao loveMusicDao=new LoveMusicDao();
List<Music> music=new ArrayList<>();
if(musicname!=null){
music= loveMusicDao.findLoveMusicBykeyAndUser_id(musicname,userid);
}else{
music=loveMusicDao.findLoveMusic(userid);
}
ObjectMapper mapper=new ObjectMapper();
//利用jackson将map转化为json对象
//write将转化后的json字符串保存到json字符输出流中,最后给客户端
mapper.writeValue(resp.getWriter(),music);
}
}
实现上传音乐功能
package Servlet;
import dao.MusicDao;
import entity.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebServlet("/upload")
@MultipartConfig
public class UploadMusicServlet extends HttpServlet {
//文件存放路径
private static final String SAVGPATH="/root/install/apache-tomcat-8.5.69/webapps/onlinemusic/music/";
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
//取出对应的value
User user=(User)req.getSession().getAttribute("user");
if(user==null){
System.out.println("没有登录不能上传");
}else{
//获取到前端页面上传的文件,上传到服务器
Part part=req.getPart("filename");
String header=part.getHeader("Content-Disposition");
int start=header.lastIndexOf("=");
String fileName=header.substring(start+1).replace("\"","");
//postman会对中文进行加密,所以在用postman时,我们需要在代码中进行解密工作,
// 但是如果使用的是谷歌浏览器,就会进行自动解密
System.out.println(fileName);
// int index = fileName.indexOf("%");
// fileName = fileName.substring(index);
// fileName = URLDecoder.decode(fileName,"utf-8");
// System.out.println("22222"+fileName);
part.write(SAVGPATH+fileName);
//往数据库中插入数据
//取到歌手
String singer=req.getParameter("singer");
System.out.println("singer"+singer);
//取到title
String[] titles=fileName.split("\\.");
String title=titles[0];
System.out.println("title"+title);
//取到url
String url="music/"+title;
System.out.println("url"+url);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
String time=simpleDateFormat.format(new Date());
int userid=user.getId();
System.out.println("userid"+userid);
MusicDao musicDao=new MusicDao();
int ret= musicDao.insert(title,singer,time,url,userid);
if(ret==1){
resp.sendRedirect("list.html");//插入成功,跳转到歌单
}else{
System.out.println("上传失败");
part.delete();//数据库都上传失败了,就要把服务器的删掉
}
//上传相同的文件在服务器就只有一份,因为part类完全避免了重复的问题
}
}
}
注意:实现功能的步骤在代码的实现里面都有详细的注解。
前端页面
注册页面
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>注册页面</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
}
.container{
width: 800px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
flex-direction: column;
}
input{
display: block;
margin-bottom: 10px;
width: 315px;
height: 35px;
font-size: 20px;
text-indent: 10px;
}
body{
background-image: url("images/3.png");
background-size:100% 100%;
background-attachment: fixed;
}
.button{
color: antiquewhite;
background-color:olive;
border: none;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="container">
<h1>请注册音乐账户</h1>
<form action="registerServlet" method="post">
<div class="form-group" >
<label >用户名:</label>
<input type="text" name="username" class="form-control" placeholder="请输入用户名"/>
</div>
<div class="form-group" >
<label >密码:</label>
<input type="password" name="password"class="form-control" placeholder="请输入密码"/>
</div>
<div class="form-group" >
<label >年龄:</label>
<input type="text" name="age" class="form-control" placeholder="请输入年龄"/>
</div>
<div class="form-group" >
<label >性别:</label>
<input type="text" name="gender" class="form-control" placeholder="请输入性别"/>
</div>
<div class="form-group" >
<label >邮箱:</label>
<input type="text" name="email" class="form-control" placeholder="请输入邮箱"/>
</div>
<input type="submit" value="注册" class="button">
</form>
</div>
</body>
</html>
登陆页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<title>这是一个音乐播放器</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-3.1.1.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<!--<script src="js/bootstrap.min.js"></script>-->
<script type="text/javascript"></script>
<style>
#body{
background-image: url("images/3.png");
background-size:100% 100%;
background-attachment: fixed;
}
</style>
<script>
//登录请求
$(function () {
$("#submit").click(function () {
var username=$("#user").val();
var password=$("#password").val();
$.ajax({
url:"loginServlet",
data:{"username":username,"password":password},
type:"POST",
dataType:"json",
success:function (data) {
//打印出来的就是map
console.log(data);
if(data.msg===true){
window.location.href="list.html";
}else{
/*window.location.reload();*/
$("#message").text("账号或密码错误,请重试!");
$("#user").val("");
$("#password").val("");
$("#verifycode").val("");
}
}
});
});
});
</script>
</head>
<body id="body">
<div class="container" style="width: 400px;margin-top: 110px;background-color: rgba(255,255,255,0.8)">
<h3 style="text-align: center;">用户登录</h3>
<!-- <form action="login" method="post">-->
<div class="form-group" >
<label for="user">用户名:</label>
<input type="text" name="username" class="form-control" id="user" placeholder="请输入用户名"/>
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" name="password" class="form-control" id="password" placeholder="请输入密码"/>
</div>
<hr/>
<div class="form-group" style="text-align: center;"><!--class="form-group"-->
<input style="width: 200px;height: 40px" id="submit" class="btn btn btn-primary" type="button" value="登录" >
</div>
<!-- </form>-->
<!-- 出错显示的信息框 -->
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" >
<span>×</span>
</button>
<strong id="message">您尚未进行登录,请您登录!</strong>
</div>
</div>
</body>
</html>
音乐列表页面
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
<!-- 指定字符集 -->
<meta charset="utf-8">
<!-- 使用Edge最新的浏览器的渲染方式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
width: 默认宽度与设备的宽度相同
initial-scale: 初始的缩放比,为1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<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="shortcut icon" href="#" />
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-3.1.1.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<!-- <script src="js/bootstrap.min.js"></script>-->
<style type="text/css">
td, th {
text-align: center;
}
</style>
<style>
#body{
/*background-image: url("images/3.png");
background-size:100% 100%;
background-attachment: fixed;*/
}
</style>
<script type="text/javascript">
$(function () {
load();
});
function load(musicName){
$.ajax({
url: "findMusic",
type:"get",
data:{musicName:musicName},
dataType: "json",
success: function(data){
console.log(data.length);
console.log(data);
var s = "";
for (var i = 0; i < data.length; i++) {
var musicUrl = data[i].url+".mp3";
s += "<tr>";
s += "<th> <input id=\""+data[i].id+ "\" type=\"checkbox\"> </th>";
s += "<td>" + data[i].title + "</td>";
s += "<td>" + data[i].singer + "</td>";
s += "<td <a href=\"\"> <audio src= \""+ musicUrl+"\" + controls=\"controls\" preload=\"auto\" loop=\"loop\"> >" + "</audio> </a> </td>";
s+="<td > <button class='btn btn-primary' οnclick=\"deleteInfo("+ data[i].id + ")\" > 删除</button> " +
"<button class='btn btn-primary' οnclick=\"loveInfo("+ data[i].id + ")\" > 喜欢</button>"+
"</td>";
s += "</tr>";
}
$("#info").html(s);
var audios = document.getElementsByTagName("audio");
// 暂停函数
function pauseAll() {
var self = this;
[].forEach.call(audios, function (i) {
// 将audios中其他的audio全部暂停
i !== self && i.pause();
})
}
// 给play事件绑定暂停函数
[].forEach.call(audios, function (i) {
i.addEventListener("play", pauseAll.bind(i));
});
}
});
}
function loveInfo(obj) {
console.log(obj);
$.ajax({
url:"uploadlovemusic",
type: "post",
//发送给后端的数据
data: {"id": obj},
dataType: "json",
success: function (data) {
if(data.msg===true){
alert("加入喜欢的列表成功");
window.location.href="loveMusic.html";
}else{
alert("加入喜欢的列表失败或者已经存在该音乐");
}
}
});
}
function deleteInfo(obj) {
console.log(obj);
$.ajax({
url:"deletemusic",
type: "post",
//发送给后端的数据
data: {"id": obj},
dataType: "json",
success: function (data) {
if(data.msg===true){
alert("删除成功");
window.location.href="list.html";
}else{
alert("删除失败");//删除时成功或者失败会弹出一个框告诉用户
}
}
});
}
$(function () {
$("#submit1").click(function () {
var name = $("#exampleInputName2").val();
load(name);
});
//请求完成了
$.when(load).done(function () {
//选取所有类型为CheckBox的元素
$("#delete").click(function () {
var i=0;
var id=new Array();
$(":checkbox").each(function () {
//如果被选中
if($(this).is(':checked')){
//获取id的值,存储到id数组当中
id[i] = $(this).attr("id");
i++;
}
});
//发送ajax请求
$.ajax({
url:"deleteselmusic",
//将id数组,发送给deleteSelectedServlet
data:{"id":id},
type: "POST",
dataType:"json",
success:function (data) {
if(data.msg===true){
alert("删除成功");
window.location.href="list.html";
}else{
alert("删除失败");
}
}
});
});
});
});
</script>
</head>
<body id="body">
<div class="container">
<h3 style="text-align: center">一起听音乐吧</h3>
<div style="float: left;">
<form class="form-inline">
<div class="form-group">
<label for="exampleInputName2">歌曲名</label>
<input name="name" type="text" class="form-control" id="exampleInputName2" >
</div>
<button id="submit1" type="button" class="btn btn-primary">查询</button>
</form>
</div>
<div style="float: right;margin-bottom: 15px">
<a class="btn btn-primary" href="loveMusic.html">喜欢列表</a>
<a class="btn btn-primary" href="upload.html">添加歌曲</a>
<a id="delete" class="btn btn-primary">删除选中</a>
</div>
<table border="1" class="table table-bordered table-hover">
<tr class="success">
<th>选择</th>
<th>歌名</th>
<th>歌手</th>
<th>歌曲</th>
<th>操作</th>
</tr>
<tbody id="info" valign="middle">
</tbody>
</table>
<div>
<nav aria-label="Page navigation">
<ul id="all" class="pagination">
</ul>
</nav>
</div>
</div>
</body>
</html>
喜欢音乐列表页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<title>这是一个音乐播放器</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-3.1.1.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<!--<script src="js/bootstrap.min.js"></script>-->
<script type="text/javascript"></script>
<style>
#body{
background-image: url("images/3.png");
background-size:100% 100%;
background-attachment: fixed;
}
</style>
<script>
//登录请求
$(function () {
$("#submit").click(function () {
var username=$("#user").val();
var password=$("#password").val();
$.ajax({
url:"loginServlet",
data:{"username":username,"password":password},
type:"POST",
dataType:"json",
success:function (data) {
//打印出来的就是map
console.log(data);
if(data.msg===true){
window.location.href="list.html";
}else{
/*window.location.reload();*/
$("#message").text("账号或密码错误,请重试!");
$("#user").val("");
$("#password").val("");
$("#verifycode").val("");
}
}
});
});
});
</script>
</head>
<body id="body">
<div class="container" style="width: 400px;margin-top: 110px;background-color: rgba(255,255,255,0.8)">
<h3 style="text-align: center;">用户登录</h3>
<!-- <form action="login" method="post">-->
<div class="form-group" >
<label for="user">用户名:</label>
<input type="text" name="username" class="form-control" id="user" placeholder="请输入用户名"/>
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" name="password" class="form-control" id="password" placeholder="请输入密码"/>
</div>
<hr/>
<div class="form-group" style="text-align: center;"><!--class="form-group"-->
<input style="width: 200px;height: 40px" id="submit" class="btn btn btn-primary" type="button" value="登录" >
</div>
<!-- </form>-->
<!-- 出错显示的信息框 -->
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" >
<span>×</span>
</button>
<strong id="message">您尚未进行登录,请您登录!</strong>
</div>
</div>
</body>
</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"/>
</head>
<body>
<!--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>
</body>
</html>
写在最后
这个项目 /利用jackson将map转化为json对象,write将转化后的json字符串保存到json字符输出流中,最后给客户端,这样就将服务器端的数据传给前端页面从而实现前后端连接。
除此之外,还要注意环境的配置,在引入依赖的时候,注意依赖的版本。
项目设计文件上传的时候,要注意文件上传的路径,使用本机Tomcat在自己电脑上运行和在Linux上的路径。
最后:在学习做项目的过程中,从业务到代码实现,从出现BUG到解决BUG,就是我最大收获!
这是一个音乐播放器注册链接:注册链接
如果你已经注册了,请直接点击登陆链接吧:登陆链接