基于Java的迷你在线小说阅读系统

基于Java的迷你在线小说在线系统

一、展示效果

在这里插入图片描述

需求分析:

  1. 创建客户端、服务器端,完成简单通信;
  2. 完成登录、注册、退出功能;
  3. 完成小说查询列表的功能
  4. 完成在线阅读小说功能
  5. 完成下载小说功能
  6. 完成上传小说功能

二、整体架构

客户端:
在这里插入图片描述
服务器:
在这里插入图片描述

三、实现步骤

1、创建客户端、服务器端,完成简单通信:创建服务器端线程类,并循环监听状态,创建客户端,请求服务器并发送消息,服务器端响应客户端。
客户端:

public void clientInit() throws IOException {
        //初始化第一步先连接服务器
        socket = new Socket();
        socket.connect(new InetSocketAddress(7171));
    }

服务器:

public void init() throws IOException, ClassNotFoundException, DocumentException {
        ServerSocket serverSocket = new ServerSocket();
        serverSocket.bind(new InetSocketAddress(7171));
        System.out.println("启动服务器,等待连接...");
        //监听
        socket = serverSocket.accept();
        System.out.println("已成功连接服务器!!!");
        postClientMessage();
    }

2、完成登录、注册、退出功能:创建用于保存登录信息的文件,接收用户登录信息并查找登录信息文件,判断是否登录成功,接收用户注册信息并保存至登录信息文件。
客户端:

//用户登录
    public void login() throws IOException, InterruptedException {
        System.out.print("请输入登录用户名:");
        String usename = input.nextLine();
        System.out.print("请输入登录密码:");
        String password = input.nextLine();
        UserEntity userEntity = new UserEntity();
        userEntity.setUsername(usename);
        userEntity.setPwd(password);
        MessageEntity messageEntity = new MessageEntity();
        //传给服务器
        messageEntity.setOprator(1);
        messageEntity.setUserEntity(userEntity);
        //发送数据给服务器
        dataUtil.sendData(messageEntity);
        //接收数据
        String s = dataUtil.receiveDate();
        //根据服务器的返回结果给出相应的处理
        resultUtil.postUserResult(s);
    }

	//用户注册
    public void register() throws IOException, InterruptedException {
        System.out.println("请输入需要注册的用户ID:");
        String userId = input.nextLine();
        System.out.print("请输入注册用户名:");
        String usename = input.nextLine();
        System.out.print("请输入注册密码:");
        String pwd = input.nextLine();

        UserEntity userEntity = new UserEntity();
        userEntity.setId(Integer.parseInt(userId));
        userEntity.setUsername(usename);
        userEntity.setPwd(pwd);

        MessageEntity messageEntity = new MessageEntity();
        //传给服务器
        messageEntity.setOprator(2);
        messageEntity.setUserEntity(userEntity);
        //发送数据给服务器
        dataUtil.sendData(messageEntity);
        //接收数据
        String s = dataUtil.receiveDate();
        //根据服务器的返回结果给出相应的处理
        resultUtil.postUserResult(s);
    }

	//用户退出
    public void quit(){
        System.out.println("正在退出系统...");
        System.out.println("-----退出系统成功-----");
        System.exit(0);
    }

服务器:

MessageEntity m = (MessageEntity) ois.readObject();
if (m.getOprator() == 1) {//登录
	//传入客户端输入的用户名和密码
	String result = userService.login(m.getUserEntity());
    //把登录结果返回给客户端
    os.write(result.getBytes());
    /*//让服务器不停地读取客户端消息
    postClientMessage();*/
} else if (m.getOprator() == 2) {//注册
	String register = userService.register(m.getUserEntity());
    os.write(register.getBytes());
     /*//让服务器不停地读取客户端消息
     postClientMessage();*/
 }

3、实现完成小说查询列表的功能:向服务器发送请求,获取书籍列表,然后返回这个列表。

