一、登录功能
1.认证实现
53-图书管理系统-登录功能-认证处理
首先完成最基础的登录功能,也就是在登录页面通过表单提交账号
和密码
到Servlet中。做相关的校验。给出不同的反应。
然后对应的Servlet中的处理逻辑
@WebServlet(name = "loginServlet",urlPatterns = {"/sys/loginServlet"})
public class LoginServlet extends HttpServlet {
private IUserService service = new UserServiceImpl();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 做登录认证的操作
String userName = req.getParameter("userName");
String password = req.getParameter("password");
// 根据账号去数据库查询记录
SysUser user = service.findByName(userName);
if(user == null ){
// 说明账号不存在
req.setAttribute("msg","登录失败!账号不存在");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}else if(!password.equals(user.getPassword())){
// 说明密码不正确
req.setAttribute("msg","登录失败!密码错误...");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}else{
// 说明登录成功
// 那么我们需要记录当前登录的用户
HttpSession session = req.getSession();
user.setPassword(null); // 记录的账号把密码置空。安全考虑
session.setAttribute(Constant.LOGIN_USER,user);
resp.sendRedirect("/main.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
5.2 认证过滤器
我们加了认证的操作后就不应该可以通过地址栏直接访问后端的功能了。所以需要添加过滤器来做认证的校验
/**
* 认证的过滤器:拦截所有的请求
* 1.判断当前是否是登录状态
* 2.请求的资源是否可以匿名访问
* 3.都不满足就跳转会登录页面
*/
@WebFilter(filterName = "authName",urlPatterns = {"/*"})
public class AuthenticationFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 对封装请求和响应的对象做向下转型
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 获取拦截的请求的访问地址
String requestURI = request.getRequestURI();
if(checkAccssible(requestURI)){
// 在没有登录的情况下可以访问的资源 登录页面 处理登录逻辑的Servlet 还有各种 js css img
// 直接放过
filterChain.doFilter(servletRequest,servletResponse);
}else{
// 访问的是需要登录后才能访问的资源
HttpSession session = request.getSession();
Object loginUser = session.getAttribute(Constant.LOGIN_USER);
if(loginUser != null){
// 是登录的状态
filterChain.doFilter(servletRequest,servletResponse);
}else{
// 说明不是登录的状态
request.setAttribute("msg","请先登录!!!");
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
}
private boolean checkAccssible(String requestURI){
List<String > urls = Arrays.asList("login.jsp","loginServlet",".css","/js/",".png",".jpg");
for (String url : urls) {
if(requestURI.contains(url)){
return true;
}
}
return false;
}
}
5.3 安全退出
登录成功后我们需要安全的退出。那么就需要删除登录成功保存在Session
中的认证凭证信息。
@WebServlet(name = "logoutServlet",urlPatterns = "/sys/logoutServlet")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 通过session注销
HttpSession session = req.getSession();
session.invalidate(); // 注销的操作
//跳转会登录页面
resp.sendRedirect("/login.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
然后main.jsp
中的安全退出
按钮点击的时候访问/sys/logoutServlet
即可
6.动态菜单
有了前面基础内容的铺垫我们就可以实现不同的用户基于不同的角色加载不同的菜单功能。那么在登录成功后需要查询当前登录用户具有的菜单信息
然后就是在main.jsp
中动态加载菜单。注意不要完了jstl
的标签库
<c:forEach items="${sessionScope.loginMenus}" var="parent">
<c:if test="${parent.parentId == -1}" >
<li>
<a href="#">
<i class="fa fa-home"></i>
<span class="nav-label">${parent.name}</span>
<span class="fa arrow"></span>
</a>
<ul class="nav nav-second-level">
<c:forEach items="${sessionScope.loginMenus}" var="sub">
<c:if test="${sub.parentId == parent.id}">
<li>
<a class="J_menuItem" href="${sub.url}" data-index="0">${sub.name}</a>
</li>
</c:if>
</c:forEach>
</ul>
</li>
</c:if>
</c:forEach>
显示的效果如下:
7.首页小功能
左上角显示当前登录用户信息及头像
<div class="dropdown profile-element">
<c:if test="${ not empty sessionScope.loginUser.img}">
<span><img alt="image" class="img-circle" src="/sys/downloadServlet?fileName=${sessionScope.loginUser.img}" width="64" height="64" /></span>
</c:if>
<c:if test="${ empty sessionScope.loginUser.img}">
<span><img alt="image" class="img-circle" src="img/profile_small.jpg" /></span>
</c:if>
<a data-toggle="dropdown" class="dropdown-toggle" href="#">
<span class="clear">
<span class="block m-t-xs"><strong class="font-bold">${sessionScope.loginUser.username}</strong></span>
<span class="text-muted text-xs block">${sessionScope.loginUser.nickname}<b class="caret"></b></span>
</span>
</a>
<ul class="dropdown-menu animated fadeInRight m-t-xs">
<li><a class="J_menuItem" href="form_avatar.html">修改头像</a></li>
<li><a class="J_menuItem" href="profile.html">个人资料</a></li>
<li><a class="J_menuItem" href="contacts.html">修改密码</a></li>
<li class="divider"></li>
<li><a href="/sys/logoutServlet">安全退出</a></li>
</ul>
</div>
效果: