日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

小说阅读器

發布時間:2023/12/10 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小说阅读器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

小說閱讀器

1.需求分析

  • 注冊
  • 登陸
  • 查看小說分類:言情、懸疑、仙俠、科幻、玄幻……
  • 根據小說分類查看小說列表
  • 閱讀小說:簡單模式 只查看某個小說的前100字左右內容
  • 下載閱讀:
  • 上傳小說
  • 退出
  • 2.架構設計

    C(Client客戶端)/S(Server服務端)架構

    客戶端:Socket相關API

    服務端:ServerSocket Thread

    數據庫:XML DOM4J

    3.難點分析

    如何讓服務端區分不同的請求

    Data Transfer Object 它一般用于后端->前端的交互使用

    VO -> View Object 它一般用于前端視圖層->后端的交互使用

    POJO -> Plain Old Java Object 主要用于后期ORM框架映射使用

    創建DTO作為數據交換對象

    上傳需要客戶端再開啟線程

    下載需要服務器在開啟線程

    這兩者socket、輸入輸出不能太早關閉

    上傳的文件要添加到對應小說分類和小說XML中,并更新MAP集合

    如何講服務處理進行拆分

    我們定義了一系列的服務類,不同的服務類專門用于處理不同的請求。

    LoginService

    RegisterService

    GetNovelClassesService

    GetNovelsService

    DownloadService

    UploadService

    在抽取一個接口Service

    讓服務繼承

    簡單工廠模式

    場景:根據客戶的描述 產生符合要求的實例。
    1.產品規范 接口

    Service

    2.符合規范的產品 接口的實現類

    LoginService

    RegisterService

    GetNovelClassesService

    GetNovelsService

    DownloadService

    UploadService

    3.生產產品的工廠

    ServiceFactory
    4.客戶

    main

    反射

    字節碼類型 Class
    3種獲取方法
    1.類名.class
    2.對象名.getClass()
    3.Class.forName(全類名)

    可以獲取一個類的所有構造、方法、屬性、注解…
    也可以對這些構造…進行使用

    /*** 服務端工廠* 簡單工廠模式:3.生產產品的工廠類* @author 周太陽* 2019年5月13日*/ public class ServiceFactory {/**存儲產品的列表*/private static HashMap<String,String> map = new HashMap<String,String>();/*** 初始化工廠*/static {// 創建SAXReader讀取XML中的DOM樹SAXReader reader = new SAXReader();try {Document document = reader.read(InitProperties.getPropertyValue("sunshine.server.config.service"));// 獲得根元素并遍歷元素Element rootElement = document.getRootElement();List<Element> elements = rootElement.elements();for (Element element : elements) {// 將對應的元素的屬性放入map集合中map.put(element.attributeValue("id"), element.attributeValue("class"));}} catch (DocumentException e) {e.printStackTrace();}}/*** @return 用反射返回對應的服務的對象* @throws Exception */public static Service getService(String service) throws Exception {try {// 得到需要服務的Class地址String className = map.get(service);// 判斷Class地址是否為空if (className == null) {// 自定義拋出throw new ClassNotFoundException();}else {// 利用反射得到對應的對象Class<?> clazz = Class.forName(className);// 返回對象return (Service)clazz.newInstance();}} catch (ClassNotFoundException e) {throw new NoSuchServiceException("該功能尚未研發成功,敬請期待!");}} }

    利用自定義的XML存儲一些類信息

    借鑒于未來一些框架思想

    如小說分類

    <?xml version="1.0" encoding="UTF-8"?> <!-- 服務器小說分類 --> <novelClasses><novelClass><classname>武俠</classname><catalog>txtcatalog/wuxia/</catalog><config>resource/novel/txt_wuxia.xml</config></novelClass><novelClass><classname>言情</classname><catalog>txtcatalog/yanqing/</catalog><config>resource/novel/txt_yanqing.xml</config></novelClass> </novelClasses>

    小說

    <?xml version="1.0" encoding="UTF-8"?> <!-- 武俠小說 --> <novellist> <novel> <name>古俠今遇</name> <author>醉人歲月</author> <description>與世隔絕三百多年的“碧湖山莊”四少俠出現在大都市中,既有古人的風采,又有現代人的韻味!</description> <filename>古俠今遇.txt</filename> </novel> <novel> <name>寒劍孤燈</name> <author>憂郁丁香</author> <description>寒劍孤燈,傳奇故事</description> <filename>寒劍孤燈.txt</filename> </novel> </novellist>

    5.使用BasiceService去實現了接口中的方法

    接口實現類都需要重復實現某些方法。

    繼承:減少重復代碼 ,提升代碼復用性。

    package org.sunshine.server.service;import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket;import org.sunshine.server.utility.DTO;/*** 服務器基本方法* 實現Service接口* 提取輸入輸出流的開啟與關閉* 和繼承service方法* @author 周太陽* 2019年5月15日*/ public abstract class BasicService implements Service{/**創建接收套接字的屬性*/private Socket socket;private ObjectInputStream ois;private ObjectOutputStream oos;/**創建保存傳輸的data對象*/private Object data;private int receive;/*** 初始化輸入輸出* @param socket */public void init(Socket socket, ObjectInputStream ois, ObjectOutputStream oos, Object data) throws Exception {// 得到當前對象的socketthis.socket = socket;this.ois = ois;this.oos = oos;// 返回數據傳輸對象DTOthis.data = data;this.receive = receive;}/*** Service方法* @throws Exception */@Overridepublic abstract void service() throws Exception;/*** 釋放資源*/@Overridepublic void destroy() throws Exception {ois.close();oos.close();socket.close();}public Socket getSocket() {return socket;}public void setSocket(Socket socket) {this.socket = socket;}public ObjectInputStream getOis() {return ois;}public void setOis(ObjectInputStream ois) {this.ois = ois;}public ObjectOutputStream getOos() {return oos;}public void setOos(ObjectOutputStream oos) {this.oos = oos;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public int getReceive() {return receive;}public void setReceive(int receive) {this.receive = receive;}}

    DAO專門用于存放數據操作代碼

    JAVA三層架構:表現層 業務邏輯層 數據訪問層

    Data Access Object 數據存取對象

    常用基本取名代碼:
    舉例:對用戶的操作
    User getUserById(Long id);
    User getUserByUserName(String name);
    List getUserListByConditions(Map<String,Object> conditions);
    void addUser(User user);
    void deleteUser(User user);
    void updateUser(User user);

    /*** 通信工具類* @author 周太陽* 2019年5月16日*/ public class Client2Service {private ObjectInputStream ois;private ObjectOutputStream oos;private Socket socket;public Client2Service(String host, int port) {super();try {socket = new Socket(host, port);oos = new ObjectOutputStream(socket.getOutputStream());ois = new ObjectInputStream(socket.getInputStream());} catch (IOException e) {e.printStackTrace();}}/*** 釋放資源* @throws IOException */public void destroy() throws IOException {oos.close();ois.close();socket.close();}/*** 發送請求* @throws IOException */public DTO requestService(DTO dto) throws Exception {oos.writeObject(dto);DTO response = (DTO)ois.readObject();// 后期操作關流可以不寫在這里destroy();return response;} }

    客戶端的"永動機"

    執行某個服務的方法的時候,這個服務的返回值是一個服務,然后通過循環繼續執行。

    public class ClientMain {private static Service service = ServiceFactory.getService(ServiceConstants.START_SERVICE);public static void main(String[] args) {while(true) {if (service == null) {System.out.println("程序結束!");break;}try {service = service.service();} catch (Exception e) {e.printStackTrace();}}}}

    服務端和客戶端公用一些代碼 common 開發階段采用工程型依賴

    如user,constructs

    /*** 用戶類常量* @author 周太陽* 2019年5月19日*/ public class UserConstants {/**用戶登錄成功*/public static final int USER_LOGIN_SUCCESS = 1;/**登錄失敗*/public static final int USER_LOGIN_FAILED = 2;/**登錄發生錯誤*/public static final int USER_LOGIN_ERROR = 3;/**用戶注冊名存在*/public static final int USER_REGISTER_ALREADY_EXISTS = 4;/**用戶注冊發生錯誤*/public static final int USER_REGISTER_ERROR = 5;/**用戶注冊成功*/public static final int USER_REGISTER_SUCCES = 6;}

    常量解決"魔法值"

    提升系統中的代碼閱讀性和維護性。
    發現有很多值使用比較頻繁,又不好記,可能后期要修改可以定義為常量

    服務常量

    反射類的服務常量

    字符串常量等……

    /*** 反射類的服務常量* @author 周太陽* 2019年5月19日*/ public class ServiceConstants {/**開始*/public static final String START_SERVICE = "start";/**登錄*/public static final String LOGIN_SERVICE = "login";/**注冊*/public static final String REGISTER_SERVICE = "register";/**獲得小說分類*/public static final String GET_NOVEL_CLASS_SERVICE = "getNovelClasses";/**獲得小說*/public static final String GET_NOVEL_SERVICE = "getNovels";/**獲得小說預覽*/public static final String GET_NOVEL_PREVIEW_SERVICE = "getPreview";/**下載*/public static final String DOWNLOAD_SERVICE = "downLoad";/**上傳*/public static final String UPLOAD_SERVICE = "upLoad"; }

    properties配置文件和Properties類

    Properties是繼承HashTable的,里面內容=左邊是鍵,=右邊是值

    可以將其用到反射上,配合永動機更方便。

    #服務器配置 #服務器端口號 sunshine.socket.server.port=8080 #獲取服務器配置文件 sunshine.server.config.service=resource/Service.xml #用戶配置文件地址 sunshine.server.config.user=resource/user/UserInfo.xml #小說分類配置文件地址 sunshine.server.config.novel.class=resource/novel/NovelClass.xml

    將配置信息存放在配置文件中(XML不推薦,因為XML需要DOM解析,使用比較復雜)

    總結

    以上是生活随笔為你收集整理的小说阅读器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。