zoukankan      html  css  js  c++  java
  • 仿9GAG制作过程(三)

    有话要说:

    这次准备讲述后台服务器的搭建以及前台访问到数据的过程。

    成果:

     准备:

    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中实现了上拉加载功能。

    大家如果有什么疑问或者建议可以通过评论或者邮件的方式联系我,欢迎大家的评论~

  • 相关阅读:
    比服务器的问题
    android studio adb.exe已停止工作(全面成功版 进程的查询和开启)
    安卓学习123
    java eclipse 安卓环境配置
    host访问goole
    Android studio自带的sample例子
    马士兵2string buffuer
    tomcat内存溢出,设置
    spring mvc 学习笔记【1】---前言
    dbutils报错:com.microsoft.sqlserver.jdbc.SQLServerException: 无法识别元数据的表
  • 原文地址:https://www.cnblogs.com/lanxingren/p/9157242.html
Copyright © 2011-2022 走看看