一、總覽和相關鏈接
這個作業屬於哪個課程 | 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
我負責后端的請求處理和數據庫交互,在進行整合工作時,常常需要詢問前端所需要的數據格式,他都能及時並明確的答復,使我們的成果整合能夠配合的非常好。遇到問題能夠及時提出並相互交流,因此問題一般能夠得到及時的解決。在結對作業的過程中,我重新認識了我的隊友,能夠積極響應並配合解決問題,互相交流想法和實現,是不可多得的編程伙伴!