建議從第三篇博文開始看起:https://blog.csdn.net/DaiYuMeng/article/details/104677362
有任何問題歡迎下方留言=w=
一、界面圖
二、難點分析
難點一:“上傳封面圖”按鈕點擊時,選擇了本地圖片後,下方要出現你選擇的圖片
(1)在該按鈕下方放入img標籤,display屬性設置爲none
(2)調用layui的upload方法
(3)upload接口
①點擊“上傳封面圖”按鈕,在本地選擇一張圖片,該圖片通過upload接口會上傳到服務器上
②然後再返回一個路徑returnPath給前臺,即該圖片的路徑(部分路徑),例子如圖:
③然後再在前面加在服務器前綴地址形成http://localhost:8080/MyBlog/upload/returnPath
(即完整的該圖片在服務器上的地址)
④如果你想查找其在本地路徑上的地址,你可以通過getServletContext()方法,我將先在WebContent目錄下新建了一個upload文件夾,所以我具體獲得路徑是使用如圖方法:
難點二:選擇父分類時,子分類聯動出現選項
(1)注意這是動態獲取後臺的數據,不是前臺固定寫好的
(2)然後獲取一級分類,調用相關接口
(3)然後獲取二級分類,使用form.on()的方法,myFirstSelect爲佈局中lay-filter的屬性值
難點三:顯示富文本編輯器,並保證提交後相關格式也會存儲在數據庫中
(1)從百度編輯器umedit的官網下載好jsp的壓縮包並解壓,放置到項目中,在文件下引入相關js文件
還有ueditor.all.js和controller.jsp中會涉及參數的修改,這個比較簡單,具體的可以百度一下,或下載我的項目查看一下
(2)進行佈局設置,注意id值爲editor,id值可以隨意設置
(3)初始化富文本編輯器
(4)使用UE.getEditor('editor').getContent方法獲取內容(含h5格式)
難點四:保證提交後,標籤選擇一項後臺存儲一項,選擇兩項後臺存儲兩項,三項同理
(由於博文和標籤是多對多的關係,故除了博文表和標籤表外還多了一張表,是博文和標籤之間的關聯表)
(1)佈局,第二個標籤和第三個標籤都有一個option,默認爲不選擇
(2)調用相關方法,顯示數據
(3)保證選擇多項時,不會選擇到重複項
(4)進入提交表單時的addArticle接口,先將其它項插入博文的表中,待成功後再進行判斷,插入博文與標籤的關聯表中
三、代碼
由於這個涉及的代碼太多了,如果有需要可以下載查看,我就放上一些我覺得容易出錯的
Upload.java(處理圖片下載文件的接口)
package servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
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 javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import pojo.Data;
import util.JsonUtil;
/**
* Servlet implementation class Upload
*/
@WebServlet("/upload")
public class Upload extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Upload() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 後臺最後進行一個判斷
* 1.判斷文件大小
* 2.判斷文件寬和高的比值
* 3.上傳失敗進行提示
* 4.通過map.put("msg","xxxxx")將值傳過來
* 5.進行文件擴展名判斷
* **/
PrintWriter writer = null;
//1.得到上傳文件的保存目錄
String savePath = this.getServletContext().getRealPath("/upload");
//ps.這個就是上傳文件夾在本地的服務器路徑
System.out.println("savePath:"+savePath);
String returnPath;
File file = new File(savePath);
//2.判斷上傳文件的保存目錄是否存在
// 如果目錄不存在或者目錄是文件
if(!file.exists()&&!file.isDirectory()) {
System.out.println(savePath+"目錄不存在,需要創建");
//3.創建目錄
file.mkdir();
}
try {
//4.使用apache文件上傳組件處理文件步驟
//4.1 創建一個DiskFileItemFactory
DiskFileItemFactory factory = new DiskFileItemFactory();
//4.2 創建一個文件上傳解碼器
ServletFileUpload upload = new ServletFileUpload(factory);
//4.3解決上傳文件名的中文亂碼
upload.setHeaderEncoding("UTF-8");
//4.4 判斷提交上來的數據是否是上傳表單的數據
if(!ServletFileUpload.isMultipartContent(request)) {
return;
}
//5.使用ServletFileUpload解析器上傳數據
List<FileItem> list = upload.parseRequest(request);
//6.遍歷 處理文件
for(FileItem item:list) {
String filename = item.getName();
if(filename==null||filename.trim().equals("")) {
continue;
}
System.out.println(filename);
//注意:不同的瀏覽器提交的文件名是不一樣的,有些瀏覽器提交上來的文件名是帶有路徑的,如: c:\a\b\1.txt,而有些只是單純的文件名,如:1.txt
//處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分
filename = filename.substring(filename.lastIndexOf("\\") + 1);
//獲取item中的上傳文件的輸入流
InputStream in = item.getInputStream();
//創建一個文件輸出流
returnPath = filename;
FileOutputStream out = new FileOutputStream(savePath+"\\"+filename);
//創建一個緩衝區
byte buffer[] = new byte[1024];
//判斷輸入流中的數據是否已經讀完的標識
int len = 0;
//循環將輸入流讀入到緩衝區當中,(len=in.read(buffer))>0就表示in裏面還有數據
while ((len = in.read(buffer)) > 0) {
//System.out.println("是否寫入進了服務器!!!");
out.write(buffer, 0, len);
}
//關閉輸入流
in.close();
//關閉輸出流
out.close();
//刪除處理文件上傳時生成的臨時文件
item.delete();
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", 0);
map.put("msg", "我從upload的servlet中返回了");
Data data = new Data();
data.setReturnPath(returnPath);
map.put("data", data);
String jsonStr = JsonUtil.beanToString(map);
writer= response.getWriter();
writer.write(jsonStr);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
writer.flush();
writer.close();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
addArticle.jsp(增加博文頁面)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@include file="../base.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>增加博文</title>
<style type="text/css">
#box {
width: 1000px;
margin-left: auto;
margin-right: auto;
background-image: url(../css/image/18.gif);
padding: 20px;
opacity: 0.8;
}
.layui-form-select dl {
z-index: 1999;
}
</style>
</head>
<body>
<div id="box">
<form class="layui-form" action="" enctype="multipart/form-data"
id="myform">
<!-- <h3 style="text-align:center;margin-bottom:20px;text-shadow:1px 1px 2px red;">增加博文</h3> -->
<div class="layui-form-item">
<label class="layui-form-label">文章標題</label>
<div class="layui-input-block" style="width: 420px;">
<input type="text" name="title" required lay-verify="required"
placeholder="請輸入標題" autocomplete="off" class="layui-input"
id="article_title">
</div>
</div>
<div class="layui-form-item" style="z-index: 1999px;">
<label class="layui-form-label">文章分類</label>
<div class="layui-input-inline" style="width: 180px;">
<select name="first_category" lay-verify="required"
id="first_category" lay-filter="myFirstSelect">
<option value=""></option>
</select>
</div>
<div class="layui-input-inline" style="width: 180px;">
<select name="second_category" lay-verify="required"
id="second_category" lay-filter="mySecondSelect">
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">置頂</label>
<div class="layui-input-block">
<input type="radio" name="isTop" value="是" title="是"> <input
type="radio" name="isTop" value="否" title="否" checked>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<!-- 在這裏放一個img標籤 默認不顯示 -->
<button type="button" class="layui-btn" id="test1">
<i class="layui-icon"></i>上傳封面圖
</button>
<!-- style="display:none;" -->
<div style="height: 20px; width: 100%;"></div>
<img src="" id="article_image" class="article_image"
style="display: none; margin-top: 20px;"></img>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文章內容</label>
<div class="layui-input-block">
<div id="editor" name="article_content"
style="width: 900px; height: 400px;"></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">標籤</label>
<div class="layui-input-inline" style="width: 150px;">
<select name="tag1" id="tag1" lay-verify="" lay-search>
</select>
</div>
<div class="layui-input-inline" style="width: 150px;">
<select name="tag2" id="tag2" lay-verify="" lay-search>
<option id="0">可不選</option>
</select>
</div>
<div class="layui-input-inline" style="width: 150px;">
<select name="tag3" id="tag3" lay-verify="" lay-search>
<option id="0">可不選</option>
</select>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">博文簡介</label>
<div class="layui-input-block">
<textarea placeholder="請輸入內容" class="layui-textarea"
id="article_desc"></textarea>
</div>
</div>
<div class="layui-form-item" style="margin-top: 50px;">
<div class="layui-input-block">
<button class="layui-btn" type="button" lay-submit
lay-filter="formDemo">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary"
style="margin-left: 12%;">重置</button>
</div>
</div>
</form>
</div>
</body>
<script>
function getFirstCategory() {
//alert("1-進入了getFirstCategory的方法");
$.post("${ctx}/getFirstCategory", {}, function(result) {
with (result) {
for (var i = 0; i < data.length; i++) {
var option = "<option id="+data[i].category_id+">"
+ data[i].category_name + "</option>";
$("#first_category").append(option);
layui.form.render('select');
}
}
}, "json");
$.ajaxSetup({
cache : false
});
}
function getFirstTag() {
$.post("${ctx}/getFirstTag", {}, function(result) {
with (result) {
for (var i = 0; i < data.length; i++) {
var option = "<option id="+data[i].tag_id+">"
+ data[i].tag_name + "</option>";
$("#tag1").append(option);
$("#tag2").append(option);
$("#tag3").append(option);
layui.form.render('select');
}
}
}, "json");
$.ajaxSetup({
cache : false
});
}
layui.use('form', function() {
//1.初始化form表單
var form = layui.form;
//2.初始化富文本編輯器
var ue = window.UE.getEditor('editor');
//3.獲得一級分類
getFirstCategory();
//補充之獲得標籤(最少選擇一個,最多選擇三個)
getFirstTag();
//4.獲得二級分類
form.on('select(myFirstSelect)', function(data2) {
var category_id = $("#first_category :selected").attr("id");
$.post("${ctx}/getSecondCatgegory", {
parent_id : category_id
}, function(result) {
with (result) {
$("#second_category").html("");
for (var i = 0; i < data.length; i++) {
//alert("2-測試進入了嗎")
var option = "<option id="+data[i].category_id+">"
+ data[i].category_name + "</option>";
$("#second_category").append(option);
layui.form.render('select');
}
}
}, "json");
$.ajaxSetup({
cache : false
});
layui.form.render('select');
});
//監聽提交
form.on('submit(formDemo)', function(data) {
var tag_id1 = $("#tag1 :selected").attr("id");
var tag_id2 = $("#tag2 :selected").attr("id");
var tag_id3 = $("#tag3 :selected").attr("id");
var category_id = $("#second_category :selected").attr("id");
var article_title = $("#article_title").val();
var article_desc = $("#article_desc").val();
var article_content = UE.getEditor('editor').getContent();
var article_image = $("#article_image").attr("src");
var article_isTop_name = $('input[name="isTop"]:checked').val();
if (article_isTop_name == '是') {
var article_isTop = 1;
} else {
var article_isTop = 0;
}
if(tag_id2==tag_id3&&tag_id2!=0){
layer.msg("不能多次選擇同一個標籤哦!", {
icon : 2
});
return;
}
if (tag_id1 === tag_id2 || tag_id1 === tag_id3) {
layer.msg("不能多次選擇同一個標籤哦!", {
icon : 2
});
return;
}
if (article_image == "") {
layer.msg("一定要上傳封面圖哦!", {
icon : 2
});
return;
}
if(article_desc==""){
layer.msg("博文簡介不能爲空哦!", {
icon : 2
});
return;
}
// 1.檢查是否提交了必填項
$.post("${ctx}/addArticle",//後臺地址
{
article_title : article_title,
article_desc : article_desc,
article_content : article_content,
article_image : article_image,
article_isTop : article_isTop,
tag_id1 : tag_id1,
tag_id2 : tag_id2,
tag_id3 : tag_id3,
category_id : category_id
},//需要提交到後臺的數據
function(result) {
if (result) {
//添加成功
alert("添加成功");
layer.msg("添加成功", {
icon : 1
});
document.getElementById("myform").reset();
} else {
layer.msg("添加失敗", {
icon : 2
});
}
},//回調函數
"json");
});
});
let UPLOAD_FILES;
layui.use('upload', function() {
var upload = layui.upload;
//提示用戶上傳圖片不可以太大了
//執行實例
var uploadInst = upload.render({
elem : '#test1' //綁定元素
,
url : '${ctx}/upload' //上傳接口
,
exts : 'jpg|png|jpeg' //可傳輸文件的後綴
,
accept : 'file' //video audio images
,
done : function(res) {
//上傳完畢回調
if (res.code == 0) {
var returnPath = res.data.returnPath;
console.log(returnPath);
$("#article_image")
.attr(
"src",
"http://localhost:8080/MyBlog/upload/"
+ returnPath);
$("#article_image").attr("style",
"display:block;width:135px;height:180px;");
}
},
error : function() {
//請求異常回調
//比如生成一個“重新上傳”的按鈕
}
});
});
</script>
<script type="text/javascript" src="${ctx}/js/umedit/ueditor.config.js"></script>
<script type="text/javascript" src="${ctx}/js/umedit/ueditor.all.min.js"></script>
<script type="text/javascript"
src="${ctx}/js/umedit/lang/zh-cn/zh-cn.js"></script>
</html>