JavaWeb——在线音乐播放器

本文详细介绍了一个在线音乐系统的实现过程,包括Spring Boot项目搭建、数据库设计、登录模块开发、音乐上传与播放功能、收藏功能等,并提供了前端页面实现的示例代码。

文章目录

效果演示

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1. 创建SpringBoot项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 数据库设计

创建 user 表:

用户 id,用户名 username,用户密码 password

创建 music 表:

音乐 id,音乐名称 title,歌手名称 singer,时间 time,歌曲路径 url,对应上传音乐的用户 userid

创建 lovemusic 表(中间表):

音乐 id,对应的用户id user_id,对应的音乐id music_id

-- 数据库
drop database if exists `onlinemusic`;
create database if not exists `onlinemusic` character set utf8;

-- 使用数据库
use `onlinemusic`;

-- 创建 user表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`password` varchar(255) NOT NULL
);

-- 创建 music 表
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(1000) NOT NULL,
`userid` int(11) NOT NULL
);

-- 创建 lovemusic
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
);

3. 配置数据库和xml

打开application.properties配置如下信息:

#配置数据库
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/onlinemusic?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=你的密码
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver


#配置xml
mybatis.mapper-locations=classpath:mybatis/**Mapper.xml

#配置springboot上传文件的大小,默认每个文件的配置最大为15Mb,单次请求的文件的总数不能大于100Mb
spring.servlet.multipart.max-file-size = 15MB
spring.servlet.multipart.max-request-size=100MB

# 配置springboot日志调试模式是否开启
debug=true

# 设置打印日志的级别,及打印sql语句
#日志级别:trace,debug,info,warn,error
#基本日志
logging.level.root=INFO
logging.level.com.example.onlinemusic.mapper=debug

#扫描的包:druid.sql.Statement类和frank包
logging.level.druid.sql.Statement=DEBUG
logging.level.com.example=DEBUG

4. 登录模块设计

4.1 创建User类

在package com.example.onlinemusic.model包中创建User类

@Data
public class User {
    private int id;
    private String username;
    private String password;
}

4.2 创建对应的Mapper和Controller

1.新建mapper包,在mapper包下新建UserMapper

@Mapper
public interface UserMapper {
    User login(User loginUser);
}

在这里插入图片描述

2.在resource目录下,新建mybatis文件夹,新建UserMapper.xml

<?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.onlinemusic.mapper.UserMapper">


</mapper>

在这里插入图片描述

5. 实现登录

5.1 登录的请求和响应设计

在这里插入图片描述

5.2 请求实现

在这里插入图片描述

@RestController // 这个注解是 @Controller 和 @RequestBody 的组合注解
@RequestMapping("/user") // 一级路由
public class UserController {

    @Autowired
    private UserMapper userMapper; // 注入 UserMapper
                // 后面要用 UserMapper里面的方法,去进行数据查询

    // 登录功能
    @RequestMapping("/login")
    // 传递两个参数 一个是 username 一个是 password
    public void login(@RequestParam String username,
                      @RequestParam String password) { // @RequestParam 注解,可以H后端参数重命名,也可以制定传参

        // 拿到 userLogin 对象,设置 用户名和密码
        User userLogin = new User();
        userLogin.setUsername(username);
        userLogin.setPassword(password);
        // 调用 userMapper的 login 方法 在数据库中 进行查询,返回 User
        User user =  userMapper.login(userLogin);

        if(user != null ) {

            System.out.println("登录成功!");
        }else {

            System.out.println("登录失败!");
        }
    }
}

UserMapper 中:

在这里插入图片描述

@Mapper
public interface UserMapper {

    // 登录功能,查询操作
    User login(User userLogin);// login 方法,返回为 User 对象
}

UserMapper.xml中:

在这里插入图片描述

<!-- 登录操作,查询 username 和 password,后面查询那个,就目录就是谁的,比如这里查询是User-->
    <select id="login" resultType="com.example.onlinemusic.model.User">
        select * from user where username=#{username} and password=#{password};
    </select>

5.3 响应实现

5.31 设置统一的响应体类工具类

在这里插入图片描述

@Data
// 这是统一响应体工具类
public class ResponseBodyMessage <T> {

    private int status; // 状态码
    private String message; // 返回的信息[出错或者没出错的原因]
    private T data; // 返回给前端的数据,有可能是 boolean 类型,类型很多这里直接用 泛型

    // 构造方法
    public ResponseBodyMessage(int status, String message, T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }
}

5.32 创建常量工具类

在这里插入图片描述

5.33 优化后完整代码

加了响应体之后,登录成功,我们再存储一下 Session

完整代码如下:

@RestController // 这个注解是 @Controller 和 @RequestBody 的组合注解
@RequestMapping("/user") // 一级路由
public class UserController {

    @Autowired
    private UserMapper userMapper; // 注入 UserMapper
                // 后面要用 UserMapper里面的方法,去进行数据查询

    // 登录功能
    @RequestMapping("/login")
    // 传递两个参数 一个是 username 一个是 password
        // 加了统一响应体类之后 返回值 不在是 void ,而是 我们的 ResponseBodyMessage
    public ResponseBodyMessage<User> login(@RequestParam String username,
                                           @RequestParam String password,
                                           HttpServletRequest request) {
        // @RequestParam 注解,可以H后端参数重命名,也可以制定传参


        // 拿到 userLogin 对象,设置 用户名和密码
        User userLogin = new User();
        userLogin.setUsername(username);
        userLogin.setPassword(password);
        // 调用 userMapper的 login 方法 在数据库中 进行查询,返回 User
        User user =  userMapper.login(userLogin);

        if(user != null ) {
            System.out.println("登录成功!");
            // 存储 session
//            request.getSession().setAttribute("USERINFO_SESSION_KEY",user);
            // 做出优化后的代码,我们将 USERINFO_SESSION_KEY 写在我们的工具包中
            request.getSession().setAttribute(Constant.USERINFO_SESSION_KEY,user);
            /**
             * request.getSession.setAttribute()是获得当前会话的session
             * 然后再setAttribute到session里面去,有效范围是session而不是request。
             */
            // 返回响应体
            return new ResponseBodyMessage<>(0,"登录成功老铁!",userLogin);
        }else {
            System.out.println("登录失败!");
            // 登录失败,做出响应
                // 在这里规定 status -1 为失败 0为成功
            return new ResponseBodyMessage<>(-1,"登录失败老铁!",userLogin);
        }
    }
}

