【Java项目实战】在线音乐播放器(从需求到产品完整解析)

准备工作必看:【Java项目实战】在线音乐播放器(前期准备)

核心功能

  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

最终效果

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第1张图片

整体架构(BS架构)

项目整体基于HTTP协议,前端使用HTML+CSS+JS构建页面整体布局,后端采用分层结构,分为Servlet层,Service层,Dao层的设计,以达到在设计上的高内聚低耦合
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第2张图片

数据库设计

我们需要设计三张表:

music表
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第3张图片
user表
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第4张图片
lovemusic表
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第5张图片

创建表

-- 数据库
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("bit","123","10","男","[email protected]");

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第6张图片

从idea的database面板连接数据库

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第7张图片
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第8张图片
下载成功:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第9张图片
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第10张图片
连接成功:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第11张图片
这样就可以通过idea查看数据库了,比较方便。当然也不是必须的,不连接自己从过cmd查看也是可以的。(自己根据情况)

lib下添加jar包

首先下载好需要的jar包,如下:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第12张图片
然后将下载的jar包复制到之前创建的lib目录里边。(上篇博客有写到,见文章开头链接)

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第13张图片
idea中也就可以看到了:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第14张图片
这里没有解压,还得继续解压,操作如下:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第15张图片
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第16张图片
选择之后点击Apply和OK。这时看到还未显示,继续:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第17张图片
之后再换回第一个下拉选项,这样就解压好了。
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第18张图片
(5.7.27版本jar包)

用户+音乐模块设计

创建entity包

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第19张图片

1、创建User类

package entity;
public class User {
     
private int id;
private String username;
private String password;
private String gender;
private int age;
private String email;
}

2、创建Music类

package entity;
public class Music {
     
private int id;
private String title;
private String singer;
private Date time;
private String url;
private int userid;
}

并生成对应的get set toString方法:

关于 Json

Json 是一种常见是数据格式组织方式. 源于 JavaScript, 是一种键值对风格的数据格式. 在Java中 我们可以采用Jackson库中的ObjectMapper类来完成 Json 的解析和构造。
学习示例:

package test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @ClassName Person
 * @Description :   json(对象-》字符串)
 * @Author Josvin
 * @Date 2021/02/18/22:41
 */
public class Person {
     
    private int id;
    private String name;
    private String password;
    public Person() {
     
        super();
    }
    public Person(int id, String name, String password) {
     
        this.id = id;
        this.name = name;
        this.password = password;
    }
    public int getId() {
     
        return id;
    }
    public void setId(int id) {
     
        this.id = id;
    }
    public String getName() {
     
        return name;
    }
    public void setName(String name) {
     
        this.name = name;
    }
    public String getPassword() {
     
        return password;
    }
    public void setPassword(String password) {
     
        this.password = password;
    }

    public static void main(String[] args) throws JsonProcessingException {
     
        ObjectMapper objectMapper = new ObjectMapper();
        Person person = new Person(1, "tom", "123");
        String jsonString = objectMapper.writeValueAsString(person);
        System.out.println("JsonString: " + jsonString);
    }
}

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第20张图片

API设计

交互的流程:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第21张图片

  1. 登录
    【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第22张图片

  2. 上传音乐
    【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第23张图片

  3. 删除某个音乐
    【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第24张图片

  4. 删除选中音乐(批量删除)
    【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第25张图片

  5. 查询音乐(支持模糊查询)
    【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第26张图片

  6. 添加喜欢音乐到喜欢列表
    【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第27张图片

  7. 查询喜欢的音乐
    【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第28张图片

  8. 移除喜欢的音乐
    在这里插入图片描述

封装数据库操作

1 创建一个util包

创建JDBCUtils类。