public class BookClientService {
    //查询服务器上小说列表
    public List<String> queryPrintAllBook(DataUtil dataUtil) throws IOException {
        List<String> list = new ArrayList<>();
        MessageEntity messageEntity =new MessageEntity();
        //只需要带一个操作
        messageEntity.setOprator(5);
        dataUtil.sendData(messageEntity);
        //阻塞
        String s = dataUtil.receiveDate();
        String[] split = s.split("-");
        for (String s1 : split) {
            list.add(s1);
        }
        return list;
    }
}

4、实现完成在线阅读小说功能:发送请求获取所有的书籍列表打印出来。然后,提示用户选择要阅读的书。发送请求以获取书的每一页的内容并打印出来,并提示用户是否要继续阅读下一页、上一页或者退出。如果用户选择上一页,它会检查当前是否在第一页,如果是则不执行任何操作。如果不是,则将页码减一。如果用户选择下一页,则将页码加一。如果用户选择退出,则结束阅读。如果服务器返回的内容是"end",则也结束阅读。
客户端:

if (info.equals("1")) {
	//阅读小说---展示小说目录
	List<String> list = (List<String>) bookClientService.queryPrintAllBook(dataUtil);
	list.stream().forEach(s -> System.out.println(s));
	System.out.print("请选择你要阅读的小说:");
	//输入小说名
	String bookName = input.nextLine();
	//用来记录有页数
	int page = 1;
	while (true) {
	    //每一次都向服务器发送要执行的操作和书的页码,让服务器根据页码来读取相应的内容
	    MessageEntity m = new MessageEntity();
	    m.setBookName(bookName);
	    m.setOprator(6);
	    m.setPage(page);
	    //向服务器发送书名,和阅读小说的操作
	    dataUtil.sendData(m);
	    //接受读取到的内容
	    String contain = dataUtil.receiveDate();
	    //打印到控制台
	    System.out.println(contain);
	    System.out.println("当前为第"+page+"页");
	    System.out.println("上一页(1)\t下一页(2)\t退出(0)");
	    System.out.println("请输入数字执行相关操作...");
	    String choose = input.nextLine();
	    if (choose.equals("1")){
	        //如果客户端要阅读上一页,就把页码数减一
	        //先要判断当前页数是不是第一页
	        if(page == 1){
	            System.out.println("----- 当前已经为第一页! -----");
	        }else {
	            page--;
	        }
	    }else if(choose.equals("2")){
	        //如果客户端选择下一页,就把页码数加一
	        page++;
	    }else if(choose.equals("0")){
	        break;
	    }
	    if(contain.equals("end")){
	        break;
	    }
	}
	System.out.println("----- 阅读完成!!! -----");
	String s = client.showMenu();
	postBookResult(s);
}

服务器:

else if(m.getOprator() == 6){//阅读小说
	//得到用户需要阅读的小说书名
	String bookName = m.getBookName();
	//去服务器的指定路径找到这本小说的路径
	File bookFile = new File(Contain.bookPath+"\\\\"+bookName+".txt");
	//先读取到程序
	FileReader fr = new FileReader(bookFile);
	//跳过字符,根据客户端的页面来定要读取的内容,用户如果要读取第2页的内容,就是跳过前面1000个字符
	fr.skip((m.getPage() - 1) * 1000);
	//一次读一千个字符
	char[] chars = new char[1000];
	int total = fr.read(chars);
	if (total != -1) {
	String contain = new String(chars, 0, total);
	//将读取的内容写到网络中
	os.write(contain.getBytes());
	}
}

5、实现完成下载小说功能:如果info等于"3",则开始下载小说的过程。首先,会查询服务器上所有的书籍列表,并打印出来。然后提示用户输入需要下载的小说名。如果用户输入的小说名在列表中不存在,它会提示用户输入正确的名称。只有输入正确的小说名时,才会发送下载请求到服务器。服务器会开始发送下载内容,这个内容是一个流。在接收服务器发送的下载内容时,如果内容以"end"结束,那么就打印"下载完成",并将剩余的内容写入到文件中。如果内容没有以"end"结束,那么就直接将内容写入到文件中。下载完成后,调用方法来处理下载结果。
客户端:

