SSM初入门(四)标准SSM框架增删改查功能实现
1.解决的问题
java.lang.NoClassDefFoundError: org/springframework/core/SmartClassLoader
这个问题是在web包的pom.xml出现红字用ALT+enter改错导致的,会导致在pom中加载了更高版本的 org/springframework/core,解决方法是把web包中的pom的 dependency的org/springframework/core删掉
只留下总包的pom.xml加载它带的 org/springframework/core即可。
2.方法实现
Java层与之前的差不多,主要对controller层参数,跳转进行设置,还有是在jsp页面进行修改,比如form action添加相对路径等。
3.监听器 过滤器
JavaWeb中,监听器是一种组件,能够监听项目的启动和停止,用户会话的创建和销毁,以及各种组件的添加、更新和删除,能够通过监听对象的状态改变,自动做出反应执行响应代码。
应用场景:启动网站后进行初始化、检测用户的数量等。
常用的监听器接口:
ServletContextListener 监听项目的启动和停止
方法:
contextInitialized 项目加载完成
contextDestroyed 项目停止
HttpSessionListener 监听用户会话的创建和销毁
sessionCreated 每一个用户第一次访问时调用
sessionDestroyed 每个用户退出系统后调用
监听器的配置:
方式1 web.xml
listener
listener-class包名+类名/listener-class
/listener
方式2 注解
@WebListener
案例:监听网站的启动
/**
* 项目的监听器
* @author chenheng
*
*/
@WebListener
public class WebApplicationListenerimplements ServletContextListener{
//项目启动
@Override
public voidcontextInitialized(ServletContextEvent sce) {
System.out.println(项目启动了!!!!);
//保存一些数据到项目中
sce.getServletContext().setAttribute(money, 999999);
}
//项目停止
@Override
public voidcontextDestroyed(ServletContextEvent sce) {
System.out.println(项目停止了!!!!!);
}
}
过滤器
能够对网站中的各种内容进行过滤(页面、Servlet、图片、文件),可以在网站内容请求和响应时进行一些操作,完成一些通用的功能。
过滤器链
在项目中可以创建多个过滤器,网站内容可能会经过多个过滤器,多个过滤器就形成了过滤器链。
实现方法:
1、实现Filter接口
init 初始化
doFilter 进行过滤
参数:
ServletRequest 请求
ServletResponse 响应
FilterChain 过滤器链
//让请求通过,执行下一个过滤器,如果不执行这个方法,请求就被拦截
chain.doFilter(request, response);
destroy 销毁
2、配置
web.xml
<!-- 配置过滤器 -->
filter
filter-nameFilter1/filter-name
filter-classcom.qianfeng.filters.Filter1/filter-class
/filter
filter-mapping
filter-nameFilter1/filter-name
url-pattern/*/url-pattern
/filter-mapping
过滤器执行的顺序:
如果是注解配置的,按名字顺序进行执行
如果是web.xml配置的,按过滤器filter定义的顺序
案例:表单重复提交问题
把表单数据多次提交给服务器
问题:1、加大服务器的负担 2、多次插入重复的数据
可能出现重复提交的情况:
1、提交表单后,用forward跳转到其它页面,刷新页面
2、提交表单后,服务器还没有响应前,多次刷新页面
3、提交表单后,服务器还没有响应前,多次点击提交按钮
4、提交表单后,跳转后点击返回,点击提交
解决方法:
1、进入表单页面前,在过滤器中创建Token(令牌)随机字符串,保存到Session中。
2、在表单中添加一个隐藏域,值是Token字符串,会和表单一起提交服务器
3、提交服务器后,将表单中Token和Session中Token进行比较,如果相同就正常提交表单,否则就是重复提交。
4、如果能够成功提交后,把Session中的Token去掉。
/**
* 生成令牌的过滤器
*/
@WebFilter({/resubmit.jsp})
public class TokenFilterimplements Filter{
@Override
public voiddoFilter(ServletRequest request, ServletResponse response, FilterChainchain)
throws IOException, ServletException {
//产生随机字符串
Stringtoken = UUID.randomUUID().toString();
//保存到Session中
HttpServletRequestres = (HttpServletRequest) request;
res.getSession().setAttribute(token, token);
//执行后面的过滤器
chain.doFilter(request, response);
}
@Override
public void init(FilterConfigfilterConfig) throws ServletException{}
@Override
public voiddestroy() {}
}
监听器能够监听项目中各种对象的状态,如项目的启动和停止、用户会话的创建和销毁、会话属性的添加删除等,然后自动调用对应的方法,在实际工作中能完成缓存的提前加载,和项目的相关配置工作。
而过滤器能过滤网站中的各种资源,给Servlet和JSP添加一些额外的功能,如:设置编码格式、对用户进行登录验证、解决重复提交问题
4.功能实现
框架搭建
controller层
@Controller
@RequestMapping("user")
public class UserController {
@Autowired
private IUserService userService;
@RequestMapping("findAll.do")//添加分页操作
public ModelAndView findAll(@RequestParam(defaultValue = "1")int page,
@RequestParam(defaultValue = "4")int size) {
List<UserInfo> infos = userService.findAll(page,size);//还要进行封装infos到page里
PageInfo pageInfo = new PageInfo(infos);
ModelAndView mv = new ModelAndView();
mv.addObject("pageInfo", pageInfo);
mv.setViewName("user-list");
return mv;
}
@RequestMapping("login.do")
public ModelAndView doLogin(UserInfo userInfo) {
Boolean flag = userService.doLogin(userInfo);
ModelAndView modelAndView = new ModelAndView();
if (flag) {
modelAndView.setViewName("main");
} else {
modelAndView.setViewName("../failer");
}
return modelAndView;
}
@RequestMapping("/delete.do")
public String delete(int id) {
userService.deleteUser(id);
return "redirect:/user/findAll.do?page=1&size=4";
}
@RequestMapping("/save.do")
public String save(UserInfo userInfo) {
userService.save(userInfo);
return "redirect:/user/findAll.do?page=1&size=4";
}
@RequestMapping("/toUpdate.do")
public ModelAndView toUpdate(ModelAndView mv, int id) {
mv.addObject("user", userService.SelectUser(id));//把要修改的那一行的数据送到updateUser.jsp
mv.setViewName("user-update");
return mv;
}
@RequestMapping("/update.do")
public String update(UserInfo userInfo) {
userService.update(userInfo);
return "redirect:/user/findAll.do?page=1&size=4";
}
@RequestMapping("/pwchange.do")
public String pwchange(UserInfo userInfo){
userService.pwchange(userInfo);
return "redirect:/user/findAll.do?page=1&size=4";
}
}
mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zhongruan.dao.IUserDao" >
<select id="findAll" resultType="com.zhongruan.bean.UserInfo" >
select * from userinfo
</select>
<select id="doLogin" parameterType="com.zhongruan.bean.UserInfo" resultType="com.zhongruan.bean.UserInfo">
select * from userinfo where username = #{username} and password = #{password}
</select>
<delete id="deleteUser" parameterType="int">
delete from userinfo where id = #{id}
</delete>
<select id="SelectUser" resultType="UserInfo" parameterType="int">
select * from userinfo where id=#{id}
</select>
<update id="update" parameterType="UserInfo" >
update userinfo set username = #{username}, password = #{password} where id = #{id}
</update>
<insert id="save" parameterType="UserInfo"> <!--useGeneratedKeys="true" keyProperty="id"-->
insert into userinfo(username,password) values(#{username},#{password})
</insert>
<update id="pwchange" parameterType="com.zhongruan.bean.UserInfo" >
update userinfo set username = #{username}, password = #{password} where id = #{id}
</update>
</mapper>
user-list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>数据 - AdminLTE2定制版</title>
<meta name="description" content="AdminLTE2定制版">
<meta name="keywords" content="AdminLTE2定制版">
<!-- Tell the browser to be responsive to screen width -->
<meta
content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"
name="viewport">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/morris/morris.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/select2/select2.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/style.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css">
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<!-- 页面头部 -->
<jsp:include page="header.jsp"></jsp:include>
<!-- 页面头部 /-->
<!-- 导航侧栏 -->
<jsp:include page="aside.jsp"></jsp:include>
<!-- 导航侧栏 /-->
<!-- 内容区域 -->
<div class="content-wrapper">
<!-- 内容头部 -->
<section class="content-header">
<h1>
用户管理 <small>全部用户</small>
</h1>
<ol class="breadcrumb">
<li><a href="${pageContext.request.contextPath}/pages/main.jsp"><i
class="fa fa-dashboard"></i> 首页</a></li>
<li><a
href="${pageContext.request.contextPath}/user/findAll.do?page=1&size=4">用户管理</a></li>
<li class="active">全部用户</li>
</ol>
</section>
<!-- 内容头部 /-->
<!-- 正文区域 -->
<section class="content"> <!-- .box-body -->
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">列表</h3>
</div>
<div class="box-body">
<!-- 数据表格 -->
<div class="table-box">
<!--工具栏-->
<div class="pull-left">
<div class="form-group form-inline">
<div class="btn-group">
<button type="button" class="btn btn-default" title="新建"
onclick="location.href='${pageContext.request.contextPath}/pages/user-add.jsp'" >
<i class="fa fa-file-o"></i> 新建
</button>
<button type="button" class="btn btn-default" title="刷新">
<i class="fa fa-refresh"></i> 刷新
</button>
</div>
</div>
</div>
<form action="#"
method="post">
<div class="col-md-4 data1">
<input type="text" class="form-control" name="username"
placeholder="username" value="">
</div>
<button type="submit" class="btn bg-maroon">搜索</button>
</form>
<!--工具栏/-->
<!--数据列表-->
<table id="dataList"
class="table table-bordered table-striped table-hover dataTable">
<thead>
<tr>
<th class="" style="padding-right: 0px"><input
id="selall" type="checkbox" class="icheckbox_square-blue">
</th>
<th class="sorting_asc">ID</th>
<th class="sorting_desc">用户名</th>
<th class="sorting_asc sorting_asc_disabled">密码</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
<c:forEach var="user" items="${pageInfo.list}">
<tr>
<td><input name="ids" type="checkbox"></td>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.password}</td>
<td class="text-center">
<a href="${pageContext.request.contextPath}/user/toUpdate.do?id=${user.id}" class="btn bg-olive btn-xs">更新</a>
<a href="${pageContext.request.contextPath}/user/delete.do?id=${user.id}" class="btn bg-olive btn-xs">删除</a>
<a href="${pageContext.request.contextPath}/pages/role-add.jsp" class="btn bg-olive btn-xs">添加角色</a>
</td>
</tr>
</c:forEach>
</tbody>
<!--
<tfoot>
<tr>
<th>Rendering engine</th>
<th>Browser</th>
<th>Platform(s)</th>
<th>Engine version</th>
<th>CSS grade</th>
</tr>
</tfoot>-->
</table>
<!--数据列表/-->
</div>
<!-- 数据表格 /-->
</div>
<!-- /.box-body -->
<div class="box-tools pull-right">
<ul class="pagination">
<li><a href="${pageContext.request.contextPath}/user/findAll.do?page=1&size=4" aria-label="Previous">首页</a></li>
<li><a href="${pageContext.request.contextPath}/user/findAll.do?page=${pageInfo.pageNum-1}&size=4">上一页</a></li>
<c:forEach
begin="1" end="${pageInfo.pages}" var="pageNum">
<li>
<a href="${pageContext.request.contextPath}/user/findAll.do?page=${pageNum}&size=4">${pageNum}</a>
</li>
</c:forEach>
<li><a href="${pageContext.request.contextPath}/user/findAll.do?page=${pageInfo.pageNum+1}&size=4">下一页</a></li>
<li><a href="${pageContext.request.contextPath}/user/findAll.do?page=${pageInfo.pages}&size=4" aria-label="Next">尾页</a></li>
</ul>
</div>
</div>
<!-- /.box-footer-->
</div>
</section>
<!-- 正文区域 /-->
</div>
<!-- @@close -->
<!-- 内容区域 /-->
<!-- 底部导航 -->
<footer class="main-footer">
<div class="pull-right hidden-xs">
<b>Version</b> 1.0.8
</div>
<strong>Copyright © 2014-2017 <a
href="http://www.itcast.cn">研究院研发部</a>.
</strong> All rights reserved. </footer>
<!-- 底部导航 /-->
</div>
<script src="../plugins/jQuery/jquery-2.2.3.min.js"></script>
<script src="../plugins/jQueryUI/jquery-ui.min.js"></script>
<script>
$.widget.bridge('uibutton', $.ui.button);
</script>
<script src="../plugins/bootstrap/js/bootstrap.min.js"></script>
<script src="../plugins/raphael/raphael-min.js"></script>
<script src="../plugins/morris/morris.min.js"></script>
<script src="../plugins/sparkline/jquery.sparkline.min.js"></script>
<script src="../plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script>
<script src="../plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script>
<script src="../plugins/knob/jquery.knob.js"></script>
<script src="../plugins/daterangepicker/moment.min.js"></script>
<script src="../plugins/daterangepicker/daterangepicker.js"></script>
<script src="../plugins/daterangepicker/daterangepicker.zh-CN.js"></script>
<script src="../plugins/datepicker/bootstrap-datepicker.js"></script>
<script
src="../plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script>
<script
src="../plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script>
<script src="../plugins/slimScroll/jquery.slimscroll.min.js"></script>
<script src="../plugins/fastclick/fastclick.js"></script>
<script src="../plugins/iCheck/icheck.min.js"></script>
<script src="../plugins/adminLTE/js/app.min.js"></script>
<script src="../plugins/treeTable/jquery.treetable.js"></script>
<script src="../plugins/select2/select2.full.min.js"></script>
<script src="../plugins/colorpicker/bootstrap-colorpicker.min.js"></script>
<script
src="../plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script>
<script src="../plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script>
<script
src="../plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script>
<script src="../plugins/bootstrap-markdown/js/markdown.js"></script>
<script src="../plugins/bootstrap-markdown/js/to-markdown.js"></script>
<script src="../plugins/ckeditor/ckeditor.js"></script>
<script src="../plugins/input-mask/jquery.inputmask.js"></script>
<script
src="../plugins/input-mask/jquery.inputmask.date.extensions.js"></script>
<script src="../plugins/input-mask/jquery.inputmask.extensions.js"></script>
<script src="../plugins/datatables/jquery.dataTables.min.js"></script>
<script src="../plugins/datatables/dataTables.bootstrap.min.js"></script>
<script src="../plugins/chartjs/Chart.min.js"></script>
<script src="../plugins/flot/jquery.flot.min.js"></script>
<script src="../plugins/flot/jquery.flot.resize.min.js"></script>
<script src="../plugins/flot/jquery.flot.pie.min.js"></script>
<script src="../plugins/flot/jquery.flot.categories.min.js"></script>
<script src="../plugins/ionslider/ion.rangeSlider.min.js"></script>
<script src="../plugins/bootstrap-slider/bootstrap-slider.js"></script>
<script>
$(document).ready(function() {
// 选择框
$(".select2").select2();
// WYSIHTML5编辑器
$(".textarea").wysihtml5({
locale : 'zh-CN'
});
});
// 设置激活菜单
function setSidebarActive(tagUri) {
var liObj = $("#" + tagUri);
if (liObj.length > 0) {
liObj.parent().parent().addClass("active");
liObj.addClass("active");
}
}
$(document)
.ready(
function() {
// 激活导航位置
setSidebarActive("admin-datalist");
// 列表按钮
$("#dataList td input[type='checkbox']")
.iCheck(
{
checkboxClass : 'icheckbox_square-blue',
increaseArea : '20%'
});
// 全选操作
$("#selall")
.click(
function() {
var clicks = $(this).is(
':checked');
if (!clicks) {
$(
"#dataList td input[type='checkbox']")
.iCheck(
"uncheck");
} else {
$(
"#dataList td input[type='checkbox']")
.iCheck("check");
}
$(this).data("clicks",
!clicks);
});
});
</script>
</body>
</html>
运行截图
登录
增加
删除
更新