package util;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.*;
/**
 * @ClassName DBUtils
 * @Description :工具类,连接数据库
 * @Author Josvin
 * @Date 2021/02/19/12:34
 */
    public class DBUtils {
     
        private static String url = "jdbc:mysql://127.0.0.1:3306/musicserver?useSSL=false";
        private static String password = "admin";
        private static String username = "root";
        private static volatile DataSource DATASOURCE;
        private static DataSource getDataSource(){
     
// 双重校验锁
            if(DATASOURCE == null){
     
                synchronized (DBUtils.class){
     
                    if(DATASOURCE == null){
     
                        DATASOURCE = new MysqlDataSource();
                        ((MysqlDataSource) DATASOURCE).setUrl(url);
                        ((MysqlDataSource) DATASOURCE).setUser(username);
                        ((MysqlDataSource) DATASOURCE).setPassword(password);
                    }
                }
            }
            return DATASOURCE;
        }
        public static Connection getConnection(){
     
            try {
     
//从池子里获取连接
                Connection connection = getDataSource().getConnection();
                return connection;
            } catch (SQLException e) {
     
                e.printStackTrace();
                throw new RuntimeException("获取数据库连接失败");
            }
        }
        public static void getClose(Connection connection, PreparedStatement statement, ResultSet resultSet) {
     
            if(resultSet!=null) {
     
                try {
     
                    resultSet.close();
                } catch (SQLException e) {
     
                    e.printStackTrace();
                }
            }
            if(statement!=null) {
     
                try {
     
                    statement.close();
                } catch (SQLException e) {
     
                    e.printStackTrace();
                }
            }
            if(connection!=null) {
     
                try {
     
                    connection.close();
                } catch (SQLException e) {
     
                    e.printStackTrace();
                }
            }
        }
}

2 创建dao包和UserDao类

2.1 实现UserDao.login

package dao;

import entity.User;
import util.DBUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @ClassName UserDao
 * @Description :有关用户的数据库操作
 * @Author Josvin
 * @Date 2021/02/19/12:43
 */
public class UserDao {
     

    // 登录
    public static User login(User loginUser) {
     
        User user = null;
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
     
            String sql = "select*from user where username=? and password=?";
            connection = DBUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);// 对 sql 语句进行预编译
            preparedStatement.setString(1, loginUser.getUsername());
            preparedStatement.setString(2, loginUser.getPassword());
            resultSet = preparedStatement.executeQuery();
         ///  在这里神魔时候用if 什么时候用while 根据查询的结果决定,在这里根据用户名和密码查询只有一条用if即可
            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"));
            }
        } catch (SQLException e) {
     
            e.printStackTrace();
        } finally {
     
            DBUtils.getClose(connection, preparedStatement, resultSet);
        }
        return user;
    }

    public static void main(String[] args) {
     
        User user = new User();
        user.setUsername("bit");
        user.setPassword("123");
        User loginUser = login(user);
        System.out.println(loginUser);
    }

}

测试:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第29张图片

2.2 实现UserDao.register

   // 注册
    public void register(User user) {
     
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
     
            connection = DBUtils.getConnection();
            preparedStatement = connection.prepareStatement("insert into user values(null,?,?,?,?,?)");
            preparedStatement.setString(1, user.getUsername());
            preparedStatement.setString(2, user.getPassword());
            preparedStatement.setString(3, user.getGender());
            preparedStatement.setInt(4, user.getAge());
            preparedStatement.setString(5, user.getEmail());
            preparedStatement.executeUpdate();
        } catch (Exception e) {
     
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
     
            DBUtils.getClose(connection, preparedStatement, null);
        }
    }

3 创建MusicDao类

3.1 实现MusicDao.findMusic

package dao;

import entity.Music;
import util.DBUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName MusicDao
 * @Description :有关于音乐的数据库操作
 * @Author Josvin
 * @Date 2021/02/19/12:44
 */
public class MusicDao {
     
    /**
     * 查询全部歌单
     */
    public List<Music> findMusic(){
     
        List<Music> musics = new ArrayList<>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
     
            conn = DBUtils.getConnection();
            ps = conn.prepareStatement("select*from music");
            rs = ps.executeQuery();
            // 查询结果不止一条
            while(rs.next()) {
     
                Music music = new Music();
                music.setId(rs.getInt("id"));
                music.setTitle(rs.getString("title"));
                music.setSinger(rs.getString("singer"));
                music.setTime(rs.getDate("time"));
                music.setUrl(rs.getString("url"));
                music.setUserid(rs.getInt("userid"));
                musics.add(music);
            }
        } catch (Exception e) {
     
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
     
            DBUtils.getClose(conn, ps, rs);
        }
        return musics;
    }
}

3.2 实现MusicDao.findMusicById

