结对作业二

软工实践 第四次作业 结对作业二


这个作业属于哪个课程 2021春软件工程实践S班
这个作业要求在哪里 作业要求
这个作业目标 深入学习web技术、学习根据原型构建网站
其他参考文献 百度、github、CSDN
结对同学 黄隽芊 221801232

git仓库链接

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:&nbsp;&nbsp;&nbsp;&nbsp;<%=item.getAbstracts() %></dd> 
                    <dd class="dd_conference">来源会议: &nbsp;&nbsp;<%=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黄隽芊:

队友真的非常好。我真的对实现这个作业一头雾水的时候,是队友一举担下处理数据的重任,才让我们的作业有了眉目。对于两个人都并不熟悉的后端,队友真的很努力,处理了数据的各项内容,让我做较为简单的前端页面,队友还教了我很多东西。非常感谢队友的帮助,让我们的作业得以实现。

posted @ 2021-03-30 09:58  HannahShaw  阅读(140)  评论(6编辑  收藏  举报