仿9GAG製作過程(三)

来源:https://www.cnblogs.com/lanxingren/archive/2018/06/08/9157242.html
-Advertisement-
Play Games

有話要說: 這次準備講述後臺伺服器的搭建以及前臺訪問到數據的過程。 成果: 準備: 搭建伺服器: 用eclipse直接創建一個web工程,並將運行環境設置為Tomcat7 接著定義了四個類來實現了一個簡單的介面(通過servlet的方式),下麵來看看這四個類 NewsBean.java 該類是段子類 ...


有話要說:

這次準備講述後臺伺服器的搭建以及前臺訪問到數據的過程。

成果:

 準備:

  1. 安裝了eclipse
  2. 安裝了Tomcat7
  3. 安裝了資料庫管理工具:Navicat

搭建伺服器:

用eclipse直接創建一個web工程,並將運行環境設置為Tomcat7

接著定義了四個類來實現了一個簡單的介面(通過servlet的方式),下麵來看看這四個類

NewsBean.java

 1 package com.lanxingren.bean;
 2 
 3 import java.util.List;
 4 
 5 public class NewsBean {
 6     
 7     //段子標識
 8     private int id;
 9     
10     //段子文本
11     private String title;
12     
13     //段子包含的圖片鏈接
14     private List<String> urls;
15     
16     //段子點贊數
17     private int like;
18     
19     //段子點踩數
20     private int unlike;
21 
22     public int getId() {
23         return id;
24     }
25 
26     public void setId(int id) {
27         this.id = id;
28     }
29 
30     public String getTitle() {
31         return title;
32     }
33 
34     public void setTitle(String title) {
35         this.title = title;
36     }
37 
38     public List<String> getUrls() {
39         return urls;
40     }
41 
42     public void setUrls(List<String> urls) {
43         this.urls = urls;
44     }
45 
46     public int getLike() {
47         return like;
48     }
49 
50     public void setLike(int like) {
51         this.like = like;
52     }
53 
54     public int getUnlike() {
55         return unlike;
56     }
57 
58     public void setUnlike(int unlike) {
59         this.unlike = unlike;
60     }
61 
62     @Override
63     public String toString() {
64         return "NewsBean [id=" + id + ", title=" + title + ", urls=" + urls + ", like=" + like + ", unlike=" + unlike
65                 + "]";
66     }
67     
68 }

該類是段子類的一個bean類,各個屬性代表的意思在代碼里已經說清楚了。

DatabaseUtil.java

 1 package com.lanxingren.util;
 2 
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.PreparedStatement;
 6 import java.sql.ResultSet;
 7 
 8 public class DatabaseUtil {
 9     
10     private static String url = "jdbc:mysql://localhost:3306/imitating9gag?serverTimezone=GMT%2B8&useSSL=false";
11     private static String user = "root";
12     private static String password = "root";
13     
14     private static Connection conn;
15     
16     //獲取資料庫連接
17     public static Connection getConnection() {
18         
19         try {
20             Class.forName("com.mysql.cj.jdbc.Driver");
21             conn = DriverManager.getConnection(url, user, password);
22         } catch (Exception e) {
23             e.printStackTrace();
24         }
25         
26         return conn;
27     }
28     
29     //關閉資料庫連接
30     public static void close (Connection conn, PreparedStatement ps) {
31         try {
32             if (ps != null) {
33                 ps.close();
34             }
35             if (conn != null) {
36                 conn.close();
37             }
38         } catch (Exception e) {
39             e.printStackTrace();
40         }
41     }
42     
43     //關閉資料庫連接
44     public static void close (Connection conn, PreparedStatement ps, ResultSet rs) {
45         try {
46             if (rs != null) {
47                 rs.close();
48             }
49             if (ps != null) {
50                 ps.close();
51             }
52             if (conn != null) {
53                 conn.close();
54             }
55         } catch (Exception e) {
56             e.printStackTrace();
57         }
58     }
59 
60 }

該類是一個工具類,主要用來創建資料庫連接以及關閉資料庫連接。

其中,由於MySQL更新到了最新的版本,所以設置了useSSL為false,否則連接會出問題。

而且,最新的MySQL其實並不需要通過Class.forName來載入驅動了。

NewsDAO.java

 1 package com.lanxingren.dao;
 2 
 3 import java.sql.Connection;
 4 import java.sql.PreparedStatement;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 import java.util.ArrayList;
 8 import java.util.List;
 9 