/**
     * 根据id查找音乐
     * @param id
     * @return
     */
    public Music findMusicById(int id){
     
        Music music = null;
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
     
            conn = DBUtils.getConnection();
            ps = conn.prepareStatement("select * from music where id=?");
            ps.setInt(1,id);
            rs = ps.executeQuery();
            if(rs.next()) {
     
                music = new Music();
                music.setId(rs.getInt("id"));
                music.setTitle(rs.getString("title"));
                music.setSinger(rs.getString("singer"));
                music.setTime(rs.getDate("time"));
                music.setUrl(rs.getString("url"));
                music.setUserid(rs.getInt("userid"));
            }
        } catch (Exception e) {
     
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
     
            DBUtils.getClose(conn, ps, rs);
        }
        return music;
    }

3.3 实现MusicDao.ifMusic

/**
     * 根据关键字查询歌单
     */
    public List<Music> ifMusic(String str){
     
        List<Music> musics = new ArrayList<>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
     
            conn = DBUtils.getConnection();
            ps = conn.prepareStatement("select*from music where title like '%"+str+"%'");
            rs = ps.executeQuery();
            while(rs.next()) {
     
                Music music = new Music();
                music.setId(rs.getInt("id"));
                music.setTitle(rs.getString("title"));
                music.setSinger(rs.getString("singer"));
                music.setTime(rs.getDate("time"));
                music.setUrl(rs.getString("url"));
                music.setUserid(rs.getInt("userid"));
                musics.add(music);
            }
        } catch (Exception e) {
     
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
     
            DBUtils.getClose(conn, ps, rs);
        }
        return musics;
    }

3.4 实现MusicDao.Insert

/**
     * 也可以直接传一个Music 对象
     * 上传音乐
     * 1、上传到服务器
     * 2、上传到数据库
     */
    public int Insert(String title, String singer, String time, String url, int userid) {
     
        Connection conn = DBUtils.getConnection();
        PreparedStatement pst=null;
        int number = 0;
        try {
     
            pst=conn.prepareStatement("insert into music(title,singer,time,url,userid) values(?,?,?,?,?)");
            pst.setString(1,title);
            pst.setString(2,singer);
            pst.setString(3,time);
            pst.setString(4,url);
            pst.setInt(5,userid);
            number = pst.executeUpdate();/// 更新数据库
            return number;
        } catch (SQLException e) {
     
            e.printStackTrace();
        }finally {
     
            DBUtils.getClose(conn, pst, null);
        }
        return 0;
    }

3.5 实现MusicDao.deleteMusicById

 /**
    *   删除歌曲:
    *
    */
    public int deleteMusicById(int id) {
     
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
     
            String sql = "delete from music where id=?";
            connection = DBUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,id);
            int ret = preparedStatement.executeUpdate();
            if(ret == 1) {
     
//同时删除中间表中的数据
//1、看中间表是否有数据,如果有删除
                if(findLoveMusicOnDel(id)) {
     
                    int ret2 = removeLoveMusicOnDelete(id);
                    if(ret2 == 1){
     
                        return 1;
                    }
                } else {
     
//如果没有找到,说明这首歌,没有被添加到喜欢的列表
                    return 1;
                }
            }
        }catch (SQLException e) {
     
            e.printStackTrace();
        }finally {
     
            DBUtils.getClose(connection,preparedStatement,null);
        }
        return 0;
    }

    /**
     * 看中间表是否有该id的音乐数据
     */
    public boolean findLoveMusicOnDel(int id) {
     
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
     
            String sql = "select * from lovemusic where music_id=?";
            connection = DBUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,id);
            resultSet = preparedStatement.executeQuery();
            if(resultSet.next()) {
     
                return true;
            }
        }catch (SQLException e) {
     
            e.printStackTrace();
        }finally {
     
            DBUtils.getClose(connection,preparedStatement,null);
        }
        return false;
    }
    /**
     * 当删除服务器上的音乐时,同时在我喜欢的列表的数据库中进行删除。
     * @param musicId
     * @return
     */
    public int removeLoveMusicOnDelete(int musicId) {
     
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
     
            String sql = "delete from lovemusic where music_id=?";
            connection = DBUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,musicId);
            int ret = preparedStatement.executeUpdate();
            if(ret == 1) {
     
                return ret;
            }
        }catch (SQLException e) {
     
            e.printStackTrace();
        }finally {
     
            DBUtils.getClose(connection,preparedStatement,null);
        }
        return 0;
    }

