仿9GAG制作过程(三)
有话要说:
这次准备讲述后台服务器的搭建以及前台访问到数据的过程。
成果:
准备:
- 安装了eclipse
- 安装了Tomcat7
- 安装了数据库管理工具: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制作过程(三)的更多相关文章
- 仿9GAG制作过程(一)
有话要说: 准备开始学习Android应用程序的一个完整的设计过程.准备做一个仿9GAG的APP,前端界面设计+后台数据爬虫+后台接口设计,整个流程体验一遍.今天准备先把前端界面的框架给完成了. 成果 ...
- 仿9GAG制作过程(五)
有话要说: 在做完了数据展示功能之后,就想着完善整个APP.发现现在后台非常的混乱,有好多点都不具备,比方说:图片应该有略缩图和原图,段子.评论.点赞应该联动起来,段子应该有创建时间等. 于是就重新设 ...
- 仿9GAG制作过程(四)
有话要说: 这次主要讲述主页面下拉刷新和上拉加载功能的实现. 主要是使用了SwipeRefreshLayout的布局方式,并在此基础上通过RecyclerView的特性增加了上拉加载的功能. 成果: ...
- 仿9GAG制作过程(二)
有话要说: 这次准备讲述用python爬虫以及将爬来的数据存到MySQL数据库的过程,爬的是煎蛋网的无聊图. 成果: 准备: 下载了python3.7并配置好了环境变量 下载了PyCharm作为开发p ...
- Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程
Android实训案例(九)--答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程 项目也是偷师的,决心研究一下数据库.所以写的还是很详细的,各位看官,耐着性子看完,实现结果不重要 ...
- BabyLinux制作过程详解
转:http://www.360doc.com/content/05/0915/14/1429_12641.shtml BabyLinux制作过程详解 作者:GuCuiwen email:win2li ...
- [PCB制作] 1、记录一个简单的电路板的制作过程——四线二项步进电机驱动模块(L6219)
前言 现在,很多人手上都有一两个电子设备,但是却很少有人清楚其中比较关键的部分(PCB电路板)是如何制作出来的.我虽然懂点硬件,但是之前设计的简单系统都是自己在万能板上用导线自己焊接的(如下图左),复 ...
- 用AE如何制作如下三个loading动效,
在本期象牙绘UED团队分享当中,我们将详细演示用AE如何制作如下三个loading动效, 其中涉及到AE表达式的应用.值曲线调整.速度曲线编辑等知识. 对于初学者来说可能信息量略大,希望通过是视频教程 ...
- Android 仿PhotoShop调色板应用(三) 主体界面绘制
版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(三) 主体界面绘制 关于PhotoShop调色板应用的实现我总结了两个最核心的部分: 1 ...
随机推荐
- Android OpenSL ES 开发:Android OpenSL 介绍和开发流程说明
一.Android OpenSL ES 介绍 OpenSL ES (Open Sound Library for Embedded Systems)是无授权费.跨平台.针对嵌入式系统精心优化的硬件音频 ...
- [Swift]LeetCode189. 旋转数组 | Rotate Array
Given an array, rotate the array to the right by k steps, where k is non-negative. Example 1: Input: ...
- [Swift]LeetCode218. 天际线问题 | The Skyline Problem
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- [Swift]LeetCode891. 子序列宽度之和 | Sum of Subsequence Widths
Given an array of integers A, consider all non-empty subsequences of A. For any sequence S, let the ...
- 解决SpringMVC中文乱码问题 -----这是服务器返回参数到前端中文乱码
方法一,使用(produces = "application/json; charset=utf-8"): @RequestMapping(value="/getUser ...
- 基于ipv6的数据抓包
一.实验拓扑 二.配置过程 以r1为例 R1: R1(config)#int f0/0 R1(config-if)#ipv6 enable R1(config-if)#ipv6 address 200 ...
- Linux查找文件内容
从当前目录递归查找文件名为 .py 中包含 conf 的文件名: find -name "*.py" | xargs grep "conf"
- BBS论坛(三十)
30.显示评论和添加评论功能完成 (1)apps/models.py class CommentModel(db.Model): __tablename__='comment' id=db.Colum ...
- Pytorch入门实例:mnist分类训练
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'denny' __time__ = '2017-9-9 9:03' import ...
- Guava 源码分析(Cache 原理)
前言 Google 出的 Guava 是 Java 核心增强的库,应用非常广泛. 我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Google 大牛们是如何设计的. 缓存 本次主要讨 ...