当前位置:网站首页>SSM练习第五天
SSM练习第五天
2022-07-26 17:31:00 【奇迹是执着的人创造的】
文章目录
第一章:授权操作
第一节:经典权限5张表的关系分析
1、数据库模型关系图

2、用户角色关系表
多对多的关系:就是两个一对多
一对多:在一的方向添加一个集合属性即可
-- 用户角色关系表 多对多 引入中间表
CREATE TABLE sys_user_role(
userId number,
roleId number,
PRIMARY KEY(userId,roleId), --联合主键:两个不能同时一样
FOREIGN KEY (userId) REFERENCES sys_USER(id),
FOREIGN KEY (roleId) REFERENCES sys_role(id)
)
3、角色权限关系表
CREATE TABLE sys_role_permission(
permissionId number,
roleId number,
PRIMARY KEY(permissionId,roleId),
FOREIGN KEY (permissionId) REFERENCES sys_permission(id),
FOREIGN KEY (roleId) REFERENCES sys_role(id)
)
4、修改用户SysUser实体
@Data
public class SysUser {
private Long id;
private String username;
private String email;
private String password;
private String phoneNum;
private int status;
//一个用户对应多个角色
private List<Role> roles = new ArrayList<>();//new出来 防止空指针
}
5、修改角色Role实体
@Data
public class Role {
private Integer id;
private String roleName;
private String roleDesc;
//一个角色被多个用户所拥有
private List<SysUser> users = new ArrayList<>();
//一个角色拥有多个权限
private List<Permission> permissions = new ArrayList<>();
}
6、修改权限Permission实体
@Data
public class Permission {
private Integer id;
private String permissionName;
private String url;
private Integer pid;//写简单的pid 不能写Permission对象 随便想想也是死循环
//一个权限被多个角色拥有
private List<Role> roles=new ArrayList<>();
}
第二节:查看用户的角色详情功能
1、页面入口

<a href="${pageContext.request.contextPath}/user/details?userId=${user.id}" class="btn bg-olive btn-xs">详情</a>
2、编写Controller
/** * 查询某用户的详情功能 * 用户有哪些角色 角色分别有哪些权限 * @param userId * @return */
@RequestMapping("/details")
public ModelAndView details(Integer userId){
LogUtils.print("用户详情:"+userId);
//查询数据--用户详情
SysUser user=userService.findById(userId);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("user",user);
modelAndView.setViewName("user-show");
return modelAndView;
}
3、编写Service
SysUser findById(Integer userId);
@Override
public SysUser findById(Integer userId) {
return userdao.findById(userId);
}
4、编写Dao
编写userDao
@Select("select * from sys_user where id = #{userId}")
@Results({
@Result(id=true,property = "id",column = "id"),//主键id 最好都加上 否则后端获取id为null
@Result(property = "roles",column = "id", //还是本张表主键id,因为是根据本张表主键id关联到role的
//根据userId查询角色列表
// cn.ahpu.dao.RoleDao.findRolesByUserId
many = @Many(select = "cn.ahpu.dao.RoleDao.findRolesByUserId"))
})
SysUser findById(Integer userId);
编写RoleDao(user下有role)
@Select("select r.* from sys_user_role ur,sys_role r where ur.roleid=r.id and ur.userid=#{userId}")
@Results({
@Result(id=true,property = "id",column = "id"),//主键id 最好加上 否则id只能用一次 后端查id就是null了
@Result(property = "permissions",column = "id", //还是本张表主键id,因为是根据本张表主键id关联到role的
many = @Many(select = "cn.ahpu.dao.PermissionDao.findPermissionsByRoleId"))
})
List<Role> findRolesByUserId(Integer userId);
编写PermissionDao(Role下有permission)
@Select("select p.* from sys_role_permission rp,sys_permission p where rp.roleid=#{roleId} and rp.permissionid=p.id")
List<Permission> findPermissionsByRoleId(Integer roleId);
5、修改前端user-show.jsp
<thead>
<tr>
<th>名称</th>
<th>描述</th>
</tr>
</thead>
<tr data-tt-id="0">
<td colspan="2">${
user.username}</td>
</tr>
<tbody>
<c:forEach items="${user.roles}" var="role" varStatus="i">
<tr data-tt-id="${role.id}" data-tt-parent-id="0">
<td>${
role.roleName }</td>
<td>${
role.roleDesc }</td>
</tr>
<%--子标签的父id要唯一对应 得用${
i.count}了 }
若dao中id@Result()里id都单独配置了
那么id可以多次使用 将i.count全部换成 role.id也不错
--%>
<c:forEach items="${role.permissions}" var="permission">
<tr data-tt-id="${role.id}-${permission.id}" data-tt-parent-id="${role.id}">
<td>${
permission.permissionName}</td>
<td>${
permission.url}</td>
</tr>
</c:forEach>
</c:forEach>
</tbody>
第三节:为用户分配角色-角色列表数据回显
1、页面入口