10 import com.lanxingren.bean.NewsBean;
11 import com.lanxingren.util.DatabaseUtil;
12 
13 public class NewsDAO {
14     
15     //page是頁數,pageSize是每頁條數
16     public List<NewsBean> queryNewsByPage (int page, int pageSize) {
17         List<NewsBean> newsList = new ArrayList<NewsBean>();
18         
19         Connection conn = DatabaseUtil.getConnection();
20         
21         String sql = "select * from news order by id desc limit " + (page - 1)*pageSize + ", " + pageSize;
22         PreparedStatement pstmt = null;
23         
24         try {
25             pstmt = (PreparedStatement)conn.prepareStatement(sql);
26             ResultSet rs = pstmt.executeQuery();
27             while (rs.next()) {
28                 NewsBean nb = new NewsBean();
29                 nb.setId(rs.getInt("id"));
30                 nb.setTitle(rs.getString("title"));
31                 nb.setLike(rs.getInt("like"));
32                 nb.setUnlike(rs.getInt("unlike"));
33                 newsList.add(nb);
34             }
35         } catch (SQLException e) {
36             e.printStackTrace();
37         }
38         finally {
39             DatabaseUtil.close(conn, pstmt);
40         }
41         
42         return newsList;
43     }
44     
45     // 根據段子id獲取段子所包含的圖片
46     public List<String> queryUrlsByNewsId (int newsId) {
47         List<String> urls = new ArrayList<String>();
48         
49         Connection conn = DatabaseUtil.getConnection();
50         
51         String sql = "select url from news_pics where newsid = " + newsId;
52         PreparedStatement pstmt = null;
53         try {
54             pstmt = conn.prepareStatement(sql);
55             ResultSet rs = pstmt.executeQuery();
56             while (rs.next()) {
57                 urls.add(rs.getString("url"));
58             }
59         } catch (Exception e) {
60             e.printStackTrace();
61         }
62         finally {
63             DatabaseUtil.close(conn, pstmt);
64         }
65         
66         return urls;
67     }
68     
69 }

該類定義了兩個方法,分別為獲取段子信息的方法和獲取圖片的方法。

其中sql用了倒序是為了讓段子按照時間流的順序在前臺展示。

QueryNewsServlet.java

package com.lanxingren.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

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 com.google.gson.Gson;
import com.lanxingren.bean.NewsBean;
import com.lanxingren.dao.NewsDAO;

@WebServlet("/QueryNewsServlet")
public class QueryNewsServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    int pageSize = 5;
       
    public QueryNewsServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/json; charset=utf-8");
        PrintWriter out = response.getWriter();
        
        String page = request.getParameter("page");
        List<NewsBean> newsList = new ArrayList<NewsBean>();
        List<NewsBean> realList = new ArrayList<NewsBean>();
        NewsDAO dao = new NewsDAO();
        
        String news = "";
        
        if (page != null) {
            newsList = dao.queryNewsByPage(Integer.parseInt(page), pageSize);
        }
        
        if (newsList != null && newsList.size() > 0) {
            for (NewsBean nb : newsList) {
                List<String> urls = dao.queryUrlsByNewsId(nb.getId());
                if (urls != null && urls.size() > 0) {
                    nb.setUrls(urls);
                    realList.add(nb);
                }
            }
        }
        
        Gson gson = new Gson();
        news = gson.toJson(realList);
        
        out.print(news);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    
}

通過註解的方式來設置servlet的地址,並將數據轉化成json輸出。

 

通過以上的方式,就完成了後臺查詢段子介面的開發,並且可通過page參數來獲取第page頁的信息,介面URL為:http://localhost:8080/Imitating9GAG/QueryNewsServlet?page=2

接著,將項目在Tomcat下啟動後臺伺服器就正式搭建完成了,通過該URL獲取的數據見下圖:

前臺獲取數據並展示:

1 public List<NewsBean> newsBeans = new ArrayList<NewsBean>();// 段子集合
2 private String baseUrl = "http://192.168.10.14:8080/Imitating9GAG/QueryNewsServlet?page=";

 

 1 new Thread(new Runnable() {
 2             @Override
 3             public void run() {
 4                 String url = baseUrl + (currentPage);
 5                 OkHttpClient client = new OkHttpClient();
 6                 Request request = new Request.Builder()
 7                         .url(url)
 8                         .build();
 9                 try {
10                     Response response = client.newCall(request).execute();
11                     String json = response.body().string();
12                     if (json != null) {
13                         Gson gson = new Gson();
14                         newsBeans.addAll(0, (List<NewsBean>)gson.fromJson(json, new TypeToken<List<NewsBean>>(){}.getType()));
15                     }
16                     Message message = new Message();
17                     message.what = QUERY_NEWS;
18                     handler.sendMessage(message);
19                 } catch (IOException e) {
20                     e.printStackTrace();
21                 }
22             }
23         }).start();

 