3.6 实现MusicDao.insertLoveMusic

/**
     * 添加音乐到“喜欢”列表中
     * 用户-》音乐
     * 多对多
     * 需要中间表
     */
    public boolean insertLoveMusic(int userId,int musicId) {
     
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
     
            String sql = "insert into lovemusic(user_id, music_id) VALUES (?,?)";
            connection = DBUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,userId);
            preparedStatement.setInt(2,musicId);
            int ret = preparedStatement.executeUpdate();
            if (ret == 1) {
     
                return true;
            }
        }catch (SQLException e) {
     
            e.printStackTrace();
        }finally {
     
            DBUtils.getClose(connection,preparedStatement,null);
        }
        return false;
    }

3.7 实现MusicDao.removeLoveMusic

/**
     * @param userId 用户id
     * @param musicId 歌曲id
     * @return 返回受影响的行数
     * 移除当前用户喜欢的这首音乐,因为同一首音乐可能多个用户喜欢
     */
    public int removeLoveMusic(int userId,int musicId) {
     
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
     
            String sql = "delete from lovemusic where user_id=? and music_id=?";
            connection = DBUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,userId);
            preparedStatement.setInt(2,musicId);
            int ret = preparedStatement.executeUpdate();
            if(ret == 1) {
     
                return ret;
            }
        }catch (SQLException e) {
     
            e.printStackTrace();
        }finally {
     
            DBUtils.getClose(connection,preparedStatement,null);
        }
        return 0;
    }

3.8 实现MusicDao.findMusicByMusicId

/**
     * 添加喜欢的音乐的时候,需要先判断该音乐是否存在
     * @param musicID
     * @return
     */
    public boolean findMusicByMusicId(int user_id,int musicID) {
     
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
     
            conn = DBUtils.getConnection();
            ps = conn.prepareStatement("select * from lovemusic where music_id=? and user_id=?");
            ps.setInt(1,musicID);
            ps.setInt(2,user_id);
            rs = ps.executeQuery();
            if(rs.next()) {
     
                return true;
            }
        } catch (Exception e) {
     
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
     
            DBUtils.getClose(conn, ps, rs);
        }
        return false;

    }

3.9 实现MusicDao.findLoveMusic

/**
     * 查询用户喜欢的全部歌单
     * @param user_id
     * @return
     */
    public List<Music> findLoveMusic(int user_id){
     
        List<Music> musics = new ArrayList<>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
     
            conn = DBUtils.getConnection();
            ps = conn.prepareStatement("select m.id as music_id,title,singer,time,url,userid from lovemusic lm,music m where lm.music_id=m.id and user_id=?");
            ps.setInt(1,user_id);
            rs = ps.executeQuery();
            while(rs.next()) {
     
                Music music = new Music();
                music.setId(rs.getInt("music_id"));
                music.setTitle(rs.getString("title"));
                music.setSinger(rs.getString("singer"));
                music.setTime(rs.getDate("time"));
                music.setUrl(rs.getString("url"));
                music.setUserid(rs.getInt("userid"));
                musics.add(music);
            }
        } catch (Exception e) {
     
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
     
            DBUtils.getClose(conn, ps, rs);
        }
        return musics;
    }

3.10 实现MusicDao.ifMusicLove

/**
     * 根据关键字查询喜欢的歌单
     * @param str
     * @return
     */
    public List<Music> ifMusicLove(String str,int user_id){
     
        List<Music> musics = new ArrayList<>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
     
            conn = DBUtils.getConnection();
//ps = conn.prepareStatement("select*from music where title like '%"+str+"%'");
            ps = conn.prepareStatement("select m.id as music_id,title,singer,time,url,userid from lovemusic lm,music m where lm.music_id=m.id and user_id=? and title like '%"+str+"%'");
            ps.setInt(1,user_id);
            rs = ps.executeQuery();
            while(rs.next()) {
     
                Music music = new Music();
                music.setId(rs.getInt("music_id"));
                music.setTitle(rs.getString("title"));
                music.setSinger(rs.getString("singer"));
                music.setTime(rs.getDate("time"));
                music.setUrl(rs.getString("url"));
                music.setUserid(rs.getInt("userid"));
                musics.add(music);
            }
        } catch (Exception e) {
     
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
     
            DBUtils.getClose(conn, ps, rs);
        }
        return musics;
    }