else if (info.equals("3")) {
   //下载之前先要做查询
   List<String> list = bookClientService.queryPrintAllBook(dataUtil);
   System.out.println("请输入需要下载的小说名进行下载:");
   list.stream().forEach(s -> System.out.println(s));
   String bookName="";
   while (true){
       bookName = input.nextLine();
       String finalBookName = bookName;
       long count = list.stream().filter(s -> s.equals(finalBookName)).count();
       if(count==0){//输入的小说名字不存在
           System.out.print("请输入正确的的小说名:");
       }else {
           break;
       }
   }
   //收集到用户输入的小说名字
   MessageEntity messageEntity = new MessageEntity();
   messageEntity.setOprator(4);
   messageEntity.setBookName(bookName);
   dataUtil.sendData(messageEntity);
   
   File file = new File(Contain.downloadPath + "\\" + bookName);
   if (!file.exists()) {
       file.createNewFile();
   }else {
       file.delete();
       file.createNewFile();
   }
   while (true) {
       String downLoadContent = dataUtil.receiveDate();
       if (downLoadContent.endsWith("end")) {
           System.out.println("----- 下载完成!!! -----");
           FileOutputStream fos = new FileOutputStream(file, true);
           fos.write(downLoadContent.replaceAll("end","").getBytes());
           break;
       }
       FileOutputStream fos = new FileOutputStream(file, true);
       fos.write(downLoadContent.getBytes());
   }
   String s = client.showMenu();
   postBookResult(s);
}

服务器:

else if(m.getOprator()==4){//下载
    //获取现需要下载的小说的名字
    String bookName = m.getBookName();
    String downLoadPath = Contain.bookPath+"\\"+ bookName;
    File downLoadFile  = new File(downLoadPath);
    long length = downLoadFile.length();
    FileInputStream fis = new FileInputStream(downLoadFile);
    DecimalFormat df = new DecimalFormat("#.0");
    int total =0;
    double percent=0.0;
    while ((total = fis.read(bs))!=-1){
        String message  = new String(bs,0,total);
        os.write(message.getBytes());
    }
    //读完了
    os.write("end".getBytes());
}

6、实现完成上传小说功能:如果info等于"2",则开始上传小说。首先,会提示用户输入需要上传的小说路径,获取该文件的大小,并打印出来。然后读取文件内容,并通过网络发送到服务器。在读取和发送过程中,会计算并显示上传的进度。当文件读取完毕后,会发送一个"end"信号给服务器,表示上传完成。最后服务器返回一个菜单信息,然后调用方法来处理上传结果。
客户端:

else if (info.equals("2")) {
    System.out.print("请输入小说路径:"); 
    String bookPathName = input.nextLine();
    //为了获取文件的大小 ---百分比
    File file = new File(bookPathName);
    //整个文件的字节数
    long length = file.length();
    System.out.println("文件长度=" + length + "个字节");
    //上传----先读到内容---写出去网络
    FileInputStream fis = new FileInputStream(file);
    //服务器那边不知道你的文件名 ---告诉服务器文件名
    String bookName = bookPathName.substring(bookPathName.lastIndexOf("\\\\"));
    int total = 0;//每次读取的字节数---读到文件末尾-1
    double temp = 0.0;//累计读了多少
    boolean flag = true;
    while ((total=fis.read(bs))!=-1) {
        temp += total;
        MessageEntity messageEntity = new MessageEntity();
        messageEntity.setOprator(3);
        if (flag) {
            messageEntity.setBookName(bookName);
            flag = false;
        }
        messageEntity.setContent(new String(bs, 0, total));
        dataUtil.sendData(messageEntity);
        //如果接受成功 这一次读取的内容上传成功
        String s = dataUtil.receiveDate();
        System.out.print("已经完成:" + String.format("%.1f", (temp / length) * 100) + "%\r");
    }
    System.out.println("----- 上传进度 = 100% -----");
    System.out.println("----- 上传完成!!! -----");
    MessageEntity messageEntity = new MessageEntity();
    messageEntity.setOprator(3);
    messageEntity.setContent("end");
    dataUtil.sendData(messageEntity);
    String r = client.showMenu();
    postBookResult(r);
}

服务器:

