Webcollector + Spring + MVC 搭建应用初探(四)
2017-01-24 01:52
621 查看
本节的内容可以看作将Webcollector + Spring + MVC 搭建应用初探(三) 中的Python(Django MVC)
代码逻辑翻译成Java(Spring MVC) 的另一种实现 相应解释参看前者(python 基本就是伪代码)
所需要掌握的仅仅是Thymeleaf(看到这个词总是想到《疯城记》中的Tealeaf) 这种模板渲染语言 具体语法不进行叙述 可以与Django模板
渲染方式对比理解。
使用的maven依赖
主页面
mainPage.html
子页面
subpage.html
上述两个页面使用的样式基本与Django的相同不再给出 可参看前者。
子页面图片下载Thread类及页面Mapping类
由于静态图片需要在编译部署前进行下载,故在部署前如下单独运行了上述ImgThread(这也是两门语言或框架的不同)
当然还需要下面的起动代码
由于代码逻辑完全相同 故不再给出截图 简单页面效果参看
Webcollector + Spring + MVC 搭建应用初探(三)
使用MVC进行渲染的情形大致是这样,下面的工作将转移到搜索引擎及推荐系统上去。
有关推荐系统的初步实现可参看
Webcollector + Spring + MVC 搭建应用初探(五)
为了对照方便,下面给出上述过程在基本的Servlet及JSP语法下的实现,这里的一个不同是,子页面实现跳页。
mainPage.jsp
subPage.jsp
代码逻辑翻译成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(); } } } } @Controller public 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 = s 4000 tringArray[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. */ @SpringBootApplication public 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>
相关文章推荐
- 微服务框架Spring Cloud介绍 Part2: Spring Cloud与微服务
- 分享微信开发Html5轻游戏中的几个坑
- springmvc实现url路由功能
- spring aop 无法代理父类方法 的解决方法
- Spring MVC过滤器-超类 GenericFilterBean
- JSP/PHP基于Ajax的分页功能实现
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring和ThreadLocal
- Spring Boot 开发微服务
- Spring AOP动态代理-切面
- 开发阶段Jetty运行Jsp报错且响应空白
- 使用MVC微信支付返回get_brand_wcpay_request:fail
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)