前言:对于之前系统地学习java之路,现在面临找工作,发现对项目的询问比较多,之前只是把自己的项目挂在了github上,还是总结一下比较好。
一、需求分析
第一眼就看上了这个项目,觉得一个可以实现用户注册登录,上传音频章节信息图书资料的项目对我而言十分合适,其中有JDBC编程实现的注册登录上传书籍等静态文本内容数据库交互操作。又有上传音频播放这种比较新鲜我没有学习过的点。拿来做项目真是极好的。
进入正题:做朗读者网的需求重点是实现小说上传和音频的上传,用户的注册和登录。
之后可以增加其他的拓展性需求,比如加个视频,美化下界面,实现用户管理,个人中心什么的。
二、实施可行性
从需求分析也能得出,目前我的水平只有开发学生信息管理系统登录注册功能时MVC那一套后端的开发,这次的开发,我的技术难点在于从头开发,相当于前端那一套得研究一下,录制音频的方法也得好好学习一下子。
可以解决:用户注册登录,添加书籍章节。
技术难点:录制音频,上传音频,播放音频。前端页面的开发。
三、技术难点解决
结合菜鸟编程和csdn上的教程找到一个视频的录制上传。
record.html文件
`
预览
录制中
以及JavaScript
// document 是在浏览器中运行时一直存在的一个变量,表示的意思是代表文档树
// html Document Object Model Tree DOM 树
// document 粗糙的可以理解成这棵树的根
// getElementById 从树上,根据 id,找到对应的结点(标签)
let preview = document.getElementById("preview");
let recording = document.getElementById("recording");
let startButton = document.getElementById("startButton");
let stopButton = document.getElementById("stopButton");
let downloadButton = document.getElementById("downloadButton");
function wait(delayInMS) {
// setTimeout(执行什么方法,多少毫秒之后)
// 类似 Java 中的定时器(Timer)
// 设定一个闹钟一样的效果
return new Promise(resolve => setTimeout(resolve, delayInMS));
}
function startRecording(stream, lengthInMS) {
console.log("开始录制");
let recorder = new MediaRecorder(stream); // 定义一个媒体录制对象
let data = [];
// 当(on) 数据(data)可用(available) 时,执行该方法
recorder.ondataavailable = function (event) {
console.log("数据可用");
// event.data 录制下来的视频和音频数据,存入 data 数组
data.push(event.data); // 线性表的尾插
};
// 开始录制
recorder.start();
// resolve 成功的时候应该执行的方法,对应 then 传入的方法
// reject 失败的时候应该执行的方法,对应 catch 传入的方法
let stopped = new Promise(function (resolve, reject) {
recorder.onstop = resolve;
recorder.onerror = function(event) {
reject(event.name);
}
});
// 持续 lengthInMS 时间后,执行 then 中的方法
let recorded = wait(lengthInMS).then(
function() {
// 20 秒之后
// 判断 recorder 是否还在录制,如果还在录制 == "recording",则,停止录制
if (recorder.state == "recording") {
console.log("停止录制");
recorder.stop();
}
}
);
return Promise.all([
stopped,
recorded
])
.then(() => data);
}
function startCapturing() {
console.log("点击采集");
// 会触发,申请权限的操作
let promise = navigator.mediaDevices.getUserMedia({
video: true, // 申请摄像头权限
audio: true // 申请麦克风权限
});
// 如果用户同意了,就执行 then 中的方法,如果失败(用户不同意 or 其他失败)会执行 catch 中的方法
let promise2 = promise.then(function(stream) {
console.log("同意授权");
// 用户同意了
// stream 变量就代表录制的视频和音频了
preview.srcObject = stream;
// 处理兼容性的,类似 if (!preview.captureStream) { preview.captureStream = preview.mozCaptureStream; }
preview.captureStream = preview.captureStream || preview.mozCaptureStream;
// 接着执行的是,当 preview 开始(on) 播放(palying) 时,执行 then 的方法
// resolve 形参对应的实参就是 xxxx 函数
return new Promise(function(resolve) {
preview.onplaying = resolve;
});
});
function xxxx() {
return startRecording(preview.captureStream(), 5000); //
}
promise2.then(xxxx) // 调用 function(resolve) { ... } 这个函数
.then(function (data) {
console.log("使用录制下来的数据");
console.log(data);
let recordedBlob = new Blob(data, { type: "video/webm" });
recording.src = URL.createObjectURL(recordedBlob);
})
.catch(e => {
console.log(e);
});
}
function stopRecording() {
console.log("点击了结束录制");
}
// startButton.addEventListener("click", startRecording); <-- 和下面的写法,目前可以认为是一样的效果
startButton.onclick = startCapturing;
// 进行事件绑定,发生了 startButton 的点击(click)事件后,
// 请执行 startRecording
// 这种形态就是俗称的回调函数(callback)
// 当 startButton 上有了 click 事件时,startButton.onclick();
stopButton.onclick = stopRecording;
// 在 stopButton 发生了(on) 点击(click)事件后,执行 stopRecording 函数

弄出来效果是这样的。到时候只保留音频录制功能就好了。
四:ER图,数据库设计
一个用户可以上传多部小说(1:n)
一个小说可以有多个章节(1:n)
一个章节对应一个音频(1:1)
ER图大概就是:
用户 —> 小说 —>章节 —> 音频

然后设置表的属性:
Users:uid,username,password
Books:bid,uid,tittle
Sections:sid,bid,name
Audios:aid,sid,uuid,type,content
uuid是逻辑主键,好处是如果audios和别的表合并那aid可能就失效了,但是uuid是独立的主键,永远可用正确。这里就用用。
五、执行建库建表代码和xml文件
create database Audio charset utf8mb4;
use Audio;
create table users (
uid int primary key auto_increment comment '用户id',
username varchar(64) not null unique comment '用户名',
password char(64) not null comment '经过sha-256计算后的用户密码'
);
create table books (
bid int primary key auto_increment comment '小说id',
uid int not null comment '上传用户id',
title varchar(100) not null comment '小说名称'
);
create table sections (
sid int primary key auto_increment comment '章节id',
bid int not null comment '属于哪本小说的id',
name varchar(100) comment '章节名称'
);
create table audios (
aid int primary key auto_increment comment '音频id',
sid int not null unique comment '属于哪个章节的id',
uuid char(36) not null comment 'uuid音频的唯一标识',
type varchar(20) not null comment '音频类型audio/wmv audio/mp3',
content longblob default null comment '音频内容'
);
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 项目基本信息 -->
<groupId>zjw</groupId>
<artifactId>AudioFiction</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- war 包形式打包,IDEA会根据这个选项,自动创建 artifacts 选项-->
<packaging>war</packaging>
<!-- 项目的字符集 + 字符集选项配置 -->
<properties>
<encoding>utf-8</encoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!-- 添加需要的第三方依赖jar包 -->
<dependencies>
<!-- 提供 Servlet 提供的标准接口 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!-- 这个 jar 包只在开发 + 编译阶段使用,运行阶段不需要 -->
<scope>provided</scope>
</dependency>
<!-- 添加 MySQL Driver 的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- 添加处理 json 数据的依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
</dependencies>
</project>
六、方法,url,功能

主要逻辑:tomcat调用servlet,servlet接入逻辑层,service,service调用DAO,DAO对数据库进行交互。

框架就搭好了。
然后开始开发Model:
六、代码开发
Model层:
package com.wanghaidong.model;
import java.io.InputStream;
public class Audio {
public String contentType;
public InputStream inputStream;
public Audio(String type, InputStream content) {
this.contentType = type;
this.inputStream = content;
}
}
package com.wanghaidong.model;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class Book {
public int bid;
public User user;
public String title;
public List<Section> sections;
public Book() {
this.sections = new ArrayList<>();
}
public Book(int bid, User user, String title) {
this.bid = bid;
this.user = user;
this.title = title;
this.sections = new ArrayList<>();
}
@Override
public String toString() {
return "Book{" +
"bid=" + bid +
", user=" + user +
", title='" + title + '\'' +
", sections=" + sections +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false;
Book book = (Book) o;
return bid == book.bid &&
Objects.equals(user, book.user) &&
Objects.equals(title, book.title) &&
Objects.equals(sections, book.sections);
}
@Override
public int hashCode() {
return Objects.hash(bid, user, title, sections);
}
}
package com.wanghaidong.model;
public class Section {
public int sid;
public String name;
// 如果关联声音,uuid 就是保存声音的 uuid
// 否则,uuid == null
public String uuid;
public Section() {
}
public Section(int sid, String uuid, String name) {
this.sid = sid;
this.uuid = uuid;
this.name = name;
}
@Override
public String toString() {
return "Section{" +
"uuid='" + uuid + '\'' +
"name='" + name + '\'' +
'}';
}
}
package com.wanghaidong.model;
import java.util.Objects;
/**
* 一般来说,model 这类对象,都需要覆写
* 1. toString
* 2. equals
* 3. hashCode
*/
public class User {
public int uid;
public String username;
public User() {
}
public User(int uid, String username) {
this.uid = uid;
this.username = username;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", username='" + username + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true; // 两个引用是不是指向同一个对象
if (!(o instanceof User)) return false; // 两个对象的类型是否一致
User user = (User) o; // 判断重要属性是否一样
return uid == user.uid &&
Objects.equals(username, user.username);
}
@Override
public int hashCode() {
return Objects.hash(uid, username);
}
}
DAO层:
package com.wanghaidong.dao;
import com.wanghaidong.model.User;
import com.wanghaidong.util.DB;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.*;
public class UserDao {
public User insert(String username, String plainPassword) throws SQLException {
String password = encrypt(plainPassword);
String sql = "insert into users (username, password) values (?, ?)";
try (Connection c = DB.getConnection()) {
try (PreparedStatement s = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
s.setString(1, username);
s.setString(2, password);
s.executeUpdate();
try (ResultSet r = s.getGeneratedKeys()) {
if (!r.next()) {
return null;
}
return new User(r.getInt(1), username);
}
}
}
}
public User select(String username, String plainPassword) throws SQLException {
String password = encrypt(plainPassword);
String sql = "select uid from users where username = ? and password = ?";
try (Connection c = DB.getConnection()) {
try (PreparedStatement s = c.prepareStatement(sql)) {
s.setString(1, username);
s.setString(2, password);
try (ResultSet r = s.executeQuery()) {
if (!r.next()) {
return null;
}
return new User(r.getInt(1), username);
}
}
}
}
// 这个做法实际上也不适合生产环境真正使用
// 但至少比明文的情况要安全一点
private String encrypt(String plain) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte[] bytes = plain.getBytes();
byte[] digest = messageDigest.digest(bytes);
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
String a = "123";
UserDao userDao = new UserDao();
String encrypt = userDao.encrypt(a);
System.out.println(encrypt);
}
}
package com.wanghaidong.dao;
import com.wanghaidong.model.Section;
import com.wanghaidong.util.DB;
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 SectionDao {
public void insert(int bid, String name) throws SQLException {
String sql = "insert into sections (bid, name) values (?, ?)";
try (Connection c = DB.getConnection()) {
try (PreparedStatement s = c.prepareStatement(sql)) {
s.setInt(1, bid);
s.setString(2, name);
s.executeUpdate();
}
}
}
public List<Section> selectByBid(int bid) throws SQLException {
// 必须用左联查询,自己思考为什么!
String sql = "select sections.sid, uuid, name " +
"from sections left join audios on sections.sid = audios.sid " +
"where bid = ? order by sections.sid";
List<Section> sections = new ArrayList<>();
try (Connection c = DB.getConnection()) {
try (PreparedStatement s = c.prepareStatement(sql)) {
s.setInt(1, bid);
try (ResultSet r = s.executeQuery()) {
while (r.next()) {
Section section = new Section(
r.getInt("sid"),
r.getString("uuid"),
r.getString("name")
);
sections.add(section);
}
}
}
}
return sections;
}
}
package com.wanghaidong.dao;
import com.wanghaidong.model.Book;
import com.wanghaidong.model.User;
import com.wanghaidong.util.DB;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class BookDao {
public Book insert(User user, String title) throws SQLException {
String sql = "insert into books (uid, title) values (?, ?)";
try (Connection c = DB.getConnection()) {
try (PreparedStatement s = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
s.setInt(1, user.uid);
s.setString(2, title);
s.executeUpdate();
try (ResultSet r = s.getGeneratedKeys()) {
if (!r.next()) {
return null;
}
return new Book(r.getInt(1), user, title);
}
}
}
}
public List<Book> selectAll() throws SQLException {
// 联表查询
String sql = "select bid, title, users.uid, users.username " +
"from books, users " +
"where books.uid = users.uid " +
"order by bid desc";
List<Book> books = new ArrayList<>();
try (Connection c = DB.getConnection()) {
try (PreparedStatement s = c.prepareStatement(sql)) {
try (ResultSet r = s.executeQuery()) {
while (r.next()) {
User user = new User(r.getInt("uid"), r.getString("username"));
Book book = new Book(r.getInt("bid"), user, r.getString("title"));
books.add(book);
}
}
}
}
return books;
}
public Book selectByBid(int bid) throws SQLException {
String sql = "select bid, title, users.uid, users.username " +
"from books, users " +
"where books.uid = users.uid and bid = ?";
try (Connection c = DB.getConnection()) {
try (PreparedStatement s = c.prepareStatement(sql)) {
s.setInt(1, bid);
try (ResultSet r = s.executeQuery()) {
if (!r.next()) {
return null;
}
User user = new User(r.getInt("uid"), r.getString("username"));
return new Book(r.getInt("bid"), user, r.getString("title"));
}
}
}
}
}
package com.wanghaidong.dao;
import com.wanghaidong.model.Audio;
import com.wanghaidong.util.DB;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class AudioDao {
public void insert(int sid, String uuid, String contentType, InputStream inputStream) throws SQLException {
String sql = "insert into audios (sid, uuid, type, content) values (?, ?, ?, ?)";
try (Connection c = DB.getConnection()) {
try (PreparedStatement s = c.prepareStatement(sql)) {
s.setInt(1, sid);
s.setString(2, uuid);
s.setString(3, contentType);
s.setBlob(4, inputStream);
s.executeUpdate();
}
}
}
public Audio select(String uuid) throws SQLException {
String sql = "select type, content from audios where uuid = ?";
try (Connection c = DB.getConnection()) {
try (PreparedStatement s = c.prepareStatement(sql)) {
s.setString(1, uuid);
try (ResultSet r = s.executeQuery()) {
if (!r.next()) {
return null;
}
return new Audio(r.getString("type"), r.getBinaryStream("content"));
}
}
}
}
}
Service层:
package com.wanghaidong.service;
import com.wanghaidong.dao.AudioDao;
import com.wanghaidong.model.Audio;
import javax.servlet.http.Part;
import java.io.IOException;
import java.sql.SQLException;
import java.util.UUID;
public class AudioService {
private AudioDao audioDao;
public AudioService() {
audioDao = new AudioDao();
}
public String save(int sid, Part audio) throws IOException, SQLException {
String uuid = UUID.randomUUID().toString();
audioDao.insert(sid, uuid, audio.getContentType(), audio.getInputStream());
return uuid;
}
public Audio get(String uuid) throws SQLException {
return audioDao.select(uuid);
}
}
Servlet层
package com.wanghaidong.service;
import com.wanghaidong.dao.BookDao;
import com.wanghaidong.dao.SectionDao;
import com.wanghaidong.model.Book;
import com.wanghaidong.model.User;
import java.sql.SQLException;
import java.util.List;
public class BookService {
private BookDao bookDao;
private SectionDao sectionDao;
public BookService() {
bookDao = new BookDao();
sectionDao = new SectionDao();
}
public List<Book> list() throws SQLException {
return bookDao.selectAll();
}
public Book post(String title, User user) throws SQLException {
return bookDao.insert(user, title);
}
public Book get(int bid) throws SQLException {
Book book = bookDao.selectByBid(bid);
if (book == null) {
return null;
}
book.sections = sectionDao.selectByBid(bid);
return book;
}
public void addSection(int bid, String name) throws SQLException {
sectionDao.insert(bid, name);
}
}
package com.wanghaidong.service;
import com.wanghaidong.dao.UserDao;
import com.wanghaidong.model.User;
import java.sql.SQLException;
public class UserService {
private UserDao userDao;
public UserService() {
userDao = new UserDao();
}
public User register(String username, String password) throws SQLException {
return userDao.insert(username, password);
}
public User login(String username, String password) throws SQLException {
return userDao.select(username, password);
}
}
package com.wanghaidong.servlet;
import com.wanghaidong.model.Audio;
import com.wanghaidong.service.AudioService;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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.sql.SQLException;
@WebServlet("/audio/get")
public class AudioGetServlet extends HttpServlet {
private AudioService audioService;
@Override
public void init() throws ServletException {
audioService = new AudioService();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String uuid = req.getParameter("uuid");
Audio audio = null;
try {
audio = audioService.get(uuid);
if (audio == null) {
resp.sendError(404, "没有这段声音");
return;
}
} catch (SQLException e) {
throw new ServletException(e);
}
resp.setContentType(audio.contentType);
ServletOutputStream outputStream = resp.getOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = audio.inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, len);
}
audio.inputStream.close();
}
}
package com.wanghaidong.servlet;
import com.wanghaidong.service.AudioService;
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.io.PrintWriter;
import java.sql.SQLException;
@MultipartConfig
@WebServlet("/upload/audio")
public class AudioUploadServlet extends HttpServlet {
private AudioService audioService;
@Override
public void init() throws ServletException {
audioService = new AudioService();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
int sid = Integer.parseInt(req.getParameter("sid"));
Part audio = req.getPart("audio");
// 保存声音,得到声音的 uuid,同时关联 sid
resp.setContentType("utf-8");
resp.setContentType("application/json");
PrintWriter writer = resp.getWriter();
try {
String uuid = audioService.save(sid, audio);
writer.printf("{\"uuid\": \"%s\"}%n", uuid);
} catch (SQLException e) {
e.printStackTrace();
resp.setStatus(500);
writer.printf("{\"reason\": \"%s\"}%n", e.getMessage());
}
}
}
package com.wanghaidong.servlet;
import com.wanghaidong.model.Book;
import com.wanghaidong.model.User;
import com.wanghaidong.service.BookService;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
@WebServlet("/post-book")
public class BookPostServlet extends HttpServlet {
private BookService bookService;
@Override
public void init() throws ServletException {
bookService = new BookService();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String title = req.getParameter("title");
HttpSession session = req.getSession();
User user = (User) session.getAttribute("user");
if (user == null) {
resp.sendRedirect("/login.html");
return;
}
try {
Book book = bookService.post(title, user);
if (book != null) {
resp.sendRedirect("/book.jsp?bid=" + book.bid);
} else {
resp.sendRedirect("/add-book.jsp");
}
} catch (SQLException e) {
throw new ServletException(e);
}
}
}
package com.wanghaidong.servlet;
import com.wanghaidong.service.BookService;
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.sql.SQLException;
@WebServlet("/post-section")
public class SectionPostServlet extends HttpServlet {
private BookService bookService;
@Override
public void init() throws ServletException {
bookService = new BookService();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
int bid = Integer.parseInt(req.getParameter("bid"));
String name = req.getParameter("name");
try {
bookService.addSection(bid, name);
} catch (SQLException e) {
throw new ServletException(e);
}
resp.sendRedirect("/book.jsp?bid=" + bid);
}
}
package com.wanghaidong.servlet;
import com.wanghaidong.model.User;
import com.wanghaidong.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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
@WebServlet("/login")
public class UserLoginServlet extends HttpServlet {
private UserService userService;
@Override
public void init() throws ServletException {
userService = new UserService();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
try {
User user = userService.login(username, password);
if (user == null) {
resp.sendRedirect("/login.html");
return;
}
HttpSession session = req.getSession();
session.setAttribute("user", user);
// 跳转回首页
resp.sendRedirect("/");
} catch (SQLException e) {
throw new ServletException(e);
}
}
}
package com.wanghaidong.servlet;
import com.wanghaidong.model.User;
import com.wanghaidong.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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
@WebServlet("/register")
public class UserRegisterServlet extends HttpServlet {
private UserService userService;
@Override
public void init() throws ServletException {
// Servlet 生命周期的内容
userService = new UserService();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 每次都带上 utf-8 的设置,字符集不会出问题
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
try {
User user = userService.register(username, password);
if (user == null) {
resp.sendRedirect("/register.html");
return;
}
HttpSession session = req.getSession();
session.setAttribute("user", user);
// 跳转回首页
resp.sendRedirect("/");
} catch (SQLException e) {
throw new ServletException(e);
}
}
}
前端代码:
<!DOCTYPE html>
<html lang="zh-hans">
<head>
<meta charset="UTF-8">
<title>AudioFiction | 用户注册</title>
</head>
<body>
<form method="post" action="register">
<div>
<label for="username">
用户名:
<input type="text" id="username" name="username" />
</label>
</div>
<div>
<label for="password">
密码:
<input type="password" id="password" name="password" />
</label>
</div>
<div>
<button type="submit">注册</button>
</div>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-hans">
<head>
<meta charset="UTF-8">
<title>AudioFiction | 用户登陆</title>
</head>
<body>
<form method="post" action="login">
<div>
<label for="username">
用户名:
<input type="text" id="username" name="username" />
</label>
</div>
<div>
<label for="password">
密码:
<input type="password" id="password" name="password" />
</label>
</div>
<div>
<button type="submit">登陆</button>
</div>
</form>
</body>
</html>
最后设计一个测试用例,接下来可以测试一下子
https://blog.youkuaiyun.com/weixin_44861663/article/details/108521624
本文详细记录了一个朗读者项目的开发过程,包括需求分析、实施可行性、技术难点解决、ER图设计、数据库创建及代码开发。项目旨在实现用户注册登录、上传音频章节、播放音频等功能,通过学习前端录制上传技术,克服了技术挑战。
212

被折叠的 条评论
为什么被折叠?



