第二次结对作业
一、总览和相关链接
这个作业属于哪个课程 | 2020春|W班 |
---|---|
这个作业要求在哪里 | 第二次结对作业要求 |
结对学号 | 221701218、221701220 |
作业正文 | 我的第二次结对作业 |
其他参考文献 | ··· |
其他链接
二、成品展示
服务器部署
基本功能演示:
全国各省份疫情概览,选择日期查看:
具体某个省份的疫情情况,选择日期查看:
拓展功能演示:
三、结对讨论过程
分工:
221701218:html静态页面,echarts渲染
221701220:网页的事件处理、数据库交互
讨论过程:
数据源的获取:
echarts传参过程:
传参实现,用url实现,具体语音讨论:
四、设计实现过程
功能结构图
实现过程
首先是要决定使用的技术,后端决定使用jsp、servlet进行Web事件的处理。前端使用BootStrap Studio进行网页初步设计,随后再具体修改相应css和js实现精确设计。
其次就是要决定数据源,我们都不会爬取数据,因此我们决定使用数据库来作为数据源供地图和图表展示。数据库的数据来自阿里云日志服务。下载日志文件并正则表达处理之后,便可以通过程序将日志文件写入到数据库当中。
网页数据展示使用Echarts,根据请求中日期等参数从数据库中获取数据,将所得数据传给Echarts渲染。
使用jsp进行数据一览的动态展示,日期修改请求提交后,展示数据库中的对应日期数据。
使用servlet处理提交的请求,获取url中的参数的值,根据参数在数据库中查找相应的数据,并设置request的属性供jsp页面展示相应数据。
五、关键代码说明
indexServlet的请求处理(疫情动态页面doGet事件)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
if(request.getParameter("dataDate") == null) {
setDataAttr("2020-03-13", request);
setIpMap("2020-03-13", request);
}
else {
setDataAttr(request.getParameter("dataDate"), request);
setIpMap(request.getParameter("dataDate"), request);
}
request.getRequestDispatcher("index.jsp").forward(request, response);
}
根据url日期参数获取相应数据,并跳转到index.jsp页面
indexServlet的具体方法
protected void setDataAttr(String date, HttpServletRequest request) {
NationDAO nationDAO = new NationDAO();
Nation nation = nationDAO.get(date);
if(nation == null) return;
request.setAttribute("ip", nation.getIp());
request.setAttribute("n_ip", nation.getN_ip());
request.setAttribute("c_ip", nation.getC_ip());
request.setAttribute("sp", nation.getSp());
request.setAttribute("n_sp", nation.getN_sp());
request.setAttribute("cure", nation.getCure());
request.setAttribute("n_cure", nation.getN_cure());
request.setAttribute("dead", nation.getDead());
request.setAttribute("n_dead", nation.getN_dead());
}
protected void setIpMap(String date, HttpServletRequest request) {
ProvinceDAO provinceDAO = new ProvinceDAO();
Map<String, Integer> ipMap = provinceDAO.getIpMap(date);
request.setAttribute("ipMap", ipMap);
}
调用数据接口类获取全国各种类型的人数和每个省现有确诊的具体数据,用于jsp和地图渲染
detialServlet的请求处理(省份详情页面doGet事件)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//response.getWriter().append("Served at: ").append(request.getContextPath());
if(request.getParameter("dataDate") == null) {
setDataAttr("2020-03-13", request);;
}
else {
setDataAttr(request.getParameter("dataDate"), request);
}
String name = request.getParameter("name");
ProvinceDAO provinceDAO = new ProvinceDAO();
request.setAttribute("dateStrings", provinceDAO.getDateStrings());
request.setAttribute("cIpList", provinceDAO.getCIpList(name));
request.setAttribute("ipList", provinceDAO.getIpList(name));
request.setAttribute("cureList", provinceDAO.getCureList(name));
request.setAttribute("deadList", provinceDAO.getDeadList(name));
request.getRequestDispatcher("detial.jsp").forward(request, response);
}
根据日期参数获取数据,更新jsp页面数值显示
Echarts渲染
var myChart3 = echarts.init(document.getElementById("map3"));
option3 = {
title: {
text: '治愈/死亡人数走势图'
},
tooltip: {
trigger: 'axis'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data:
[
<%
for(int i=0; i<dateStrings.size(); i++) {
%>
<%="\'" + dateStrings.get(i) + "\',"%>
<%
}
%>
]
},
yAxis: {
type: 'value'
},
series: [
{
name: '累计治愈',
type: 'line',
smooth: true,
data:
[
<%
List<Integer> cureList = (ArrayList<Integer>)request.getAttribute("cureList");
for(int i=0; i<cureList.size(); i++) {
%>
<%=cureList.get(i) + ","%>
<%
}
%>
]
},
{
name: '累计死亡',
type: 'line',
data:
[
<%
List<Integer> deadList = (ArrayList<Integer>)request.getAttribute("deadList");
for(int i=0; i<deadList.size(); i++) {
%>
<%=deadList.get(i) + ","%>
<%
}
%>
]
}
]
};
myChart3.setOption(option3);
使用jsp向Echarts中填充数据,绘制折线图
从获取空获取地图显示数据
public Map<String, Integer> getIpMap(String date) {
Map<String, Integer> ipMap = new HashMap();
try (Connection c = DBUtil.getConnection(); Statement s = c.createStatement()) {
String sql = "select * from province where p_date = \'" + date + "\'";
ResultSet rs = s.executeQuery(sql);
while(rs.next()) {
ipMap.put(rs.getString(1), rs.getInt(5));
}
} catch (SQLException e) {
e.printStackTrace();
}
return ipMap;
}
地图需要省份和确诊人数的对应关系,因此选用用Map数据类型,用于渲染地图Echarts
六、心路历程与收获
- 221701218
这一次的结对作业,我做的工作是比较偏前端的,编程上的困难主要来自于对echarts的使用不熟悉,以及一些html、css、javascript的知识久不用生疏了(虽然页面框架主要是用bootstrap studio完成,)整体来说个人的部分不是很困难。主要困难来自于结对过程的交流,以及github的dev使用,还有数据获取也是来之不易的,由于我们都没有爬取数据的经验,所以一开始便抛弃了爬取数据的想法,想要使用静态文件的方法,本来的打算是想使用助教的数据的,后来发现网上的数据更加全面且丰富,所以又转头手动获取网络数据并存储于数据库中待用。
总之,结对合作相比个人开发,更加凸显协同合作的重要性,具体到编程里,就是一些重要参数的传递。通过结对过程出现的困难,我发现我们对结对开发缺乏经验,技术的不足也限制了我们程序的质量如数据存储于数据库可能更新就不是很及时,因此,学习新技术、互相讨论是很重要的
- 221701220
一开始看到作业要求,感觉要涉及的技术有很多,而自己的技术积累不够,便陷入了迷茫的状态。作业布置当晚,我们语音通话确定了技术选用和分工任务。随着编程的不断进行,对于技术的应用和程序的逻辑逐渐清晰。过程中也遇到了许多问题,数据源的处理、图表的渲染等,这都是不曾接触过的内容,此次作业也让我学习了这方面的技术。结对作业到此结束,虽然算不上完美,但是也比较满意,第一次和他人共同完成项目也积累了合作经验。希望接下来的小组作业我再有所进步。
七、评价结对队友
- 221701218
我的队友是一个可靠的队友,跟他结对的感受就是他是一个坚强的后盾,有什么问题随时都能跟他交流,即时不能得到解决也能有了一个大致方向。他也是一个规律、有计划的人,把任务安排的井井有条,保证任务能够在进度条上平稳前进。同时,他也是一个善于沟通的人,不管是自己遇到的问题,还是发现队友的问题都能够及时与队友沟通,尽快解决问题是结对任务走回正轨。总之,他真的是一个值得信赖的好队友.
- 221701220
我负责后端的请求处理和数据库交互,在进行整合工作时,常常需要询问前端所需要的数据格式,他都能及时并明确的答复,使我们的成果整合能够配合的非常好。遇到问题能够及时提出并相互交流,因此问题一般能够得到及时的解决。在结对作业的过程中,我重新认识了我的队友,能够积极响应并配合解决问题,互相交流想法和实现,是不可多得的编程伙伴!