一次在使用听书软件喜马拉雅时,觉得这个软件做的很好,给用户提供了极大的方便和帮助,特别是晚上睡不着的时候,在喜马拉雅上听一段郭德纲的相声,非常加速入眠时间,好的睡眠等于好的生产力,。我很喜欢喜马拉雅,想着自己也可以尝试做一个简易版的喜马拉雅网页,实现主要的听书服务,基于自己有编程的基础和经验,想要自己做一个类似的的听书网页,给他取名就是“听书”,简洁直观。

我将在这篇博客记录自己听书项目的逻辑梳理和记录。

听书项目大纲

主要角色(2个):普通用户+up主

普通用户注册登录后就成为了up主。

主要功能(多个功能)

针对不同角色拥有的不同的主要实现功能

普通用户:

  1. 在首页中获取全部专辑列表
  2. 在首页中根据keyword查找想要专辑列表
  3. 指定专辑中的故事进行故事声音播放

up主:(在普通用户的基础上拥有自己的特有功能)

  1. 浏览自己创建的专辑
  2. 新建专辑
  3. 为专辑录制故事

次要功能

展示专辑的播放量(MySQL事务的具体使用)

库表详情

概念

需要设计3个Tables保存网页具体信息:
用户(User)+专辑(Album)+故事(Story)

关系

用户 创建 专辑(1:m)
用户 创建 故事(1:m)
专辑 包含 故事(1:m)
故事 绑定 声音(1:1)

展示页面详情

不要求用户登录情况下可以展示的页面:
首页(专辑列表页)
专辑详情页(故事列表页)
故事播放页

用户注册/登录时展示的页面:
注册/登录页面

用户处于登录状态时展示的页面:
我的专辑页面(我的专辑列表页面)
新建专辑页面
专辑编辑页面
新建故事页面(故事录制页)

听书项目梳理

MySQL建库表部分详情

MySQL数据库名称为”listen“。
listen数据库里一共有三个表。分别为User,Album,Story。

User:(需要4个字段保存相应的信息)
UserId + User登录名称 + User昵称 + 用户登录密码

uid(INT+PK、NN、AI) + username(VARCHAR+NN、UQ) +  nickname(VARCHAR+NN)  +  password(CHAR(128)+NN)

将用户密码用sha-512算法加密,所以password字段Datatybe必须为CHAR(128)。

Album:(需要5个字段保存相应的信息)
AlbumId + 专辑名称 + 创建专辑的UserId + 专辑封面(以封面图片的URL格式保存) + 专辑的播放次数(播放次数设置默认值为0)

aid(INT+PK、NN、AI) + name(VARCHAR+NN)+uid(INT+NN) + cover(VARCHAR+NN)+ count(INT+ NN + DEfault:‘0’)

专辑的播放次数由专辑中各个故事的播放次数相加。

Story(需要5个字段保存相应的信息)
StoryId + 故事名称 + 故事所属的StoryId + 故事播放次数(播放次数设置默认值为0) + 故事录制的声音文件

sid(INT+PK、NN、AI) + name(VARCHAR+NN)+aid(INT+NN) +  count(INT+ NN + DEfault:‘0’) +  audio(LONGBLOB+NN)

audio字段的Datatybe为LONGBLOB,因为声音字段保存为二进制数据格式。

听书项目Java语言具体实现

需要的maven依赖

        <!-- 以war包的形式打包 -->
<packaging>war</packaging><!-- 需要用到1.8版本的maven --><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><!-- servlet技术的依赖 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!-- MySQL数据库的依赖 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency><!-- jackson格式的依赖 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.11.4</version></dependency><!-- 操作 redis 的依赖 --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.6.3</version></dependency></dependencies>

Java语言的实现逻辑

简单的将项目代码分层。

接入层:servlet包 + api包
服务层:service包
数据访问层:dao包(DAO:Data Access Object)

model包

=将用户(User)+专辑(Album)+故事(Story)类实现放入model包里。=

model包里只存放自定义的三个类。

三个类的具体变量根据MySQL的字段和其数据类型定义。

util包

数据库的连接实现类:DBUtil。
使用单例模式的二次判断书写DBUtil里的具体代码。
配置相关信息:PropertiesUtil。

api包

  1. 类名:AlbumListApi >>> 拉取专辑列表API >>> URL:/api/album-list.json
