您的位置:首页 > 编程语言 > Java开发

Webcollector + Spring + MVC 搭建应用初探(四)

2017-01-24 01:52 621 查看
本节的内容可以看作将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();
}
}
}
}

@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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息