JavaWeb个人博客项目:手把手教你实现博客后台系统之添加博文8

建议从第三篇博文开始看起: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">&#xe67c;</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>

最后,如果有任何问题欢迎在下方给我留言,我看到的话就会回复哒=w=

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章