else if (m.getOprator() == 3) {//上传小说
    //当次上传小说的内容
    String content = m.getContent();
    if(content.equals("end")){
        //一部小说已经传完
        uploadFile=null;
        continue;
    }
    //这部分内容写到--对应的文件夹当中去---
    //1、文件文件
    if(uploadFile==null){
        uploadFile = new File(Contain.bookPath + "\\" + m.getBookName());
    }
    if (!uploadFile.exists()) {//如果文件不存在则创建
        uploadFile.createNewFile();
    }else {
        if (!XMLUtil.isEmpty(m.getBookName())) {//服务器已经存在小说 重写上传
            uploadFile.delete();//先删除
            uploadFile.createNewFile();//重写创建
        }
    }
    FileWriter fileWriter = new FileWriter(uploadFile,true);
    fileWriter.write(content);
    //这一次成功
    os.write("success".getBytes());
    fileWriter.close();
}

四、总结

1、序列化与反序列化的路径需要保持一致,即报包名要相同,否则会出现异常;
在这里插入图片描述
在这里插入图片描述
2、在Java中,"/“是转义符,”\"才表示路径
在这里插入图片描述
在这里插入图片描述
3、使用DOM4J解析XML文件,首先需要将XML文件加载到内存中。DOM4J提供了一个名为SAXReader的类,可以方便地读取XML文件并将其转换为DOM树。

  • 创建SAX解析器SAXReader对象,用于读取xml文件

    SAXReader saxReader = new SAXReader();
    
  • 读取xml文件,得到Document对象

    Document document = saxReader.read(xmlFile);
    
  • 通过Document对象获取根元素

    Element element = document.getRootElement();
    
  • 通过父元素获取子元素

    1、获取迭代器:elementIterator(),迭代获取。
    2、指定元素名:element(元素名) 获取指定元素名的第一个子元素
    3、获取指定元素: elements(元素名) List 指定元素名的所有的子元素

  • 通过元素获取属性

    1、获取迭代器:attributeIterator(),迭代获取。
    2、指定索引(0开始)或名字:attribute(索引)、attribute(属性名)

4、极致的封装,把抽象的数据(变量)和实现的方法(函数)封装在一起,形成一个对象。这样做的目的是隔离出影响范围,让代码更容易理解和维护。体现了六大设计原则中的单一原则(即:一个类、接口、方法只负责一项职责),也是“高内聚,低耦合”的体现。
例如:
在这里插入图片描述

五、完整代码

链接:https://pan.baidu.com/s/1L3BusUK5eb6FNvX5D_03RA
提取码:zngj

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是Java迷你青春购物系统的简介: 该系统包含客户信息管理、商品信息管理、购物信息管理和退出系统功能。用户可以通过菜单选择所需的功能,然后进行相应的操作。具体功能如下: 1.客户信息管理:用户可以添加、删除、修改和查询客户信息。客户信息包括客户编号、姓名、性别、年龄和电话号码。 2.商品信息管理:用户可以添加、删除、修改和查询商品信息。商品信息包括商品编号、名称、单价和库存数量。 3.购物信息管理:用户可以添加、删除和查询购物信息。购物信息包括购物编号、客户编号、商品编号、购买数量和购买日期。 4.退出系统:用户可以退出系统。 以下是Java迷你青春购物系统的代码示例: ```java import java.util.Scanner; public class ShoppingSystem { public static void main(String[] args) { Scanner input = new Scanner(System.in); int choice = 0; while (choice != 4) { System.out.println("请选择功能:"); System.out.println("1.客户信息管理"); System.out.println("2.商品信息管理"); System.out.println("3.购物信息管理"); System.out.println("4.退出系统"); choice = input.nextInt(); switch (choice) { case 1: System.out.println("客户信息管理"); // TODO: 添加、删除、修改和查询客户信息 break; case 2: System.out.println("商品信息管理"); // TODO: 添加、删除、修改和查询商品信息 break; case 3: System.out.println("购物信息管理"); // TODO: 添加、删除和查询购物信息 break; case 4: System.out.println("退出系统"); break; default: System.out.println("输入错误,请重新输入!"); break; } } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值