一、總覽和相關連結
這個作業屬于哪個課程 | 2020春|W班 |
---|---|
這個作業要求在哪裡 | 第二次結對作業要求 |
結對學号 | 221701218、221701220 |
作業正文 | 我的第二次結對作業 |
其他參考文獻 | ··· |
其他連結
Github倉庫位址
代碼規範
二、成品展示
伺服器部署
我是雲位址連結
基本功能示範:
全國各省份疫情概覽,選擇日期檢視:
具體某個省份的疫情情況,選擇日期檢視:
拓展功能示範:
三、結對讨論過程
分工:
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
一開始看到作業要求,感覺要涉及的技術有很多,而自己的技術積累不夠,便陷入了迷茫的狀态。作業布置當晚,我們語音通話确定了技術選用和分工任務。随着程式設計的不斷進行,對于技術的應用和程式的邏輯逐漸清晰。過程中也遇到了許多問題,資料源的處理、圖表的渲染等,這都是不曾接觸過的内容,此次作業也讓我學習了這方面的技術。結對作業到此結束,雖然算不上完美,但是也比較滿意,第一次和他人共同完成項目也積累了合作經驗。希望接下來的小組作業我再有所進步。
七、評價結對隊友
我的隊友是一個可靠的隊友,跟他結對的感受就是他是一個堅強的後盾,有什麼問題随時都能跟他交流,即時不能得到解決也能有了一個大緻方向。他也是一個規律、有計劃的人,把任務安排的井井有條,保證任務能夠在進度條上平穩前進。同時,他也是一個善于溝通的人,不管是自己遇到的問題,還是發現隊友的問題都能夠及時與隊友溝通,盡快解決問題是結對任務走回正軌。總之,他真的是一個值得信賴的好隊友.
我負責後端的請求處理和資料庫互動,在進行整合工作時,常常需要詢問前端所需要的資料格式,他都能及時并明确的答複,使我們的成果整合能夠配合的非常好。遇到問題能夠及時提出并互相交流,是以問題一般能夠得到及時的解決。在結對作業的過程中,我重新認識了我的隊友,能夠積極響應并配合解決問題,互相交流想法和實作,是不可多得的程式設計夥伴!