上一篇博文介绍了注册和登录模块,未看过的人欢迎翻我之前博文~
接下来就进入登录成功后的主界面,这里主要实现主界面的基础布局和管理员管理模块=w=
GitHub地址:https://github.com/DaiPanda/Blog-of-Dai
照例有任何问题欢迎下方评论>3<
一、 后台主界面
1.1 图片演示
(默认进入博文管理的博文列表界面,这里暂时不介绍博文管理模块,以后会更)
1.2 详细分析
①登录成功后,登录的用户名将会显示在右上角,譬如刚刚那张图片的“胖达”
(使用session,之前登录成功后先是将登陆的adm对象保存在session中,再进行转发的,具体代码参考上一篇博文。
如果在index.jsp中获得对象为null,则代表未通过登录页面而是直接在地址栏中输入主页面的地址,这样会重定向到登录页面。)
图示如下:
②总的后台布局使用的是layui框架,主要是使用iframe实现页面的嵌套
(使用iframe标签,相关a标签中的target值对应iframe的name值)
图示如下:
③相关步骤如下:
第一步:通过layui的后台框架将index.jsp的大体结构搭好
第二步:对官方的后台框架进行修改,主要修改左侧导航栏的代码内容
第三步:使用iframe布局达到页面嵌套的效果,即点击不同的导航栏按钮右侧链接不同的页面
第四步:通过session判断是否经过了登录页面
1.3 目录结构
要想实现如图主界面,除了之前几篇博文写的准备工作以外,你还需要这样的目录结构
当然,之前的准备工作没有看的,建议从个人博客的第三篇博文看起
地址:https://blog.csdn.net/DaiYuMeng/article/details/104677362
1.4 详细代码
index.jsp文件:
<%@page import="pojo.Adm"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@include file="base.jsp"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1">
<title>熊猫后台</title>
<%
String name;
Adm a = (Adm) request.getSession().getAttribute("admin");
if (a == null) {
response.sendRedirect("login.jsp");
return;
} else {
name = a.getAdm_name();
}
%>
<style>
.layui-body {
border: none !important;
}
.mydiv {
width: 100%;
position: relative;
top: 0%;
left: 0%;
}
.myframe {
background-color: rgb(250, 250, 250);
position: relative;
top: 50%;
left: 50%;
margin-left: -550px;
}
</style>
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-header" style="background: skyblue; opacity: 0.7">
<div class="layui-logo">IPanda 博客后台管理系统</div>
<!-- 头部区域(可配合layui已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
<li class="layui-nav-item"><a href="">控制台</a></li>
<li class="layui-nav-item"><a href="">商品管理</a></li>
<li class="layui-nav-item"><a href="">用户</a></li>
<li class="layui-nav-item"><a href="javascript:;">其它系统</a>
<dl class="layui-nav-child">
<dd>
<a href="">邮件管理</a>
</dd>
<dd>
<a href="">消息管理</a>
</dd>
<dd>
<a href="">授权管理</a>
</dd>
</dl></li>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item"><a href="javascript:;"> <img
src="https://gss0.bdstatic.com/-4o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike272%2C5%2C5%2C272%2C90/sign=19ee1139ffdeb48fef64a98c9176514c/810a19d8bc3eb135d7ee3ce3aa1ea8d3fd1f44b9.jpg"
class="layui-nav-img"> <span id="uname"><%=name%></span>
</a>
<dl class="layui-nav-child">
<!--${ctx}/user/index.jsp -->
<dd>
<a href="#" target="myframe">基本资料</a>
</dd>
<dd>
<a href="">安全设置</a>
</dd>
</dl></li>
<li class="layui-nav-item"><a href="login.jsp">退了</a></li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item layui-nav-itemed"><a class=""
href="javascript:;">博文管理</a>
<dl class="layui-nav-child">
<dd>
<a href="${ctx}/article/listArticle.jsp" target="myframe">博文列表</a>
</dd>
<dd>
<a href="${ctx}/article/addArticle.jsp" target="myframe">添加博文</a>
</dd>
</dl></li>
<li class="layui-nav-item"><a href="javascript:;">评论管理</a>
<dl class="layui-nav-child">
<dd>
<a href="${ctx}/comment/listComment.jsp" target="myframe">评论列表</a>
</dd>
<%-- <dd><a href="${ctx}/comment/addComment.jsp" target ="myframe">添加评论</a></dd> --%>
</dl></li>
<li class="layui-nav-item"><a href="javascript:;">分类管理</a>
<dl class="layui-nav-child">
<dd>
<a href="${ctx}/category/listCategory.jsp" target="myframe">分类列表</a>
</dd>
<dd>
<a href="${ctx}/category/addCategory.jsp" target="myframe">添加分类</a>
</dd>
</dl></li>
<li class="layui-nav-item"><a href="javascript:;">标签管理</a>
<dl class="layui-nav-child">
<dd>
<a href="${ctx}/tag/listTag.jsp" target="myframe">标签列表</a>
</dd>
<dd>
<a href="${ctx}/tag/addTag.jsp" target="myframe">添加标签</a>
</dd>
</dl></li>
<li class="layui-nav-item"><a href="javascript:;">友链管理</a>
<dl class="layui-nav-child">
<dd>
<a href="${ctx}/friend/listFriend.jsp" target="myframe">友链列表</a>
</dd>
<dd>
<a href="${ctx}/friend/addFriend.jsp" target="myframe">添加友链</a>
</dd>
</dl></li>
<li class="layui-nav-item"><a href="javascript:;">管理员管理</a>
<dl class="layui-nav-child">
<dd>
<a href="${ctx}/adm/listAdm.jsp" target="myframe">管理员列表</a>
</dd>
<%-- <dd><a href="${ctx}/adm/addAdm.jsp" target ="myframe">添加管理员</a></dd> --%>
</dl></li>
</ul>
</div>
</div>
<div class="layui-body" style="background-color: rgb(250, 250, 250);">
<!-- 内容主体区域 -->
<div class="mydiv">
<iframe name="myframe" width="1100" height="728" frameborder="0"
class="myframe" src="article/listArticle.jsp"></iframe>
</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
© Daipanda.com - 使用layui框架
</div>
</div>
<script>
//JavaScript代码区域
layui.use('element', function() {
var element = layui.element;
});
</script>
</body>
</html>
二、管理员模块
1.1 图片演示
①管理员列表(含分页)
②编辑管理员
③删除管理员
1.2 详细分析
①管理员管理在左侧导航栏第六个管理的位置,相关具体代码在index.jsp中位置如下:
(总体代码在上方)
②listAdm.jsp是使用layui里的经典的数据表格布局,这就对他从后台传回来的数据有一定的要求,官网要求如下:
(详细介绍及扩展部分见官网:https://www.layui.com/doc/modules/table.html)
③layui的table布局中有三种渲染方法:方法渲染、自动渲染、静态表格渲染,这里使用的是方法渲染,要求如下:
cols里面各个field对应于每一列的表头,其field的值应该与后台传过来的属性变量名是一样的,这里我的命名和数据库中字段名也是一样的
(这里渲染的数据还可以使用自定义列模板templet,以后再更该用法)
④listAdm.jsp渲染数据表格时还使用了分页效果,相关步骤如下:
第一步:设置开启table的分页效果(page:true)
第二步:servlet层获取limit(默认10)和page(默认1)参数值
第三步:通过AdmDaoImpl.java里的getPageAdm(page,limit)方法返回相关管理员每页数据,是一个ArrayList对象
第四步:通过AdmDaoImpl.java里的getAllAdm()方法返回相关管理员总数,是一个int变量
代码图示如下:
⑤前台回调数据实现管理员列表时,具体来说接收的是符合一定规则的json数据,这里我掌握了两个方法
第一个方法:(1)先使用map集合,保存相关数据格式
(2)再利用google的json解析包将map格式转为string格式,google的json包目录如下,没有的可以私信我
(3)然后返回给前台,ajax回调时选择json格式就会自动把其转换为json格式
(我使用这个方法,但我觉得这个相对下面比较复杂)
第二个方法:也是先使用map存储数据,再利用json的jar包,首先你需要如下jar包,没有的可以私信我
代码图示如下:
⑥listAdm.jsp使用了layui经典的弹出层效果制作编辑管理员信息,图例如下:
操作步骤:根据满足条件的事件触发执行弹出层动画,弹出层由另外的页面(editAdm.jsp)组成
⑦综上,listAdm.jsp详细步骤如下
第一步:运用方法渲染的格式,其table的id值与渲染表格的elem值要对应
图示如下:
第二步:使用layui的数据表格table结构,在url里写入对应的数据接口(管理员列表的数据接口)
图示如下:
第二步:写入对应的工具条模板,就相当于操作模板,注意script的type值
图示如下:
第三步:监听工具条,layEvent对应
举例如下:
第四步:(1)点击某一项的编辑按钮时,它就触发监听工具条的事件,通过layEvent确定触发的是“编辑”事件
(2)利用弹出层的content属性,走到servlet层,同时将adm_id传回去
(3)它获取adm_id是通过data.adm_id的方法,因为之前渲染数据时数据接口返回的值都存在data里头
图示如下:
(4)它先走selectAdm这个控制层的接口,然后从Dao层的getOneAdm()通过adm_id读取对应的一条管理员的数据,返回的是Adm对象,将其对应信息保存在request属性中,最后再将数据转发到editAdm.jsp页面
图示如下:
(5)编辑弹出层主要是利用layui的form组件,利用getAttribute()方法获得上一步存储的属性值
图示如下:
第五步:(1)点击某一项的删除按钮时,它就触发监听工具条的事件,通过layEvent确定触发的是“删除”事件
(2)利用layui提供的confirm弹出对话框,提示用户执行下一步操作
(3)当用户点击“确定”时,先删除对应行的DOM结构(假删除),再通过ajax向服务端发送删除指令,调用delAdm接口,传过去adm_id(真删除)
图示如下:
(4)在delAdm接口中,先获得传过来的id,再利用Dao层的deleteAdm(int id)方法,这个方法返回一个boolean值
(5)将这个boolean值返回给前端,然后前端通过这个值判断是否删除成功,删除成功就会弹出“删除成功”提示
图示如下:
1.3 具体代码
首先,Adm.java、AdmDao.java以及AdmDaoImpl.java等已经在上一篇博文里详细写了,这里就不赘述了
①src-->在servlet包里-->新建一个Servlet文件,命名为ListAdm-->在URL mappings中改名为/listAdm-->键入代码,如下
ListAdm.java
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
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 org.json.JSONArray;
import org.json.JSONObject;
import com.google.gson.JsonObject;
import dao.AdmDao;
import dao.AdmDaoImpl;
import pojo.Adm;
import util.JsonUtil;
/**
* Servlet implementation class ListAdm
*/
@WebServlet("/listAdm")
public class ListAdm extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ListAdm() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int limit = 0;
int page = 0;
PrintWriter writer = null;
try {
limit = Integer.parseInt(request.getParameter("limit"));
page = Integer.parseInt(request.getParameter("page"));
AdmDao a = new AdmDaoImpl();
ArrayList<Adm> aList = a.getPageAdm(page, limit);
ArrayList<Adm> aListTotal = a.getAllAdm();
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", 0);
map.put("msg", "");
map.put("count", aListTotal.size());
map.put("data", aList);
//String jsonStr = JsonUtil.beanToString(map);
//writer.write(jsonStr);
writer= response.getWriter();
net.sf.json.JSONObject jsonStr = net.sf.json.JSONObject.fromObject(map);
writer.print(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);
}
}
②src-->在servlet包里-->新建一个Servlet文件,命名为SelectAdm-->在URL mappings中改名为/selectAdm-->键入代码,如下
SelectAdm.java
package servlet;
import java.io.IOException;
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 dao.AdmDao;
import dao.AdmDaoImpl;
import dao.CategoryDao;
import dao.CategoryDaoImpl;
import pojo.Adm;
import pojo.Category;
/**
* Servlet implementation class SelectAdm
*/
@WebServlet("/selectAdm")
public class SelectAdm extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public SelectAdm() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
int adm_id = Integer.parseInt(request.getParameter("adm_id"));
AdmDao a = new AdmDaoImpl();
Adm adm = a.getOneAdm(adm_id);
if(adm!=null) {
request.setAttribute("adm_id", adm.getAdm_id());
request.setAttribute("adm_name",adm.getAdm_name());
request.setAttribute("adm_password", adm.getAdm_passward());
request.getRequestDispatcher("adm/editAdm.jsp").forward(request, response);//转发到成功页面
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @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);
}
}
③src-->在servlet包里-->新建一个Servlet文件,命名为EditAdm-->在URL mappings中改名为/editAdm-->键入代码,如下
EditAdm.java
package servlet;
import java.io.IOException;
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 dao.AdmDao;
import dao.AdmDaoImpl;
import pojo.Adm;
/**
* Servlet implementation class EditAdm
*/
@WebServlet("/editAdm")
public class EditAdm extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public EditAdm() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result = "false";
PrintWriter writer = null;
try {
int adm_id = Integer.parseInt(request.getParameter("adm_id"));
String adm_name = request.getParameter("adm_name");
String adm_password = request.getParameter("adm_password");
Adm adm = new Adm();
adm.setAdm_id(adm_id);
adm.setAdm_name(adm_name);
adm.setAdm_passward(adm_password);
AdmDao a = new AdmDaoImpl();
boolean flag = a.updateAdm(adm);
System.out.println(flag);
if(flag) {
result ="true";
}
writer = response.getWriter();
writer.write(result);
}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);
}
}
④在WebContent的adm目录下-->新建jsp文件,命名为listAdm.jsp-->键入代码,如下
listAdm.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">
<link href="../css/base.css" rel="stylesheet" media="screen" />
<title>管理员列表</title>
</head>
<body>
<div id="box">
<table id="demo" lay-filter="test"></table>
</div>
</body>
<!-- 这里实现了分页效果 -->
<script>
layui.use('table', function() {
var table = layui.table;
//开始渲染表格
table.render({
elem : '#demo',//要渲染的表格id
height : 480,//表格的高度
width : 635,//表格的宽度
url : '${ctx}/listAdm', //数据接口
page : true, //开启分页
cols : [ [ //表头
{
field : 'adm_id',
title : 'ID',
width : 80,
sort : true,
fixed : 'left'
},
{
field : 'adm_name',
title : '管理员昵称',
width : 160,
},
{
field : 'adm_password',
title : '管理员密码',
width : 210
}, {
title : '操作',
toolbar : '#barDemo',
width : 180
} ] ],
done:function(res){
//如果是异步请求数据方式,res即为你接口返回的信息
console.log(res);
}
});
//监听工具条
table.on('tool(test)', function(obj) { //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"
var data = obj.data; //获得当前行数据
var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
var tr = obj.tr; //获得当前行 tr 的DOM对象
if (layEvent === 'detail') { //查看
/*
后来可以查看父id的值
*/
layer.msg("你今天真好看!!", {
icon : 1
});
} else if (layEvent === 'del') { //删除
layer.confirm('真的删除该管理员么??', function(index) {
obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
layer.close(index);
//向服务端发送删除指令
$.post("${ctx}/delAdm", {
adm_id : data.adm_id
}, function(result) {
if (result) {
layer.msg("删除成功!!", {
icon : 1
});
table.reload('demo');
}
}, "json");
});
layer.close(index);
} else if (layEvent === 'edit') { //编辑
//弹出层
layer.open({
title : ["编辑管理员","text-align:center"],
type : 2,
offset : [ "80px" ],//位置
area : [ "500px", "220px" ],//大小
content : ['${ctx}/selectAdm?adm_id=' + data.adm_id,"no"], //这里content是一个URL,如果你不想让iframe出现滚动条,你还可以content: ['http://sentsin.com', 'no']
anim:1,
//当窗口关闭时执行
end : function() {
table.reload('demo');
}
});
}
});
});
</script>
<!--工具条模板 -->
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-xs" lay-event="detail">查看</a>
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
</html>
⑥在WebContent的adm目录下-->新建jsp文件,命名为editAdm.jsp-->键入代码,如下
editAdm.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>
</head>
<body>
<!-- session由服务器产生,保存在服务器的内存中,sessionid会返回给客户端 -->
<%
int adm_id = (int)request.getAttribute("adm_id");
String adm_name = (String)request.getAttribute("adm_name");
String adm_password = (String)request.getAttribute("adm_password");
%>
<form class="layui-form" action="">
<!-- hidden = "hidden" -->
<input value = "<%=adm_id %>" hidden = "hidden" id = "tid">
<div class="layui-form-item">
<label class="layui-form-label">管理员名:</label>
<div class="layui-input-inline" style="width: 200px;">
<input type="text" name="title" lay-verify="title"
autocomplete="off" placeholder="请输入管理员名称" class="layui-input"
id="adm_name" name="adm_name" value = "<%=adm_name%>">
<span id="tip" style="color:red;margin-top:20px;"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">管理员密码:</label>
<div class="layui-input-inline" style="width: 200px;">
<input type="text" name="title" lay-verify="title"
autocomplete="off" placeholder="请输入管理员密码" class="layui-input"
id="adm_password" name="adm_password" value = "<%=adm_password%>">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<div class="layui-btn" lay-submit="" lay-filter="demo1" id="sub">立即提交</div>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
<script type="text/javascript">
layui.use([ 'layer' ], function() {
var isOk = false;
$("#adm_name").blur(function(){
if ($("#adm_name").val() == "") {
layer.msg("不能输入为空哦!", {
icon : 2
});
return;
}else {
$.post('isExist',
{
username : $('#adm_name').val()
},
function(result) {
//alert(typeof result);
if(result=="true"){
//alert(1);
isOk = false;
//利用jquery对元素设置样式
$('#username').css("border", "1px solid red");
$('#tip').html('该用户已存在');
$('#tip').css("color", "red");
return;
}else{
//alert(2);
isOk = true;
//利用jquery对元素设置样式
$('#username').css("border", "1px solid gray");
//html() 设置标签之间的 内容
$('#tip').html('该用户名可用');
$('#tip').css("color", "green");
}
}, "text");
}
});
$("#sub").click(function(){
if (!isOk) {
layer.msg("管理员名是唯一的哦!", {
icon : 2
});
return;
}else{
$.post("${ctx}/editAdm",//后台地址
{
adm_password : $("#adm_password").val(),
adm_name : $("#adm_name").val(),
adm_id : $("#tid").val()
},//需要提交到后台的数据
function(result) {
if (result) {
//修改成功
layer.msg("修改成功", {
icon : 1
});
//假设这是iframe页
var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
parent.layer.close(index); //再执行关闭
}
},//回调函数
"json");
}
});
});
</script>
</body>
</html>
1.4 易错点分析之转发与重定向的区别
(1)转发地址栏不会发生变化,显示的依然是上一个地址栏的地址
(2)转发一般带ServletRequest和Servletresponse对象过去,所以数据不会丢失
(3)重定向地址栏会发生变化
(4)重定向没有带数据过去,即数据会丢失
如果有任何问题,欢迎在下方留言~
我如果看到了就一定会回复的=w=
注:GitHub下载地址在文章顶部,也传到了csdn下载上面,希望能对你有所帮助;
也欢迎关注我的个人微信公众号【大胖猫的马太效应】,回复关键字JavaWeb博客后台管理系统获得本后台项目所有源码噢~