Service层设计实现

1.实现UserService

package service;

import dao.UserDao;
import entity.User;

/**
 * @ClassName UserService
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/20/17:10
 */
public class UserService {
     
    //登录方法
    public User login(User loginUser) {
     
        UserDao userDao = new UserDao();
        User user = userDao.login(loginUser);
//System.out.println("UserService "+ user);
        return user;
    }
    // 注册方法
    public void register(User user) {
     
        UserDao userDao = new UserDao();
        userDao.register(user);
    }
}

2.实现MusicService

package service;

/**
 * @ClassName MusicService
 * @Description :TODO
 * Service 层是一个中间层,可以整合Dao层的功能。也就是将Dao层的各个模块嵌套起来,实现逻辑关系
 * @Author Josvin
 * @Date 2021/02/20/17:10
 */
public class MusicService {
     
    //TODO

}

Servlet设计与实现

1.LoginServlet实现

package servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import dao.UserDao;
import entity.User;
import service.UserService;

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;

/**
 * @ClassName LoginServlet
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/20/19:22
 */
@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);
        //UserDao dao = new UserDao();
        Map<String ,Object> return_map = new HashMap<>();
        User loginUser =new User(); //创建一个数据库实体类对象
        loginUser.setUsername(username);
        loginUser.setPassword(password);
        try {
     
            //User user = dao.login(loginUser);
            UserService userService = new UserService();
            User user = userService.login(loginUser);
            if(user != null) {
     
                req.getSession().setAttribute("user", user);//绑定数据
                return_map.put("msg",true);
                System.out.println("登陆成功!");
            }else {
     
                System.out.println("登陆失败!");
                return_map.put("msg",false);
            }
        } catch (Exception e) {
     
            e.printStackTrace();
        }
        ObjectMapper mapper = new ObjectMapper(); //利用Jackson将map转化为json对象
        mapper.writeValue(resp.getWriter(),return_map);// return_map 返回给前端
    }

}

测试:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第30张图片
测试出现错误,不见跳转检查发现前端代码没写url:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第31张图片

修改之后,点击登录则会跳转页面:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第32张图片

2.FindMusicServlet实现

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.List;

/**
 * @ClassName FindMusicServlet
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/20/20:27
 */
@WebServlet("/findMusic")
public class FindMusicServlet extends HttpServlet {
     
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html; charset=utf-8");
        System.out.println("测试查找函数");
        String str = req.getParameter("musicName");
        MusicDao dao = new MusicDao();
        List<Music> musics = null;
        if(str!=null) {
     
            musics = dao.ifMusic(str);//关键字查询
        }else {
     
            musics = dao.findMusic();
        }
        for (Music music : musics) {
     
            System.out.println(music.getUrl());
        }
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(resp.getWriter(),musics);
    }
}

测试出现错误不见页面显示歌曲:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第33张图片
下来开始解决错误:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第34张图片
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第35张图片
应该是我在数据库插入的时间那个字段出现了问题,注意中文和英文:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第36张图片
这样就可以播放了:
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第37张图片

3.删除音乐信息实现

3.1 删除某个音乐(DeleteMusicServlet)

**
 * @ClassName DeleteMusicServlet
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/21/20:44
 */
