- 退出(注销)
在controller中清空session,覆盖cookie
在2个过滤器中需要放过退出的请求
* 页面注销时提示一个询问框
```java //LogoutController.java package com.duyi.qxgl07.controller;
import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;
public class LogoutController extends HttpServlet { @Override //@Auto(“com.qxgl.login”) protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //清空登录成功时装载数据 //清空session req.getSession().removeAttribute(“loginUser”);
//覆盖浏览器cookie(清空效果)Cookie c = new Cookie("tokenId","-1"); //由于返回值为-1,就是时间等于0,所以直接清空//让时效等于0 -- 当时间为0c.setMaxAge(0);resp.addCookie(c);resp.sendRedirect("/");}
}
* 角色概要设计 (建表,建实体)<br /> create table t_role(<br /> rid int primary key auto_increment, //自增<br /> rname varchar(16),<br /> rdescription varchar(32),<br /> yl1 varchar(16), //表示与角色的关联<br /> yl2 varchar(16)<br /> )<br /> <br /> * 思考: 用户和角色的关系 (一对一,一对多,多对多)<br /> 理论上应该是一对多关系<br /> 需要在user表整增加一个关联角色表的外键rid<br /> create table t_user(<br /> uid , <br /> ....<br /> rid (外键)<br /> )<br /> 由于user表已经创建并使用<br /> 为了不影响之前的操作<br /> 不建议修改user表<br /> 我们可以考虑新建一个用户和角色的中间表,存储用户和角色的关系<br /> <br /> create table t_user_role(<br /> uid int , <br /> rid int ,<br /> primary key(uid,rid)<br /> )<br />* 功能管理概要设计<br /> create table t_fun(<br /> fid int primary key auto_increment,<br /> fname varchar(16) , -- "权限管理" , "数据导入" ,"用户管理"<br /> ftype int, -- 功能类别 1菜单,2按钮<br /> fhref varchar(64), -- 菜单对应的请求 "" "findUser"<br /> fauth varchar(32), -- 权限标识 <br /> pid int, -- 当前功能所属的父级功能id , 根菜单的父级功能是-1<br /> yl1 varchar(16),<br /> yl2 varchar(16)<br /> )<br /> 1 权限管理 1 null com.qxgl -1<br /> 2 用户管理 1 "findUser" com.qxgl.user 1<br /> 3 用户新建 2 "" com.qxgl.user.add 2<br /> 4 用户删除 2 "" com.qxgl.user.del 2<br /> 5 角色管理 1 "findRole" com.qxgl.role 1<br /> * 通过分析,功能权限功能分为2种<br /> 1.功能菜单,主页面左侧统一展示<br /> * 由于不同的用户,可能会有不同的权限,会分配不同的功能菜单<br /> * 张三可能有10个菜单<br /> * 李四可能有5个菜单<br /> * 无论用户分配了几个权限菜单,最终展示的时候应该是通过循环展示的。<br /> * 因为每一个功能菜单都会有对应的功能请求<br /> * 这些请求应该是随着菜单循环展示的时候,被装入菜单选项。<br /> * 所以这个请求也需要像菜单名字一样,存储在数据库中2.功能按钮,分散在不同的网页中,现在不同位置<br /> * 与菜单不同,按钮是不需要对应请求<br /> * 按钮显示的位置不确定<br /> * 所以需要在页面设计的时候,根据需求自定义按钮位置<br /> * 点击按钮发送的功能请求也是自定义按钮时匹配,不需要存储在数据库中<br /> * 权限标识属性<br /> * 不同的用户具有不同的权限<br /> * 在浏览器展示的效果就是不同的用户可以看到不同的菜单,可以看到不同的按钮<br /> * 无论看到哪些菜单和按钮,最终使用通过菜单和按钮完成背后的请求操作<br /> * 菜单或按钮背后的请求我们可以通过浏览器url直接发送<br /> * 所有当前用户是否具有当前url请求的权限,不能仅关注浏览器是否展示了对应的菜单和按钮<br /> * 还需要在服务端判断是否具有该请求的权限<br /> * 为每一个功能请求分配一个权限码 :com.qxgl.user.add<br /> * 用户具有该权限,就可以完成该权限码对应的请求<br /> * 该权限码对应哪些请求,可以使用注解配置在请求的方法上<br /> dmc用户 具有用户管理权限 权限码是com.qxgl.user<br /> <br /> class UserAddServlet{<br />//自定义注解,具有指定权限码的用户才能完成当前请求 userAdd<br /> @Auth("com.qxgl.user")<br /> service(){}<br /> }<br /> <br /> class UserDeleteServlet{<br /> @Auto("com.qxgl.user)<br /> serivce(){}<br /> }<br /> <br /> class UserEditServlet{<br /> @Auto("com.qxgl.user.edit")<br /> serivce(){}<br /> }//验证权限需要过滤器```java//AuthFilter.javapackage com.duyi.qxgl.util;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class AuthFilter extends HttpFilter {@Overrideprotected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {//每次请求调用对应的servlet方法之前,需要判断一下当前用户具有的权限码和要访问的servlet方法上注解表示的权限码是否匹配//从数据库中获得当前用户具有的权限->权限码//通过过滤器获得servlet方法上注解->权限码// 过滤器的使用体现AOP->责任链模式->有一个链对象chain->链中包含了要执行的所有切面filter和最终目标servlet//2个权限码比较//chain是一个接口,将他变为一个实现类}}
- 登录时验证码刷新
* 点击验证码,更换/刷新验证码//reloadCode.js -- webvar no=1; //设置一个全局变量function reloadCode(){//改换验证码,<img src="2.jpg">重新设置src属性//找到这个标签var img = document.getElementById('codeImg'); //验证码的图片//重新发送一次验证码的请求 -- 需要让每一次的请求参数发生变化//让服务器认为不是同一次请求img.src='generatcheckcode?no='+no++;}
权限关系:
用户
1 dmc 123
2 zzt 123
角色
11 vip1
22 vip2
功能
1 权限管理 1 null com.qxgl -1
2 用户管理 1 “findUser” com.qxgl.user 1
3 用户新建 2 “” com.qxgl.user.add 2
4 用户删除 2 “” com.qxgl.user.del 2
5 角色管理 1 “findRole” com.qxgl.role 1
用户角色
1 , 11
角色功能
11,1
11,2
11,3
//LoginView.javapackage com.duyi.qxgl.view;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;//是一个用来动态拼装登录页面的servletpublic class LoginView extends HttpServlet {/*一般4开头的都代表没找到405 : 表示处理请求的方法没有找到service可以处理get和post请求doGet可以处理get请求doPost可以处理post请求*/@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//拼页面String f = req.getParameter("f");//服务器响应时使用utf-8处理resp.setCharacterEncoding("utf-8");StringBuilder html = new StringBuilder();html.append("<html>");html.append(" <head>");html.append(" <title>登录222</title>");//告诉浏览器显示时按照 utf-8处理html.append(" <meta charset=\"utf-8\"/>");html.append(" <link rel=\"stylesheet\" type=\"text/css\" href=\"layui/css/layui.css\" />");html.append(" <script src=\"layui/layui.all.js\"></script>");html.append(" <style>");html.append(" body{");html.append(" width:100%;");html.append(" height:100%;");html.append(" background-image: url(imgs/img.png);");html.append(" background-repeat: repeat-x;");html.append(" background-size: 100% 100%;");html.append(" }");html.append(" .layui-card{");html.append(" width:350px;");html.append(" margin:100px auto ;");html.append(" opacity: 0.8;");html.append(" }");html.append(" tr{");html.append(" height:50px;");html.append(" }");html.append(" </style>");html.append(" <script>");//需要判断,在显示if(f != null && "9".equals(f)){html.append("alert('用户名密码错误');");}if(f != null && "8".equals(f)){html.append("alert('验证码为空或不正确');");}html.append(" </script>");html.append(" </head>");html.append(" <body>");html.append(" <div class=\"layui-card\">");html.append(" <div class=\"layui-card-header\">用户登录</div>");html.append(" <div class=\"layui-card-body\">");html.append(" <form action=\"login\" method=\"post\">");html.append(" <table>");html.append(" <tr>");html.append(" <td>用户名:</td>");html.append(" <td>");html.append(" <input type=\"text\" name=\"uname\" required lay-verify=\"required\" class=\"layui-input\">");html.append(" </td>");html.append(" </tr>");html.append(" <tr>");html.append(" <td>密码:</td>");html.append(" <td><input type=\"password\" name=\"upass\" class=\"layui-input\" /></td>");html.append(" </tr>");html.append(" <tr>");html.append(" <td colspan='2'><input style='width:100px;height:30px;' type=\"text\" name=\"code\" class=\"layui-input-inline\"/><img id='codeImg' src='generatcheckcode' onclick='reloadCode()' /></td>");html.append(" </tr>");html.append(" <tr>");html.append(" <td colspan='2'><input type=\"checkbox\" name=\"autoflag\" /> 1周内自动登录</td>");html.append(" </tr>");html.append(" <tr>");html.append(" <td> <button>登录</button> </td>");html.append(" </tr>");html.append(" </table>");html.append(" </form>");html.append(" </div>");html.append(" </div>");html.append(" </body>");html.append(" <script src='js/reloadcode.js'></script>");html.append("</html>");//将网页直接响应回去resp.getWriter().write(html.toString());/*servlet 和 jsp都可以拼装动态网页servlet = java(主场) + htmljsp = java + html(主场)*/}}
