一、项目介绍
1.1 课题目的
本项目旨在设计并实现一个基于java的在线阅读小说系统,综合练习java基础知识,重点考察网络通信、IO流以及继承、多态、封装等知识点;
1.2 意义
1.2.1 编写一个在线小说阅读系统是一个复杂且多方面的任务。客户端、服务器端,完成简单通信这不仅是构建整个系统的基础,还涉及到网络通信和数据交换的基本概念。客户端和服务器端的架构是现代互联网应用的基本组成部分。
1.2.2 构建一个在线小说阅读系统不仅涉及多个技术领域的知识,还有助于提高人们的阅读体验、丰富文化生活并促进创作与分享
1.3设计方案
本课题主要是完成一款基java的系统,本项目会采用网络通信的方式,先通过分析整个项目的功能模块,设计API,将服务器与客户端进行通信,使整个项目变得更加健壮,可维护。
大致设计方案可分为:
1.3.1 首先根据项目课题分析出整个项目的功能模块和项目需求
1.3.2 根据划分的功能模块
1.3.3 搭建开发环境并且搭建好项目的目录结构
1.3.4 根据需求完成开发
1.3.5 进行真机调试,修复bug
二、功能模块
2.1 大概的功能模块如下:
2.1.1 用户登陆
2.1.2 用户注册
2.1.3 小说查询
2.1.4 小说上传
2.1.5 小说下载
2.1.6 小说阅读
2.2 界面设计
由于没有写前端与数据库,本项目是完全基于Java后端的,界面设置在控制台完成,用户数据存放在XML文件里
2.2.1 欢迎菜单界面
2.2.2 登陆成功界面
2.2.3 登陆失败界面
2.2.4 注册界面
2.2.5 XML用户消息存放详情
2.2.6 查询小说界面
2.2.7 上传小说界面
2.2.8 下载小说界面
2.2.9 阅读小说界面
三、部分模块代码展示
项目总体目录结构
登陆模块部分代码
流程交互图
3.1 Client
Client 接收用户操作请求
public void menue() throws IOException, InterruptedException, ClassNotFoundException {
System.out.println("欢迎使用线上阅读系统");
System.out.println("请选择功能");
System.out.println("1、登陆");
System.out.println("2、注册");
System.out.println("3、退出系统");
String no = sc.nextLine();
if (no.equals("1")){ //登陆
userClientService.login();
}
3.2 UserClientServer
UserClientServer将用户提交的数据封装成一个MessageEntity类,提供DataUti类l发送给服务器
public void login() throws IOException, InterruptedException, ClassNotFoundException {
System.out.println("请输入登陆用户名");
String userName = sc.nextLine();
System.out.println("请输入登陆用户密码");
String password = sc.nextLine();
UserEntity userEntity = new UserEntity();
userEntity.setUserName(userName);
userEntity.setPassword(password);
MessageEntity messageEntity = new MessageEntity();
messageEntity.setOperate(1);
messageEntity.setUserEntity(userEntity);
//传给服务器
dataUtil.sendData(messageEntity);
//接受数据
String result = dataUtil.reveiveData();
//根据服务器返回的结果取完成不同的处理
resultUtil.postUserResult(result);
}
3.3 MessageEntity
messageEntity 为一个实体类,提供封装好的属性,例如操作数,username,password等,发送给服务器
public class MessageEntity implements Serializable {
private String bookName;
//执行什么操作
/**
* 1、登录
* 2、注册
* 3、选择阅读小说
* 4、上传小说
* 5、下载小说
*/
private int operate;
private UserEntity userEntity;
private String content;
private int packageNo ;
public int getPackageNo() {return packageNo;}
public void setPackageNo(int packageNo) {this.packageNo = packageNo;}
public String getContent() {return content;}
public void setContent(String content) {this.content = content;}
public String getBookName() {return bookName;}
public void setBookName(String bookName) {this.bookName = bookName;}
public int getOperate() {return operate;}
public void setOperate(int operate) {this.operate = operate;}
public void setUserEntity(UserEntity userEntity) {this.userEntity = userEntity;}
public UserEntity getUserEntity() {return userEntity;}
}
3.4 DataUtil
DataUtil 只负责客户端与服务器之间的通信,通过socket方法,将服务器与客户端联系起来
public void sendData(MessageEntity messageEntity) throws IOException {
OutputStream os = socket.getOutputStream();
if (oos == null) {
oos = new ObjectOutputStream(os);
}
//写到服务器
oos.writeObject(messageEntity);
}
//接收数据
public String reveiveData() throws IOException {
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
int total = br.read(chars);
String result = new String(chars,0,total);
return result;
}
3.5 ServerApp
接收客户端发过来的message,对message的操作数 进行不同的操作
public void postClientMessage() throws IOException, ClassNotFoundException, DocumentException {
DataUtil dataUtil = new DataUtil(socket);
if(ois==null) {
os = socket.getOutputStream();
is = socket.getInputStream();
ois = new ObjectInputStream(is);
}
while (true){
//接受客户端的数据
//由于约定了发送的是messageEnttiy对象 所有通过对象流获取发送过来的对象
MessageEntity message = (MessageEntity) ois.readObject();
if (message.getOperate()== 1){ //登陆
//客户端输入的用户名和密码
String result = userService.login(message.getUserEntity());
os.write(result.getBytes());
}
3.6 UserService
将XMLUtil 遍历返回的所有用户信息存放到一个 List 集合当中,将发过来的用户信息进行处理,并将结果返回到ServerApp
3.7 XMLUtil
通过dom4j jar包提供的api,遍历并返回所有用户信息
3.8 ResultUtil
处理服务器返回的结果,并显示
public void postUserResult(String result) throws IOException, InterruptedException, ClassNotFoundException {
if(result.equals(Contain.LOGINSUCRESULT)){
System.out.println("登陆成功");
String info = ct.menueSecondary();
postBookResult(info);
}else if (result.equals(Contain.LOGINFAIRESULT)){
System.out.println("登陆失败,请重新操作");
ct.menue();
}
四、收获与总结
本次项目收获挺大的,网络编程和IO流 的能力有了进一步提升,对于面向对象编程也有了进一步的认识,单一职责、封装也有了更深的体会,但也认识到了自己的不足,对于基础知识掌握并不是很牢固,很多知识点也忘了,这也是一个查漏补缺的机会