1. 改造OA 54
1.1 使用什么技术改造呢? 54-55
Servlet + JSP + EL表达式 + JSTL标签。进行改造。
- 在前端HTML代码中,有一个标签,叫做base标签,这个标签可以设置整个网页的基础路径。
- 这不是Java的语法,也不是JSP的语法。是HTML中的一个语法。HTML中的一个标签。通常出现在head标签中。
< base href="http://localhost:8080/oa/">
- 在当前页面中,凡是路径没有以“/”开始的,都会自动将base中的路径添加到这些路径之前。
- < a href="ab/def">
- 等同于:< a href="http://localhost:8080/oa/ab/def">
- 需要注意:在JS代码中的路径,保险起见,最好不要依赖base标签。JS代码中的路径最好写上全路径。
base标签的写法
<base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
2. 当前的OA项目存在什么缺陷? 56
- DeptServlet、EmpServlet、OrderServlet。每一个Servlet都是处理自己相关的业务。在这些Servlet执行之前都是需要判断用户是否登录了。如果用户登录了,可以继续操作,如果没有登录,需要用户登录。这段判断用户是否登录的代码是固定的,并且在每一个Servlet类当中都需要编写,显然代码没有得到重复利用。包括每一个Servlet都要解决中文乱码问题,也有公共的代码。这些代码目前都是重复编写,并没有达到复用。怎么解决这个问题?
- 可以使用Servlet规范中的Filter过滤器来解决这个问题。
3. 实现oa项目中当前登录在线的人数。 61
- 什么代表着用户登录了?
- session.setAttribute("user", userObj); User类型的对象只要往session中存储过,表示有新用户登录。
- 什么代表着用户退出了?
- session.removeAttribute("user"); User类型的对象从session域中移除了。
- 或者有可能是session销毁了。(session超时)
代码在com.bjpowernode.oa.bean.
javabean Dept
package com.bjpowernode.oa.bean;
import java.util.Objects;
//这就是一个普通的java类,这个类可以封装零散的数据,代表了一个部门对象
public class Dept {
private String deptno;
private String dname;
private String loc;
public Dept() {
}
public String getDeptno() {
return deptno;
}
public void setDeptno(String deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
@Override
public String () {
return "Dept{" +
"deptno='" + deptno + '\'' +
", dname='" + dname + '\'' +
", loc='" + loc + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dept dept = (Dept) o;
return Objects.equals(deptno, dept.deptno) &&
Objects.equals(dname, dept.dname) &&
Objects.equals(loc, dept.loc);
}
@Override
public int hashCode() {
return Objects.hash(deptno, dname, loc);
}
}
User(展示在线人数的)
package com.bjpowernode.oa.bean;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpSessionBindingEvent;
import jakarta.servlet.http.HttpSessionBindingListener;
//这个javabean负责展示用户在线人数 61
public class User implements HttpSessionBindingListener {
@Override
public void valueBound(HttpSessionBindingEvent event) {
//用户登录了
//User类型的对象向session域中存放了
//获取ServletContext域对象
//因为我们要存储所有的用户,所以放在最大的application域中(application域相当于ServletContext)
ServletContext application = event.getSession().getServletContext();
//获取在线人数
Object onlinecount = application.getAttribute("onlinecount");
if(onlinecount==null){//第一次取可能为空
application.setAttribute("onlinecount",1);//如果第一次取空,我们就存入一个
}else{
int count = (Integer)onlinecount;
count++;//用户登录了加1
application.setAttribute("onlinecount",count);//存入ServletContext域
}
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
//用户退出了
//User类型的对象向session域中删除了
//获取ServletContext对象
ServletContext application = event.getSession().getServletContext();
//获取在线人数
Integer onlinecount =(Integer) application.getAttribute("onlinecount");
onlinecount--;//用户退出了登录减1
application.setAttribute("onlinecount",onlinecount);//存入ServletContext域
}
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
com.bjpowernode.oa.utils
工具类DBUtil
package com.bjpowernode.oa.utils;
import java.sql.*;
import java.util.ResourceBundle;
/**
* JDBC的工具类 27
*/
public class DBUtil {
// 静态变量:在类加载时执行。
// 并且是有顺序的。自上而下的顺序。
// 属性资源文件绑定
private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc");
// 根据属性配置文件key获取value
private static String driver = bundle.getString("driver");
private static String url = bundle.getString("url");
private static String user = bundle.getString("user");
private static String password = bundle.getString("password");
static {
// 注册驱动(注册驱动只需要注册一次,放在静态代码块当中。DBUtil类加载的时候执行。)
try {
// "com.mysql.jdbc.Driver" 是连接数据库的驱动,不能写死。因为以后可能还会连接Oracle数据库。
// 如果连接oracle数据库的时候,还需要修改java代码,显然违背了OCP开闭原则。
// OCP开闭原则:对扩展开放,对修改关闭。(什么是符合OCP呢?在进行功能扩展的时候,不需要修改java源代码。)
//Class.forName("com.mysql.jdbc.Driver");
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接对象
* @return conn 连接对象
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
// 获取连接
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
}
/**
* 释放资源
* @param conn 连接对象
* @param ps 数据库操作对象
* @param rs 结果集对象
*/
public static void close(Connection conn, Statement ps, ResultSet rs){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
代码在com.bjpowernode.oa.web.action
DeptServlet
package com.bjpowernode.oa.web.action;
import com.bjpowernode.oa.bean.Dept;
import com.bjpowernode.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
//使用jsp改造单表的CRUD操作 38
@WebServlet({"/dept/list","/dept/detail","/dept/delete","/dept/save","/dept/modify"})
public class DeptServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取session(这个session是不需要新建的) 44
// 只是获取当前session,获取不到这返回null
/*HttpSession session = request.getSession(false);
//这里解释if里面为什么有两个判断条件,因为第一保证session不为null这毋庸置疑
// ,但是session.getAttribute里的username还要不为空呢,因为系统是默认访问index文件的
// ,这样默认访问index文件也会产生一个session会话,所以要加上第二个条件
if(session!=null && session.getAttribute("username")!=null){
String servletPath = request.getServletPath();//得到路径
if("/dept/list".equals(servletPath)){
doList(request,response);
}else if("/dept/detail".equals(servletPath)){
doDetail(request,response);
}else if("/dept/delete".equals(servletPath)){
doDel(request,response);
}else if("/dept/save".equals(servletPath)){
doSave(request, response);
}else if("/dept/modify".equals(servletPath)){
doModify(request,response);
}
}else{
//没有登陆过自动跳转登陆页面
//重定向
//三种写法
//response.sendRedirect("/oa/index.jsp");//普通老老实实写法
//response.sendRedirect("/oa");//省略index.jsp,因为会自动访问index文件
response.sendRedirect(request.getContextPath()+"/index.jsp");//动态获取根写法,自动找到登录页面
}*/
String servletPath = request.getServletPath();//得到路径
if("/dept/list".equals(servletPath)){
doList(request,response);
}else if("/dept/detail".equals(servletPath)){
doDetail(request,response);
}else if("/dept/delete".equals(servletPath)){
doDel(request,response);
}else if("/dept/save".equals(servletPath)){
doSave(request, response);
}else if("/dept/modify".equals(servletPath)){
doModify(request,response);
}
}
//保存部门信息 40
private void doSave(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
//获取部门信息
// 注意乱码问题(Tomcat10不会出现这个问题)
request.setCharacterEncoding("UTF-8");
String deptno = request.getParameter("deptno");
String dname = request.getParameter("dname");
String loc = request.getParameter("loc");
//连接数据库执行insert语句
Connection conn = null;
PreparedStatement ps = null;
int count = 0;
try {
conn = DBUtil.getConnection();
String sql = "insert into dept(deptno, dname, loc) values(?,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1,deptno);
ps.setString(2,dname);
ps.setString(3,loc);
count = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn,ps,null);
}
if(count==1) {
// 这里最好使用重定向(浏览器会发一次全新的请求。)
// 浏览器在地址栏上发送请求,这个请求是get请求。
response.sendRedirect(request.getContextPath()+"/dept/list");
}
}
//根据部门编号删除相应的部门 40
private void doDel(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
//获取部门编号
String deptno = request.getParameter("deptno");
//连接数据库,查询部门信息
Connection conn = null;
PreparedStatement ps = null;
int count = 0;
try {
conn = DBUtil.getConnection();
String sql = "delete from dept where deptno = ?";
ps = conn.prepareStatement(sql);
ps.setString(1,deptno);
count = ps.executeUpdate();//返回删除受影响的条数
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn,ps,null);
}
if(count == 1){
//删除成功
//重定向到列表页面
String contextPath = request.getContextPath();//获取应用的根路径
response.sendRedirect(contextPath+"/dept/list");
}
}
//根据部门编号获取部门信息 39
private void doDetail(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
//创建部门对象
Dept dept = new Dept();
//获取部门编号
String dno = request.getParameter("dno");
//根据部门编号获取部门信息 将部门信息封装成咖啡豆(即javabean)
//连接数据库,查询部门信息
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = DBUtil.getConnection();
String sql = "select dname,loc from dept where deptno=?";
ps = conn.prepareStatement(sql);
ps.setString(1,dno);
rs = ps.executeQuery();
//这个结果集中只有一条数据,因此不需要while循环,只需要if
if(rs.next()){
String dname = rs.getString("dname");
String loc = rs.getString("loc");
//封装对象(创建豆子javabean)
dept.setDeptno(dno);
dept.setDname(dname);
dept.setLoc(loc);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn,ps,rs);
}
//这个豆子只有一个,所以不需要袋子(也就是不需要集合了),只需要将这个袋子放入到request域当中
request.setAttribute("dept",dept);
//转发(不是重定向因为要跳转到JSP做数据展示)
//request.getRequestDispatcher("/detail.jsp").forward(request,response);
//获取不同的标识(这个标识是我们再list.jsp修改和详情中自己加的,用来区分修改和详情的操作)
//因为我们可以根据不同的标记取转发到不同的页面 40
/* String f = request.getParameter("f");
if("m".equals(f)){
//转发到修改页面
request.getRequestDispatcher("/edit.jsp").forward(request,response);
}else if("d".equals(f)){
//转发到详情页面
request.getRequestDispatcher("/detail.jsp").forward(request,response);
}*/
//我们将上述代码简化 这就是一个路径拼接 getParameter("f")得到标记 40
String forward = "/"+request.getParameter("f")+".jsp";
//根据得到的拼接的路径进行转发
request.getRequestDispatcher(forward).forward(request,response);
}
//连接数据库,查询所有的部门信息,将部门信息收集好,然后跳转到JSP做页面展示。38
private void doList(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
//准备一个容器,用来专门存储部门
List depts = new ArrayList<>();
//连接数据库,查询所有的部门信息
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//获取连接
conn = DBUtil.getConnection();
String sql = "select deptno,dname,loc from dept";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
//遍历结果集
while(rs.next()){
//从结果集中取出
String deptno = rs.getString("deptno");
String dname = rs.getString("dname");
String loc = rs.getString("loc");
//将以上零散的数据封装成java对象
Dept dept = new Dept();
dept.setDeptno(deptno);
dept.setDname(dname);
dept.setLoc(loc);
//将部门对象放入到list集合中
depts.add(dept);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭连接
DBUtil.close(conn,ps,rs);
}
//将一个集合放入到请求域当中
request.setAttribute("deptList",depts);
//转发不要重定向
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
//修改操作 40
private void doModify(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//解决请求体的中文乱码问题
request.setCharacterEncoding("UTF-8");
//获取表单数据
String deptno = request.getParameter("deptno");
String dname = request.getParameter("dname");
String loc = request.getParameter("loc");
//连接数据库执行更新语句
Connection conn = null;
;
PreparedStatement ps = null;
int count = 0;
try {
conn = DBUtil.getConnection();
String sql = "update dept set dname = ?,loc = ? where deptno = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, dname);
ps.setString(2, loc);
ps.setString(3, deptno);
count = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn, ps, null);
}
if (count == 1) {
//更新成功
//重定向
response.sendRedirect(request.getContextPath() + "/dept/list");
}
}
}
UserServlet
package com.bjpowernode.oa.web.action;
import com.bjpowernode.oa.bean.User;
import com.bjpowernode.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//专门处理用户登录 41
//Servlet负责业务处理
//JSP负责页面展示
@WebServlet({"/user/login","/user/exit"})
public class UserServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String servletPath = request.getServletPath();
if("/user/login".equals(servletPath)){
doLogin(request,response);//调用登录
}else if("/user/exit".equals(servletPath)){
doExit(request,response);//调用退出
}
}
//退出 45
protected void doExit(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取session对象,销毁session
HttpSession session = request.getSession(false);
if (session !=null){
//从session域中删除user对象
session.removeAttribute("user");
//手动销毁session对象
session.invalidate();
//销毁cookie 54-55
Cookie[] cookies = request.getCookies();
if(cookies != null){
for (Cookie cookie : cookies) {//循环遍历cookie
//设置cookie的有效时间为0,表示删除cookie
cookie.setMaxAge(0);
//设置一下cookie的路径
cookie.setPath(request.getContextPath());//删除cookie是注意路径问题
//响应cookie给浏览器,浏览器端会将之前的cookie覆盖
response.addCookie(cookie);
}
}
//跳转登录页面
//这是重定向
response.sendRedirect(request.getContextPath());
}
}
//登录
protected void doLogin(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
boolean success = false;//登录成功标志
//验证用户名和密码是否正确
//获取用户名和密码
// 前端你是这样提交的:username=admin&password=123
String username = request.getParameter("username");
String password = request.getParameter("password");
//连接数据库验证用户名和密码
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = DBUtil.getConnection();
String sql = "select * from t_user where username=? and password=?";
//编译sql
ps = conn.prepareStatement(sql);
//给?赋值
ps.setString(1,username);
ps.setString(2,password);
//执行sql
rs = ps.executeQuery();
//这个结果集中做多只有一条数据
if (rs.next()) {
//登录成功
success = true;
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,rs);
}
if(success){
// 获取session对象(这里的要求是:必须获取到session 44
// ,没有session也要新建一个session对象。)
HttpSession session = request.getSession();//session对象一定不为空null
//session.setAttribute("username",username);//将用户名存入
//这两行是为了展示在线人数的(上面那个写法也对就是没有这个功能) 61
User user = new User(username, password);
session.setAttribute("user",user);
//登陆成功了,并且用户选择了十天内免登录
String f = request.getParameter("f");
if("1".equals(f)){
//创建cookie对象存储登录名
Cookie cookie1 = new Cookie("username",username);
//创建cookie对象存储密码
Cookie cookie2 = new Cookie("password", password);
//设置cookie的有效时间为十天
cookie1.setMaxAge(60*60*24*10);
cookie2.setMaxAge(60*60*24*10);
//设置cookie的path(只要访问这个应用,浏览器就一定携带这两个cookie)
cookie1.setPath(request.getContextPath());
cookie2.setPath(request.getContextPath());
//响应cookie给浏览器
response.addCookie(cookie1);
response.addCookie(cookie2);
}
//登陆成功,跳转到用户列表页面
response.sendRedirect(request.getContextPath()+"/dept/list");
}else{
//登录失败,跳转到失败页面
response.sendRedirect(request.getContextPath()+"/error.jsp");
}
}
}
WelcomeServlet
package com.bjpowernode.oa.web.action;
import com.bjpowernode.oa.bean.User;
import com.bjpowernode.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//十天内免登录欢迎页 48
@WebServlet("/welcome")
public class WelcomeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//先获取cookie
//这个cookie[]数组可能是null,如果不是null,数组的长度一定是大于0的
Cookie[] cookies = request.getCookies();//得到cookie数组
String username = null;
String password = null;
if (cookies != null) {//如果cookie不为null
for (Cookie cookie : cookies) {//循环遍历cookie数组
String name = cookie.getName();//先得到cookie的name,然后在得到value
//因为有两个cookie,所以根据不同的cookie的name得到不同的value
if("username".equals(name)){
username = cookie.getValue();
}else if("password".equals(name)){
password = cookie.getValue();
}
}
}
//要在这里使用username和password变量
if(username != null && password != null){
//验证用户名和密码是否正确
Connection conn =null;
PreparedStatement ps = null;
ResultSet rs = null;
boolean success = false;
try {
conn = DBUtil.getConnection();
String sql = "select * from t_user where username = ? and password = ?";
ps = conn.prepareStatement(sql);
ps.setString(1,username);
ps.setString(2,password);
rs = ps.executeQuery();
if(rs.next()){
//登陆成功
success = true;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn,ps,rs);
}
if(success){
//获取session对象
HttpSession session = request.getSession();
//session.setAttribute("username",username);
//这两行是为了展示在线人数的(上面那个写法也对就是没有这个功能) 61
User user = new User(username, password);
session.setAttribute("user",user);
//正确,表示登陆成功
response.sendRedirect(request.getContextPath()+"/dept/list");
}else{
//错误,表示登录失败
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
}else{
//跳转登录页面
//这里使用重定向
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
}
}
OrderServlet
package com.bjpowernode.oa.web.action;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
//管理的登录的类 57
public class OrderServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//要想进入这个servlet,一定会右这个servlet自己的路径,但是当我们输入这个servlet的路径时
//会被过滤器拦截,因为我们设置的过滤器任何路径都拦截(除了那几种情况)
}
}
EmpServlet
package com.bjpowernode.oa.web.action;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
//员工的登录的类 57
public class EmpServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//要想进入这个servlet,一定会右这个servlet自己的路径,但是当我们输入这个servlet的路径时
//会被过滤器拦截,因为我们设置的过滤器任何路径都拦截(除了那几种情况)
}
}
代码在com.bjpowernode.oa.web.filter
LoginCheckFilter
package com.bjpowernode.oa.web.filter;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
//这是一个过滤器 负责过滤登陆代码的 57
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res
, FilterChain chain) throws IOException, ServletException {
//以下两行是强制类型转换
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
//获取请求路径
String servletPath = request.getServletPath();
// 获取session(这个session是不需要新建的) 44
// 只是获取当前session,获取不到这返回null
HttpSession session = request.getSession(false);
//这里解释if里面为什么有两个判断条件,因为第一保证session不为null这毋庸置疑
// ,但是session.getAttribute里的username还要不为空呢,因为系统是默认访问index文件的
// ,这样默认访问index文件也会产生一个session会话,所以要加上第二个条件
/**
* 什么情况下不能拦截? 57
* 目前写的路径是:/* 表示所有的请求均拦截。
*
* 用户访问 index.jsp的时候不能拦截
* 用户已经登录了,这个需要放行,不能拦截。
* 用户要去登录,这个也不能拦截。
* WelcomeServlet也不能拦截。
*/
//不拦截(就是不用登录了)
//这个if表示什么时候什么样的请求不进行拦截,
// /index.jsp是要去登陆,如果进行拦截,那么我们的登录界面就显示不出来(因为chain是继续执行下面的代码的
// ,你都被拦截了,index.jsp中的代码还没执行呢)
// /welcome是欢迎界面(程序开始第一个执行的界面,如果对他进行拦截那么它后面的代码就无法执行)
// /user/login是判断登陆是都成功的,如果对他进行拦截,那么就无法判断了(因为我本来是去判断,你一拦截
// 却是又要我取登录界面)
// /user/exit是判断退出的,如果对他进行拦截,那么就无法判断了()就会导致session和cookie无法被销毁
//因为拦截后被你拉去又要登陆了
//(session != null && session.getAttribute("username") != null)这个表示登陆过了
// ,就不需要拦截了
/*if("/index.jsp".equals(servletPath) || "/welcome".equals(servletPath) ||
"/user/login".equals(servletPath) || "/user/exit".equals(servletPath)
|| (session != null && session.getAttribute("username") != null)){*/
if("/index.jsp".equals(servletPath) || "/welcome".equals(servletPath) ||
"/user/login".equals(servletPath) || "/user/exit".equals(servletPath)
|| (session != null && session.getAttribute("user") != null)){
//在session和提交的username不为空的情况下,继续往下走
chain.doFilter(request,response);
}else{
//进行拦截(就是让去登录)
//没有登陆过自动跳转登陆页面
//重定向
//三种写法
//response.sendRedirect("/oa/index.jsp");//普通老老实实写法
//response.sendRedirect("/oa");//省略index.jsp,因为会自动访问index文件
response.sendRedirect(request.getContextPath()+"/index.jsp");//动态获取根写法,自动找到登录页面
}
}
}
配置文件 src.resources
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bjpowernode
user=root
password=lzl
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置欢迎页面 48-->
<welcome-file-list>
<welcome-file>welcome</welcome-file>
</welcome-file-list>
<!-- 配置登录检查的过滤器,过滤所有的路径 57-->
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.bjpowernode.oa.web.filter.LoginCheckFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
index.jsp
<%@page contentType="text/html;charset=UTF-8"%>
<%--进行jsp更改 38 把这个页面改成登录页面 41--%>
<%--访问jsp时不生成session对象 44--%>
<%@page session="false" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>欢迎使用OA系统</title>
</head>
<body>
<%-- 前端发送请求路径的时候,如果请求路径是绝对路径,要以 / 开始,加项目名。--%>
<%-- 以下这样写代码,oa项目名写死了。这种设计显然是不好的。--%>
<%-- <a href="/oa/list.jsp">查看部门列表</a>--%>
<%-- <a href="<%=request.getContextPath()%>/list.jsp">查看部门列表</a>--%>
<%-- 执行一个Servlet,查询数据库,收集数据--%>
<%-- <a href="<%=request.getContextPath() %>/dept/list">查看部门列表</a>--%>
<%-- <hr>--%>
<%-- 调用方法获取应用的根路径--%>
<%-- <%=request.getContextPath()%> <%–类似于out.print(request.getContextPath()); –%>--%>
<%-- 画一个用户登录页面 41--%>
<h1>用户登录</h1>
<hr>
<form action = "${pageContext.request.contextPath}/user/login" method="post">
username:<input type="text" name="username"/><br>
password:<input type="password" name="password"/><br>
<input type="checkbox" name="f" value="1"/>十天内免登录<br>
<input type="submit" value="login"/>
</form>
</body>
</html>
list.jsp
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page contentType="text/html;charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>部门列表页面</title>
<%-- 设置整个网页的基础路径为http://localhost:8080/oa/ 54--%>
<%-- <base href="http://localhost:8080/oa/">--%>
<%-- 写成动态的 55--%>
<base href="${pageContext.request.scheme}://${pageContext.request.serverName}
:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
</head>
<body>
<%-- 显示一个登录名 和在线人数 44--%>
<h3>欢迎${user.username},在线人数${onlinecount}人</h3>
<%-- 写一个安全退出的功能 45--%>
<a href="user/exit">[退出系统]</a>
<script type="text/javascript">
function del(dno){
//弹出确认框,用户点击确定,返回true,点击取消返回false
var ok = window.confirm("亲,删了不可恢复哦");
if(ok){
//发送请求进行删除数据操作
//在js代码当中如何发送请求给服务器
//四种写法想服务器发送请求
//document.location.href = "请求路径"
//document.location = "请求路径"
//window.location.href = "请求路径"
//window.location = "请求路径"
/*注意html的base标签可能对JS代码不起作用。所以JS代码最好前面写上"/oa" */
document.location.href="${pageContext.request.contextPath}/dept/delete?deptno="+dno;
}
}
</script>
<h1 align="center">部门列表</h1>
<hr >
<table border="1px" align="center" width="50%">
<tr>
<th>序号</th>
<th>部门编号</th>
<th>部门名称</th>
<th>操作</th>
</tr>
<c:forEach items="${deptList}" varStatus="deptStatus" var="dept">
<tr>
<td>${deptStatus.count}</td>
<td>${dept.deptno}</td>
<td>${dept.dname}</td>
<td>
<a href="javascript:void(0)" onclick="del(${dept.deptno})">删除</a>
<a href="dept/detail?f=edit&dno=${dept.deptno}">修改</a>
<a href="dept/detail?f=detail&dno=${dept.deptno}">详情</a>
</td>
</tr>
</c:forEach>
</table>
<hr >
<a href="add.jsp">新增部门</a>
</body>
</html>
add.jsp
<%@page contentType="text/html;charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>新增部门</title>
</head>
<body>
<%-- 显示一个登录名 44--%>
<h3>欢迎${username}</h3>
<h1>新增部门</h1>
<hr >
<form action="${pageContext.request.contextPath}/dept/save" method="post">
部门编号<input type="text" name="deptno"/><br>
部门名称<input type="text" name="dname"/><br>
部门位置<input type="text" name="loc"/><br>
<input type="submit" value="保存"/><br>
</form>
</body>
</html>
detail.jsp
<%@page contentType="text/html;charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>部门详情</title>
</head>
<body>
<%-- 显示一个登录名 44--%>
<h3>欢迎${username}</h3>
<h1>部门详情</h1>
<hr >
部门编号:${dept.deptno} <br>
部门名称:${dept.dname}<br>
部门位置:${dept.loc}<br>
<input type="button" value="后退" onclick="window.history.back()"/>
</body>
</html>
edit.jsp
<%@page contentType="text/html;charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>修改部门</title>
</head>
<body>
<%-- 显示一个登录名 44--%>
<h3>欢迎${username}</h3>
<h1>修改部门</h1>
<hr >
<form action="${pageContext.request.contextPath}/dept/modify" method="post">
部门编号<input type="text" name="deptno" value="${dept.deptno}" readonly /><br>
部门名称<input type="text" name="dname" value="${dept.dname}"/><br>
部门位置<input type="text" name="loc" value="${dept.loc}"/><br>
<input type="submit" value="修改"/><br>
</form>
</body>
</html>
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录失败</title>
</head>
<body>
<%--登录失败页面 41--%>
登陆失败,请<a href="${pageContext.request.contextPath}/index.jsp">重新登录</a>
</body>
</html>