Android音乐播放器开发(1)—服务端
1. 说明
本音乐播放器基于Android开发,原为我和另外两个小伙伴在上学期间一起做的一个小项目,近来有时间整理一下。之前我有文章已经介绍了播放界面的功能实现(Android音乐播放器开发),但介绍的比较粗糙,接下来会做更细致化的整理。源码已同步到Gitee仓库,GitHub仓库,觉得还不错的话帮忙点个“star”吧,非常感谢。
服务端使用的是比较传统的servlet和jdbc传递数据,整理完之后,新版本会修改为SSM框架,更加简洁高效。安卓端使用的也都是基础的工具,比如音乐播放功能的实现也是借助于入门级的MediaPlayer类,目前关于安卓端没有什么更改的想法。
2. 数据库
要实现音乐播放器,数据库是必不可少的。为简化项目开发,现针对音乐播放器只设计两张表:歌曲表和用户表。顾名思义,歌曲表用来存储歌曲信息,用户表用来存储用户信息。
2.1 数据库设计
涉及到的属性如下图所示:
- 歌曲表
- 用户表
(各位如果感兴趣的话,也可以将用户关闭播放器时的当前歌曲播放时长同样记录下来,这样更加符合现在主流的播放器设计)
2.2 数据库创建
数据库工具选用MySQL,为服务端提供数据支持
- 创建数据库
CREATE DATABASE `MusicPlayer`;
- 创建歌曲表
USE `MusicPlayer`;
DROP TABLE IF EXISTS `music`;
CREATE TABLE `music` (
`music_id` int(5) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`author` varchar(50) NOT NULL,
`address` varchar(50) NOT NULL,
`img` varchar(50) NOT NULL,
`create_time` datetime NOT NULL,
`change_time` datetime,
`remark` text,
PRIMARY KEY (`music_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
- 创建用户表
CREATE TABLE `user` (
`userid` int(5) NOT NULL AUTO_INCREMENT,
`account` varchar(20) NOT NULL,
`password` varchar(20) NOT NULL,
`music_id` int(5) NOT NULL DEFAULT '0',
`pattern` int(5) NOT NULL DEFAULT '0',
`create_time` datetime NOT NULL,
`change_time` datetime,
`remark` text,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
3. 数据处理
工具:IDEA
语言:Java
3.1 准备工作
MVC
业务逻辑处理涉及数据的传输与存储。这里使用了比较旧的MVC三层架构。(当然本项目相对简单,可以将所有业务揉到一起写,但为了结构更加清晰,使用了该架构)
接下来简单介绍以下设计思路。
什么是MVC?MVC由Model(模型)、View(视图)和Controller(控制器)三层组成。
在web项目中,三层结构各有其作用:
-
Controller(servlet)
- 接收用户请求(request),并作出相应请求
- 将业务逻辑交给业务层处理
- 控制视图的跳转
-
Model
- 处理业务:业务逻辑(service)
- 数据持久化:CRUD(Dao)
-
View
- 展示数据
- 发起servlet请求
值得注意的是,在本项目中,视图是交给Android端来处理的,而Android端有着自己的数据处理业务,因此,在服务端不存在视图层,而控制器也不负责视图跳转,只剩下数据处理的部分。
JDBC
这里简单介绍一下JDBC
程序通过数据库驱动才能和数据库进行数据的交互,SUN公司提供了Java操作数据库的规范,就是jdbc,开发人员学习jdbc接口即可,不同的数据库厂商开发各自的数据库驱动
操作数据库包含以下几个步骤:
-
加载驱动程序,由于不同的数据库厂商有着自己的数据库驱动,因此操作不同的数据库需要加载不同的驱动,而MySQL对应的驱动为
com.mysql.jdbc.Driver
-
获取数据库连接,得到一个Connection
-
获取Statement对象,Statement对象用来执行增删查改操作。在Statement中,对数据没有进行改动的操作(也就是查询操作),执行executeQuery方法,而对数据有改动的操作(增、删、改),执行executeUpdate方法。另外,为防止SQL注入,常使用PreparedStatement对象。
-
如果执行的是查询操作,会返回一个结果集ResultSet
释放资源时,由后向前依次释放。
3.2 建立maven项目
- 新建一个maven项目
new–>project–>maven–>webapp
- 导入连接jdbc依赖(pom.xml),我使用的是5.1.49的版本
- 导入junit依赖,方便测试
- 导入fastjson依赖,后续需要使用json进行数据传输
- servlet依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
3.3 JavaBean
java项目中对应数据库基本表建立对应的实体类,方便数据的传输
ORM:对象关系映射:
- 表–>对应java类
- 字段–>对应属性
- 行记录–>对象
- 歌曲表
import java.util.Date;
public class music {
private int musicId;
private String name;
private String author;
private String address;
private String img;
private Date createTime;
private Date changeTime;
private String remark;
public music(){
}
@Override
public String toString() {
return "music{" +
"musicId=" + musicId +
", name='" + name + '\'' +
", author='" + author + '\'' +
", address='" + address + '\'' +
", img='" + img + '\'' +
", createTime=" + createTime +
", changeTime=" + changeTime +
", remark='" + remark + '\'' +
'}';
}
public int getMusicId() {
return musicId;
}
public void setMusicId(int musicId) {
this.musicId = musicId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getChangeTime() {
return changeTime;
}
public void setChangeTime(Date changeTime) {
this.changeTime = changeTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
- 用户表
import java.util.Date;
public class user {
private int userId;
private String account;
private String password;
private int musicId;
private int time;
private int pattern;
private Date createTime;
private Date changeTime;
private String remark;
public user(){
}
@Override
public String toString() {
return "user{" +
"userId=" + userId +
", account='" + account + '\'' +
", password='" + password + '\'' +
", musicId=" + musicId +
", time=" + time +
", pattern=" + pattern +
", createTime=" + createTime +
", changeTime=" + changeTime +
", remark='" + remark + '\'' +
'}';
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getMusicId() {
return musicId;
}
public void setMusicId(int musicId) {
this.musicId = musicId;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public int getPattern() {
return pattern;
}
public void setPattern(int pattern) {
this.pattern = pattern;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getChangeTime() {
return changeTime;
}
public void setChangeTime(Date changeTime) {
this.changeTime = changeTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
3.4 Dao(持久层)
Dao层是直接操作数据库的模块,在这里真正执行增删查改命令,操作数据库借助了JDBC工具(之前已导入依赖)
- db.properties
我这里使用了一个properties文件存储连接数据库的必要信息(当然这里可以直接写在业务代码中,但写在配置文件中对于后期维护来说更加简洁,更改数据库配置只需要修改配置文件即可),然后将所需数据解析到类中。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/musicplayer?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
- BaseDao
在这里将通用的逻辑代码单独拎了出来,包括建立数据库连接、关闭数据库连接、执行增删查改操作
//操作数据库的公共类
public class BaseDao {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try {
InputStream in = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");//读取配置文件返回数据流
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//加载驱动
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取连接
public static Connection getConnextion() throws SQLException {
//获取
return DriverManager.getConnection(url, username, password);
}
//释放资源
public static boolean closeResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) {
boolean flag = true;
if (resultSet!=null) {
try {
resultSet.close();
//GC回收
resultSet = null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}
if (preparedStatement!=null) {
try {
preparedStatement.close();
//GC回收
preparedStatement = null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}
if (connection!=null) {
try {
connection.close();
//GC回收
connection = null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}
return flag;
}
//编写查询公共类
public static ResultSet execute(Connection connection, String sql,Object[] params,ResultSet resultSet,PreparedStatement preparedStatement) throws SQLException {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
//setObject占位符从1开始,数组从0开始
preparedStatement.setObject(i+1,params[i]);
}
resultSet = preparedStatement.executeQuery();
return resultSet;
}
//编写增、删、改公共方法
public static int execute(Connection connection, String sql,Object[] params,PreparedStatement preparedStatement) throws SQLException {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
//setObject占位符从1开始,数组从0开始
preparedStatement.setObject(i+1,params[i]);
}
int updateRows = preparedStatement.executeUpdate();
return updateRows;
}
}
编写增删查改公共方法时涉及到了java方法的重载,可以看到,查询相比增、删、改所使用的参数多一个查询结果集ResultSet
//查询
execute(Connection connection, String sql,Object[] params,ResultSet resultSet,PreparedStatement preparedStatement)
//增、删、改
execute(Connection connection, String sql,Object[] params,PreparedStatement preparedStatement)
CRUD
CRUD就是对数据库执行增删查改操作,程序写到这里就需要考虑到音乐播放器的需求了。
为简化项目开发,现只提出五点数据需求(什么?竟然没有歌曲的添加、歌曲信息的修改……因为如果写这些的话我还得再加一个后台管理系统,目前没这个想法(手动狗头))
前三点都非常好理解,现在介绍一下第四点和第五点。
- 退出时保存当前正在播放的内容:当用户再次打开APP时显示的是上次关闭APP时所听的歌曲
- 获取歌曲所有信息,这个目的是用于音乐播放的数据来源。针对歌曲数量比较少的情况使用此方法还可,但是一旦歌曲数量足够多,加载所有歌曲信息将会占据大量内存空间,因此这里需要各位大佬自行优化
- 两个接口
分别给music表和user表建立对应的接口,表示对这两个表进行增删查改操作
- MusicDao
public interface MusicDAO {
//获取所有歌曲信息
public List<Music> getMusicList(Connection connection) throws SQLException;
}
- UserDao
public interface UserDao {
//获取用户信息
public User getUser(Connection connection, String account) throws SQLException;
//添加用户信息
public int insertUser(Connection connection, User user) throws SQLException;
//更改密码
public int changePassword(Connection connection, User user) throws SQLException;
//退出时保存当前所听歌曲
public int saveMusic(String account, int musicId) throws SQLException;
}
- UserDao实现类(UserDaoImpl)
- getUser(获取用户信息)
public User getUser(Connection connection, String account) throws SQLException {
ResultSet resultSet = null;
PreparedStatement preparedStatement = null;
User user = new User();
if (connection!=null) {
String sql = "select * from user where account = ?";
Object[] params = {account}; //存储参数
resultSet = BaseDao.execute(connection, sql, params, resultSet, preparedStatement);
if(resultSet.next()){
user.setAccount(account);
user.setMusicId(resultSet.getInt("music_id"));
user.setPassword(resultSet.getString("password"));
user.setPattern(resultSet.getInt("pattern"));
user.setCreateTime(resultSet.getDate("create_time"));
user.setChangeTime(resultSet.getDate("change_time"));
user.setRemark(resultSet.getString("remark"));
}
BaseDao.closeResource(null,preparedStatement,resultSet);
}
return user;
}
- insertUser(添加用户信息)
public int insertUser(Connection connection, User user) throws SQLException {
PreparedStatement preparedStatement = null;
int insertRows = 0;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
if (connection!=null) {
String sql = "insert into user(`account`, `password`, `create_time`) values(?,?,?)";
Object[] params = {user.getAccount(), user.getPassword(), df.format(new Date())};
insertRows = BaseDao.execute(connection, sql, params, preparedStatement);
BaseDao.closeResource(null,preparedStatement,null);
}
return insertRows;
}
到这里,已经实现了添加用户信息和查询用户信息两项功能,那么我们可以进行一轮测试,先插入一个用户,再查询该用户信息。借助于junit,可以很方便地对代码进行测试。
//测试添加用户信息
@Test
public void testInsert() throws SQLException {
Connection connection = null;
int i = 0;
try {
connection = BaseDao.getConnextion();
} catch (SQLException e) {
e.printStackTrace();
}
User user = new User();
user.setAccount("cun");
user.setPassword("123456");
if(connection!=null){
i = insertUser(connection, user);
}
if(i!=0){
System.out.println("插入成功");
}
BaseDao.closeResource(connection,null,null); //在哪里开启的connection,就在哪里关闭
}
测试结果如下,根据测试结果可以看出,我们已经插入了一条数据
//测试用户信息查询
@Test
public void testSelect() throws SQLException {
Connection connection = null;
String account = "cun";
User user = null;
try {
connection = BaseDao.getConnextion();
} catch (SQLException e) {
e.printStackTrace();
}
user = getUser(connection, account);
if(user != null){
System.out.println(user.getPassword());
}
BaseDao.closeResource(connection,null,null);
}
测试结果如下,根据测试结果可知,查询出的用户密码正是我们所插入的用户密码。由此表明,两个功能实现正常。
- changePassword(更改用户密码)
public int changePassword(Connection connection, User user) throws SQLException {
PreparedStatement preparedStatement = null;
int updateRows = 0;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
if(connection!=null){
String sql = "update user set password=?, change_time=? where account = ?";
Object[] params = {user.getPassword(), df.format(new Date()), user.getAccount()};
updateRows = BaseDao.execute(connection, sql, params, preparedStatement);
BaseDao.closeResource(null,preparedStatement,null);
}
return updateRows;
}
测试密码更改
@Test
public void testUpdate() throws SQLException {
Connection connection = BaseDao.getConnextion();
User user1 = new User();
user1.setAccount("cun");
user1.setPassword("456789");
int i = changePassword(connection, user1);
User user2 = new User();
if(i>0){
user2 = getUser(connection, "cun");
}
System.out.println(user2.getPassword());
BaseDao.closeResource(connection,null,null);
}
密码已经由原来的123456修改为456789了,修改成功!
- saveMusic(保存音乐id)
public int saveMusic(Connection connection, String account, int musicId) throws SQLException {
PreparedStatement preparedStatement = null;
int updateRows = 0;
if(connection!=null){
String sql = "update user set music_id=? where account = ?";
Object[] params = {musicId, account};
updateRows = BaseDao.execute(connection, sql, params, preparedStatement);
BaseDao.closeResource(null,preparedStatement,null);
}
return updateRows;
}
测试
@Test
public void test() throws SQLException {
Connection connection = BaseDao.getConnextion();
int i = saveMusic(connection, "cun", 5);
User user = new User();
if(i>0){
user = getUser(connection, "cun");
}
System.out.println(user.getMusicId());
BaseDao.closeResource(connection,null,null);
}
测试结果表明已将音乐id保存到了用户信息中了,测试成功!
- MusicDao实现类(MusicDaoImpl)
五点需求现在只剩下获取所有歌曲信息了
- getMusicList
public List<Music> getMusicList(Connection connection) throws SQLException {
ArrayList<Music> musicList = new ArrayList<Music>();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
if (connection!=null) {
String sql = "select * from music";
Object[] params = {};
resultSet = BaseDao.execute(connection, sql, params, resultSet, preparedStatement);
while(resultSet.next()){
Music music = new Music();
music.setName(resultSet.getString("name"));
music.setAuthor(resultSet.getString("author"));
music.setAddress(resultSet.getString("address"));
music.setImg(resultSet.getString("img"));
music.setCreateTime(resultSet.getDate("create_time"));
music.setChangeTime(resultSet.getDate("change_time"));
music.setRemark(resultSet.getString("remark"));
musicList.add(music);
}
BaseDao.closeResource(null,preparedStatement,resultSet);
}
return musicList;
}
要想进行测试,数据库中music表中必须存在数据,现在直接插入一条歌曲信息
INSERT INTO `music` VALUES ('0', '下坠', 'Corki', 'xiazhui.mp3', 'xiazhui.jpg', now(), null, null);
测试getMusicList方法
@Test
public void test() throws SQLException {
Connection connection = BaseDao.getConnextion();
List<Music> musicList = getMusicList(connection);
if(musicList.size()>0){
System.out.println(musicList);
}
BaseDao.closeResource(connection,null,null);
}
3.5 Service(服务)
Service层处理内部逻辑。Servlet接收到请求后,将具体的业务逻辑交给Service去处理,涉及到数据的部分,Service再去调用Dao层实现数据的增删查改。
实际上,在本项目中,Service层的大部分程序在Dao层的测试程序中出现过,因此这一部分非常容易理解。
- 还是建立两个接口。
- MusicService
public interface MusicService {
//获取所有的歌曲信息
public List<Music> getMusicList();
}
- UserService
public interface UserService {
//用户登录
public User login(String account);
//根据用户账户修改密码
public boolean updatePwd(String account, String password);
//注册新用户
public boolean insertUser(String account, String password);
//保存当前歌曲信息
public boolean updateMusic(String account, int musicId);
}
- UserService实现类(UserServiceImpl)
- dao层
业务层都会调用dao层,所以我们直接使用无参构造引入dao层
private UserDao userDao;
public UserServiceImpl(){
userDao = new UserDaoImpl();
}
- login(用户登录)
public User login(String account, String password) {
Connection connection = null;
User user = null;
try {
connection = BaseDao.getConnextion();
user = userDao.getUser(connection, account);
} catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection, null, null);
}
return user;
}
- updatePwd(更改密码)
public boolean updatePwd(String account, String password) {
boolean flag = false;
Connection connection = null;
User user = new User();
user.setAccount(account);
user.setPassword(password);
try {
connection = BaseDao.getConnextion();
if(userDao.changePassword(connection, user)>0){
flag = true;
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection, null, null);
}
return flag;
}
- insertUser(插入新用户)
public boolean insertUser(String account, String password) {
boolean flag = false;
Connection connection = null;
User user = new User();
user.setAccount(account);
user.setPassword(password);
try{
connection = BaseDao.getConnextion();
if(userDao.insertUser(connection, user)>0){
flag = true;
}
}catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection, null, null);
}
return flag;
}
- updateMusic(保存用户的歌曲信息)
public boolean updateMusic(String account, int musicId) {
boolean flag = false;
Connection connection = null;
try{
connection = BaseDao.getConnextion();
if(userDao.saveMusic(connection, account, musicId)>0){
flag = true;
}
}catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection, null, null);
}
return flag;
}
- MusicService实现类(MusicServiceImpl)
- 同样首先拿到MusicDao
private MusicDao musicDao;
public MusicServiceImpl(){
musicDao = new MusicDaoImpl();
}
- getMusicList(获取全部歌曲信息)
public List<Music> getMusicList() {
List<Music> musicList = new ArrayList<Music>();
Connection connection = null;
try {
connection = BaseDao.getConnextion();
musicList = musicDao.getMusicList(connection);
}catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection, null, null);
}
return musicList;
}
3.6 Util(工具类)
在写servlet层之前,先构建一个工具类。
由于从数据库获取的数据都使用了实体类,而服务端的数据需要向Android端进行传输,使用实体类不方便,这里将数据进一步转化为json文件进行传输。
jsonUtil
- getUserJson
提供了User类转json的方法。
//user转json
public String getUserJson(User user){
JSONObject userJson = new JSONObject();
if(user!=null){
userJson.put("userId", user.getUserId());
userJson.put("account", user.getAccount());
userJson.put("password", user.getPassword());
userJson.put("music_id", user.getMusicId());
userJson.put("pattern", user.getPattern());
userJson.put("createTime", user.getCreateTime());
userJson.put("changeTime", user.getChangeTime());
userJson.put("remark", user.getRemark());
}
return userJson.toString();
}
- getMusicJson
//music转json
public String getMusicJson(Music music){
JSONObject musicJson = new JSONObject();
if(music != null){
musicJson.put("musicId", music.getMusicId());
musicJson.put("name", music.getName());
musicJson.put("author", music.getAuthor());
musicJson.put("address", music.getAddress());
musicJson.put("img", music.getImg());
musicJson.put("createTime", music.getCreateTime());
musicJson.put("changeTime", music.getChangeTime());
musicJson.put("remark", music.getRemark());
}
return musicJson.toString();
}
- getJsonArray
//List<Music>转JsonArray
public String getJsonArray(List<Music> musicList){
JSONObject musicJson = new JSONObject();
JSONArray musicJsonArray = new JSONArray();
for (Music music:musicList) {
musicJson.put("musicId", music.getMusicId());
musicJson.put("name", music.getName());
musicJson.put("author", music.getAuthor());
musicJson.put("address", music.getAddress());
musicJson.put("img", music.getImg());
musicJson.put("createTime", music.getCreateTime());
musicJson.put("changeTime", music.getChangeTime());
musicJson.put("remark", music.getRemark());
musicJsonArray.add(musicJson);
}
return musicJsonArray.toString();
}
3.7 Servlet
- LoginServlet
用于登录系统。这里继承了HttpServlet,需要改写父类的doGet和doPost方法
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String responseJson = "";
//从android端获取用户名和密码
String userAccount = req.getParameter("account");
String userPassword = req.getParameter("password");
//与数据库中的密码进行比对
UserService userService = new UserServiceImpl();
User user = userService.login(userAccount);
if(user != null){
JsonUtil jsonUtil = new JsonUtil();
responseJson = jsonUtil.getUserJson(user);
}
resp.getWriter().append(responseJson).flush();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- UpdatePwdServlet
更改密码,注意这里首先验证旧密码是否符合数据库中保存的密码,符合才能进行更新操作
public class UpdatePwdServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String response = "";
//从android端获取用户名和密码
String userAccount = req.getParameter("account");
String userPassword = req.getParameter("oldPassword");
String newPassword = req.getParameter("newPassword");
//先验证旧密码与数据库中的是否相同
UserService userService = new UserServiceImpl();
User user = userService.login(userAccount);
if(user != null){
if(user.getPassword().equals(userPassword)){
boolean flag = userService.updatePwd(userAccount, newPassword);
if(flag){
response = "{'result':'修改成功!'}";
}
else{
response = "{'result':'修改失败!'}";
}
}
else{
response = "{'result':'旧密码错误!'}";
}
}
resp.getWriter().append(response).flush();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- SignUpServlet
注册新用户
public class SignUpServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String response = "";
//从android端获取用户名和密码
String userAccount = req.getParameter("account");
String userPassword = req.getParameter("password");
UserService userService = new UserServiceImpl();
boolean flag = userService.insertUser(userAccount, userPassword);
if(flag){
response = "{'result':'注册成功!'}";
}else{
response = "{'result':'注册失败!'}";
}
resp.getWriter().append(response).flush();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- SaveMusicServlet
向用户表中保存歌曲信息
public class SaveMusicServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String response = "";
//从android端获取用户名和密码
String userAccount = req.getParameter("account");
int musicId = Integer.parseInt(req.getParameter("musicId"));
UserService userService = new UserServiceImpl();
boolean flag = userService.updateMusic(userAccount, musicId);
if(flag){
response = "{'result':'保存成功!'}";
}else{
response = "{'result':'保存失败!'}";
}
resp.getWriter().append(response).flush();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- GetMusicListServlet
获取所有歌曲信息
public class GetMusicListServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String response = "";
MusicService musicService = new MusicServiceImpl();
List<Music> musicList = musicService.getMusicList();
if(musicList.size()>0){
JsonUtil jsonUtil = new JsonUtil();
response = jsonUtil.getJsonArray(musicList);
}
else{
response = "{'result':'获取歌曲列表失败!'}";
}
resp.getWriter().append(response).flush();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4. 配置Tomcat
在IDEA中直接配置一个Tomcat
- Run–>Edit Configurations
- “+”–>Tomcat Server–>Local
- 修改Name
- Deloyment–>"+"–>Artifact
- 选中当前项目,一定要选择下面这种类型的
- 修改Application context–>Apply–>ok
配置完成后就会显示刚配置的tomcat,直接点击“运行”即可启动tomcat
- 配置servlet映射,这个是为了在其它环境访问服务端(
web.xml
)
- servlet:绑定servlet类
- servlet-mapping:设置访问地址url
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>servlet.user.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SaveMusicServlet</servlet-name>
<servlet-class>servlet.user.SaveMusicServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SaveMusicServlet</servlet-name>
<url-pattern>/SaveMusic</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SignUpServlet</servlet-name>
<servlet-class>servlet.user.SignUpServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SignUpServlet</servlet-name>
<url-pattern>/SignUp</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>UpdatePwdServlet</servlet-name>
<servlet-class>servlet.user.UpdatePwdServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UpdatePwdServlet</servlet-name>
<url-pattern>/UpdatePwd</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>GetMusicListServlet</servlet-name>
<servlet-class>servlet.music.GetMusicListServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GetMusicListServlet</servlet-name>
<url-pattern>/GetMusicList</url-pattern>
</servlet-mapping>
</web-app>
- 测试
使用GET方法请求服务端数据(GET和POST是HTTP请求的两种基本方法,具体区别这里不再赘述),具体表现在使用GET方法时数据被放在请求的URL中。
- 启动Tomcat
启动成功后,会在浏览器打开默认的web界面,此时的url是http://localhost:8080/musicplayer/
- 测试登录
url:http://localhost:8080/musicplayer/login?account=cun&password=456789
配置servlet映射后,访问登录的servlet即为/login,在?后加入参数,以上的url表示设置account为cun,设置password为456789。浏览器的显示结果如下,由结果可知,数据传输成功。
使用错误的密码进行测试:
- 测试修改密码
url:http://localhost:8080/musicplayer/UpdatePwd?account=cun&oldPassword=456789&newPassword=123456
再看一遍数据库,发现数据确实已经被修改为123456
- 测试注册
url:http://localhost:8080/musicplayer/SignUp?account=abc&password=456789
数据库中已经有了账户为abc的数据
- 测试保存歌曲信息到用户表中
url:http://localhost:8080/musicplayer/SaveMusic?account=abc&musicId=4
数据库中的信息已经被更改
- 测试获取歌曲信息
url:http://localhost:8080/musicplayer/GetMusicList
5. 结语
至此,服务端代码已基本完成,一部分程序还没有做测试,下一步编写Android程序,结合Tomcat,测试在服务端提取数据。
回顾一下,服务端:
- 工具:IDEA开发工具、MySQL数据库、Tomcat;
- 技术:servlet、jdbc、MVC架构
6.
近来发现一些小伙伴不看开头啊。
程序已经放到两个仓库了,觉得有帮助到你的话,就请给本文点个赞,给仓库点个star吧!万分感谢!
更多推荐
所有评论(0)