根据用户有没有传关键字 keyword 做不同的处理。实现根据关键字在专辑列表中查找(模糊匹配)的功能。
从数据库中获取符合条件的专辑列表。
创建一个专辑的线性表albumList,元素类型为Album,保存从数据库中拉取到的符合条件的专辑列表。创建匿名类result存放返回的所有信息。
拉取成功时返回success = true,和拉取到的专辑列表Object类型数据data(将result序列化为JSON字符串放入resp对象中)。
拉取失败返回success = false,打印异常栈,便于找到出错原因,把异常中的消息作为错误原因写到 API 中,返回异常原因(将result序列化为JSON字符串放入resp对象中)。

2.类名:AlbumDetailApi >>> 专辑详情页API >>> URL:/api/album-detail.json

点击专辑名称,实现根据aid查找相应的专辑详情。
从album表中查询该专辑的元信息。(name + cover)
从story表中查找属于该专辑的故事列表。(name + sid)
查询不到则输出“aid 对应的专辑不存在”,查询成功则返回专辑的详细信息及专辑的故事列表(顺序展示)。
  1. 类名:StoryDetailApi >>> 故事播放页API >>> URL:/api/story-detail.json
获取 sid,读取 story 的信息。动态资源的实现过程和专辑详情页API:AlbumDetailApi差不多。
  1. AbsApiServlet >>> 将API中公共代码都抽象到类中
实现一个abstract class,将req、resp、序列化Json里的公共代码抽象到里面。
  1. 类名:APIException >>> 实现自己的异常类
定义受查异常extends RuntimeException。
  1. 类名: AlbumEditorApi >>> 专辑编辑页 >>> URL: /api/album-editor.json
专辑编辑页要对异常情况正确反馈给用户。比如:未登陆之类的。
  1. 类名:MyAlbumListApi >>> 我的专辑列表页 >>> URL:/api/my-album-list.json
在用户登录的前提下,展示登录用户的专辑列表。
  1. 类名:NewStoryApi >>> 故事录制页 >>> URL:/api/new-story.json
根据专辑id将故事的名字,所属专辑id和故事的声音录制信息插入story数据表中。

需要的API接口最终有8个。

servlet包

  1. 类名:RegisterServlet >>> 实现用户注册的动态资源 >>> URL:/register
form表单的形式提交,没用Ajax形式提交。
1.读取用户信息;2.在存储中进行数据保存(INSERT);3.完成登录(Session中保存当前登录用户信息);4.注册成功后引导浏览器回到首页(重定向)。
注册失败抛出异常。
在用户密码放面:基于安全考虑,我们不保存用户的明文密码,我们利用 SHA-512 算法对密码做 hash。实现自己的hash密码。
  1. 类名:LoginServlet >>> 实现用户登录的动态资源 >>> URL:/login
form表单的形式提交。
3. 读取用户写下的信息;2. 通过 MySQL 查询,得到用户对象(查不到对应的用户,代表用户名密码错误);3. 完成登录;4.引导用户去首页。
登录失败抛出异常。
根据登录时用户名和提交的密码hash后在数据库中查询,如果找到则查询登录成功,否则,失败。
  1. 类名:NewAlbumServlet >>> 新建专辑的动态资源 >>> URL: /new-album
后端有责任进行权限验证:要求用户必须登录后才能使用该资源。未登录情况下输出:“用户未登录”。
需要注意图片是以二进制形式传递上来的,使用req.getPart()方法。
我们需要一个 FileOutputStream,把图片保存成本地的一个文件。
新专辑的name, cover保存到数据库。
cover需要保存在数据库里的是能正常访问的URL。
  1. GetAudioServlet >>> 故事播放 >>>URL:/get-audio
负责故事播放的相关处理。
  1. 类名:CurrentUserApi >>> 获取当前用户的登陆状态的API >>> URL:/api/current-user.json
创建匿名类result存放返回的所有信息。
登录状态时返回logged = true,和登录的user对象具体信息(将result对象序列化为JSON字符串放入resp对象中)。
非登录状态时返回logged = false。

一共需要实现5个类在servlet包里。

service包

  1. 类名:AlbumService
主要负责业务逻辑,类似多表进行数据拼接.

dao包

DAO层负责:纯粹的数据存储访问:每张表的 增删查改。

  1. ==类名:AlbumDao ==
负责来联系Java代码和专数据库。主要操作包括选择专辑和新建专辑。
  1. ==类名:StoryDao ==
负责选出故事列表。

前端实现

主要做的是Ajax、DOM树的修改和css样式的编写。

HTML页面(静态资源)

  1. == index.html >>> 首页 >>> 页面名称:听书 | 首页==
首页分为两大部分。
上半部分(header)为首页的导航栏和头部分。包括听书项目的标志brand”听“+搜索功能的入口search+登录/注册和之后的新建专辑/我的专辑的功能区function。
下半部分(main)为展示专辑列表部分。最新创建的专辑放在最前面。
使用的JS资源:index.js + header.js + func.js
  1. register.html >>> 用户注册页面 >>> 页面名称:听书 | 注册