6. 实现加密登录

6.1 Bcrypt加密设计

Bcrypt就是一款加密工具,可以比较方便地实现数据的加密工作。你也可以简单理解为它内部自己实现了随机加盐处理 。我们使用MD5加密,每次加密后的密文其实都是一样的,这样就方便了MD5通过大数据的方式进行破解。Bcrypt生成的密文是60位的。而MD5的是32位的。Bcrypt破解难度更大

添加如下依赖到 pom.xml:

<!-- security依赖包 (加密)-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>

在 SpringBoot 启动类添加如下代码:

@SpringBootApplication(exclude ={org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class})

在这里插入图片描述

为什么要加 spring-boot 启动类注解:

当启动类,没有加这个过滤的时候,我们发现不能进行登录。
这是因为在SpringBoot中,默认的Spring Security生效了的,此时的接口都是被保护的,我们需要通过验证才能正常的访问。此时通过上述配置,即可禁用默认的登录验证。

实质我们并没有用到 Security 这个框架,而是用到了里面其中的一个类,仅此而以

在这里插入图片描述

创建 BcryptTest 测试类:

public class BcryptTest {
    public static void main(String[] args) {
//模拟从前端获得的密码
        // String password = "123456";
        // 获取 BCrypt 对象
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

        // encode 对我们输入的密码进行加密处理 得到新的密码
        String newPassword = bCryptPasswordEncoder.encode(password);

        System.out.println("加密的密码为: " + newPassword);

//使用matches方法进行密码的校验
        boolean same_password_result = bCryptPasswordEncoder.matches(password, newPassword);
//返回true
        System.out.println("加密的密码和正确密码对比结果: " + same_password_result);
        boolean other_password_result = bCryptPasswordEncoder.matches("987654", newPassword);
//返回false
        System.out.println("加密的密码和错误的密码对比结果: " + other_password_result);
    }
}

6.2 加密登录实现

逻辑如下:

1.根据用户名名称 查询 当前是否存在这样的用户[用户名:默认是唯一的]

2.取出当前用户的密码,进行匹配,查看密码是否是一样的,一样就登录成功

6.21 创建包config,新建AppConfig类

这里为什么要建一个 AppConfig 类,是为了方便我们后面的对象注入,比如我 我们要在 加密登录中 注入 BCryptPasswordEncoder,我们就需要先创建一个对象,通过 @Bean 注解,将它输入到 Spring 容器中

在这里插入图片描述

当然直接在 UserController 当中进行 实例化创建 BCryptPasswordEncoder 对象也是一样的

//@Configuration:表明当前类是一个配置类,被注解的类内部包含有一个或多个被@Bean注解的方法,用于构建
//bean定义,初始化Spring容器。
//@Bean注解:用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方
//法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
//SpringIOC 容器管理一个或者多个bean,这些bean都需要在@Configuration注解下进行创建,在一个方法上使用
//@Bean注解就表明这个方法需要交给Spring进行管理。
@Configuration
public class AppConfig {
    @Bean
    public BCryptPasswordEncoder getBCryptPasswordEncoder() {
        return  new BCryptPasswordEncoder();
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

偷偷敲代码的青花瓷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值