軟工實踐 第四次作業 結對作業二
這個作業屬於哪個課程 | 2021春軟件工程實踐S班 |
---|---|
這個作業要求在哪里 | 作業要求 |
這個作業目標 | 深入學習web技術、學習根據原型構建網站 |
其他參考文獻 | 百度、github、CSDN |
結對同學 | 黃雋芊 221801232 |
git倉庫鏈接
代碼規范鏈接
PSP表格
PSP2.1 | Personal Software Process Stages | 預估耗時(分鍾) | 實際耗時(分鍾) |
---|---|---|---|
Planning | 計划 | 15 | 20 |
·Estimate | ·估計這個任務需要多少時 | 15 | 20 |
·Development | 開發 | 3580 | 4025 |
·Analysis | ·需求分析(包括學習新技術) | 360 | 400 |
·Design Spec | ·生成設計文檔 | 40 | 30 |
·Design Review | ·設計復審 | 10 | 20 |
·Coding Standard | ·代碼規范 | 20 | 25 |
·Design | ·具體設計 | 90 | 120 |
·Coding | ·具體編碼 | 3000 | 3300 |
·Code Review | ·代碼復審 | 60 | 50 |
·Test | ·測試(自我測試,修改代碼,提交修改) | 60 | 80 |
Reporting | 報告 | 60 | 70 |
·Test Repor | ·測試報告 | 35 | 40 |
·Size Measurement | ·計算工作量 | 10 | 15 |
·Postmortem & Process Improvement Plan | ·事后總結, 並提出過程改進計划 | 15 | 15 |
合計 | 3575 | 4115 |
成品展示
- 可對論文列表進行查詢
- 可對論文列表進行刪除;
- 分析論文信息,提取top10個熱門領域,形成關鍵詞圖譜,點擊某個關鍵詞可展現相關的論文
- 對多年間,ECCV頂會的熱詞呈現熱度走勢對比
結對討論過程描述
1.剛開始分工
2.准備工作
3.后端進程
4.前端界面和問題討論
5.收藏夾和刪除功能的討論
6.論文列表搜索頁面的討論
7.關鍵詞圖譜的討論
8.熱度走勢圖的討論
9.宿舍討論過程
描述設計實現
使用MVC開發流程實現項目架構,利用Servlet+JSP+Jdbc的功能開發流程。
項目架構:
以下功能結構圖包括本次作業的流程(需求分析,實現方式,分工)
以下數據結構設計圖以及項目結構是關於數據結構的一些設計。數據通過MYSQL數據庫來管理,由ItemsDao封裝所有對數據的查詢,返回需要的對象,由前台實現數據的顯示
代碼說明
數據庫設計
CREATE TABLE `paperslist` (
`id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`abstracts` varchar(8191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`conference` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`keyword` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`link` varchar(8191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
代碼設計
從json文件夾取出數據
public void readECCVFileContent(String path) throws FileNotFoundException {
String key = "";
items item = new items();
JSONReader reader=new JSONReader(new FileReader(path));
//開始解析最外層的對象
reader.startObject();
//遍歷最外層的對象
while (reader.hasNext()){
String longkeyword = "";
key = reader.readString(); //讀取鍵的值
if(key.equals("摘要")){
String abstracts = reader.readObject().toString();
item.setAbstracts(abstracts);
}
else if(key.equals("會議和年份")){
String conference = reader.readObject().toString();
item.setConference(conference);
}
else if(key.equals("關鍵詞")){
reader.startArray();//開始解析數組
while (reader.hasNext()){
String keyword = reader.readString();
longkeyword += keyword;
longkeyword += ",";
}
item.setKeyword(longkeyword);
reader.endArray();
}
else if(key.equals("發布時間")){
String time = reader.readObject().toString();
item.setTime(time);
}
else if(key.equals("論文名稱")){
String title = reader.readObject().toString();
System.out.println("論文:" + title);
item.setTitle(title);
}
else if(key.equals("原文鏈接")){
String link = reader.readObject().toString();
item.setLink(link);
}
}
try {
Connection conn = DBHelper.getConnection();
saveDataToDb(conn,item);
} catch (Exception e) {
// 省略
}
reader.endObject();
}
解釋思路:
其實剛開始拿到json數據還是有點頭痛,怎么把數據取出來還是有點困難,於是上網搜索,覺得使用JSONReader來讀數據在一層一層遍歷解析。第一次拆Json數據,花費了很多時間調試。
獲取所有論文信息
public ArrayList<items> getAllItems() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
// 論文集合
ArrayList<items> list = new ArrayList<items>();
try {
conn = DBHelper.getConnection();
String sql = "select * from paperslist;";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while (rs.next()) {
items item = new items();
item.setId(rs.getString("id"));
item.setAbstracts(rs.getString("abstracts"));
item.setConference(rs.getString("conference"));
item.setKeyword(rs.getString("keyword"));
item.setTime(rs.getString("time"));
item.setTitle(rs.getString("title"));
item.setLink(rs.getString("link"));
// 把一個論文加入集合
list.add(item);
}
return list;
} catch (Exception ex) {
//省略
} finally {
// 省略
}
}
解釋思路:
items是設計的關於論文的類,位於entity包里,那么從數據庫取出數據就是執行sql語句,同樣在相同類下也有根據論文標題,論文id搜索返回論文信息的方法,就是執行的sql語句不同。
獲取top10熱詞
public List<Map.Entry<String, Integer>> getHotkw (String str){
int num = 0;
TreeMap<String, Integer> map = new TreeMap<>();
String lowerStr = str.toLowerCase();
String[] word = lowerStr.split(",");
int len = word.length;
String tw = null;
for (int i = 0; i < len; i++) {
tw = word[i];
if (!map.containsKey(tw)) {
map.put(tw, 1);
}
else {
num = map.get(tw);
map.put(tw, num + 1);
}
}
List<Map.Entry<String, Integer>> hotWords = WordCountMethod.highFreqWord(map);
return hotWords;
}
解釋思路:
上次作業寫了wordcount程序,這一次剛好獲取的時候可以復用,就想到搬了上一次WordCountMethod.highFreqWord(map)
的函數,前期是獲取所有論文關鍵詞拼成字符串,再拆成一個個鍵值對存儲在Map中,最后按需獲取top的熱詞。
獲取排名前幾的熱詞近幾年的數據
public int[] keyYearNum(int kw) {
//獲取所有關鍵詞
String allKw = getKeywordsFromDB();
//獲取排好序的關鍵詞數據
String[] topkw = words(getHotkw(allKw));
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
int year = 2016;
//存儲三年該熱詞出現次數
int[] num = new int[3];
try {
conn = DBHelper.getConnection();
for(int i = 0;i < 3;i++) {
String sql = "select * from paperslist where conference like ? and keyword like ?;";
stmt = conn.prepareStatement(sql);
//模糊查詢匹配語句
String y = "%" + year + "%";
String kw1 = "%"+ topkw[kw] + "%";
stmt.setString(1, y);
stmt.setString(2, kw1);
rs = stmt.executeQuery();
while (rs.next()) {
num[i]++;
}
year += 2;
}
return num;
} catch (Exception ex) {
//省略
} finally {
//省略
}
}
解釋思路:
題目要求是多年間頂會的熱詞呈現熱度走勢,那么需要熱詞也要熱詞數據,其實上一個功能已經取出熱詞以及排名,那只要取出前幾名的熱詞分別再多年的數據,正好數據中有提供論文發布年份,那就可以用sql條件查詢語句,設置關鍵詞和年份兩個條件查詢符合的論文返回論文數。
servlet處理前端傳來請求轉發數據
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
if(request.getParameter("action")!=null){
this.action = request.getParameter("action");
//如果是添加論文進收藏夾
if(action.equals("add")){
if(addToCollection(request,response)){
request.getRequestDispatcher("/success.jsp").forward(request, response);
}
else{
request.getRequestDispatcher("/failure.jsp").forward(request, response);
}
}
//如果是顯示收藏夾
if(action.equals("show")){
request.getRequestDispatcher("/collection.jsp").forward(request, response);
}
//如果是執行刪除收藏夾的論文
if(action.equals("delete")){
if(deleteFromCollection(request,response)){
request.getRequestDispatcher("/collection.jsp").forward(request, response);
}
else{
request.getRequestDispatcher("/collection.jsp").forward(request, response);
}
}
}
}
解釋思路:
位於collectionServlet中,用於處理前端收藏,刪除,展示收藏夾的請求,傳輸數據,再重定向到相應jsp頁面。
添加論文進收藏夾
private boolean addToCollection(HttpServletRequest request, HttpServletResponse response){
String id = request.getParameter("id");
String number = request.getParameter("num");
items item = idao.getItemsById(Integer.parseInt(id));
//是否是第一次給收藏夾添加論文,需要給session中創建一個新的收藏夾對象
if(request.getSession().getAttribute("collection")==null){
collection collection = new collection();
request.getSession().setAttribute("collection",collection);
}
collection collection = (collection)request.getSession().getAttribute("collection");
if(collection.addPaperInCollection(item, Integer.parseInt(number))){
return true;
}
else{
return false;
}
}
//添加論文進收藏夾
public boolean addPaperInCollection(items item ,int number){
if(paperlist.containsKey(item)){
paperlist.put(item, paperlist.get(item)+number);
}
else{
paperlist.put(item, number);
}
return true;
}
解釋思路:
獲取前端傳來的論文id和num,判斷是否第一次給收藏夾添加論文,如果是,就新建一個收藏夾對象,如果不是就收藏文章。方法寫在collection類中。
從收藏夾刪除論文
private boolean deleteFromCollection(HttpServletRequest request, HttpServletResponse response){
String id = request.getParameter("id");
collection coll = (collection)request.getSession().getAttribute("collection");
items item = idao.getItemsById(Integer.parseInt(id));
if(coll.removePaperFromCollection(item)){
return true;
}
else{
return false;
}
}
//從收藏夾移除論文
public boolean removePaperFromCollection(items item){
paperlist.remove(item);
return true;
}
前端jsp實現論文信息顯示
<table id="table" >
<tr>
<td>
<!-- 論文循環開始 -->
<%
ItemsDao itemsDao = new ItemsDao();
ArrayList<items> list = new ArrayList<items>();
//如果有獲取到key說明是搜索后跳轉的頁面,就根據收到的key進行模糊搜索返回論文集合
if(request.getParameter("key")!=null){
list = itemsDao.getItemsByTitle(request.getParameter("key"));
}
//沒有獲得key,返回所有論文信息
else{
list = itemsDao.getAllItems();
}
if(list!=null&&list.size()>0){
for(int i=0;i<list.size();i++){
items item = list.get(i);
%>
<div>
<dl>
<dt clsaa="dt_title">
<a href="details.jsp?id=<%=item.getId()%>"><%=item.getTitle() %></a>
</dt>
<dd class="dd_abstract">abstract: <%=item.getAbstracts() %></dd>
<dd class="dd_conference">來源會議: <%=item.getConference() %></dd>
</dl>
</div>
<!-- 論文循環結束 -->
<%
}
}
%>
</td>
</tr>
</table>
論文模糊搜索
<form action="">
<input type="text" name="key" value="" placeholder="輸入論文題目查找 支持模糊查詢">
<a href="main.jsp?keyword=document.getElementById("key").value"><input type="submit" value="搜索"></a>
</form>
解釋思路:
獲取輸入框的value,作為跳轉回首頁攜帶的數據,加載首頁時判斷是否有攜帶數據,有則執行函數搜索返回相應論文。
心路歷程和收獲
221801226肖寒:
之前一直接觸的是靜態網頁的開發,在上學期web程序設計實踐接觸了php使用yii模板開發博客,但是還不是很熟練。在第一次寒假作業時候寫的學習規划是前端,確實都有在一步步的學習,發現布置的作業也很貼合我學習路線。這一次學習了jsp+servlet+jdbc的MVC設計模式開發了小小小的論文查詢系統,但是也有不足。
這一次我是和隊友0基礎的學做jsp+servlet,我是做后端和數據連接,剛開始的環境構建就遇到一些問題,但是我們都一起解決。這一次真的體會到結對編程,兩個人並肩作戰的感受。感謝小黃同學前端綠色簡約的UI和無私的幫助,交流非常順利,👍。
這一次對github的項目管理逐漸熟悉,學會了創建分支合並分支發布release版本,除了github有時候連接真的容易崩之外,其他都很好用。
221801232黃雋芊:
在上次做完原型之后,一直都很擔心實踐的問題,這次還是逃不過。一開始沒有什么思路,真的毫無頭緒,然后和隊友商量着着先把數據弄出來,先把要做的能簡化就簡化,首先要先有個東西做出來。我花了好久先搭了jsp的環境,html和css因為以前有學過,所以並不難。主要就是細心和耐心,還是做得不夠好看,希望下次有機會可以做得更好看。但是頁面還需要和隊友的數據連接,自己有很多不會的地方,多虧了隊友的幫助,后期還要調試修改,一起努力。新學了echarts,這次只簡單地做了折線圖,其實可以用來制作各種圖表。而且通過結對作業對github的使用也更加了解和熟練了。自己還有很多不會的地方,做得真的不夠好,希望可以在一次次作業中進步,學會更多東西。
結對過程,隊友評價
221801226肖寒:
話不多說就是nice!兩個小白相互支持,主要是交流非常順利,而且態度積極。對於前端UI小黃做了很多樣式的調整,而且處理前后端數據的時候也是我們一起完成,對接很順利。感覺這次作業完成的很順利!
221801232黃雋芊:
隊友真的非常好。我真的對實現這個作業一頭霧水的時候,是隊友一舉擔下處理數據的重任,才讓我們的作業有了眉目。對於兩個人都並不熟悉的后端,隊友真的很努力,處理了數據的各項內容,讓我做較為簡單的前端頁面,隊友還教了我很多東西。非常感謝隊友的幫助,讓我們的作業得以實現。