Webcollector + Spring + MVC 搭建应用初探(四)
来源:互联网 发布:我国茶叶出口数据5014 编辑:程序博客网 时间:2024/06/01 16:52
本节的内容可以看作将Webcollector + Spring + MVC 搭建应用初探(三) 中的Python(Django MVC)
代码逻辑翻译成Java(Spring MVC) 的另一种实现 相应解释参看前者(python 基本就是伪代码)
所需要掌握的仅仅是Thymeleaf(看到这个词总是想到《疯城记》中的Tealeaf) 这种模板渲染语言 具体语法不进行叙述 可以与Django模板
渲染方式对比理解。
使用的maven依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.3.RELEASE</version> </parent> <dependencies> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies>
主页面
mainPage.html
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><link rel="stylesheet" type="text/css" href="/static/style.css" /><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>The SubPage of Application</title></head><body> <div th:each="mainCategory: ${mainSubCategoryMap.keySet()}"> <h5 th:text="${mainCategory}"></h5> <ul th:each="subCategory: ${mainSubCategoryMap.get(mainCategory).keySet()}"> <li><a th:attr="href=@{'/bilibili/' + ${subCategory}}" th:text="${subCategory}"/></li> </ul> <br/> </div></body></html>
子页面
subpage.html
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><link rel="stylesheet" type="text/css" href="/static/SubPageStyle.css" /><meta http-equiv="refresh" th:content="${refresh_context}"/><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>The SubPage of Application</title></head><body th:style="'background-image:url(/static/image/'+ ${subCategory} + '.jpg); background-repeat:no-repeat; background-position: 100% 100%; background-color: lightgoldenrodyellow;'"> <h4 th:text="${subCategory}"></h4> <h4 th:text="'显示视频数量 ' + ${videoHashList.size()}"></h4> <div th:each="videoHash: ${videoHashList}"> <div id = "video_area"> <a th:href='${videoHash.get("url")}'><img th:src='${videoHash.get("img")}'/></a> <br/> <font size="1" color="green" th:text='${videoHash.get("video_name")}'></font> </div> <br/> </div> <p id = "refresh_bottom"> <input type="button" value="refresh" onclick="location=location"/> </p></body></html>
上述两个页面使用的样式基本与Django的相同不再给出 可参看前者。
子页面图片下载Thread类及页面Mapping类
package com.bilibili;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.PathVariable;import redis.clients.jedis.Jedis;import java.io.*;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.ArrayList;import java.util.Collections;import java.net.HttpURLConnection;import java.net.URL;import java.io.File;/** * Created by ehang on 2017/1/23. */class ImgThread extends Thread{ private String subCategory; public ImgThread(String subCategory){ this.subCategory = subCategory; } @Override public void run(){ String img_path = System.getProperty("user.dir") + "\\src\\main\\resources\\static\\image"; String img_file_name = img_path + String.format("\\%s.jpg", subCategory); File img_file = new File(img_file_name); if (!img_file.exists()){ String img_url = "https://image.baidu.com/search/index?tn=baiduimage&word=动漫" + subCategory + "壁纸"; URL url; try{ url = new URL(img_url); HttpURLConnection httpURLConnection =(HttpURLConnection) url.openConnection(); InputStream urlStream = httpURLConnection.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlStream)); String sCurrentLine = ""; String response_text = ""; while((sCurrentLine = bufferedReader.readLine())!= null) { response_text += sCurrentLine + "\n"; } int start_index = response_text.indexOf("thumbURL\""); start_index += "thumbURL\"".length(); start_index += response_text.substring(start_index).indexOf("\"") + 1; int end_index = start_index + response_text.substring(start_index).indexOf("\""); img_url = response_text.substring(start_index, end_index); url = new URL(img_url); httpURLConnection =(HttpURLConnection) url.openConnection(); urlStream = httpURLConnection.getInputStream(); DataInputStream da = new DataInputStream(urlStream); FileOutputStream fout = new FileOutputStream(img_file_name); DataOutputStream dout = new DataOutputStream(fout); int temp ; while ((temp = da.read()) != -1) { dout.write(temp); } da.close(); fout.close(); dout.close(); }catch (Exception e){ e.printStackTrace(); } } }}@Controllerpublic class GreetingController { private Jedis jedis = new Jedis("127.0.0.1", 6379); private final String mainSubCategoryMap = "Map:BiliBili:%s"; private final String subCategoryUrl = "Mid:BiliBili:%s"; private final String videoHashFormat = "Video:BiliBili:%s"; private final int subPageVideoCount = 30; private HashMap<String, Boolean> refresh_dict = new HashMap<>(); @RequestMapping("/bilibili") public String mainPage(Model model){ Map<String, Map<String, String>> mapRequire = new HashMap<>() ; for(String mainMapKey :jedis.keys(String.format(mainSubCategoryMap, "*"))){ String[] stringArray = mainMapKey.split(":"); String mainCategory = stringArray[stringArray.length - 1]; Map<String, String> temp_dict = new HashMap<>(); Set<Map.Entry<String, String>>entry = jedis.hgetAll(mainMapKey).entrySet(); for (Iterator<Map.Entry<String, String>> ite = entry.iterator();ite.hasNext();) { Map.Entry<String, String> kv = ite.next(); temp_dict.put(kv.getKey(), kv.getValue()); } mapRequire.put(mainCategory, temp_dict); } model.addAttribute("mainSubCategoryMap", mapRequire); return "mainPage"; } @RequestMapping("/bilibili/{subCategory}") public String subPage(@PathVariable String subCategory, Model model){ subCategory = subCategory.replace("/", "+"); ArrayList<String> MidList = new ArrayList<>(); for(String mid: jedis.smembers(String.format(subCategoryUrl, subCategory))){ MidList.add(mid); } Collections.shuffle(MidList); ArrayList<Map<String, String>> ListRequire = new ArrayList<>(); for(int i = 0;i < subPageVideoCount;i++) { String videoHashKey = String.format(videoHashFormat, MidList.get(i)); ListRequire.add(jedis.hgetAll(videoHashKey)); } model.addAttribute("subCategory", subCategory); model.addAttribute("videoHashList", ListRequire); ImgThread imgThread = new ImgThread(subCategory); imgThread.run(); if (!refresh_dict.keySet().contains(subCategory)){ model.addAttribute("refresh_context", "2"); refresh_dict.put(subCategory ,true); } else model.addAttribute("refresh_context", ""); return "subPage"; }}
由于静态图片需要在编译部署前进行下载,故在部署前如下单独运行了上述ImgThread(这也是两门语言或框架的不同)
package com.bilibili;import redis.clients.jedis.Jedis;import java.util.Iterator;import java.util.Map;import java.util.Set;/** * Created by ehang on 2017/1/24. */public class ImgStarter { private static final String mainSubCategoryMap = "Map:BiliBili:%s"; private static Jedis jedis = new Jedis("127.0.0.1", 6379); public static void main(String[] args){ for(String mainMapKey :jedis.keys(String.format(mainSubCategoryMap, "*"))){ String[] stringArray = mainMapKey.split(":"); String mainCategory = stringArray[stringArray.length - 1]; Set<Map.Entry<String, String>> entry = jedis.hgetAll(mainMapKey).entrySet(); for (Iterator<Map.Entry<String, String>> ite = entry.iterator(); ite.hasNext();) { Map.Entry<String, String> kv = ite.next(); String subCategory = kv.getKey(); try{ subCategory = subCategory.replace("/", "+"); ImgThread imgThread = new ImgThread(subCategory); imgThread.start(); imgThread.join(); }catch (Exception e){ e.printStackTrace(); } } } }}
当然还需要下面的起动代码
package com.bilibili;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * Created by ehang on 2017/1/23. */@SpringBootApplicationpublic class Application { public static void main(String []args){ SpringApplication.run(Application.class, args); }}
由于代码逻辑完全相同 故不再给出截图 简单页面效果参看 Webcollector + Spring + MVC 搭建应用初探(三)
使用MVC进行渲染的情形大致是这样,下面的工作将转移到搜索引擎及推荐系统上去。
有关推荐系统的初步实现可参看 Webcollector + Spring + MVC 搭建应用初探(五)
为了对照方便,下面给出上述过程在基本的Servlet及JSP语法下的实现,这里的一个不同是,子页面实现跳页。
package main.com.bilibili;/** * Created by ehangzhou on 2017/2/18. */import java.io.IOException;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;import javax.servlet.RequestDispatcher;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import redis.clients.jedis.Jedis;@WebServlet( urlPatterns = {"/bilibili"})public class MainPageServlet extends HttpServlet { private Jedis jedis = new Jedis("127.0.0.1", 6379); private final String mainSubCategoryMap = "Map:BiliBili:%s"; @Override public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException{ Map<String, Map<String, String>> mapRequire = new HashMap<>() ; for(String mainMapKey :jedis.keys(String.format(mainSubCategoryMap, "*"))){ String[] stringArray = mainMapKey.split(":"); String mainCategory = stringArray[stringArray.length - 1]; Map<String, String> temp_dict = new HashMap<>(); Set<Map.Entry<String, String>> entry = jedis.hgetAll(mainMapKey).entrySet(); for (Iterator<Map.Entry<String, String>> ite = entry.iterator(); ite.hasNext();) { Map.Entry<String, String> kv = ite.next(); temp_dict.put(kv.getKey(), kv.getValue()); } mapRequire.put(mainCategory, temp_dict); } request.setAttribute("mainSubCategoryMap", mapRequire); RequestDispatcher rd = request.getRequestDispatcher("/mainPage.jsp"); rd.forward(request, response); }}
mainPage.jsp
<%-- Created by IntelliJ IDEA. User: ehangzhou Date: 2017/2/18 Time: 11:30 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><%@ taglib uri ="http://java.sun.com/jsp/jstl/core" prefix="c" %><html><link rel="stylesheet" type="text/css" href="static/style.css" /><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>The MainPage of Application</title></head><body><c:forEach items="${mainSubCategoryMap}" var = "mapItem"> <h5>${mapItem.key}</h5> <ul> <c:forEach items="${mapItem.value}" var = "subCategory"> <li><a href="bilibili/${subCategory.key}">${subCategory.key}</a></li> </c:forEach> </ul> <br/></c:forEach></body></html>
package main.com.bilibili;/** * Created by ehangzhou on 2017/2/18. */import redis.clients.jedis.Jedis;import java.io.IOException;import java.util.*;import javax.servlet.RequestDispatcher;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.net.URLDecoder;@WebServlet( urlPatterns = {"/bilibili/*"})public class SubPageServlet extends HttpServlet { private Jedis jedis = new Jedis("127.0.0.1", 6379); private final String subCategoryUrl = "Mid:BiliBili:%s"; private final String videoHashFormat = "Video:BiliBili:%s"; private final int subPageVideoCount = 25; private final int subPageUpperCount = 10; private ArrayList<String> MidList = null; private void initMidList(String subCategory){ MidList = new ArrayList<>(); for(String mid: jedis.smembers(String.format(subCategoryUrl, subCategory))){ MidList.add(mid); } } private String getSubCategory(HttpServletRequest request)throws IOException{ String[] strArray = request.getRequestURI().split("/"); String subCategory = URLDecoder.decode(strArray[strArray.length - 1], "UTF-8"); subCategory = subCategory.replace("/", "+"); return subCategory; } private int getPageNum(){ return MidList.size() / subPageVideoCount; } private void generatePage(HttpServletRequest request, HttpServletResponse response, int page)throws IOException, ServletException{ String subCategory = getSubCategory(request); if (MidList == null){ initMidList(subCategory); } ArrayList<Map<String, String>> ListRequire = new ArrayList<>(); for(int i = (page - 1) *subPageVideoCount ;i < page * subPageVideoCount;i++) { String videoHashKey = String.format(videoHashFormat, MidList.get(i)); ListRequire.add(jedis.hgetAll(videoHashKey)); } request.setAttribute("subCategory", subCategory); request.setAttribute("videoHashList", ListRequire); int pageTotalNum = getPageNum(); if (pageTotalNum > subPageUpperCount){ pageTotalNum = subPageUpperCount; } request.setAttribute("pageTotalNum", pageTotalNum); RequestDispatcher rd = request.getRequestDispatcher("/subPage.jsp"); rd.forward(request, response); } @Override public void doGet(HttpServletRequest request ,HttpServletResponse response)throws IOException, ServletException{ int page = 1; generatePage(request, response, page); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException{ int page = Integer.valueOf(request.getParameter("page")); generatePage(request, response, page); }}
subPage.jsp
<%-- Created by IntelliJ IDEA. User: ehangzhou Date: 2017/2/18 Time: 13:14 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><%@ taglib uri ="http://java.sun.com/jsp/jstl/core" prefix="c" %><html><link rel="stylesheet" type="text/css" href="/static/SubPageStyle.css" /><head> <title>The SubPage of Application</title></head><script type="text/javascript"> function goTo(page) { var xmlhttp; if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function(){ var newDoc=document.open("text/html","replace"); newDoc.write(xmlhttp.response); newDoc.close(); } xmlhttp.open("POST",url = window.location.href,true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send("page=" + page); }</script><body style="background-image: url('/static/image/${subCategory}.jpg'); background-repeat:no-repeat; background-position: 100% 100%; background-color: lightgoldenrodyellow;"><h4>${subCategory}</h4><h4>显示视频数量${videoHashList.size()}</h4><c:forEach items="${videoHashList}" var="videoHash"> <div id = "video_area"> <a href="${videoHash.url}"><img src = "${videoHash.img}"></a> <br/> <font size="1" color="green">${videoHash.video_name}</font> </div> <br/></c:forEach><br/><br/><div id = "pageArea"><% for (int i = 1;i <= (int)request.getAttribute("pageTotalNum"); i++){ out.println("<button type=\"button\" onclick=goTo(" + String.valueOf(i) + ")>" + String.valueOf(i) + "</button>"); }%></div><br/></body></html>
0 0
- Webcollector + Spring + MVC 搭建应用初探(四)
- Webcollector + Spring + MVC 搭建应用初探(一)
- Webcollector + Spring + MVC 搭建应用初探(二)
- Webcollector + Spring + MVC 搭建应用初探(三)
- Webcollector + Spring + MVC 搭建应用初探(五)(Crab 推荐系统实例)
- Webcollector + Spring + MVC 搭建应用初探(六)(Lenskit 推荐系统实例)
- webcollector 初探(一)
- webcollector 初探(二)
- webcollector 初探(三)
- Spring搭建Web应用(MVC)起步(Tomcat环境)
- Spring MVC的初步搭建(应用篇)
- Spring mvc 环境搭建以及基本应用
- 初探Spring MVC
- Spring MVC初探
- Spring MVC(一)搭建
- Spring源代码解析(四):Spring MVC
- Spring源代码解析(四):Spring MVC
- Spring源代码解析(四):Spring MVC
- 微信小程序教程系列
- Leetcode——313. Super Ugly Number
- 搭建Ruby on Rails
- Qt creator 如何从.Ui文件中获取控件?类似findViewBy功能的实现
- 【H.264/AVC视频编解码技术详解】十三、熵编码算法(3):CAVLC原理
- Webcollector + Spring + MVC 搭建应用初探(四)
- linux的ssh登录
- 【Android开发】Dialog的使用
- svn和ftp的不同应用场合
- ubuntu安装phantomjs
- Codeforces 602B - Approximating a Constant Range(DP)
- 【Unity3d】UGUI小贴士:使用不规则按钮
- 2016-工作的第二年
- 问题六十三:怎么用ray tracing画sphere sweeping图形