2、编写Controller
@RequestMapping("/addRoleToUserUI")
public ModelAndView addRoleToUserUI(Integer userId){
LogUtils.print("addRoleToUserUI:"+userId);
//所有角色
List<Role> roles = roleService.findAll();
//当前用户拥有的角色 直接将当前用户传过去也行 延迟加载还能起点作用
SysUser user = userService.findById(userId);
//方便选中已有的 换种写法
List<Role> userOwnedRoles = user.getRoles();
//把该用户拥有的角色id存到list放到前端
//id变成一个list 前端方便判断该id是否在数组中 el ${fn:contains(ids,id)}
List<Integer> ids=new ArrayList<>();
for (Role role : userOwnedRoles) {
ids.add(role.getId());
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("roles",roles);
modelAndView.addObject("ids",ids);
//真正执行添加业务时需要userId 因此也需要传过去
modelAndView.addObject("userId",user.getId());//user.getId()而不直接写userId "永远使用最后一次得到的数据"
modelAndView.setViewName("user-role-add");
return modelAndView;
}
3、页面回显数据(user-role-add.jsp)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<section class="content">
<input type="hidden" name="userId" value="${userId}"><%--用户id隐藏域--%>
<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">角色名称</th>
<th class="sorting">角色描述</th>
</tr>
</thead>
<tbody>
<c:forEach items="${roles}" var="role">
<tr>
<td><input name="ids" type="checkbox" value="${role.id}" <%--<c:if test="${fn:contains(ids, role.id)}">checked="checked"</c:if>--%>
<%--大神更牛的写法--%>
${fn:contains(ids, role.id)?"checked":" "}
></td>
<td>${role.id}</td>
<td>${role.roleName }</td>
<td>${role.roleDesc}</td>
</tr>
</c:forEach>
</tbody>
</table>
第四节:为用户分配角色-更新关系到用户角色中间表
1、页面入口

2、编写Controller
/** * 给指定用户添加指定角色 * @param userId 需要添加角色的用户id * @param ids 添加角色的id数组 * @return */
@RequestMapping("/addRolesToUser")
public String addRolesToUser(Integer userId,Integer[] ids){
userService.addRolesToUser(userId,ids);
return "redirect:/user/findAll";
}
3、编写Service
接口
/** * 添加角色列表到用户 * @param userId * @param ids */
void addRolesToUser(Integer userId, Integer[] ids);
实现
@Override
public void addRolesToUser(Integer userId, Integer[] ids) {
//先清空该用户拥有的所有角色
userdao.delRolesFromUser(userId);
if(ids!=null){
for (Integer roleId : ids) {
userdao.saveRoleToUser(userId,roleId);
}
}
}
4、编写Dao
/** * 清空用户原来有的所有角色 * @param userId */
@Delete("delete from sys_user_role where userId=#{userId}")
void delRolesFromUser(Integer userId);
/** * 为用户添加一个角色 * @param userId * @param roleId */
@Insert("insert into sys_user_role values(#{param1},#{param2})")
void saveRoleToUser(Integer userId, Integer roleId);
第五节:为角色添加权限数据回显(和user添加role雷同)
1、页面入口

<a href="${pageContext.request.contextPath}/role/addPermissionsToRoleUI?roleId=#{role.id}" class="btn bg-olive btn-xs">添加权限</a>
2、编写Controller
/** * 添加权限到角色的数据回显 * @param roleId * @return */
@RequestMapping("/addPermissionsToRoleUI")
public ModelAndView addPermissionsToRoleUI(Integer roleId){
LogUtils.print(roleId);
//获取所有权限
List<Permission> permissions = permissionService.findAll();
//获取角色已有权限id列表
Role role = roleService.findById(roleId);
List<Permission> rolePermissions = role.getPermissions();
List<Integer> ids=new ArrayList<>();
for (Permission p : rolePermissions) {
ids.add(p.getId());
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("permissions",permissions);
modelAndView.addObject("ids",ids);
modelAndView.addObject("roleId",roleId);
modelAndView.setViewName("role-permission-add");
return modelAndView;
}
3、编写Service
Role findById(Integer roleId);
@Override
public Role findById(Integer roleId) {
return roleDao.findById(roleId);
}
4、编写Dao
@Select("select * from sys_role where id=#{roleId}")
@Results({
@Result(property = "id",column = "id"),
@Result(property = "permissions",column = "id",
many=@Many(select = "cn.ahpu.dao.PermissionDao.findPermissionsByRoleId",fetchType = FetchType.LAZY)
)
})
Role findById(Integer roleId);
5、前端页面(role-permission-add.jsp)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<form action="${pageContext.request.contextPath}/role/addPermissionToRole.do" method="post">
<!-- 正文区域 -->
<section class="content"> <input type="hidden" name="roleId" value="${roleId}">
<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">权限名称</th>
<th class="sorting">URL</th>
</tr>
</thead>
<tbody>
<c:forEach items="${permissions}" var="permission">
<tr>
<td><input name="ids" type="checkbox" value="${permission.id}" ${fn:contains(ids, permission.id)?"checked":""} ></td>
<td>${permission.id}</td>
<td>${permission.permissionName }</td>
<td>${permission.url}</td>
</tr>
</c:forEach>
</tbody>
</table>
<!--订单信息/--> <!--工具栏-->
<div class="box-tools text-center">
<button type="submit" class="btn bg-maroon">保存</button>
<button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button>
</div>
<!--工具栏/--> </section>
<!-- 正文区域 /-->
</form>
第六节:为角色添加权限-实际保存即往中间表插入记录(和user添加role雷同)
1、页面入口


2、编写Controller
/** * 为角色添加权限 动数据库表 * @param roleId * @param ids * @return */
@RequestMapping("/addPermissionsToRole")
public String addPermissionsToRole(Integer roleId,Integer[] ids){
LogUtils.print(ids);
LogUtils.print(roleId);
roleService.addPermissionsToRole(roleId,ids);
return "redirect:/role/findAll";
}
3、编写service
void addPermissionsToRole(Integer roleId, Integer[] ids);
/** * 为角色roleId 添加 ids这么多的权限 * @param roleId * @param ids */
@Override
public void addPermissionsToRole(Integer roleId, Integer[] ids) {
//删除roleId所有权限
roleDao.delPermissionsFromRole(roleId);
if(ids!=null){
for (Integer permissionId : ids) {
roleDao.savePermissionToRole(roleId,permissionId);
}
}
}
4、编写dao
@Delete("delete from sys_role_permission where roleid=#{roleId}")
void delPermissionsFromRole(Integer roleId);
/** * 注意参数顺序 * @param roleId * @param permissionId */
@Insert("insert into sys_role_permission values(#{param2},#{param1})")
void savePermissionToRole(Integer roleId, Integer permissionId);
第七节:为用户设置真正的角色
修改UserServiceImpl的loadUserByUsername方法,为用户设置真正的角色
/** * 通过用户名 得到用户对象 * 创建用户详情对象,返回 */
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//根据用户名获取用户(SysUser)对象--同时查询相应角色
SysUser sysUser = userdao.findByUsername(username);
if(sysUser==null) return null;
/* 添加的都是假的角色对象 真正的角色对象需要到数据库内查 //配置文件里没有指定角色了 需要自己创建角色对象 //创建角色的集合对象 Collection<GrantedAuthority> authorities=new ArrayList<>(); //创建临时角色对象 正常情况下应该是数据库角色表中查的 GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_USER"); //对象添加到集合中 authorities.add(grantedAuthority); //User是安全框架内实现了UserDetails接口的一个类 //第三个参数是:角色列表对象 (此处角色名ROLE_USER自己定义 xml里需要这个名字) //{noop}前缀表示不加密 该把不加密去掉了*/
//添加数据库里真正的角色对象
Collection<GrantedAuthority> authorities=new ArrayList<>();
//登录时授权给用户 有哪些权限就授予哪些权限
for (Role role : sysUser.getRoles()) {
//LogUtils.print(role.getRoleName());
//创建角色对象
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_"+role.getRoleName());
//添加角色对象到集合
authorities.add(grantedAuthority);
}
//用户名 密码 角色
UserDetails user = new User(sysUser.getUsername(),sysUser.getPassword(),authorities);
return user;
}
userdao.findByUsername(username);,加个一对多结果集映射,否则查不到用户所拥有的权限
//根据用户名查询用户对象 唯一对象(username必须唯一)
@Select("select * from sys_user where username = #{username} and status=1")
@Results({
@Result(id=true,property = "id",column = "id"),//主键id 最好都加上 否则后端获取id为null
@Result(property = "roles",column = "id", //还是本张表主键id,因为是根据本张表主键id关联到role的
many = @Many(select = "cn.ahpu.dao.RoleDao.findRolesByUserId",fetchType = FetchType.LAZY))
})
SysUser findByUsername(String username);
第二章:授权后的安全控制
第一节:在JSP页面控制菜单权限(不显示UI)
在JSP页面中使用security:authorize标签,可以控制菜单是否显示。security:authorize标签的 access=“hasAnyRole(‘ROLE_USER’,‘ROLE_ADMIN’)”。因为标签的access使用的是表达式,所以需要将spring- security.xml配置文件的use-expressions设置为true。
1、spring-security.xml配置文件
1、使用表达式改为true: use-expressions=“true”
2、access不能直接写权限名而要写成:access="hasAnyRole(‘ROLE_USER’,‘ROLE_ADMIN’)”
表示拥有’ROLE_USER’,'ROLE_ADMIN’中任意一个权限就初步可以访问/**任意路径(真正目的是啥权限都没有时无法访问本网站任意未放行路径)
3、前端jsp 先加上标签库 然后
系统管理UI用 <security:authorize access=“hasRole(‘ROLE_ADMIN’)”></security:authorize>包裹
基础数据UI用<security:authorize access=“hasAnyRole(‘ROLE_ADMIN’,‘ROLE_USER’)”></security:authorize>包裹

jsp:
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
<security:authorize access="hasRole('ROLE_ADMIN')">
<li class="treeview"><a href="#"> <i class="fa fa-cogs"></i>
<span>系统管理</span> <span class="pull-right-container"> <i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li id="system-setting"><a href="${pageContext.request.contextPath}/user/findAll"> <i class="fa fa-circle-o"></i> 用户管理
</a></li>
<li id="system-setting"><a href="${pageContext.request.contextPath}/role/findAll"> <i class="fa fa-circle-o"></i> 角色管理
</a></li>
<li id="system-setting"><a href="${pageContext.request.contextPath}/permission/findAll">
<i class="fa fa-circle-o"></i> 权限管理
</a></li>
<li id="system-setting"><a href="${pageContext.request.contextPath}/pages/syslog-list.jsp"> <i class="fa fa-circle-o"></i> 访问日志
</a></li>
</ul></li>
</security:authorize>
<%--ROLE_ADMIN和ROLE_USER都可以使用 换言之啥权限都没有连基础数据都不能访问--%>
<security:authorize access="hasAnyRole('ROLE_ADMIN','ROLE_USER')">
<li class="treeview"><a href="#"> <i class="fa fa-cube"></i>
<span>基础数据</span> <span class="pull-right-container"> <i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li id="system-setting"><a href="${pageContext.request.contextPath}/product/findAll">
<i class="fa fa-circle-o"></i> 产品管理
</a></li>
<li id="system-setting"><a href="${pageContext.request.contextPath}/order/findAll">
<i class="fa fa-circle-o"></i> 订单管理
</a></li>
</ul></li>
</security:authorize>
第二节:在服务器端控制权限(拦截请求 防止用户直接输入url访问)
虽然页面菜单对不同角色显示类不同的菜单,但是如果直接访问服务器端的url还是可以访问到资源信息的,所以好 需要对服务器端的资源进行安全控制。
控制方式就是借助于Spring的AOP,对Controller的的访问进行权限的功能增强。 修改spring-security.xml配置文件,添加aop的自动代理
1、修改spring-mvc.xml配置
添加配置:
<!--AOP 当下面一行的配置也放在spring-mvc.xml本文件内时此配置可有可无 当下面一行配置放在spring-security.xml中 本配置必须有 开启注解动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!--配置开启security的注解支持 必须加上-->
<security:global-method-security secured-annotations="enabled"/>
没办法提示了,自己手动加: 复制后改下名字即可
2、在需要进行控制的Controller上添加@Secured注解
指定拥有哪些权限时方可访问本Controller,用户任意一个权限即可
@Secured({
"ROLE_ADMIN"})
public class UserController
@Secured({
"ROLE_ADMIN"})
public class RoleController
@Secured({
"ROLE_ADMIN"})
public class PermissionController
@Secured({
"ROLE_ADMIN","ROLE_USER"})
public class ProductController
3、更换默认403 forbidden界面
spring-security.xml里加一行配置
<security:access-denied-handler error-page="/failer.jsp"></security:access-denied-handler>

第三章:系统日志功能
第一节:AOP记录日志
1、日志表sys_log和实体Log
sql语句
create sequence log_seq;
CREATE TABLE sys_log(
id number PRIMARY KEY,
visitTime DATE,
username VARCHAR2(50),
ip VARCHAR2(30),
method VARCHAR2(200)
)
实体类
SysLog.java
@Data
public class SysLog {
private Long id;
private Date visitTime;//访问时间
private String username;//访问者用户名
private String ip;//访问者ip
private String method;//访问的全限定类名.方法
}
2、springmvc.xml配置文件中开启aop的自动代理
之前应该已经加过了
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
3、在web.xml中配置监听request对象的监听器
springmvc会自动将httpservletrequest放到IOC容器中 即springmvc不需要加此配置
其他框架不会 其他web层框架想要注入request就必须加此配置
<!--配置请求监听器:当请求发生时,在容器中创建请求对象-->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
4、编写切面类(切面类内部有增强)

spring-mvc.xml得多扫描一个包了
LogAop代码实现
package cn.ahpu.log;
import cn.ahpu.domain.SysLog;
import cn.ahpu.domain.SysUser;
import cn.ahpu.service.LogService;
import cn.ahpu.utils.LogUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/** * @author 寒面银枪 * @create 2020-05-16 16:53 * * 注解配置AOP * 提供一个类配置为切面类 * 切面=切入点+通知 * 通知类型 * 前置增强:@Before * 后置增强:@AfterReturning * 最终增强:@After * 异常增强:@AfterThrowing * 环绕增强:@Around * */
//注意xml里加上扫描log包
@Component
@Aspect
public class LogController {
@Autowired
LogService logService;
@Autowired
HttpServletRequest request;//只有springmvc放到IOC中了 换一个框架可能就没了
@Pointcut("execution(* cn.ahpu.controller.*.*(..))")
public void pointcut(){
}
/** * 环绕增强 * @param joinPoint 连接点对象--可以执行真实方法--只在环绕增强中使用 * 连接点就是拦截的方法 */
@Around("pointcut()") //织入
public Object around(ProceedingJoinPoint joinPoint){
//创建日志对象
SysLog sysLog = new SysLog();
//将日志对象封装
//1.访问时间 visitTime
sysLog.setVisitTime(new Date());
//2.访问用户名 username 安全框架内得到 注意是安全框架的User 不是自己写SysUser
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
sysLog.setUsername(user.getUsername());
//3.访问ip 还是得得到request对象 仔细想想哪里有? IOC容器里肯定有 直接注入一下就行了嘛
String ipAddr = request.getRemoteAddr();
sysLog.setIp(ipAddr);
//4.访问全限定类名
//被拦截类的全限定类名
String className = joinPoint.getTarget().getClass().getName();
//方法名称
String methodName = joinPoint.getSignature().getName();
sysLog.setMethod(className+"."+methodName);
//将日志对象存储到数据库
LogUtils.print(sysLog);
logService.save(sysLog);
try {
//执行真实的方法--必须返回真实方法返回值 否则所有方法被拦截 返回值都不返回 就不会跳转了
return joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
}
5、Service代码实现
LogService
public interface LogService {
void save(SysLog sysLog);
}
@Service
public class LogServiceImpl implements LogService {
@Autowired
LogDao logDao;
@Override
public void save(SysLog log) {
logDao.save(log);
}
}
6、Dao代码实现
public interface LogDao {
@Insert("insert into sys_log values(log_seq.nextval,#{visitTime},#{username},#{ip},#{method})")
void save(SysLog log);
}
第二节 查询日志
1、页面入口


2、编写Controller
/** * 查询所有日志 分页查询 */
@RequestMapping("/findAll")
public ModelAndView findAll(
@RequestParam(value = "currPage",required = false,defaultValue = "1") Integer currPage,
@RequestParam(value = "pageSize",required = false,defaultValue = "5") Integer pageSize
){
PageInfo<SysLog> pageHelper = logService.findAllByPageHelper(currPage, pageSize);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("pageHelper", pageHelper);
modelAndView.setViewName("syslog-list");
return modelAndView;
}
3、编写service
public interface LogService {
void save(SysLog sysLog);
/** * 查询所有日志 * @return */
List<SysLog> findAll();
/** * 分页查询所有 * @param currPage * @param pageSize * @return */
PageInfo<SysLog> findAllByPageHelper(Integer currPage, Integer pageSize);
}
@Override
public PageInfo<SysLog> findAllByPageHelper(Integer currPage, Integer pageSize) {
//指定分页参数
PageHelper.startPage(currPage,pageSize);
//查询全部 分页参数已经被绑定到当前线程 拦截器根据参数帮你做到拦截
List<SysLog> logs = logDao.findAll();
//创建PageInfo对象 控制页面最多显示5个页码
PageInfo<SysLog> pageInfo = new PageInfo<>(logs, 5);
//返回
return pageInfo;
}
4、编写dao
@Select("select * from sys_log")
List<SysLog> findAll();
5、修改domain
加个字段方便访问
@Data
public class SysLog {
private Long id;
private Date visitTime;//访问时间
private String visitTimeStr;
private String username;//访问者用户名
private String ip;//访问者ip
private String method;//访问的全限定类名.方法
public String getVisitTimeStr() {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
String timeStr = sdf.format(visitTime);
return timeStr;
}
}
6、修改页面
<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">访问时间</th>
<th class="sorting">访问用户</th>
<th class="sorting">访问IP</th>
<th class="sorting">访问方法</th>
</tr>
</thead>
<tbody>
<c:forEach items="${pageHelper.list}" var="syslog" varStatus="i">
<tr>
<td><input name="ids" type="checkbox"></td>
<td>${i.count}</td>
<td>${syslog.visitTimeStr }</td>
<td>${syslog.username }</td>
<td>${syslog.ip }</td>
<td>${syslog.method}</td>
</tr>
</c:forEach>
</tbody>
</table>
<!--数据列表/-->
<!--工具栏-->
<div class="pull-left">
<div class="form-group form-inline">
<div class="btn-group">
<button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();">
<i class="fa fa-refresh"></i> 刷新
</button>
</div>
</div>
</div>
<div class="box-tools pull-right">
<div class="has-feedback">
<input type="text" class="form-control input-sm" placeholder="搜索"> <span class="glyphicon glyphicon-search form-control-feedback"></span>
</div>
</div>
<!--工具栏/-->
</div>
<!-- 数据表格 /-->
</div>
<!-- /.box-body -->
<!-- .box-footer-->
<div class="box-footer">
<div class="pull-left">
<div class="form-group form-inline">
第${pageHelper.pageNum} 页,
总共${pageHelper.pages} 页,共${pageHelper.total} 条数据。 每页
<select class="form-control" name="pageSize" id="pageSize" onchange="gotoPage(1)">
<%--前10个用循环写 方便--%>
<c:forEach begin="1" end="10" var="i">
<option value="${i}">${i}</option>
</c:forEach>
<option value="15">15</option>
<option value="20">20</option>
<option value="30">30</option>
<option value="40">40</option>
<option value="50">50</option>
</select> 条
</div>
</div>
<div class="box-tools pull-right">
<ul class="pagination" id="gotoLi">
<%--超链接里访问js函数 必须加前缀javascript:--%>
<li><a href="javascript:gotoPage(1)" aria-label="Previous">首页</a></li>
<%--prePage多方便--%>
<li><a href="javascript:gotoPage(${pageHelper.prePage})">上一页</a></li>
<%--页面上显示几个页码也简单可控了 实在太方便了--%>
<c:forEach begin="${pageHelper.navigateFirstPage}" end="${pageHelper.navigateLastPage}" var="i">
<li><a href="javascript:gotoPage(${i})">${i}</a></li>
</c:forEach>
<li><a href="javascript:gotoPage(${pageHelper.nextPage})">下一页</a></li>
<li><a href="javascript:gotoPage(${pageHelper.pages})" aria-label="Next">尾页</a></li>
</ul>
</div>
</div>
js:
<script type="text/javascript">
//方法写在外面 会自动执行 注意先得给每个option加上value="xx" 不能没有value属性
//每页显示几条的数据回显 select option
$("#pageSize option[value=${pageHelper.pageSize}]").prop("selected","selected");
//跳转页面
function gotoPage(currPage) {
//页面的越界检查此处判断也很方便
if(currPage<1||currPage>${
pageHelper.pages}) return;
var pageSize=$("#pageSize").val();
location.href="${pageContext.request.contextPath}/log/findAll?currPage="+currPage+"&pageSize="+pageSize;
}
</script>
边栏推荐
- Point cloud target detection Kitti dataset bin file visualization, one-stop solution
- DTS is equipped with a new self-developed kernel, which breaks through the key technology of the three center architecture of the two places Tencent cloud database
- 【集训Day2】Sculpture
- Spark数据格式UnsafeRow
- 深度学习实验:Softmax实现手写数字识别
- 3、 Topic communication: create your own information format
- 236. 二叉树的最近公共祖先
- Kindergarten system based on SSM
- COSCon'22城市/学校/机构出品人征集令
- [static code quality analysis tool] Shanghai daoning brings you sonarource/sonarqube download, trial and tutorial
猜你喜欢
![[training day3] delete](/img/7b/40bfb7710427696a27796428d849ba.png)
[training day3] delete

It is said that the salary of Alibaba P7 is really fragrant

面试OPPO,16道题甩过来,我人傻了

Interview with celebrities | open source is a double-edged sword for security -- Wei Jianfan, author of the Chinese translation of cathedral and market

Three ways of de duplication in SQL

大咖访谈 | 开源对安全是双刃剑——《大教堂与集市》中文译本作者卫剑钒

如何组装一个注册中心?

CentOS installs docker and MySQL and redis environments
![[training Day2] sculpture](/img/d9/2e2ee8b4d995a29204afba889da635.png)
[training Day2] sculpture

LeetCode50天刷题计划(Day 1—— 两数相加 11.00-12.30)
随机推荐
Vector CANape - How to Send Receive CAN Message in CANape
【翻译】为什么你需要一个API网关来管理对你的API的访问?
【集训Day2】Torchbearer
Is it safe for me to open the securities account of CITIC and find the channel manager?
Machine learning by Li Hongyi 2. Regression
Linux Installation mysql8.0.29 detailed tutorial
3、 Topic communication: create your own information format
Rookie cpaas platform microservice governance practice
9、 Alternative implementation of client for service communication
After vs code is formatted, the function name will be automatically followed by a space
【静态代码质量分析工具】上海道宁为您带来SonarSource/SonarQube下载、试用、教程
【数字IC】深入浅出理解AXI-Lite协议
有一说一,阿里P7的薪资待遇是真的香
AI zhetianchuan DL regression and classification
老子云携手福昕鲲鹏,首次实现3D OFD三维版式文档的重大突破
202. Happy number
It is said that the salary of Alibaba P7 is really fragrant
VIM multiline operation
成为测试/开发程序员,小张:现实就来了个下马威......
The user experience center of Analysys Qianfan bank was established to help upgrade the user experience of the banking industry