由於請求網路是一個耗時操作,因此放進了子線程中。在子線程中請求網路並將返回的數據放入段子集合中。

Handler如下:

 1  // 請求網路結束後的更新View
 2     private Handler handler = new Handler() {
 3         @Override
 4         public void handleMessage(Message msg) {
 5             switch (msg.what) {
 6                 case QUERY_NEWS:
 7                     recyclerView.getAdapter().notifyDataSetChanged();
 8                     break;
 9                 case UPDATE_NEWS:
10                     recyclerView.getAdapter().notifyDataSetChanged();
11                     swipeRefreshLayout.setRefreshing(false);
12                     break;
13                 case LOAD_MORE:
14                     ((NewsAdapter)recyclerView.getAdapter()).changeStatus(NewsAdapter.UNLOADING);
15                     currentState = NewsAdapter.UNLOADING;
16                     break;
17             }
18         }
19     };

 

結束語:

這樣,獲取數據+後臺伺服器搭建+前臺頁面展示的過程整個就已經完整了。

下一篇準備講述官方自帶的SwipeRefreshLayout刷新控制項。

由於該控制項沒有上拉載入功能,於是就在RecyclerView中實現了上拉載入功能。

 

大家如果有什麼疑問或者建議可以通過評論或者郵件的方式聯繫我,歡迎大家的評論~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當我們瀏覽網頁的時候,經常會看到像下麵這些好看的圖片,你是否想把這些圖片保存下載下來。 我們最常規的做法就是通過滑鼠右鍵,選擇另存為。但有些圖片點擊滑鼠右鍵的時候並沒有另存為選項,或者你可以通過截圖工具截取下來,但這樣就降低圖片的清晰度,並且這樣效率很低。 那腫麽辦呢? 我們可以通過python 來 ...
  • Description 下麵程式的輸出結果是: destructor B destructor A 請完整寫出 class A。 限制條件:不得為 class A 編寫構造函數。 ~~~~ include using namespace std; class A { // Your Code Her ...
  • 一、概念 早期的 Java API 只支持由本地系統套接字型檔提供所謂的阻塞函數來支持網路編程。由於是阻塞 I/O ,要管理多個併發客戶端,需要為每個新的客戶端Socket 創建一個 Thread 。這將導致一系列的問題,第一,在任何時候都可能有大量的線程處於休眠狀態(不可能每時每刻都有對應的併發數) ...
  • 必需學會SpringBoot基礎知識 Takes an opinionated view of building production-ready Spring applications. Spring Boot favors convention over configuration and is ...
  • 本篇教大家如何用Python來實現QQ機器人,如有不足歡迎在評論方指出! 簡單介紹 安裝方法 可在 Python個版本下使用,用 pip 安裝: 使用方法 一、啟動 QQBot 二、操作 QQBot QQBot 啟動後,在另一個控制台視窗使用 qq 命令來操作 QQBot ,目前提供以下命令: li ...
  • 現有要求如下: 通過cmd的方式,求簡單表達式的值。 比如輸入 java Expression 3 + 4 得到的結果為:7 代碼: import java.text.DecimalFormat; public class Expression { public static void main(S ...
  • 本節主要內容:1. 初識⽂件操作2. 只讀(r, rb)3. 只寫(w, wb)4. 追加(a, ab)5. r+讀寫6. w+寫讀7. a+寫讀(追加寫讀)8. 其他操作⽅法9. ⽂件的修改以及另⼀種打開⽂件句柄的⽅式 主要內容:⼀. 初識⽂件操作使⽤python來讀寫⽂件是⾮常簡單的操作. 我們 ...
  • 一、常用字元串操作 upper(x)把字母變成大寫 lower(x)把字母變成小寫 split(str,num) 對字元串進行切割,返回一個列表:str-分隔符,預設為所有的空字元,包括空格,換行(\n),製表符(\t)等;num -- 分割次數 strip(chars ) 移除字元串頭尾指定的字元 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...