JavaWeb_(视频网站)_五、视频模块1 视频上传
视频模块
保存视频流程图
提交博客页面 submit-post-blog.html
提交视频页面 submit-post-video.html
在上传视频请求@RequestMapping("/submitPostVideo")中添加数据
@RequestMapping("/submitPostVideo") public String submitPostVideo(Model model) { User user = (User)session.getAttribute("user"); baseDataUtils.getData(model, user.getId().toString() ); List<Catagory> catagoryList = catagoryService.findAllCatagory(); model.addAttribute("catagoryList",catagoryList); return "submit-post-video.html"; }
将提交视频页面submit-post-video.html前端页面相同功能模仿提交博客页面submit-post-blog.html
完善submit-post-video.html上传视频页面(二级分类->Tag->富文本->视频上传)
添加文本框,处理图片上传、表情包
添加一级分类,二级分类
在腾讯云控制台中获得访问视频上传权限的appid和appkey
通过videoSign()函数得到视频上传访问的权限
//得到签名 @RequestMapping("/videoSign") @ResponseBody public String videoSign() { Signature sign = new Signature(); sign.setSecretId("AKIDkNsDQWZOYYVSHu49kDh9Uh1FSo3BsnLm"); sign.setSecretKey("XDn1a3NWzN0Tp4vH3zpSp5fEX2Rq9KYg"); sign.setCurrentTime(System.currentTimeMillis() / 1000); sign.setRandom(new Random().nextInt(java.lang.Integer.MAX_VALUE)); sign.setSignValidDuration(3600 * 24 * 2); String signature = ""; try { signature = sign.getUploadSignature(); System.out.println("signature : " + signature); } catch (Exception e) { System.out.print("获取签名失败"); e.printStackTrace(); } return signature; }
package com.Gary.betobe.controller; import java.util.List; import java.util.Random; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.Gary.betobe.domain.Catagory; import com.Gary.betobe.domain.User; import com.Gary.betobe.service.CatagoryService; import com.Gary.betobe.utils.BaseDataUtils; import com.Gary.betobe.utils.Signature; @Controller public class VideoController { @Autowired private BaseDataUtils baseDataUtils; @Autowired private HttpSession session; @Autowired private CatagoryService catagoryService; //得到签名 @RequestMapping("/videoSign") @ResponseBody public String videoSign() { Signature sign = new Signature(); sign.setSecretId("AKIDkNsDQWZOYYVSHu49kDh9Uh1FSo3BsnLm"); sign.setSecretKey("XDn1a3NWzN0Tp4vH3zpSp5fEX2Rq9KYg"); sign.setCurrentTime(System.currentTimeMillis() / 1000); sign.setRandom(new Random().nextInt(java.lang.Integer.MAX_VALUE)); sign.setSignValidDuration(3600 * 24 * 2); String signature = ""; try { signature = sign.getUploadSignature(); System.out.println("signature : " + signature); } catch (Exception e) { System.out.print("获取签名失败"); e.printStackTrace(); } return signature; } @RequestMapping("/submitPostVideo") public String submitPostVideo(Model model) { User user = (User)session.getAttribute("user"); baseDataUtils.getData(model, user.getId().toString() ); List<Catagory> catagoryList = catagoryService.findAllCatagory(); model.addAttribute("catagoryList",catagoryList); return "submit-post-video.html"; } @RequestMapping("/singleVideoV2") public String singleVideoV1() { return "single-video-v2.html"; } }
<script type="text/javascript" th:inline="javascript"> //视频上传 function getSignature(){ var sign; alert("Gary getSign"); $.ajax({ url:[[@{~/videoSign}]], async:false, type:"POST", success:function(result) { sign = result; } }) return sign; } //获得签名 const tcVod = new TcVod.default({ getSignature:getSignature }) var videoFile; var coverFile; function videoFileChange(e) { //赋值Vodie videoFile = e.files[0]; $("#videoFileSpan").text(e.files[0].name); } function coverFileChange(e) { //赋值Cover coverFile = e.files[0]; $("#videoCoverSpan").text(e.files[0].name); } function uploadVOD(){ //上传 const uploader = tcVod.upload({ videoFile:videoFile, coverFile:coverFile, }) //事件的监听 //视频上传完成时 uploader.on('video_upload',function(info){ alert("success") }) //视频上传进度 uploader.on('video_progress',function(info){ }) } function catagoryClick(str,id) { //alert(str) //删除二级选项的节点 //获得父元素 var subCatagoryId = document.getElementById("subCatagoryId") //获得父元素下的所有子元素 var childs = subCatagoryId.childNodes; //删除,节点的索引会动态改变,所以我们从后往前删除 for(var i = childs.length - 1; i>=0; i--) { subCatagoryId.removeChild(childs[i]); } //切割str var subCatagory = new Array(); subCatagory = str.split("|"); //1,MAD for(var i = 0;i<subCatagory.length;i++) { var idList = new Array(); idList = subCatagory[i].split(",") //创建节点 var option = document.createElement("option"); //赋值 option.innerHTML = idList[1]; option.setAttribute("onclick","subCatagoryClick("+idList[0]+")") //添加节点 subCatagoryId.appendChild(option); } $("#catagoryIdInput").val(id); } function subCatagoryClick(id) { $("#subCatagoryIdInput").val(id); } </script>
前台submit-post-video.html上传视频及封面文件按钮点击事件
<div class="large-12 columns submit-post"> <div class="upload-video"> <label for="videoUpload" class="button">Upload File</label> <input onchange="videoFileChange(this)" required="required" type="file" id="videoUpload" class="show-for-sr"> <span id="videoFileSpan">No file chosen</span> </div> <br> <div class="upload-video"> <label for="imgUpload" class="button">Upload Cover</label> <input onchange="coverFileChange(this)" required="required" type="file" id="imgUpload" class="show-for-sr"> <span id="videoCoverSpan">No Cover chosen</span> </div> <br> <a href="javascript:void(0);" onclick="uploadVOD()" style="background: #656fc3;border-bottom: 3px solid #424da9" class="button"> Upload Video </a> </div>
javascript处理视频上传逻辑
<script type="text/javascript" th:inline="javascript"> //视频上传 function getSignature(){ var sign; alert("Gary getSign"); $.ajax({ url:[[@{~/videoSign}]], async:false, type:"POST", success:function(result) { sign = result; } }) return sign; } //获得签名 const tcVod = new TcVod.default({ getSignature:getSignature }) var videoFile; var coverFile; function videoFileChange(e) { //赋值Vodie videoFile = e.files[0]; $("#videoFileSpan").text(e.files[0].name); } function coverFileChange(e) { //赋值Cover coverFile = e.files[0]; $("#videoCoverSpan").text(e.files[0].name); } function uploadVOD(){ //上传 const uploader = tcVod.upload({ videoFile:videoFile, coverFile:coverFile, }) //事件的监听 //视频上传完成时 uploader.on('video_upload',function(info){ alert("success") }) //视频上传进度 uploader.on('video_progress',function(info){ }) } function catagoryClick(str,id) { //alert(str) //删除二级选项的节点 //获得父元素 var subCatagoryId = document.getElementById("subCatagoryId") //获得父元素下的所有子元素 var childs = subCatagoryId.childNodes; //删除,节点的索引会动态改变,所以我们从后往前删除 for(var i = childs.length - 1; i>=0; i--) { subCatagoryId.removeChild(childs[i]); } //切割str var subCatagory = new Array(); subCatagory = str.split("|"); //1,MAD for(var i = 0;i<subCatagory.length;i++) { var idList = new Array(); idList = subCatagory[i].split(",") //创建节点 var option = document.createElement("option"); //赋值 option.innerHTML = idList[1]; option.setAttribute("onclick","subCatagoryClick("+idList[0]+")") //添加节点 subCatagoryId.appendChild(option); } $("#catagoryIdInput").val(id); } function subCatagoryClick(id) { $("#subCatagoryIdInput").val(id); } </script>
需要再表单中给页面传递三个参数:videoUrl、coverImage、videoFileId
<input id="videoUrl" name="videoUrl" required="required" hidden="hidden"> <input id="videoFileId" name="videoFileId" required="required" hidden="hidden"> <input id="coverImage"name="coverImage" required="required" hidden="hidden">
<form data-abide novalidate> <div data-abide-error class="alert callout submit-post" style="display: none;"> <p><i class="fa fa-exclamation-triangle"></i> There are some errors in your form.</p> </div> <div class="row"> <div class="large-12 columns submit-post"> <label>Title <input type="text" placeholder="enter you video title..." required> <span class="form-error"> Yo, you had better fill this out, it's required. </span> </label> </div> <div class="large-12 columns submit-post"> <label>Meta keywords: <textarea placeholder="enter meta keywords"></textarea> </label> <p>IF you want to put your custom meta Keywords then put here otherwise your post Keywords will be the default meta Keywords</p> </div> <div class="large-12 columns"> <span class="submit-post"> <label>Description </label> </span> <!-- 富文本 --> <div class="summernote"></div> </div> <div class="large-12 columns submit-post"> <h6 class="borderBottom">Choose Video File And Cover:</h6> </div> <div class="large-12 columns submit-post"> <div class="upload-video"> <label for="videoUpload" class="button">Upload File</label> <input onchange="videoFileChange(this)" required="required" type="file" id="videoUpload" class="show-for-sr"> <span id="videoFileSpan">No file chosen</span> </div> <br> <div class="upload-video"> <label for="imgUpload" class="button">Upload Cover</label> <input onchange="coverFileChange(this)" required="required" type="file" id="imgUpload" class="show-for-sr"> <span id="videoCoverSpan">No Cover chosen</span> </div> <br> <a href="javascript:void(0);" onclick="uploadVOD()" style="background: #656fc3;border-bottom: 3px solid #424da9" class="button"> Upload Video </a> </div> <input id="videoUrl" name="videoUrl" required="required" hidden="hidden"> <input id="videoFileId" name="videoFileId" required="required" hidden="hidden"> <input id="coverImage"name="coverImage" required="required" hidden="hidden"> <div class="large-12 columns"> <div class="post-category submit-post"> <label>Choose Video Category: <select> <option th:each="catagory:${catagoryList}" th:onclick="catagoryClick([[${#setUtils.getSubCatagorys(catagory.subCatagorys)}]],[[${catagory.id}]])" th:text="${catagory.catagory}">one</option> </select> <input id="catagoryIdInput" name="catagoryId" type="text" style="display: none;" required="required"> </label> </div> <div class="post-category submit-post"> <label>Choose Video Sub-Category: <select id="subCatagoryId"> <option value="">one</option> <option value="">two</option> <option value="">three</option> </select> <input id="subCatagoryIdInput" name="subCatagoryId" type="text" style="display: none;" required="required" > </label> </div> </div> <div class="large-12 columns submit-post"> <label>Tags: <!-- 英文,隔开 --> <input name="tagsinput" id="tagsinputval" class="tagsinput" data-role="tagsinput" placeholder="输入后回车"/> </label> </div> <div class="large-12 columns submit-post"> <button class="button expanded" type="submit" name="submit">publish now</button> </div> </div> </form>
在页面添加一个进度条
<div class="upload-video"> <label for="imgUpload" class="button">Upload Cover</label> <input onchange="coverFileChange(this)" required="required" type="file" id="imgUpload" class="show-for-sr"> <span id="videoCoverSpan">No Cover chosen</span> </div> <br> <a href="javascript:void(0);" onclick="uploadVOD()" style="background: #656fc3;border-bottom: 3px solid #424da9" class="button"> Upload Video </a> <div class="skillbar css"> <span id="progressSpan" class="percent">70%</span> <div id="progressDiv" class="filled" data-width="70%"></div> </div>
在javascript中处理视频上传后完成的进度
function uploadVOD(){ //上传 const uploader = tcVod.upload({ videoFile:videoFile, coverFile:coverFile, }) //事件的监听 //视频上传完成时 uploader.done().then(function (doneResult) { $("#videoUrl").val(doneResult.video.url); $("#coverImage").val(doneResult.cover.url); $("#videoFileId").val(doneResult.fileId); $("#progressSpan").text("100%"); $("#progressDiv").width("100%"); layer.msg("上传视频成功!!"); }) //视频上传进度 uploader.on('video_progress', function(info) { var progress = info.percent * 100 + "%" //console.log(progress) $("#progressSpan").text(progress); $("#progressDiv").width(progress); }) }
<!doctype html> <html class="no-js" lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>BeTube video</title> <link rel="stylesheet" href="css/app.css"> <link rel="stylesheet" href="css/theme.css"> <link rel="stylesheet" href="css/font-awesome.min.css"> <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800' rel='stylesheet' type='text/css'> <link rel="stylesheet" type="text/css" href="layerslider/css/layerslider.css"> <link rel="stylesheet" href="css/owl.carousel.min.css"> <link rel="stylesheet" href="css/owl.theme.default.min.css"> <link rel="stylesheet" href="css/jquery.kyco.easyshare.css"> <link rel="stylesheet" href="css/responsive.css"> <!-- 富文本 --> <link rel="stylesheet" href="js/bootstrap3.3.5.css"> <link href="dist/summernote.css" rel="stylesheet" /> <!-- 标签 --> <link rel="stylesheet" type="text/css" href="css/css.css"/> <script src="js/jquery.js"></script> <script src="js/bootstrap3.3.5.js"></script> <script src="dist/summernote.js"></script> <!-- 中文--> <script src="dist/lang/summernote-zh-CN.js"></script> <!-- 视频SDK --> <script src="//unpkg.com/vod-js-sdk-v6"></script> <!--进度条--> <link rel="stylesheet" href="css/an-skill-bar.css"> <!-- 初始化summernote --> <script > var emojis; var emojiUrls; $.ajax({ url:'https://api.github.com/emojis', async:false }).then(function(data){ emojis = Object.keys(data); emojiUrls = data; }) $(function() { $('.summernote').summernote({ height : 200, tabsize : 2, lang : 'zh-CN', callbacks: { onImageUpload:function(files) { var formData = new FormData(); formData.append("file",files[0]); formData.append("summernote","videoSummernote"); $.ajax({ type:"POST", cache:false, url:"/uploadImageAJAX", data:formData, processData:false, contentType:false, dataType:"json", success:function(result) { $(".summernote").summernote("insertImage",result.summernoteImage,"xxx"); }, error:function(result) { alert("失败") } }) } }, hint:{ match: /:([\-+\w]+)$/, search:function(keyword,callback) { callback($.grep(emojis,function(item) { return item.indexOf(keyword) === 0; })) }, template:function(item) { var content = emojiUrls[item]; return '<img src="'+content+'" width="20" />:' +item+':'; }, content:function(item) { var url = emojiUrls[item]; if(url) { return $("<img />").attr("src",url).css("width",20)[0]; } return ''; } } }); }); </script> </head> <body> <div class="off-canvas-wrapper"> <div class="off-canvas-wrapper-inner" data-off-canvas-wrapper> <!--header--> <div th:replace="~{fragments/header::header}"></div> <!-- End Header --> <!--breadcrumbs--> <section id="breadcrumb"> <div class="row"> <div class="large-12 columns"> <nav aria-label="You are here:" role="navigation"> <ul class="breadcrumbs"> <li><i class="fa fa-home"></i><a href="#">Home</a></li> <li><a href="#">profile</a></li> <li> <span class="show-for-sr">Current: </span> submit post </li> </ul> </nav> </div> </div> </section><!--end breadcrumbs--> <!-- profile top section --> <section class="topProfile topProfile-inner" th:style="'background: url(/upload/'+${user.coverImage}+') no-repeat;'"> <div class="main-text"> <div class="row"> <div class="large-12 columns"> <h3>World’s Biggest</h3> <h1>Powerfull Video Theme</h1> </div> </div> </div> <div class="profile-stats"> <div th:replace="~{fragments/user-bar::userBar}"></div> </div> </section><!-- End profile top section --> <div class="row"> <!-- left sidebar --> <div class="large-4 columns"> <div th:replace="~{fragments/profile::profile}"></div> </div><!-- end sidebar --> <!-- right side content area --> <div class="large-8 columns profile-inner"> <!-- profile settings --> <section> <div class="row secBg"> <div class="large-12 columns"> <div class="heading submit-post"> <i class="fa fa-pencil-square-o"></i> <h4>Add new video post</h4> </div> <div class="row"> <div class="large-12 columns"> <form data-abide novalidate> <div data-abide-error class="alert callout submit-post" style="display: none;"> <p><i class="fa fa-exclamation-triangle"></i> There are some errors in your form.</p> </div> <div class="row"> <div class="large-12 columns submit-post"> <label>Title <input type="text" placeholder="enter you video title..." required> <span class="form-error"> Yo, you had better fill this out, it's required. </span> </label> </div> <div class="large-12 columns submit-post"> <label>Meta keywords: <textarea placeholder="enter meta keywords"></textarea> </label> <p>IF you want to put your custom meta Keywords then put here otherwise your post Keywords will be the default meta Keywords</p> </div> <div class="large-12 columns"> <span class="submit-post"> <label>Description </label> </span> <!-- 富文本 --> <div class="summernote"></div> </div> <div class="large-12 columns submit-post"> <h6 class="borderBottom">Choose Video File And Cover:</h6> </div> <div class="large-12 columns submit-post"> <div class="upload-video"> <label for="videoUpload" class="button">Upload File</label> <input onchange="videoFileChange(this)" required="required" type="file" id="videoUpload" class="show-for-sr"> <span id="videoFileSpan">No file chosen</span> </div> <br> <div class="upload-video"> <label for="imgUpload" class="button">Upload Cover</label> <input onchange="coverFileChange(this)" required="required" type="file" id="imgUpload" class="show-for-sr"> <span id="videoCoverSpan">No Cover chosen</span> </div> <br> <a href="javascript:void(0);" onclick="uploadVOD()" style="background: #656fc3;border-bottom: 3px solid #424da9" class="button"> Upload Video </a> <div class="skillbar css"> <span id="progressSpan" class="percent">0%</span> <div id="progressDiv" class="filled" data-width="0%"></div> </div> </div> <input id="videoUrl" name="videoUrl" required="required" hidden="hidden"> <input id="videoFileId" name="videoFileId" required="required" hidden="hidden"> <input id="coverImage"name="coverImage" required="required" hidden="hidden"> <div class="large-12 columns"> <div class="post-category submit-post"> <label>Choose Video Category: <select> <option th:each="catagory:${catagoryList}" th:onclick="catagoryClick([[${#setUtils.getSubCatagorys(catagory.subCatagorys)}]],[[${catagory.id}]])" th:text="${catagory.catagory}">one</option> </select> <input id="catagoryIdInput" name="catagoryId" type="text" style="display: none;" required="required"> </label> </div> <div class="post-category submit-post"> <label>Choose Video Sub-Category: <select id="subCatagoryId"> <option value="">one</option> <option value="">two</option> <option value="">three</option> </select> <input id="subCatagoryIdInput" name="subCatagoryId" type="text" style="display: none;" required="required" > </label> </div> </div> <div class="large-12 columns submit-post"> <label>Tags: <!-- 英文,隔开 --> <input name="tagsinput" id="tagsinputval" class="tagsinput" data-role="tagsinput" placeholder="输入后回车"/> </label> </div> <div class="large-12 columns submit-post"> <button class="button expanded" type="submit" name="submit">publish now</button> </div> </div> </form> </div> </div> </div> </div> </section><!-- End profile settings --> </div><!-- end left side content area --> </div> <!-- footer --> <div th:replace="~{fragments/footer::footer}"></div> <!--end off canvas content--> </div><!--end off canvas wrapper inner--> </div> <script src="layer/layer.js"></script> <!-- 进度条 --> <script src="js/an-skill-bar.js"></script> <script src="js/main.js"></script> <!-- 标签 --> <script src="js/tagsinput.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript" th:inline="javascript"> //视频上传 function getSignature(){ var sign; alert("Gary getSign"); $.ajax({ url:[[@{~/videoSign}]], async:false, type:"POST", success:function(result) { sign = result; } }) return sign; } //获得签名 const tcVod = new TcVod.default({ getSignature:getSignature }) var videoFile; var coverFile; function videoFileChange(e) { //赋值Vodie videoFile = e.files[0]; $("#videoFileSpan").text(e.files[0].name); } function coverFileChange(e) { //赋值Cover coverFile = e.files[0]; $("#videoCoverSpan").text(e.files[0].name); } function uploadVOD(){ //上传 const uploader = tcVod.upload({ videoFile:videoFile, coverFile:coverFile, }) //事件的监听 //视频上传完成时 uploader.done().then(function (doneResult) { $("#videoUrl").val(doneResult.video.url); $("#coverImage").val(doneResult.cover.url); $("#videoFileId").val(doneResult.fileId); $("#progressSpan").text("100%"); $("#progressDiv").width("100%"); layer.msg("上传视频成功!!"); }) //视频上传进度 uploader.on('video_progress', function(info) { var progress = info.percent * 100 + "%" //console.log(progress) $("#progressSpan").text(progress); $("#progressDiv").width(progress); }) } function catagoryClick(str,id) { //alert(str) //删除二级选项的节点 //获得父元素 var subCatagoryId = document.getElementById("subCatagoryId") //获得父元素下的所有子元素 var childs = subCatagoryId.childNodes; //删除,节点的索引会动态改变,所以我们从后往前删除 for(var i = childs.length - 1; i>=0; i--) { subCatagoryId.removeChild(childs[i]); } //切割str var subCatagory = new Array(); subCatagory = str.split("|"); //1,MAD for(var i = 0;i<subCatagory.length;i++) { var idList = new Array(); idList = subCatagory[i].split(",") //创建节点 var option = document.createElement("option"); //赋值 option.innerHTML = idList[1]; option.setAttribute("onclick","subCatagoryClick("+idList[0]+")") //添加节点 subCatagoryId.appendChild(option); } $("#catagoryIdInput").val(id); } function subCatagoryClick(id) { $("#subCatagoryIdInput").val(id); } </script> <!--end off canvas wrapper--> <!-- script files --> <script src="bower_components/jquery/dist/jquery.js"></script> <script src="bower_components/what-input/what-input.js"></script> <script src="bower_components/foundation-sites/dist/foundation.js"></script> <script src="js/jquery.showmore.src.js" type="text/javascript"></script> <script src="js/app.js"></script> <script src="layerslider/js/greensock.js" type="text/javascript"></script> <!-- LayerSlider script files --> <script src="layerslider/js/layerslider.transitions.js" type="text/javascript"></script> <script src="layerslider/js/layerslider.kreaturamedia.jquery.js" type="text/javascript"></script> <script src="js/owl.carousel.min.js"></script> <script src="js/inewsticker.js" type="text/javascript"></script> <script src="js/jquery.kyco.easyshare.js" type="text/javascript"></script> </body> </html>
接下来创建Video实体,封装基本字段和复杂字段
分析复杂字段
package com.Gary.betobe.domain; import java.util.HashSet; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.Lob; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; @Entity public class Video { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String title; @Lob private String content; private String keyword; private String createTime; private Integer viewNum; private Integer seconds; private String videoFileId; private String videoUrl; private String coverImage; //复杂字段 //视频属于的分类 @ManyToOne(targetEntity = Catagory.class) @JoinColumn(name = "catagory_id") private Catagory catagory; //视频属于的小分类 @ManyToOne(targetEntity = SubCatagory.class) @JoinColumn(name = "sub_catagory_id") private SubCatagory subCatagory; //发布视频的用户 @ManyToOne(targetEntity = User.class) @JoinColumn(name = "user_id") private User user; //视频中的标签 @ManyToMany @JoinTable( name = "video_tag", joinColumns = @JoinColumn(name = "video_id"), inverseJoinColumns = @JoinColumn(name="tag_id") ) private Set<Tag> videoTags = new HashSet<Tag>(); //JPA标准 protected Video() { } public Video(Long id, String title, String content, String keyword, String createTime, Integer viewNum, Integer seconds, String videoFileId, String videoUrl, String coverImage, Catagory catagory, SubCatagory subCatagory, User user, Set<Tag> videoTags) { super(); this.id = id; this.title = title; this.content = content; this.keyword = keyword; this.createTime = createTime; this.viewNum = viewNum; this.seconds = seconds; this.videoFileId = videoFileId; this.videoUrl = videoUrl; this.coverImage = coverImage; this.catagory = catagory; this.subCatagory = subCatagory; this.user = user; this.videoTags = videoTags; } public String getVideoUrl() { return videoUrl; } public void setVideoUrl(String videoUrl) { this.videoUrl = videoUrl; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getKeyword() { return keyword; } public void setKeyword(String keyword) { this.keyword = keyword; } public String getCreateTime() { return createTime; } public void setCreateTime(String createTime) { this.createTime = createTime; } public Integer getViewNum() { return viewNum; } public void setViewNum(Integer viewNum) { this.viewNum = viewNum; } public Integer getSeconds() { return seconds; } public void setSeconds(Integer seconds) { this.seconds = seconds; } public String getVideoFileId() { return videoFileId; } public void setVideoFileId(String videoFileId) { this.videoFileId = videoFileId; } public String getCoverImage() { return coverImage; } public void setCoverImage(String coverImage) { this.coverImage = coverImage; } public Catagory getCatagory() { return catagory; } public void setCatagory(Catagory catagory) { this.catagory = catagory; } public SubCatagory getSubCatagory() { return subCatagory; } public void setSubCatagory(SubCatagory subCatagory) { this.subCatagory = subCatagory; } public Set<Tag> getVideoTags() { return videoTags; } public void setVideoTags(Set<Tag> videoTags) { this.videoTags = videoTags; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
package com.Gary.betobe.domain; import java.util.HashSet; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; //大分类 @Entity public class Catagory { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String catagory; //大分类下的所有博客 @OneToMany(targetEntity = Blog.class) @JoinColumn(name="catagory_id") private Set<Blog> blogs = new HashSet<Blog>(); //该大分类下的所有小分类 @OneToMany(targetEntity = SubCatagory.class) @JoinColumn(name="catagory_id") private Set<SubCatagory> subCatagorys = new HashSet<SubCatagory>(); //该标签下的所有视频 @OneToMany(targetEntity = Video.class) @JoinColumn(name="catagory_id") private Set<Video> videos = new HashSet<>(); protected Catagory() { } public Catagory(Long id, String catagory, Set<Blog> blogs, Set<SubCatagory> subCatagorys, Set<Video> videos) { super(); this.id = id; this.catagory = catagory; this.blogs = blogs; this.subCatagorys = subCatagorys; this.videos = videos; } //@Override //public String toString() { // return "Catagory [id=" + id + ", catagory=" + catagory + ", blogs=" + blogs + ", subCatagorys=" + subCatagorys // + "]"; //} public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCatagory() { return catagory; } public void setCatagory(String catagory) { this.catagory = catagory; } public Set<Blog> getBlogs() { return blogs; } public void setBlogs(Set<Blog> blogs) { this.blogs = blogs; } public Set<SubCatagory> getSubCatagorys() { return subCatagorys; } public void setSubCatagorys(Set<SubCatagory> subCatagorys) { this.subCatagorys = subCatagorys; } public Set<Video> getVideos() { return videos; } public void setVideos(Set<Video> videos) { this.videos = videos; } }
package com.Gary.betobe.domain; import java.util.HashSet; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; //小分类 @Entity public class SubCatagory { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String subCatagory; //该小分类下的所有博客 @OneToMany(targetEntity = Blog.class) @JoinColumn(name="sub_catagory_id") private Set<Blog> blogs = new HashSet<Blog>(); //这个小分类属于哪一个大分类 @ManyToOne(targetEntity = Catagory.class) @JoinColumn(name="catagory_id") private Catagory catagory; @OneToMany(targetEntity = Video.class) @JoinColumn(name = "sub_catagory_id") private Set<Video> videos = new HashSet<>(); //小分类与标签,多对多 @ManyToMany @JoinTable( name="sub_catagory_tag", joinColumns = @JoinColumn(name = "sub_catagory_id"), inverseJoinColumns = @JoinColumn(name="tag_id") ) private Set<Tag> tags = new HashSet<Tag>(); protected SubCatagory() { } public SubCatagory(Long id, String subCatagory, Set<Blog> blogs, Catagory catagory, Set<Video> videos, Set<Tag> tags) { super(); this.id = id; this.subCatagory = subCatagory; this.blogs = blogs; this.catagory = catagory; this.videos = videos; this.tags = tags; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getSubCatagory() { return subCatagory; } public void setSubCatagory(String subCatagory) { this.subCatagory = subCatagory; } public Set<Blog> getBlogs() { return blogs; } public void setBlogs(Set<Blog> blogs) { this.blogs = blogs; } public Catagory getCatagory() { return catagory; } public void setCatagory(Catagory catagory) { this.catagory = catagory; } public Set<Tag> getTags() { return tags; } public void setTags(Set<Tag> tags) { this.tags = tags; } public Set<Video> getVideos() { return videos; } public void setVideos(Set<Video> videos) { this.videos = videos; } }
package com.Gary.betobe.domain; import java.util.HashSet; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; //标签 @Entity public class Tag { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String tag; //该标签下的所有博客 @ManyToMany(mappedBy = "blogTags") private Set<Blog> tagBlogs = new HashSet<Blog>(); //该标签下的所有小分类 @ManyToMany(mappedBy = "tags") private Set<SubCatagory> subCatagoryTage = new HashSet<SubCatagory>(); @ManyToMany(mappedBy = "videoTags") private Set<Video> tagVideos = new HashSet<>(); protected Tag() { } public Tag(Long id, String tag, Set<Blog> tagBlogs, Set<SubCatagory> subCatagoryTage, Set<Video> tagVideos) { super(); this.id = id; this.tag = tag; this.tagBlogs = tagBlogs; this.subCatagoryTage = subCatagoryTage; this.tagVideos = tagVideos; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTag() { return tag; } public void setTag(String tag) { this.tag = tag; } public Set<Blog> getTagBlogs() { return tagBlogs; } public void setTagBlogs(Set<Blog> tagBlogs) { this.tagBlogs = tagBlogs; } public Set<SubCatagory> getSubCatagoryTage() { return subCatagoryTage; } public void setSubCatagoryTage(Set<SubCatagory> subCatagoryTage) { this.subCatagoryTage = subCatagoryTage; } public Set<Video> getTagVideos() { return tagVideos; } public void setTagVideos(Set<Video> tagVideos) { this.tagVideos = tagVideos; } }
package com.Gary.betobe.domain; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.Lob; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; private String email; private String firstName; private String lastName; private String displayName; //个人首页 private String webUrl; private String phone; //个人描述 @Lob //长文本 ->lob对应mysql的数据类型 longtext private String description; //social Link private String qqLink; private String weixinLink; //封面头像 private String coverImage; //头像 private String headImage; //创建时间 private String createTime; //用户发的所有评论 @OneToMany(targetEntity = Comment.class) @JoinColumn(name = "user_id") private Set<Comment> comments = new HashSet<Comment>(); //用户发的博客 @OneToMany(targetEntity = Blog.class) @JoinColumn(name = "user_id") private Set<Blog> blogs = new HashSet<Blog>(); //用户发的视频 @OneToMany(targetEntity = Video.class) @JoinColumn(name="user_id") private Set<Video> videos = new HashSet<Video>(); //我关注了哪些用户 //该用户关注了哪些用户 在保存的时候,会级联保存所有临时对象 @ManyToMany(cascade = CascadeType.PERSIST) @JoinTable( name="user_follow", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "follow_id") ) private Set<User> follows = new HashSet<User>(); //用户,同意了哪些评论 @ManyToMany @JoinTable( name="agree_user_comment", joinColumns = @JoinColumn(name="user_id"), inverseJoinColumns = @JoinColumn(name = "comment_id") ) private Set<Comment> agreeComments = new HashSet<Comment>(); //用户,不同意了哪些评论 @ManyToMany @JoinTable( name="disagree_user_comment", joinColumns = @JoinColumn(name="user_id"), inverseJoinColumns = @JoinColumn(name="comment_id") ) private Set<Comment> disagreeComments = new HashSet<Comment>(); //用户同意了哪些回复 @ManyToMany @JoinTable( name="agree_user_reply", joinColumns = @JoinColumn(name="user_id"), inverseJoinColumns = @JoinColumn(name="reply_id") ) private Set<Reply> agreeReplys = new HashSet<Reply>(); //用户不同意了哪些回复 @ManyToMany @JoinTable( name="disagree_user_reply", joinColumns=@JoinColumn(name="user_id"), inverseJoinColumns = @JoinColumn(name="reply_id") ) private Set<Reply> disagreeReplys = new HashSet<>(); //JPA的标准 protected User() { } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", firstName=" + firstName + ", lastName=" + lastName + ", displayName=" + displayName + ", webUrl=" + webUrl + ", phone=" + phone + ", description=" + description + ", qqLink=" + qqLink + ", weixinLink=" + weixinLink + ", coverImage=" + coverImage + ", headImage=" + headImage + ", createTime=" + createTime + ", comments=" + comments + ", blogs=" + blogs + ", videos=" + videos + ", follows=" + follows + ", agreeComments=" + agreeComments + ", disagreeComments=" + disagreeComments + ", agreeReplys=" + agreeReplys + ", disagreeReplys=" + disagreeReplys + "]"; } public User(Long id, String username, String password, String email, String firstName, String lastName, String displayName, String webUrl, String phone, String description, String qqLink, String weixinLink, String coverImage, String headImage, String createTime, Set<Comment> comments, Set<Blog> blogs, Set<Video> videos, Set<User> follows, Set<Comment> agreeComments, Set<Comment> disagreeComments, Set<Reply> agreeReplys, Set<Reply> disagreeReplys) { super(); this.id = id; this.username = username; this.password = password; this.email = email; this.firstName = firstName; this.lastName = lastName; this.displayName = displayName; this.webUrl = webUrl; this.phone = phone; this.description = description; this.qqLink = qqLink; this.weixinLink = weixinLink; this.coverImage = coverImage; this.headImage = headImage; this.createTime = createTime; this.comments = comments; this.blogs = blogs; this.videos = videos; this.follows = follows; this.agreeComments = agreeComments; this.disagreeComments = disagreeComments; this.agreeReplys = agreeReplys; this.disagreeReplys = disagreeReplys; } public Set<Blog> getBlogs() { return blogs; } public void setBlogs(Set<Blog> blogs) { this.blogs = blogs; } public Set<Reply> getAgreeReplys() { return agreeReplys; } public void setAgreeReplys(Set<Reply> agreeReplys) { this.agreeReplys = agreeReplys; } public Set<Reply> getDisagreeReplys() { return disagreeReplys; } public void setDisagreeReplys(Set<Reply> disagreeReplys) { this.disagreeReplys = disagreeReplys; } public Set<Comment> getComments() { return comments; } public void setComments(Set<Comment> comments) { this.comments = comments; } public Set<Comment> getAgreeComments() { return agreeComments; } public void setAgreeComments(Set<Comment> agreeComments) { this.agreeComments = agreeComments; } public Set<Comment> getDisagreeComments() { return disagreeComments; } public void setDisagreeComments(Set<Comment> disagreeComments) { this.disagreeComments = disagreeComments; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getWebUrl() { return webUrl; } public void setWebUrl(String webUrl) { this.webUrl = webUrl; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getQqLink() { return qqLink; } public void setQqLink(String qqLink) { this.qqLink = qqLink; } public String getWeixinLink() { return weixinLink; } public void setWeixinLink(String weixinLink) { this.weixinLink = weixinLink; } public String getCoverImage() { return coverImage; } public void setCoverImage(String coverImage) { this.coverImage = coverImage; } public String getHeadImage() { return headImage; } public void setHeadImage(String headImage) { this.headImage = headImage; } public String getCreateTime() { return createTime; } public void setCreateTime(String createTime) { this.createTime = createTime; } public Set<User> getFollows() { return follows; } public void setFollows(Set<User> follows) { this.follows = follows; } public String getDisplayName() { return displayName; } public void setDisplayName(String displayName) { this.displayName = displayName; } public Set<Video> getVideos() { return videos; } public void setVideos(Set<Video> videos) { this.videos = videos; } }
VideoController.class接收封装视频请求@RequestMapping("saveVideo")
@RequestMapping("saveVideo") public String saveVideo(Video video,String tagsinput,String catagoryId,String subCatagoryId) { System.out.println("video" + video); System.out.println("tagsinput" + tagsinput); System.out.println("catagoryId" + catagoryId); System.out.println("subCatagoryId" + subCatagoryId); Catagory catagory = catagoryService.findCatagoryById(catagoryId); video.setCatagory(catagory); //封装小分类 SubCatagory subCatagory = subCatagoryService.findSubCatagoryById(subCatagoryId); //封装创建事件 Date date = new Date(System.currentTimeMillis()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm"); String createTime = format.format(date); video.setCreateTime(createTime); // tagsinput = tagsinput.toUpperCase(); //封装标签 String[] tags = tagsinput.split(","); Set<Tag> videoTags = new HashSet<>(); for(int i=0;i<tags.length;i++) { Tag tag = null; //如果标签不存在 if(tagService.findTagByTag(tags[i])==null) { tag = new Tag(null,tags[i],new HashSet<>(),new HashSet<>(),new HashSet<>()); //保存该标签 tag = tagService.saveTag(tag); } //如果标签存在 else { tag = tagService.findTagByTag(tags[i]); } //维护video与tag的关系 videoTags.add(tag); //维护subCatagory与tag之间的多对多关系 subCatagory.getTags().add(tag); tag.getSubCatagoryTage().add(subCatagory); } //维护video与小标签的关系 video.setSubCatagory(subCatagory); //维护video与tag的关系 video.setVideoTags(videoTags); //封装发布video的用户 User user = (User) session.getAttribute("user"); video.setUser(user); //封装浏览数目 video.setViewNum(0L); //保存video videoService.saveVideo(video); return "redirect:/index"; }
提交视频后,会将视频上传到数据库保存起来
(如需转载学习,请标明出处)