用户注册时需要提交自己的用户名username(数据库中的用户名是不能重复的)+昵称nickname(可以重复)+ 用户的密码password。
提交到”/register“类。
<form method="post" action="/register">
  1. login.html >>> 用户登录页面 >>> 页面名称:听书 | 登录
用户登录时需要提交自己注册过的用户名username + 用户注册的密码password。
提交到”/login“类。
<form method="post" action="/login">
  1. album-detail.html >>> 专辑详情页面 >>> 页面名称:听书 | 专辑详情
展示专辑的元信息和故事列表。
使用的JS资源:album-detail.js + func.js
  1. story-detail.html >>> 故事详情页面 >>> 页面名称:听书 | 故事播放
展示故事的名字和故事的声音播放。
使用的JS资源:story-detail.js + func.js
  1. new-album.html >>> 新建专辑页面 >>> 页面名称:听书 | 新建专辑
提交到“/new-album”类。
<form method="post" action="/new-album" enctype="multipart/form-data">
用户新建专辑时需要提交专辑名称name和上传专辑封面图片cover。
新建专辑时,Tomcat正处于运行时,我们不进行重新部署。我么使用静态方式访问图片,图片资源保存在target下的项目的相对应的图片目录下。不能放在webapp下。
  1. album-editor.html >>> 专辑编辑页面 >>> 页面名称:听书 | 专辑编辑
专辑编辑页面有专辑的元信息和新建故事功能。
使用的JS资源:album-editor.js + func.js
  1. my-album-list.html >>> 我的专辑页面 >>> 页面名称:听书 | 我的专辑
取到专辑列表时,每个专辑都添加一个 <li> 标签。
使用的JS资源:func.js + header.js + my-album-list.js
  1. new-story.html >>> 新建故事页面(故事录制页面) >>> 页面名称:声音录制并上传
<form method="post" action="/api/new-story.json" enctype="multipart/formdata">
里面包含填写故事名称,授权,开始,停止,上传按钮。
使用的JS资源:new-story.js

一共需要实现9个HTML页面。


HTML部分参考HTML语言文档。

JS部分

  1. func.js
前后分离过程中有大量的 AJAX 操作,实现ajax方法。
实现getParameter方法,要实现功能是:从 url 的 query string 部分,获取需要的参数。用spilt方法一点一点分割。
  1. header.js
作用在index.html里的header,表现在首页的上半部分。
实现header方法,要实现功能是:将还未登录的首页中 header 部分的功能区注册 和登录 登陆后替换成 新建专辑 和 我的专辑。
  1. index.js
作用在index.html里的main,表现在首页的下半部分。
当浏览器把所有的资源都加载到位时,再去执行我们的 main 方法。
先从 url 中的 query string 部分,获取 keyword 参数。
为了使得中文可以正常传输,我们把 keyword 做 url 编码。var url = "/api/album-list.json?keyword=" + encodeURIComponent(keyword)。
实现main方法:要实现功能是:拉取专辑列表,遍历专辑列表,针对每个专辑创建 html,以有序列表<ol><li>元素形式展现。
如果main方法拉取失败,以alert弹窗的形式输出失败原因。
  1. album-detail.js
实现main方法,main方法里实现:更新 meta 信息,把故事列表中的故事添加到 story-list 中。
  1. story-detail.js
实现main方法,main方法里实现: 从 url 上获取 sid,展示故事的名字和故事的声音播放。
  1. album-editor.js
登陆后,在我的专辑页面点击专辑名称,进入专辑编辑页面。从 url 中获取 aid(query string)。
负责更新 meta 信息和把故事列表中的故事添加到 story-list 中。
  1. my-album-list.js
对于我的专辑列表页面的展示。
展示内容包含每张专辑列表的专辑名称,专辑封面和专辑播放次数。
  1. new-story.js
负责新建故事也就是故事录制页面的js部分。
包括获取声音数据和用户每个操作之后的输出响应。

一共需要实现8个JS页面。

JS部分参考JavaScript编程语言文档。

CSS部分

CSS样式部分,只实现了首页的CSS和新建故事页面(故事的录制页面)。
首页:

新建故事页面(故事的录制页面):


CSS部分参考CSS编程语言文档。
参考使用的颜色网站:https://flatuicolors.com。