@WebServlet("/deleteServlet")
public class DeleteMusicServlet extends HttpServlet {
     
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        System.out.println("删除指定音乐!");
        req.setCharacterEncoding("utf-8");
        resp.setContentType("application/json;charset=utf-8");
        Map<String,Object> map=new HashMap<>();
        String strId = req.getParameter("id");
        int id = Integer.parseInt(strId);
        System.out.println("id:"+ id);
        try {
     
            MusicDao musicDao = new MusicDao();
//1.查找有没有当前id
            Music music = musicDao.findMusicById(id);
//没有这个id的音乐 直接返回
            if(music == null) return;
//2、如果有就开始删除库中的音乐
            int delete = musicDao.deleteMusicById(id);
            System.out.println("delete:"+delete);
            if(delete == 1){
     
//3、数据库删除完成后,检查还是否存在。如果不存在,那么删除掉磁盘上的文件
                File file = new File("E:\\Java_code\\JavaCode\\OnlineMusic\\web\\"+music.getUrl()+".mp3");
                System.out.println("文件是否存在:"+file.exists());
                System.out.println("file: "+file);
                if(file.delete()){
     
//证明删除成功
                    map.put("msg",true);
                    System.out.println("删除文件成功!");

                }else {
     
                    map.put("msg",false);
                    System.out.println("文件名:"+file.getName());
                    System.out.println("删除文件失败!");
                }
            }else {
     
                map.put("msg",false);
            }
        }catch (Exception e) {
     
            e.printStackTrace();
        }
//将map转化为json
        ObjectMapper mapper=new ObjectMapper();
        mapper.writeValue(resp.getWriter(),map);
    }
}

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第38张图片
在这里插入图片描述
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第39张图片

数据库和服务器都删掉了。

3.2 删除选中音乐


/**
 * @ClassName DeleteSelMusicServlet
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/21/21:04
 */
@WebServlet("/deleteSelMusicServlet")
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");
        String[] values = req.getParameterValues("id[]");
        System.out.println("deleteSelectedServlet:"+Arrays.toString(values));
//删除
        int sum=0;
        Map<String,Object> map=new HashMap<>();
        MusicDao musicDao = new MusicDao();
        for (int i = 0; i < values.length; i++) {
     
            int j = Integer.parseInt(values[i]);
            System.out.println("j :" + j);
//调用Service层方法删除
            Music music = musicDao.findMusicById(j);
            int delete = musicDao.deleteMusicById(j);
//sum=sum+delete;
            if (delete == 1) {
     
//3、数据库删除完成后,检查还是否存在。如果不存在,那么删除掉磁盘上的文件
                File file = new File("E:\\Java_code\\JavaCode\\OnlineMusic\\web\\" + music.getUrl() + ".mp3");
                System.out.println("文件是否存在:" + file.exists());
                System.out.println("file: " + file);
                if (file.delete()) {
     
//证明删除成功
//map.put("msg", true);
                    sum = sum + delete;
                } else {
     
//map.put("msg", false);
                    System.out.println("文件名:" + file.getName());
                    System.out.println("删除文件失败!");
                }
            }
        }
        System.out.println("sum: "+sum);
//sum==values.length 说明选中的所有元素已经全部删除了
        if(sum==values.length){
     
//证明删除成功
            map.put("msg",true);
        }else {
     
            map.put("msg",false);
        }
//将map转化为json
        ObjectMapper mapper=new ObjectMapper();
        mapper.writeValue(resp.getWriter(),map);
    }
}

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第40张图片

4. 上传音乐

上传音乐分为2步:

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

4.1 第一步:将音乐上传到服务器

/**
 * @ClassName UploadMusicServlet
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/21/19:45
 */

@WebServlet("/upload")
//@MultipartConfig
public class UploadMusicServlet extends HttpServlet {
     
