稍微总结下,根据当前的项目结构图:
简单说下当前已经实现的逻辑如下:
1,login.jsp是用户登录页
2,点击登录按钮后,登录页表单提交到/LoginServlet
3,如果用户名、密码错误,跳转到error.jsp并在error.jsp页面显示错误信息
4,如果用户名、密码正确,根据角色不同跳转到不同页面(此处暂时未实现,但是逻辑是这么设计的,而且也留好了设计的位置)
5,以校长角色登录后,跳转到schoolmaster.jsp。
6,在schoolmaster.jsp中点击菜单栏任意链接,将通过/RouteServlet将右侧内容区域更换为链接指向的网页。
重点是6,既然我们已经能控制点击不同菜单,右侧显示不同内容,所以也没有必要为每种角色单独设计一个登录后的页面了。我们可以在登录成功的时候记录下登录用户的角色,然后根据角色在登录成功页面显示不同的菜单。这样的话,我们只需要一个后台jsp页面就行了。
好的,接下来我们具体实现下task3-x:根据登录用户角色不同在同一后台页面显示不同的菜单和内容
。
task3-1:
,登录页面login.jsp不作任何变化。
task3-2:
,在LoginServlet的doPost方法中,添加记录登录用户信息的语句如下:
package servlet;
import java.io.*;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import command.LoginCommand;
import entity.User;
import exception.MyException;
public class LoginServlet extends HttpServlet {//用于处理登录请求的LoginServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);//直接调用doPost方法处理get请求
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {//处理post请求
//设置输入输出格式、编码
response.setContentType("text/html");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//获取用户在网页输入的用户名和密码
String userName=request.getParameter("userName");
String userPassword=request.getParameter("userPassword");
//数据库操作
LoginCommand lc=new LoginCommand();
User user=null;
try {
user=lc.checkLogin(userName, userPassword);
if(user==null)
throw new MyException(new Date(),"用户名或者密码错误","用户名或者密码错误");
//根据user.getUserRole();用户角色显示不同内容
request.getSession().setAttribute("loginUser", user);//重点!
request.getRequestDispatcher("/index.jsp").forward(request,response);//跳转到index.jsp
} catch (MyException e) {
//跳转到错误提示页面,并提示用户错误信息
request.setAttribute("errorInfo", e.getInfo());//设置错误信息
request.getRequestDispatcher("/error.jsp").forward(request,response);//跳转到error.jsp
}
}
}
其实就添加了两句:
request.getSession().setAttribute("loginUser", user);//重点!
request.getRequestDispatcher("/index.jsp").forward(request,response);//跳转到index.jsp
重点只有第一句,request.getSession()是获取Session对象,所谓的Session就是用来标记某一个浏览器客户端和服务器之间的会话的。之前request.setAttribute中保存的对象,只在一次请求之间有效,比如登录页面跳转到Servlet有效,再跳转就丢失了,服务器不负责一直保存该对象。而Session中保存的对象,只要浏览器没关闭,程序员不删除,没有超时(时间很久浏览器端没有操作也会自动丢失),就一直存在,所以非常适合用来保存登录用户的信息。
task3-3:
,保存了含有用户信息的loginUser对象到Session作用域中之后,跳转到index.jsp页面,我们将schoolmaster.jsp页面的内容拷贝到index.jsp页面,并修改如下(哈哈,其实只修改了 <title>index.jsp</title>
一处),修改完成后schoolmaster.jsp页面完成任务,退出历史舞台:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!-- 使用c:标签需要添加本行代码 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>index.jsp</title>
<style type="text/css">
/*星号表示选择全部,设置外边距0,内边距0,字体大小12px,宋体*/
*{
margin:0px;
padding:0px;
font-size:12px;
font-family:"宋体";
}
/*整个body区域背景色为#F5F5F5,这个很简单,自己下载个取色器,找个漂亮的网页,取个颜色就行*/
body {
background-color: #FCFCFC;
}
/*在top、left、right外面套用一层main是为了控制宽度,并且整体居中*/
#main{
width:1000px;
margin:0px auto;
}
/*宽度占满它爹的宽度,高度64px是瞎试的,不好看再调整,猫哥喜欢用16px、32px、64px、128px这些,你懂的。
背景色猫哥继续取色器
line-height表示文字占用的高度,它也是64那就是文字占用高度跟top区域高度是一样的嘛,所以文字就居中了*/
#top{
width:100%;
height:64px;
background-color:#000000;
line-height:64px;
}
/*文字颜色取色器,标题部分啊文字用微软雅黑,大气!*/
#top_title{
line-height:64px;
font-family:"微软雅黑";
color:#FFFFFF;
float:left;
font-size:32px;
margin-left:16px;
}
/*颜色依然是自己取色的*/
#top_info{
color:#71777D;
float:right;
line-height:64px;
font-size:16px;
margin-right:16px;
}
/*宽度占200px差不多了吧
float表示漂浮,left的话就是靠左了,所以这个left区域就得靠左飘飘了
内部的东西跟边距有点距离好看点,暂时定为10px,上下左右都是哦*/
#left{
width:200px;
height:536px;/*猫哥认为600-64=536*/
float:left;
background-color:#EEEEEE;
padding:10px;
}
/*调整id=left的div中的ul标签下的li标签的样式为上边距10px,左边距15px*/
#left ul li{
margin:10px 0px 0px 15px;
}
/*注意逗号表示同时设置两组对象的CSS属性
a:link表示未访问的链接,a:visited表示已访问的链接,颜色凭爱好了*/
#left a:link, #left a:visited {
color: #333333;
text-decoration:none;/*不要下划线*/
}
/*a:hover表示鼠标悬停的链接,a:active表示被选择的链接*/
#left a:hover, #left a:active {
color: #0AA770;
text-decoration:none;
}
/*同理right向右飘*/
#right{
width:760px;/*1000-200-10*4=760,此处一定要注意padding的内容会拓宽div整体宽度,有志于前端的可以专门去研究下*/
min-width:600px;
height:536px;/*猫哥认为600-64=536*/
float:right;
background-color:#FFFFFF;
padding:10px;
}
</style>
</head>
<body>
<div id="main">
<div id="top">
<div id="top_title">
猫哥培训班作业管理系统
</div><!-- 标题部分 -->
<div id="top_info">
已登录用户名:张三
</div><!-- 登录用户信息部分 -->
</div><!-- top部分是标题栏 -->
<div id="left">
<ul>
<li><a href="/HomeworkSystem/RouteServlet?type=userManage">人员管理</a></li>
<li><a href="/HomeworkSystem/RouteServlet?type=viewInfo">信息查询</a></li>
</ul>
</div><!-- left部分是菜单栏 -->
<div id="right">
<c:if test="${empty type}">
欢迎来到猫哥培训班管理系统
</c:if>
<c:if test="${not empty type}">
<jsp:include page="${type}" flush="true"></jsp:include>
</c:if>
</div><!-- right部分是具体内容显示区 -->
</div>
</body>
</html>
task3-4:
,为了区分已登录用户的信息,我们将index.jsp中的:
<div id="top_info">
已登录用户名:张三
</div><!-- 登录用户信息部分 -->
修改为:
<div id="top_info">
欢迎您,尊敬的:${loginUser.userName}
</div><!-- 登录用户信息部分 -->
忘了告诉看官,$操作符及其强大,不光能读request作用域中的attribute,也能读session作用域中的attribute。(要是request和session中重名咋办,哈哈,你别让它重名不就噢了,就算重名也有办法,不过这个跑题了,自行百度)。
task3-5:
,这样就通了,不同用户登录后,都是登录到index.jsp,还能显示不同的信息,非常好。为了测试我们添加一个测试类EntityFactory用来创建测试的实体类User,这个EntityFactory也放在entity包下好了。
package entity;
public class EntityFactory {
public static Object CreateEntity(String type){
if(type.equals("User")){
User user=new User();
user.setUserId(-1);
user.setUserName("张校长");
user.setUserPassword("1234");
user.setUserRole((Role)EntityFactory.CreateEntity("Role"));//设置UserRole,也可以手工写
return user;
}
else if(type.equals("Role")){
Role role=new Role();
role.setRoleId(-1);//不存在的,虚构的
role.setRoleName("校长");
return role;
}
return null;
}
}
task3-6:
,我们将从数据库查询的地方修改为直接使用测试工厂类生成一个:
package command;
import java.util.Date;
import entity.EntityFactory;
import entity.User;
import exception.MyException;
public class LoginCommand {//从此处向数据库类下操作指令
public User checkLogin(String userName,String userPassword) throws MyException{
if(userName.equals("")||userPassword.equals("")){
//抛出输入信息异常
throw new MyException(new Date(),"用户名或者密码为空","用户名或者密码为空");
}
User user=null;
try{
//从数据库中执行查询,此处暂时使用测试工厂类创建一个代替
user=(User)EntityFactory.CreateEntity("User");
}catch(Exception e){
throw new MyException(new Date(),e.getMessage(),"数据库访问异常");
}
return user;
}
}
task3-7:
,重新部署、启动后测试。用户名密码随便输入,都会以一个校长角色登录。如下图:
好的,接下来,只需要实现根据不同登录角色加载不同的左侧菜单这一功能就OK啦。
热门评论
Role role=new Role();
Role是什么意思
请问使用${ }用加什么东西吗?
user.setUserRole((Role)EntityFactory.CreateEntity("Role"));这里报错呀,