“听书”项目大纲+梳理相关推荐

  1. 小熊听书项目的详细介绍

    目录 一.项目概述 二.项目需求 2.1功能需求 2.2 其他需求 2.3系统功能流程图 2.4总体设计 三.开发环境 四.准备工作 五.介绍文件的存放规则 六.各部分功能的详细介绍 1.建立数据库与 ...

  2. 不爱听书项目测试细则

    前言 软件测试流程:需求分析->测试计划->测试设计->测试执行->测试报告 一.需求分析 "不爱听书"是一个为用户提供创作音乐和收听音频的平台.对于该项目 ...

  3. 听书项目开发过程及重难点总结(用户管理)

    文章目录 一.需求分析 二.前后端交互 1. 注册 **前端** **后端** 2.登录 前端 后端 三.项目开发重难点 1.编写一个Servlet 2.session和session会话机制 1)S ...

  4. PWA项目实战分享(听书APP)

    PWA项目实战分享 - BookPlayer 每天听本书App 因为自己有个需求,特别的痒,昼夜难免.第二天就开始起手做这个项目,利用业余时间,大概持续了10天时间(因为边学边做),从设计到数据(包括 ...

  5. 关于自己项目(听书系统)的简介

    听书系统(类似于喜马拉雅) 文章目录 前言 准备工作 1.库表的创建 (1)用户表users(做主表): (2) 音频表track : (3)专辑表albums: (4)关系表relations: 2 ...

  6. 我的项目——不爱听书系统

    一.项目简介 访问不爱听书系统,用户可以根据自己的喜好选择对应的专辑进行内容播放:若想录制并上传自己的音频,创建专属专辑就需要在创作中心进行注册登录. 二.准备工作 1.库表的创建 2.后端对象(类) ...

  7. 听书 app,学习用途

    Ting 项目地址:zjw-swun/Ting 简介: 听书 app,学习用途 更多:作者   提 Bug 标签: 我是听书重度用户,因为某喜下架了很多我喜欢听的免费资源,,比如<我当算命先生那 ...

  8. 爱看小说手机网源码全站带3w数据带采集,ThinkPHP内核小说网站源码带听书等全部插件

    源码介绍 会员分享的一款自带2w数据爱看小说网源码全站带数据打包,ThinkPHP内核小说网站源码带听书等全部插件 还带了采集规则,采集是没问题的但是不保证时效,早下载早采集!! 喜欢的拿去研究学习吧 ...

  9. 互联网日报 | 1月19日 星期二 | 腾讯音乐全资收购懒人听书;字节跳动整合硬件业务专注教育硬件;PSA与FCA正式完成合并...

    今日看点 ✦ 北京超10万滴滴司机完成疫苗接种,APP将显示已接种标签 ✦ 字节跳动调整硬件业务调整:原锤子科技团队并入教育硬件团队 ✦ 腾讯音乐27亿元收购懒人听书100%股权,后者将保持独立运营 ...

最新文章

  1. [微信官方文档] 小程序-错误码信息与解决方案表
  2. OpenStack环境搭建(一:Virtual Box 5.1 环境的安装及配置)
  3. 7、斐波那契数列、跳台阶、变态跳台阶、矩形覆盖------------剑指offer系列
  4. Photoshop自由变换图形大小
  5. 解惑解释性语言与编译性语言
  6. [转] 理解SVG transform坐标变换
  7. 第十四题: 以下代码的输出结果是?
  8. Tips--Docker常用命令
  9. 巩固知识体系!淘宝秒杀脚本java
  10. 传说中的神器: shared_ptr/weak_ptr/scoped_ptr
  11. 3D目标检测论文汇总
  12. [导入]基于D3D Effect的引擎模式探讨。
  13. IDEA 配置SVN ,SVN安装后没有svn.exe
  14. 字节跳动不需要总部大楼
  15. 接入 钉钉 OA 审批
  16. PS教程:一分钟搞定 超简单PS皮肤美白方法
  17. Ambari2.7.4配置HIVE_AUX_JARS_PATH
  18. 贼有趣:朱茵变杨幂,人工智能换脸让明星不再担心自己演技?
  19. 尝试做一个好的技术Leader, 建立“去中心化团队”
  20. 第一课行列式性质与几何意义

热门文章

  1. Python 基础笔记
  2. 使用ADB命令来停用、卸载荣耀20 PRO的系统应用
  3. mysql安装被打断_MySQL 安装,被中断.the wizard was interrupted...
  4. 《深入理解Spring Cloud与微服务构建》书籍目录
  5. 酷比魔方i7 安装android x86 无线调试
  6. LER在MPLS域中的全称是什么?
  7. 创建获奖场景平面设计
  8. ChatGPT来临,架构师何去何从?
  9. WP8手机安装《神庙逃亡》的教程
  10. php实现微信公众号分享,php版微信公众号自定义分享内容实现方法