    private final String SAVEPATH="E:\\Java_code\\JavaCode\\OnlineMusic\\web\\music\\";
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=utf-8");
        User user = (User) request.getSession().getAttribute("user");
        if (user == null) {
     
            request.setAttribute("Msg", "请登录后再进行上传");
            response.getWriter().write("

请登录后再进行上传 "+"

"
); } else { // 上传 FileItemFactory factory = new DiskFileItemFactory();// ServletFileUpload upload = new ServletFileUpload(factory);// List<FileItem> items = null; try { items = upload.parseRequest(request); } catch (FileUploadException e) { e.printStackTrace(); return; } System.out.println("items:"+items ); FileItem item = items.get(0); System.out.println("item: "+item); String fileName = item.getName(); System.out.println("fileName"+fileName); request.getSession().setAttribute("fileName", fileName); try { item.write(new File(SAVEPATH, fileName)); } catch (Exception e) { e.printStackTrace(); } // 上传到数据库 response.sendRedirect("uploadsucess.html"); } } }

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第41张图片
【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第42张图片
通过之前登录会把用户信息写在Session之中,我们在往数据库中添加信息就可以获取用户信息。

4.2 第二步:将音乐信息存放到数据库


/**
 * @ClassName UploadInsertServlet
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/21/20:11
 */
@WebServlet("/uploadsucess")
public class UploadInsertServlet extends HttpServlet {
     
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html; charset=utf-8");
        String strings = (String)req.getSession().getAttribute("fileName");
        String[] titles = strings.split("\\.");// 去掉.mp3
        String title = titles[0];
        System.out.println("title:" + title);
        String url = "music\\"+title;
        System.out.println("url:"+url);
        String singer = req.getParameter("singer");
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String time=sdf.format(new Date());
        MusicDao dao = new MusicDao();
        User user = (User) req.getSession().getAttribute("user");
        int user_id = user.getId();
        int num = dao.insert(title,singer,time,url,user_id);
        if(num!=0){
     
            resp.sendRedirect("list.html");
        }
    }
}

5.添加喜欢的音乐到喜欢列表

/**
 * @ClassName LoveMusicServlet
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/21/21:25
 */
@WebServlet("/loveMusicServlet")
public class LoveMusicServlet 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 strId = req.getParameter("id");
        int musicId = Integer.parseInt(strId);
        System.out.println("musicID: "+musicId);
        User user = (User) req.getSession().getAttribute("user");
        int user_id = user.getId();
        MusicDao musicDao = new MusicDao();
        Map<String,Object> map=new HashMap<>();
//插入之前需要先查看是否该音乐已经被添加到喜欢列表
        boolean effect = musicDao.findMusicByMusicId(user_id,musicId);
        if(effect) {
     
            map.put("msg",false);
        }else {
     
            boolean flg = musicDao.insertLoveMusic(user_id,musicId);
            if(flg) {
     
                map.put("msg",true);
            }else {
     
                map.put("msg",false);
            }
        }
        ObjectMapper mapper=new ObjectMapper();
        mapper.writeValue(resp.getWriter(),map);
    }
}

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

/**
 * @ClassName FindLoveMusicServlet
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/21/21:38
 */
@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 str = req.getParameter("loveMusicName");
        System.out.println("loveMusicName:"+str);
        User user = (User) req.getSession().getAttribute("user");
        int user_id = user.getId();
        MusicDao musicDao = new MusicDao();
        List<Music> musics = null;
        if(str!=null) {
     
            musics = musicDao.ifMusicLove(str,user_id);//关键字查询
        }else {
     
            musics = musicDao.findLoveMusic(user_id);
        }
        for (Music music : musics) {
     
            System.out.println(music.getUrl());
        }
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(resp.getWriter(),musics);
    }
}

【Java项目实战】在线音乐播放器(从需求到产品完整解析)_第43张图片

7.移除我喜欢的音乐


/**
 * @ClassName RemoveLoveServlet
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/02/21/21:51
 */
@WebServlet("/removeLoveServlet")
public class RemoveLoveServlet extends HttpServlet {
     
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        req.setCharacterEncoding("utf-8");
        resp.setContentType("application/json;charset=utf-8");
        User user = (User) req.getSession().getAttribute("user");
        int user_id = user.getId();
        Map<String,Object> map=new HashMap<>();
        String strId = req.getParameter("id");
        int music_id = Integer.parseInt(strId);
        MusicDao musicDao = new MusicDao();
        int delete = musicDao.removeLoveMusic(user_id,music_id);
        if(delete == 1) {
     
            map.put("msg",true);
        }else {
     
            map.put("msg",false);
        }
        ObjectMapper mapper=new ObjectMapper();
        mapper.writeValue(resp.getWriter(),map);
    }
}

前端页面的设计

前端采用HTML+CSS+JS设计。
直接在百度上搜索 “免费网页模板”, 能找到很多免费模板网站. 可以直接基于现成的漂亮的页面进行修改.
tips: 做减法比做加法更容易.
将网页模板解压缩, 拷贝到项目的webapp 或者 web 目录中.
网址分享:
http://tpl.amazeui.org/
https://ajz.fkw.com/pro11.html?_ta=150&kw=145

部署(后续。。。)

你可能感兴趣的:(web项目,数据库,java,mysql,web,项目)