有话要说:

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

成果:

准备:

  1. 安装了eclipse
  2. 安装了Tomcat7
  3. 安装了数据库管理工具:Navicat

搭建服务器:

用eclipse直接创建一个web工程,并将运行环境设置为Tomcat7

接着定义了四个类来实现了一个简单的接口(通过servlet的方式),下面来看看这四个类

NewsBean.java

 package com.lanxingren.bean;

 import java.util.List;

 public class NewsBean {

     //段子标识
private int id; //段子文本
private String title; //段子包含的图片链接
private List<String> urls; //段子点赞数
private int like; //段子点踩数
private int unlike; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public List<String> getUrls() {
return urls;
} public void setUrls(List<String> urls) {
this.urls = urls;
} public int getLike() {
return like;
} public void setLike(int like) {
this.like = like;
} public int getUnlike() {
return unlike;
} public void setUnlike(int unlike) {
this.unlike = unlike;
} @Override
public String toString() {
return "NewsBean [id=" + id + ", title=" + title + ", urls=" + urls + ", like=" + like + ", unlike=" + unlike
+ "]";
} }

该类是段子类的一个bean类,各个属性代表的意思在代码里已经说清楚了。

DatabaseUtil.java

 package com.lanxingren.util;

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet; public class DatabaseUtil { private static String url = "jdbc:mysql://localhost:3306/imitating9gag?serverTimezone=GMT%2B8&useSSL=false";
private static String user = "root";
private static String password = "root"; private static Connection conn; //获取数据库连接
public static Connection getConnection() { try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
} return conn;
} //关闭数据库连接
public static void close (Connection conn, PreparedStatement ps) {
try {
if (ps != null) {
ps.close();
}
if (conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} //关闭数据库连接
public static void close (Connection conn, PreparedStatement ps, ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
if (ps != null) {
ps.close();
}
if (conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} }

该类是一个工具类,主要用来创建数据库连接以及关闭数据库连接。

其中,由于MySQL更新到了最新的版本,所以设置了useSSL为false,否则连接会出问题。

而且,最新的MySQL其实并不需要通过Class.forName来加载驱动了。

NewsDAO.java

 package com.lanxingren.dao;

 import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import com.lanxingren.bean.NewsBean;
import com.lanxingren.util.DatabaseUtil; public class NewsDAO { //page是页数,pageSize是每页条数
public List<NewsBean> queryNewsByPage (int page, int pageSize) {
List<NewsBean> newsList = new ArrayList<NewsBean>(); Connection conn = DatabaseUtil.getConnection(); String sql = "select * from news order by id desc limit " + (page - 1)*pageSize + ", " + pageSize;
PreparedStatement pstmt = null; try {
pstmt = (PreparedStatement)conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
NewsBean nb = new NewsBean();
nb.setId(rs.getInt("id"));
nb.setTitle(rs.getString("title"));
nb.setLike(rs.getInt("like"));
nb.setUnlike(rs.getInt("unlike"));
newsList.add(nb);
}
} catch (SQLException e) {
e.printStackTrace();
}
finally {
DatabaseUtil.close(conn, pstmt);
} return newsList;
} // 根据段子id获取段子所包含的图片
public List<String> queryUrlsByNewsId (int newsId) {
List<String> urls = new ArrayList<String>(); Connection conn = DatabaseUtil.getConnection(); String sql = "select url from news_pics where newsid = " + newsId;
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
urls.add(rs.getString("url"));
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
DatabaseUtil.close(conn, pstmt);
} return urls;
} }

该类定义了两个方法,分别为获取段子信息的方法和获取图片的方法。

其中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获取的数据见下图:

前台获取数据并展示:

 public List<NewsBean> newsBeans = new ArrayList<NewsBean>();// 段子集合
