多对多的关系:就是两个一对多
一对多:在一的方向添加一个集合属性即可
-- 用户角色关系表 多对多 引入中间表
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)
)
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)
)
@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出来 防止空指针
}
@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<>();
}
@Data
public class Permission {
private Integer id;
private String permissionName;
private String url;
private Integer pid;//写简单的pid 不能写Permission对象 随便想想也是死循环
//一个权限被多个角色拥有
private List<Role> roles=new ArrayList<>();
}
<a href="${pageContext.request.contextPath}/user/details?userId=${user.id}" class="btn bg-olive btn-xs">详情</a>
/**
* 查询某用户的详情功能
* 用户有哪些角色 角色分别有哪些权限
* @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;
}
SysUser findById(Integer userId);
@Override
public SysUser findById(Integer userId) {
return userdao.findById(userId);
}
@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);
@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);
@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);
<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>
@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;
}
<%@ 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">IDth>
<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}"
<%--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>
/**
* 给指定用户添加指定角色
* @param userId 需要添加角色的用户id
* @param ids 添加角色的id数组
* @return
*/
@RequestMapping("/addRolesToUser")
public String addRolesToUser(Integer userId,Integer[] ids){
userService.addRolesToUser(userId,ids);
return "redirect:/user/findAll";
}
接口
/**
* 添加角色列表到用户
* @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);
}
}
}
/**
* 清空用户原来有的所有角色
* @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);
<a href="${pageContext.request.contextPath}/role/addPermissionsToRoleUI?roleId=#{role.id}" class="btn bg-olive btn-xs">添加权限a>
/**
* 添加权限到角色的数据回显
* @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;
}
Role findById(Integer roleId);
@Override
public Role findById(Integer roleId) {
return roleDao.findById(roleId);
}
@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);
<%@ 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">IDth>
<th class="sorting">权限名称th>
<th class="sorting">URLth>
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>
/**
* 为角色添加权限 动数据库表
* @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";
}
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);
}
}
}
@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 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页面中使用security:authorize标签,可以控制菜单是否显示。security:authorize标签的 access=“hasAnyRole(‘ROLE_USER’,‘ROLE_ADMIN’)”。因为标签的access使用的是表达式,所以需要将spring- security.xml配置文件的use-expressions设置为true。
1、使用表达式改为true: use-expressions=“true”
2、access不能直接写权限名而要写成:access="hasAnyRole(‘ROLE_USER’,‘ROLE_ADMIN’)”
表示拥有’ROLE_USER’,'ROLE_ADMIN’中任意一个权限就初步可以访问/**任意路径(真正目的是啥权限都没有时无法访问本网站任意未放行路径)
3、前端jsp 先加上标签库 然后
系统管理UI用
基础数据UI用
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还是可以访问到资源信息的,所以好 需要对服务器端的资源进行安全控制。
控制方式就是借助于Spring的AOP,对Controller的的访问进行权限的功能增强。 修改spring-security.xml配置文件,添加aop的自动代理
添加配置:
<aop:aspectj-autoproxy proxy-target-class="true">aop:aspectj-autoproxy>
<security:global-method-security secured-annotations="enabled"/>
指定拥有哪些权限时方可访问本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
spring-security.xml里加一行配置
<security:access-denied-handler error-page="/failer.jsp"></security:access-denied-handler>
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;//访问的全限定类名.方法
}
之前应该已经加过了
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
springmvc会自动将httpservletrequest放到IOC容器中 即springmvc不需要加此配置
其他框架不会 其他web层框架想要注入request就必须加此配置
<!--配置请求监听器:当请求发生时,在容器中创建请求对象-->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
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;
}
}
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);
}
}
public interface LogDao {
@Insert("insert into sys_log values(log_seq.nextval,#{visitTime},#{username},#{ip},#{method})")
void save(SysLog log);
}
/**
* 查询所有日志 分页查询
*/
@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;
}
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;
}
@Select("select * from sys_log")
List<SysLog> findAll();
加个字段方便访问
@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;
}
}
<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">IDth>
<th class="sorting">访问时间th>
<th class="sorting">访问用户th>
<th class="sorting">访问IPth>
<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>
<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">15option>
<option value="20">20option>
<option value="30">30option>
<option value="40">40option>
<option value="50">50option>
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>