结对作业二
这个作业属于哪个课程 | 2021春软件工程实践/S班 |
---|---|
结对学号 | 221801109 、221801130 |
这个作业要求在哪里 | 结对作业二 |
作业的目标 | 阅读《构建之法》并体现成果、完成原型模型设计、撰写博客 |
其他参考文献 | CSDN、简书、《构建之法》、GitHub |
git仓库链接和代码规范链接
项目服务器链接
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
• Estimate | • 估计这个任务需要多少时间 | 60 | 60 |
Development | 开发 | ||
• Analysis | • 需求分析 (包括学习新技术) | 600 | 550 |
• Design Spec | • 生成设计文档 | 120 | 100 |
• Design Review | • 设计复审 | 60 | 100 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
• Design | • 具体设计 | 500 | 550 |
• Coding | • 具体编码 | 900 | 950 |
• Code Review | • 代码复审 | 240 | 180 |
• Test | • 测试(自我测试,修改代码,提交修改) | 100 | 180 |
Reporting | 报告 | 150 | 140 |
• Test Repor | • 测试报告 | 60 | 70 |
• Size Measurement | • 计算工作量 | 30 | 20 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 60 | 50 |
合计 | 2750 | 2800 |
成品展示
1、查询功能(模糊搜索):
2、翻页功能
3、查看论文详情功能
4、删除功能
5、热词分析功能(ICCV、ECCV、CVPR)
6、查看top10领域
7、完整呈现结果 —— GIF动图:
结对讨论过程描述
首先拿到题目进行了需求分析,互相讨论之后大致了解了题目所要实现的功能。经过资料查询和探讨之后,我们决定采用jsp+servlet技术来实现本次作业。我们将讨论过程分为三部分。
第一部分:web前端讨论。
问题:制作怎样的web前端,如何制作?
解决:由于第一次结对时已经对平台原型进行了较为充分的讨论,所以我们以原型模型为模板,进行原型模型样式的前端设计;查阅和复习web前端知识。
第二部分:前后端交互讨论。
问题:如何实现页面功能、页面的跳转,以及页面之间、servlet之间如何传值
解决:由于这部分两人都没有什么经验,于是在这部分上花费了大部分时间进行资料查询共享,疑惑点讨论,最后采用form表单以及href方式解决问题。
第三部分:页面美化讨论
问题:当前页面初步成型,实现了大部分功能,但页面较不美观,如何进行页面美化?
解决:在网上查阅资料并讨论最终通过CSS实现了页面美化。
结对过程截图:
设计实现过程
首先我们根据作业一中设计的原型模型,对前端网页进行了初步的设计,达到了原形模型大部分的页面预期效果。
然后完成Jason数据的解析,并将解析的数据,按照设计好的数据库模型存入数据库。
之后根据前端的设计,进行后端的逻辑开发:首先完成与数据库的对接,然后对各个页面的逻辑功能进行开发设计,完成页面跳转,数据读取,数据分析,以及模糊查询等一系列功能,完成了对已爬取的论文列表进行操作。之后分别再echarts官网和动态柱状图视频中学习了词云图和热度趋势的制作,顺利制作出TOP10词云图和三大平台热度走势。
最后对基本完成的平台进行了进一步美化,至此平台初步完成。
功能结构图:
代码说明
一、论文操作
1、定义文章类接口
public interface PostDAO {
int getTotal();
void delete(String title) ;
List<Post> list();
List<Post> list(String text);
}
2、关键接口实现
@Override
public List<Post> list() {
String sql = "select * from post";
List<Post> postList = new ArrayList<>();
try (Connection c = DBUtil.getConnection(); Statement s = c.createStatement()) {
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
String title = rs.getString("title");
String content = rs.getString("content");
String link = rs.getString("link");
String keyWord = rs.getString("keyWord");
String time = rs.getString("time");
String platform = rs.getString("platform");
postList.add(new Post(title, content, link, keyWord, time, platform));
}
} catch (SQLException e) {
e.printStackTrace();
}
return postList;
}
@Override
public List<Post> list(String text) {
String sql = "select * from post where title like '%" + text + "%' or keyword like '%" + text + "%' ";
List<Post> postList = new ArrayList<>();
try (Connection c = DBUtil.getConnection(); Statement s = c.createStatement()) {
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
String title = rs.getString("title");
String content = rs.getString("content");
String link = rs.getString("link");
String keyWord = rs.getString("keyWord");
String time = rs.getString("time");
String platform = rs.getString("platform");
postList.add(new Post(title, content, link, keyWord, time, platform));
}
} catch (SQLException e) {
e.printStackTrace();
}
return postList;
}
3、通过PostServlet调用文章类接口进行模糊查询并将得到的List返回index.jsp中,实现文章显示功能。
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");
List<Post> list = new ArrayList<>();
`
`
`
postList = postDAO.list(string);
req.setAttribute("key",string);
req.setAttribute("postList",list);
req.setAttribute("count",count);
req.setAttribute("page",page);
req.getRequestDispatcher("/index.jsp").forward(req,resp);
}
<c:forEach items="${postList}" var="post">
<tr>
<td width="15%">${post.title} </td>
<td width="15%">${post.content} "></td>
<td width="26%">${post.keyWord} <input type="hidden" id="key" name="key" value="${key}"></td>
<td width="20%">${post.link}</td>
<td width="8%">${post.time}</td>
<td width="8%">${post.platform}</td>
<td width="5%">
<input type="button" id="see" name="see" value="查看" onclick="window.location='content?title=${post.title}&key=${key}'">
</td>
</tr>
</c:forEach>
4、实现翻页功能,通过每次只读取List中十条记录的方式来实现翻页功能;当触发向前翻页按钮时,list读取向前回滚十条;触发向后翻页按钮,list往后读取十条;通过count和page返回当前页数和总页数。
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");
List<Post> list = new ArrayList<>() ;
int count = 0;
String string = " ";
System.out.println(req.getParameter("key"));
if (req.getParameter("nex") != null) { //往后翻页
count = (Integer.parseInt(req.getParameter("nex")) + 1) * 10;
string = req.getParameter("string2");
} else if (req.getParameter("pre") != null) { //往前翻页
count = (Integer.parseInt(req.getParameter("pre")) - 1) *10;
string = req.getParameter("string1");
}
List<Post> postList = new ArrayList<>();
postList = postDAO.list(string);
int size = postList.size();
int page = 1;
if (size % 10 == 0) {// 如果记录总条数对每页显示记录数取整等于0,则表示页面数刚好分完。
page = size / 10;
list = postList.subList(count, count+10);
} else {// 如果取不尽,那么就添加一页来放剩余的记录
if (size <= 10) {
page = 1;
list = postList.subList(count, size);
} else {
page = postList.size() / 10 + 1;
if (count < (page-1)*10 ) {
list = postList.subList(count, count+10);
} else {
list = postList.subList(count, count+postList.size()-(page-1)*10);
}
}
}
}
<form method="post" id="form4" action="<%=path%>/hello">
<c:if test="${key!=null}">
<input type="hidden" id="string1" name="string1" value="${key}">
<input type="hidden" id="pre" name="pre" value="${count}">
</c:if>
<input type="submit" id="previous" value="Previous" style="margin-left: 70%" >
</form>
<form method="post" id="form5" action="<%=path%>/hello">
<c:if test="${key!=null}">
<input type="hidden" id="string2" name="string2" value="${key}">
<input type="hidden" id="nex" name="nex" value="${count}">
</c:if>
<input type="submit" id="next" value="Next" style="margin-left: 1%" >
</form>
共 ${page}页
当前第 ${count+1}页
5、实现删除功能,通过DeleteServlet调用文章类的接口,实现论文删除功能
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");
String title = req.getParameter("string1");
String string = req.getParameter("string2");
userDAO.delete(title);
this.getServletContext().setAttribute("key",string);
req.getRequestDispatcher("/hello").forward(req,resp);
}
二、论文分析
1、三大平台热度趋势,通过echarts使用动态柱状图实现不同年份的热词变化趋势。下面只出示ICCV平台关键代码,另外两个平台以此类推。
资料参考:https://www.bilibili.com/video/BV177411h781?t=372&p=2
<script type="text/javascript">
xAxis: [
{
type:'category',
data: countryList,
axisPointer: {
type: 'shadow'
},
axisLabel: {
formatter: function (value) {
return '{value|' + value + '}';
},
margin: 20,
rich: {
`
`
`
}
}
},
],
yAxis:[
{
name:'热度',
type:'value',
nameTextStyle:{
fontSize:18
},
axisLabel:{
fontSize:18
}
},
],
},
options:[]
};
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
2、TOP10个热门领域,KeyWordServlet通过调用数据库获取十个热门关键词,并将关键词和各自对应频率返回到jsp中通过Echarts词云图形式展现出来,通过随机数生成方式使每次刷新词云图的位置和颜色皆可发生变化。
资料参考:https://github.com/ecomfe/echarts-wordcloud
<script>
var chart = echarts.init(document.getElementById('cloud'));
var option = {
series: [ {
textStyle: {
color: function () {
return 'rgb(' + [
Math.round(Math.random() * 255),
Math.round(Math.random() * 255),
Math.round(Math.random() * 255),
0.8
].join(',') + ')';
}
},
emphasis: {
textStyle: {
shadowBlur: 10,
shadowColor: '#333'
}
},
data: [
{
name: '${keyWordList[0]}',
value: ${valueList[0]}
}
`
`
`
]
} ]
};
chart.setOption(option);
chart.on('click',function(params){
var name = params.data.name;
window.location.href="hello?string="+name;
//alert(name);
console.log(name);
});
window.onresize = chart.resize;
</script>
心路历程和收获
221801109池毓地:这次结对加深了我对web开发的理解,帮助我更好的掌握了前端的设计与美化,同时初步了解了前后端交互的实现方法,是一次很有意义的作业。本次开发过程中,我的表现并不是太好,很多时候我都表现的像个什么都不会的小白,但是我明白了一个道理,只要愿意学习,并没有什么事是无法解决的,因此不断的学习才是进步的来源。
221801130梁扬新:本次结对作业,让我学习到了很多的技术,包括但不限于前后端的交互、服务器的搭建等,对我的编程水平有很大的提升。通过这次的编程,我对团队项目的开发有了更好的掌握,包括团队开发的总体进度,团队的任务分配等,对我的项目管理能力也有很大的提升。总体而言,本次结对是一次十分有意义的开发。
评价结对队友
221801109池毓地:我的队友扬新是一个做事十分认真负责,条理清晰的人,对整个项目的进度有较好的把控。同时他十分有耐心,面对拖后腿的我,没有嫌弃,而是十分认真的教会了我各种开发技能,是一个十分难得的好队友。很多时候我对他说的技术一头雾水,而扬新看到我的窘迫,总是一脸淡定的和我说:“没关系的,交给我吧”,然后将解决的方法传授给我,让我在完成任务的同时获得了能力的提升。
221801130梁扬新:我的队友毓地总是能够热情的对待讨论分配的任务,每次当遇到困难时都会他非常认真去学习。其实实践就是一个互相促进的过程。我对前端的设计美化并不是太在行,而毓地较好的弥补了我这方面的弱点,对前端进行了较好的设计美化;在这次结对过程中,再一次体验到合作的好处,总而言之,这次结对收获颇丰!