private String baseUrl = "http://192.168.10.14:8080/Imitating9GAG/QueryNewsServlet?page=";
 new Thread(new Runnable() {
@Override
public void run() {
String url = baseUrl + (currentPage);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
try {
Response response = client.newCall(request).execute();
String json = response.body().string();
if (json != null) {
Gson gson = new Gson();
newsBeans.addAll(0, (List<NewsBean>)gson.fromJson(json, new TypeToken<List<NewsBean>>(){}.getType()));
}
Message message = new Message();
message.what = QUERY_NEWS;
handler.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();

由于请求网络是一个耗时操作,因此放进了子线程中。在子线程中请求网络并将返回的数据放入段子集合中。

Handler如下:

  // 请求网络结束后的更新View
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case QUERY_NEWS:
recyclerView.getAdapter().notifyDataSetChanged();
break;
case UPDATE_NEWS:
recyclerView.getAdapter().notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
break;
case LOAD_MORE:
((NewsAdapter)recyclerView.getAdapter()).changeStatus(NewsAdapter.UNLOADING);
currentState = NewsAdapter.UNLOADING;
break;
}
}
};

结束语:

这样,获取数据+后台服务器搭建+前台页面展示的过程整个就已经完整了。

下一篇准备讲述官方自带的SwipeRefreshLayout刷新控件。

由于该控件没有上拉加载功能,于是就在RecyclerView中实现了上拉加载功能。

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

仿9GAG制作过程(三)的更多相关文章

  1. 仿9GAG制作过程(一)

    有话要说: 准备开始学习Android应用程序的一个完整的设计过程.准备做一个仿9GAG的APP,前端界面设计+后台数据爬虫+后台接口设计,整个流程体验一遍.今天准备先把前端界面的框架给完成了. 成果 ...

  2. 仿9GAG制作过程(五)

    有话要说: 在做完了数据展示功能之后,就想着完善整个APP.发现现在后台非常的混乱,有好多点都不具备,比方说:图片应该有略缩图和原图,段子.评论.点赞应该联动起来,段子应该有创建时间等. 于是就重新设 ...

  3. 仿9GAG制作过程(四)

    有话要说: 这次主要讲述主页面下拉刷新和上拉加载功能的实现. 主要是使用了SwipeRefreshLayout的布局方式,并在此基础上通过RecyclerView的特性增加了上拉加载的功能. 成果: ...

  4. 仿9GAG制作过程(二)

    有话要说: 这次准备讲述用python爬虫以及将爬来的数据存到MySQL数据库的过程,爬的是煎蛋网的无聊图. 成果: 准备: 下载了python3.7并配置好了环境变量 下载了PyCharm作为开发p ...

  5. Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程

    Android实训案例(九)--答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程 项目也是偷师的,决心研究一下数据库.所以写的还是很详细的,各位看官,耐着性子看完,实现结果不重要 ...

  6. BabyLinux制作过程详解

    转:http://www.360doc.com/content/05/0915/14/1429_12641.shtml BabyLinux制作过程详解 作者:GuCuiwen email:win2li ...

  7. [PCB制作] 1、记录一个简单的电路板的制作过程——四线二项步进电机驱动模块(L6219)

    前言 现在,很多人手上都有一两个电子设备,但是却很少有人清楚其中比较关键的部分(PCB电路板)是如何制作出来的.我虽然懂点硬件,但是之前设计的简单系统都是自己在万能板上用导线自己焊接的(如下图左),复 ...

  8. 用AE如何制作如下三个loading动效,

    在本期象牙绘UED团队分享当中,我们将详细演示用AE如何制作如下三个loading动效, 其中涉及到AE表达式的应用.值曲线调整.速度曲线编辑等知识. 对于初学者来说可能信息量略大,希望通过是视频教程 ...

  9. Android 仿PhotoShop调色板应用(三) 主体界面绘制

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(三) 主体界面绘制    关于PhotoShop调色板应用的实现我总结了两个最核心的部分:   1 ...

随机推荐

  1. Python爬取房产数据,在地图上展现!

    小伙伴,我又来了,这次我们写的是用python爬虫爬取乌鲁木齐的房产数据并展示在地图上,地图工具我用的是 BDP个人版-免费在线数据分析软件,数据可视化软件 ,这个可以导入csv或者excel数据. ...

  2. [Swift]LeetCode374. 猜数字大小 | Guess Number Higher or Lower

    We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to gues ...

  3. [Swift]LeetCode525. 连续数组 | Contiguous Array

    Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1. ...

  4. Java面向对象特征之封装

    package practice;/** * @功能 创建动物类,对动物的属性进行封装 * @author square 凉 * */public class Animal { /**  * 动物姓名 ...

  5. redis 系列20 服务器上

    一.客户端与服务端交互 本篇简单介绍下服务器,服务器运行涉及的内部原理知识很多,主要了解Redis服务器内部要做哪些事情,需要开发人员去干预的比较少.Redis服务器负责与多个客户端建立网络连接,处理 ...

  6. Python爬虫入门教程 2-100 妹子图网站爬取

    妹子图网站爬取---前言 从今天开始就要撸起袖子,直接写Python爬虫了,学习语言最好的办法就是有目的的进行,所以,接下来我将用10+篇的博客,写爬图片这一件事情.希望可以做好. 为了写好爬虫,我们 ...

  7. 记录阿里云服务器mysql被黑

    前言 比上次服务器被黑还要恐怖的数据库被黑,再次强调,数据库不备份不做安全,你就可以准备跑路了. 这次记录一下整个被黑的过程,以及整个检查和处理的过程. 发现 上个月某一天,网站出现了无法登录的情况, ...

  8. 阿里云HBase携X-Pack再进化,重新赋能轻量级大数据平台

    一.八年双十一,造就国内最大最专业HBase技术团队 阿里巴巴集团早在2010开始研究并把HBase投入生产环境使用,从最初的淘宝历史交易记录,到蚂蚁安全风控数据存储.持续8年的投入,历经8年双十一锻 ...

  9. 开源 serverless 产品原理剖析 - Kubeless

    背景 Serverless 架构的出现让开发者不用过多地考虑传统的服务器采购.硬件运维.网络拓扑.资源扩容等问题,可以将更多的精力放在业务的拓展和创新上. 随着 serverless 概念的深入人心, ...

  10. Magicodes.NET框架之路——V0.0.0.5 Beta版发布

    最近写代码的时间实在不多,而且今年又打算业余学习下Unity3D以及NodeJs(用于开发游戏后台),因此完善框架的时间更不多了.不过我会一直坚持下去的,同时我也希望有兴趣的同学可以加入Push你的代 ...