学习java的日子 Day64 学生管理系统 web2.0 web版本
MVC设计模式
概念 - 代码的分层
MVC:项目分层的思想
字母 | 表示 | 层 | 理解 |
---|---|---|---|
M | Modle | 模型层 | 业务的具体实现 |
V | View | 视图层 | 展示数据 |
C | Controller | 控制器层 | 控制业务流程(跳转) |
1.细化理解层数
Controller:控制器层,用于存放Servlet(页面跳转)
View:视图层,用于存放前端页面(jsp)
Modle-Biz/service:逻辑业务层,用于存放业务具体的实现
Modle-Dao/mapper:数据持久层,用于存放操作数据的实现(数据的增删改查)
MVC涉及到了前端,而后端只涉及到了MC
1.1 优缺点
缺点:使用MVC不能减少代码量, 还会增加系统结构和实现的复杂性
优点:整个项目结构清晰,业务逻辑清晰,降低了代码的耦合性,代码的重用性高
注意:一般来说,使用设计模式都会增加代码量
1.2 各层的命名规范
Controller控制器层:controller/servlet/action/web
Modle-Biz 逻辑业务层:service/biz
Modle-Dao 数据持久层:dao/persist/mapper
2.学生管理系统 web2.0 mvc版本
具体的业务逻辑详情请见 Day59 学生管理系统 web1.0(直接使用servlet+jsp写的),v2.0只是使用mvc分层思想进行构造
项目结构:(总结里有展示所有层)
注意:mapper层、service层、controller层
2.1 学生 student
StudentMapper
通过具体的业务,判断需要用到什么增删查改,然后写数据库增删查改的接口,让实现类去实现
public interface StudentMapper {//添加学生public void add(String username,String password,String name,String sex,int age,String hobbies,String photo);//删除学生,通过usernamepublic void delete(String username);//更新学生的密码,通过username和newPasswordpublic void update(String username,String newPassword);//更新学生信息(除了密码),通过username去操作,没有更新照片public void update(String username,String name,String sex,int age,String hobbies);//更新学生信息(除了密码),通过username更新,有更新照片public void update(String username,String name,String sex,int age,String hobbies,String photo);//获取学生信息,通过usernamepublic Student getStudent(String username);//获取学生信息,通过username和usernamepublic Student getStudent(String username,String password);//获取学生的所有集合信息,用于分页,offset--偏移量,count--数据条数public List<Student> getStudents(int offset,int count);//获取当前表的总条数public int getAllCount();
}
StudentMapperImpl
具体操作数据库的增删查改,可以使用自己写的DBUtils 工具类
public class StudentMapperImpl implements StudentMapper {@Overridepublic void add(String username, String password, String name, String sex, int age, String hobbies, String photo) {try {DBUtils.commonUpdate("insert into student(username,password,name,sex,age,hobbies,photo) values(?,?,?,?,?,?,?)",username,password,name,sex,age, hobbies,photo);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void delete(String username) {try {DBUtils.commonUpdate("delete from student where username = ?",username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String newPassword) {try {DBUtils.commonUpdate("update student set password=? where username=?",newPassword,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String name, String sex, int age, String hobbies) {try {DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=? where username=?",name,sex,age,hobbies,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String name, String sex, int age, String hobbies, String photo) {try {DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=?,photo=? where username=?",name,sex,age,hobbies,photo,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic Student getStudent(String username) {Student student = null;try {student = DBUtils.commonQueryObj(Student.class, "select * from student where username = ?", username);} catch (SQLException e) {throw new RuntimeException(e);}return student;}@Overridepublic Student getStudent(String username, String password) {Student student = null;try {student = DBUtils.commonQueryObj(Student.class, "select * from student where username = ? and password = ?", username, password);} catch (SQLException e) {throw new RuntimeException(e);}return student;}@Overridepublic List<Student> getStudents(int offset, int count) {List<Student> students = null;try {students = DBUtils.commonQueryList(Student.class, "select * from student limit ?,?", offset, count);} catch (SQLException e) {throw new RuntimeException(e);}return students;}@Overridepublic int getAllCount() {int allcount = 0;try {allcount = DBUtils.getAllCount("student");} catch (SQLException e) {throw new RuntimeException(e);}return allcount;}
}
service业务逻辑层
具体的业务流程,存放Servlet
不用进行跳转,在Controller层进行跳转
有返回值的返回true/false就可以了
StudentService
public interface StudentService {//是否成功注册功能public boolean isRegister(String username);//注册功能public boolean register(HttpServletRequest request, HttpServletResponse response);//初始化学生信息功能public void initModify(HttpServletRequest request, HttpServletResponse response);//修改学生信息功能public void modify(HttpServletRequest request, HttpServletResponse response);//获取学生信息列表,方便分页public void getStudents(HttpServletRequest request, HttpServletResponse response);//删除学生功能public void delete(HttpServletRequest request, HttpServletResponse response);//添加学生的功能public boolean add(HttpServletRequest request, HttpServletResponse response);
}
StudentServiceImpl
实现 StudentService接口,写具体的业务逻辑
public class StudentServiceImpl implements StudentService {private StudentMapper studentMapper = new StudentMapperImpl();//是否成功注册功能@Overridepublic boolean isRegister(String username) {Student student = studentMapper.getStudent(username);if(student == null){//允许注册return true;}return false;}//注册功能(注册表单是二进制流,涉及到了图片上传)@Overridepublic boolean register(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Student> parseRequestData = ParseRequestDataUtils.parseRequest(request, Student.class, "upload\\student");Student stu = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();boolean register = isRegister(stu.getUsername());if(register){//将数据插入到学生表中studentMapper.add(stu.getUsername(),stu.getPassword(),stu.getName(),stu.getSex(),stu.getAge(),stu.getHobbies(),stu.getPhoto());//将头像存储到本地磁盘try {IOUtils.copy(in,out);in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}return true;}else{try {in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}request.setAttribute("msg","注册失败 -- 账号已注册");return false;}}//初始化学生信息功能@Overridepublic void initModify(HttpServletRequest request, HttpServletResponse response) {String username = request.getParameter("username");Student student = studentMapper.getStudent(username);request.setAttribute("student",student);}//修改学生信息功能@Overridepublic void modify(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Student> parseRequestData = ParseRequestDataUtils.parseRequest(request, Student.class, "upload\\student");Student stu = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();try {if(stu.getPhoto() != null){//说明用户修改头像studentMapper.update(stu.getUsername(),stu.getName(), stu.getSex(), stu.getAge(),stu.getHobbies(),stu.getPhoto());IOUtils.copy(in,out);//文件复制}else{studentMapper.update(stu.getUsername(),stu.getName(), stu.getSex(), stu.getAge(),stu.getHobbies());}if(in != null){in.close();}if(out != null){out.close();}} catch (IOException e) {throw new RuntimeException(e);}String role = (String) request.getSession().getAttribute("role");if("student".equals(role)){//更新Session里的数据request.getSession().setAttribute("name",stu.getName());//更新Cookie里的数据response.addCookie(CookieUtils.createCookie("name",stu.getName(),60*60*24*5));if(stu.getPhoto() != null){request.getSession().setAttribute("photo",stu.getPhoto());response.addCookie(CookieUtils.createCookie("photo",stu.getPhoto(),60*60*24*5));}}}//获取学生信息列表,方便分页@Overridepublic void getStudents(HttpServletRequest request, HttpServletResponse response) {//获取当前页数int curPage = Integer.parseInt(request.getParameter("curPage"));//设置URLString url = "student?action=doGetStudents&curPage=";//设置当前页的数据条数int count = 15;//计算偏移量int offset = (curPage-1)*count;//计算总页数int allCount = studentMapper.getAllCount();int totalPage = PageUtils.getTotalPage(allCount,count);//从数据库获取学生的集合List<Student> students = studentMapper.getStudents(offset,count);//处理学生集合List<StudentDto> studentDtos = DtoUtils.studentDtoListHandler(students);//封装Page对象Page<StudentDto> page = new Page<>(url, curPage, totalPage, studentDtos);//将数据存入到请求对象中request.setAttribute("page",page);}//删除学生功能@Overridepublic void delete(HttpServletRequest request, HttpServletResponse response) {String username = request.getParameter("username");studentMapper.delete(username);}//添加学生的功能@Overridepublic boolean add(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Student> parseRequestData = ParseRequestDataUtils.parseRequest(request, Student.class, "upload\\student");Student stu = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();boolean register = isRegister(stu.getUsername());if(register){//将数据插入到学生表中studentMapper.add(stu.getUsername(),stu.getPassword(),stu.getName(),stu.getSex(),stu.getAge(),stu.getHobbies(),stu.getPhoto());//将头像存储到本地磁盘try {IOUtils.copy(in,out);in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}return true;}else{try {in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}request.setAttribute("msg","添加失败 -- 账号已添加");return false;}}}
ParseRequestDataUtils
package com.qf.utils;public class ParseRequestDataUtils {public static <T> ParseRequestData parseRequest(HttpServletRequest request,Class<T> clazz,String path){ParseRequestData<T> parseRequestData = new ParseRequestData<>();//创建文件上传工厂类的对象DiskFileItemFactory factory = new DiskFileItemFactory();//创建文件上传类的对象ServletFileUpload upload = new ServletFileUpload(factory);HashMap<String, String> map = new HashMap<>();try {//解析请求List<FileItem> list = upload.parseRequest(request);for (FileItem fileItem : list) {if(fileItem.isFormField()){//文本数据String name = fileItem.getFieldName();String value = fileItem.getString("UTF-8");String v = map.get(name);if(v == null){//说明是第一次添加map.put(name,value);}else{//不是第一次添加就需要拼接(多选框的情况)map.put(name,v + "," + value);}}else{//二进制数据//D:\\apache-tomcat-8.0.49\\webapps\\Day23_upload_war_exploded\\upload\\student//D:\\apache-tomcat-8.0.49\\webapps\\Day23_upload_war_exploded\\upload\\teacherString realPath = request.getServletContext().getRealPath(path);//文件存储目录 -- 自定义路径\\用户名realPath = realPath + File.separator + map.get("username");File file = new File(realPath);if(!file.exists()){file.mkdirs();}String fileName = fileItem.getName();//获取文件名//自定义路径\\用户名\\tx01.jpgrealPath = realPath + File.separator + fileName;//拼接路径InputStream in = fileItem.getInputStream();if(in.available() != 0){FileOutputStream out = new FileOutputStream(realPath);parseRequestData.setIn(in);parseRequestData.setOut(out);map.put("photo",path + File.separator + map.get("username") + File.separator + fileName);}}}} catch (FileUploadException e) {throw new RuntimeException(e);} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}Set<Map.Entry<String, String>> entries = map.entrySet();for (Map.Entry<String, String> entry : entries) {System.out.println(entry);}T t = null;try {t = clazz.newInstance();//将map中的数据映射到实体类对象中BeanUtils.populate(t,map);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);}parseRequestData.setT(t);return parseRequestData;}
}
controller
根据每一个前端传过来的action功能来判断跳转
判断功能进行页面跳转
action=“student?action=doRegister”,前端设置路径加上action=xxx功能
Controller进行具体的判断,成功就重定向,失败就转发
@WebServlet("/student")
public class StudentController extends BaseServlet {private StudentService studentService = new StudentServiceImpl();//注册功能public void doRegister(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean register = studentService.register(request, response);if(register){response.sendRedirect("login.jsp");}else{request.getRequestDispatcher("register.jsp").forward(request,response);}}//初始化修改功能public void doInitModify(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {studentService.initModify(request,response);request.getRequestDispatcher("stuInfo.jsp").forward(request,response);}//修改功能public void doModify(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {studentService.modify(request,response);String role = (String) request.getSession().getAttribute("role");if("student".equals(role)){response.sendRedirect("index.jsp");}else if("teacher".equals(role)){request.getRequestDispatcher("student?action=doGetStudents&curPage=1").forward(request,response);}else if("admin".equals(role)){request.getRequestDispatcher("student?action=doGetStudents&curPage=1").forward(request,response);}}//展示数据功能public void doGetStudents(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {studentService.getStudents(request,response);request.getRequestDispatcher("stuList.jsp").forward(request,response);}//删除功能public void doDelete(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {studentService.delete(request,response);request.getRequestDispatcher("student?action=doGetStudents&curPage=1").forward(request,response);}//添加学生功能public void doAddStu(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean register = studentService.register(request, response);if(register){request.getRequestDispatcher("student?action=doGetStudents&curPage=1").forward(request,response);}else{request.getRequestDispatcher("stuAdd.jsp").forward(request,response);}}//是否注册学生的提示功能(ajax)public void isRegister(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");boolean register = studentService.isRegister(username);String code;if(register){code="1";}else {code="-1";}response.getWriter().write(code);}
}
BaseServlet
给控制层重写的servlet,以前继承HttpServlet,就会写很多的if-else判断,太麻烦了
package com.qf.servlet;public class BaseServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//url -- http://localhost:8080/Day24_MVC_war_exploded/user?action=doLoginString action = request.getParameter("action");//doLogin//获取Controller类的class对象Class<? extends BaseServlet> clazz = this.getClass();try {//根据action获取Controller类对应的方法对象Method method = clazz.getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);//设置操作权限method.setAccessible(true);//调用方法method.invoke(this,request,response);} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}
}
2.2 老师 teacher
TeacherMapper
明确数据库的功能
public interface TeacherMapper {//添加老师public void add(String username,String password,String name,String sex,int age,int courseId,String photo);//删除老师,通过usernamepublic void delete(String username);//更新老师的密码,通过username和newPasswordpublic void update(String username,String newPassword);//更新老师信息(除了密码),通过username去操作,没有更新照片public void update(String username,String name,String sex,int age,int courseId);//更新老师信息(除了密码),通过username更新,有更新照片public void update(String username,String name,String sex,int age,int courseId,String photo);//获取老师信息,通过usernamepublic Teacher getTeacher(String username);//获取老师信息,通过username和usernamepublic Teacher getTeacher(String username,String password);//获取老师的所有集合信息,用于分页,offset--偏移量,count--数据条数public List<Teacher> getTeachers(int offset,int count);//获取当前表的总条数public int getAllCount();
}
StudentMapperImpl
public class StudentMapperImpl implements StudentMapper {@Overridepublic void add(String username, String password, String name, String sex, int age, String hobbies, String photo) {try {DBUtils.commonUpdate("insert into student(username,password,name,sex,age,hobbies,photo) values(?,?,?,?,?,?,?)",username,password,name,sex,age, hobbies,photo);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void delete(String username) {try {DBUtils.commonUpdate("delete from student where username = ?",username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String newPassword) {try {DBUtils.commonUpdate("update student set password=? where username=?",newPassword,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String name, String sex, int age, String hobbies) {try {DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=? where username=?",name,sex,age,hobbies,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String name, String sex, int age, String hobbies, String photo) {try {DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=?,photo=? where username=?",name,sex,age,hobbies,photo,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic Student getStudent(String username) {Student student = null;try {student = DBUtils.commonQueryObj(Student.class, "select * from student where username = ?", username);} catch (SQLException e) {throw new RuntimeException(e);}return student;}@Overridepublic Student getStudent(String username, String password) {Student student = null;try {student = DBUtils.commonQueryObj(Student.class, "select * from student where username = ? and password = ?", username, password);} catch (SQLException e) {throw new RuntimeException(e);}return student;}@Overridepublic List<Student> getStudents(int offset, int count) {List<Student> students = null;try {students = DBUtils.commonQueryList(Student.class, "select * from student limit ?,?", offset, count);} catch (SQLException e) {throw new RuntimeException(e);}return students;}@Overridepublic int getAllCount() {int allcount = 0;try {allcount = DBUtils.getAllCount("student");} catch (SQLException e) {throw new RuntimeException(e);}return allcount;}
}
业务逻辑层
TeacherService
public interface TeacherService {public boolean isAdd(String username);public boolean add(HttpServletRequest request, HttpServletResponse response);public void initModify(HttpServletRequest request, HttpServletResponse response);public void modify(HttpServletRequest request, HttpServletResponse response);public void getTeachers(HttpServletRequest request, HttpServletResponse response);public void delete(HttpServletRequest request, HttpServletResponse response);
}
TeacherServiceImpl
public class TeacherServiceImpl implements TeacherService {private TeacherMapper teacherMapper = new TeacherMapperImpl();private CourseService courseService = new CourseServiceImpl();@Overridepublic boolean isAdd(String username) {Teacher teacher = teacherMapper.getTeacher(username);if(teacher == null){return true;}return false;}@Overridepublic boolean add(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Teacher> parseRequestData = ParseRequestDataUtils.parseRequest(request, Teacher.class, "upload\\teacher");Teacher t = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();boolean add = isAdd(t.getUsername());if(add){//将数据插入到老师表中teacherMapper.add(t.getUsername(),t.getPassword(),t.getName(),t.getSex(),t.getAge(),t.getCourseId(),t.getPhoto());//将头像存储到本地磁盘try {IOUtils.copy(in,out);in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}return true;}else{try {in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}request.setAttribute("msg","添加失败 -- 账号已存在");return false;}}@Overridepublic void initModify(HttpServletRequest request, HttpServletResponse response) {String username = request.getParameter("username");Teacher teacher = teacherMapper.getTeacher(username);request.setAttribute("teacher",teacher);courseService.getCourses(request,response);}@Overridepublic void modify(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Teacher> parseRequestData = ParseRequestDataUtils.parseRequest(request, Teacher.class, "upload\\teacher");Teacher tea = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();try {if(tea.getPhoto() != null){//说明用户修改头像teacherMapper.update(tea.getUsername(),tea.getName(), tea.getSex(), tea.getAge(),tea.getCourseId(),tea.getPhoto());IOUtils.copy(in,out);}else{teacherMapper.update(tea.getUsername(),tea.getName(), tea.getSex(), tea.getAge(),tea.getCourseId());}if(in != null){in.close();}if(out != null){out.close();}} catch (IOException e) {throw new RuntimeException(e);}String role = (String) request.getSession().getAttribute("role");if("teacher".equals(role)){//更新Session里的数据request.getSession().setAttribute("name",tea.getName());//更新Cookie里的数据response.addCookie(CookieUtils.createCookie("name",tea.getName(),60*60*24*5));if (tea.getPhoto() != null){request.getSession().setAttribute("photo",tea.getPhoto());response.addCookie(CookieUtils.createCookie("photo",tea.getPhoto(),60*60*24*5));}}}@Overridepublic void getTeachers(HttpServletRequest request, HttpServletResponse response) {//获取当前页数int curPage = Integer.parseInt(request.getParameter("curPage"));//设置URLString url = "teacher?action=doGetTeachers&curPage=";//设置当前页的数据条数int count = 15;//计算偏移量int offset = (curPage-1)*count;//计算总页数int allCount = teacherMapper.getAllCount();int totalPage = PageUtils.getTotalPage(allCount,count);//从数据库获取老师的集合List<Teacher> teachers = teacherMapper.getTeachers(offset,count);//处理老师集合List<TeacherDto> teacherDtos = DtoUtils.teacherDtoListHandler(teachers);//封装Page对象Page<TeacherDto> page = new Page<>(url, curPage, totalPage, teacherDtos);//将数据存入到请求对象中request.setAttribute("page",page);}@Overridepublic void delete(HttpServletRequest request, HttpServletResponse response) {String username = request.getParameter("username");teacherMapper.delete(username);}
}
控制器层
TeacherController
@WebServlet("/teacher")
public class TeacherController extends BaseServlet {private TeacherService teacherService = new TeacherServiceImpl();public void doInitModify(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {teacherService.initModify(request,response);request.getRequestDispatcher("teaInfo.jsp").forward(request,response);}public void doModify(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {teacherService.modify(request,response);request.getRequestDispatcher("teacher?action=doGetTeachers&curPage=1").forward(request,response);}public void doGetTeachers(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {teacherService.getTeachers(request,response);request.getRequestDispatcher("TeaList.jsp").forward(request,response);}public void doDelete(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {teacherService.delete(request,response);request.getRequestDispatcher("teacher?action=doGetTeachers&curPage=1").forward(request,response);}public void doAddTea(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean add = teacherService.add(request,response);if(add){request.getRequestDispatcher("teacher?action=doGetTeachers&curPage=1").forward(request,response);}else{request.getRequestDispatcher("teaAdd.jsp").forward(request,response);}}}
2.3 用户 user
user是学生和老师的父类,两个都有的功能就写在user里
注意:在数据库中没有user这个表,这是把学生和老师相同的功能提出来了,放在user里
UserService
public interface UserService {//绘制验证码功能public void drawCode(HttpServletRequest request, HttpServletResponse response);//登录功能public boolean login(HttpServletRequest request, HttpServletResponse response);//记住我功能public void rememberMe(HttpServletResponse response,String username,String name,String role,String photo);//安全退出功能public void loginOut(HttpServletRequest request, HttpServletResponse response);//修改验证码功能public boolean resetPassword(HttpServletRequest request, HttpServletResponse response);}
UserServiceImpl
public class UserServiceImpl implements UserService {private StudentMapper studentMapper = new StudentMapperImpl();private TeacherMapper teacherMapper = new TeacherMapperImpl();private AdminMapper adminMapper= new AdminMapperImpl();//绘制验证码功能@Overridepublic void drawCode(HttpServletRequest request, HttpServletResponse response) {//设置宽高的变量int width = 120;int height = 30;//创建画布BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//获取画笔Graphics graphics = image.getGraphics();//设置背景色 -- 填充矩形graphics.setColor(Color.BLUE);graphics.fillRect(0,0,width,height);//设置验证码Random random = new Random();String[] codes = {"A","B","C","D","E","F","G","H","J","K","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9"};Color[] colors = {Color.CYAN,Color.BLACK,Color.GREEN,Color.PINK,Color.WHITE,Color.RED,Color.ORANGE};StringBuffer sb = new StringBuffer();for (int i = 0; i < 4; i++) {String randomCode = codes[random.nextInt(codes.length)];Color randomColor = colors[random.nextInt(colors.length)];graphics.setColor(randomColor);//设置随机颜色graphics.setFont(new Font("宋体",Font.BOLD,20+random.nextInt(10)));//设置字体(字体,样式,大小)graphics.drawString(randomCode,20+i*25,15+random.nextInt(10));//设置单个验证码sb.append(randomCode);}//将系统验证码设置到Session对象中(会话对象)HttpSession session = request.getSession();//获取请求里的JSESSIONID(客户端Cookie里的数据),如果没有就创建Session对象,如果有就从Session容器中获取会话对象session.setAttribute("sysCode",sb.toString());//设置干扰线graphics.setColor(Color.YELLOW);for (int i = 0; i < 3; i++) {graphics.drawLine(random.nextInt(width),random.nextInt(height),random.nextInt(width),random.nextInt(height));//绘制直线(x1,y1,x2,y2) -> 两点为一线}//将画布以jpg形式的文件传出给客户端try {ImageIO.write(image,"jpg",response.getOutputStream());} catch (IOException e) {throw new RuntimeException(e);}}//登录功能@Overridepublic boolean login(HttpServletRequest request, HttpServletResponse response) {//获取请求中的数据String username = request.getParameter("username");String password = request.getParameter("password");String userCode = request.getParameter("userCode");String rememberMe = request.getParameter("rememberMe");String role = request.getParameter("role");//从Session对象中获取系统的验证码String sysCode = (String) request.getSession().getAttribute("sysCode");if(sysCode.equalsIgnoreCase(userCode)){//验证码正确User user = null;if("student".equals(role)){user = studentMapper.getStudent(username,password);}else if("teacher".equals(role)){user = teacherMapper.getTeacher(username,password);} else if ("admin".equals(role)) {user = adminMapper.getAdmin(username, password);}if(user != null){//登录成功//判断是否记住我if(rememberMe != null){if("admin".equals(role)){rememberMe(response,user.getUsername(),user.getPassword(),role);HttpSession session = request.getSession();session.setAttribute("username",user.getUsername());session.setAttribute("password",user.getPassword());session.setAttribute("role",role);return true;}else if ("student".equals(role) || "teacher".equals(role)){rememberMe(response,user.getUsername(),user.getName() ,role,user.getPhoto());//将数据存储到Session中HttpSession session = request.getSession();session.setAttribute("username",user.getUsername());session.setAttribute("name",user.getName());session.setAttribute("role",role);session.setAttribute("photo",user.getPhoto());return true;}}if("admin".equals(role)){HttpSession session = request.getSession();session.setAttribute("username",user.getUsername());session.setAttribute("name",user.getPassword());session.setAttribute("role",role);}else if ("student".equals(role) || "teacher".equals(role)){//将数据存储到Session中HttpSession session = request.getSession();session.setAttribute("username",user.getUsername());session.setAttribute("name",user.getName());session.setAttribute("role",role);session.setAttribute("photo",user.getPhoto());}return true;}else{//登录失败 -- 账号或密码错误request.setAttribute("msg","登录失败 -- 账号或密码错误");return false;}}else{//登录失败 - 验证码错误request.setAttribute("msg","登录失败 -- 验证码错误");return false;}}//管理员的记住我private void rememberMe(HttpServletResponse response, String username, String password, String role) {response.addCookie(CookieUtils.createCookie("username",username,60*60*24*5));response.addCookie(CookieUtils.createCookie("password",password,60*60*24*5));response.addCookie(CookieUtils.createCookie("role",role,60*60*24*5));}//记住我功能@Overridepublic void rememberMe(HttpServletResponse response,String username, String name, String role, String photo) {//将凭证添加到Cookie中response.addCookie(CookieUtils.createCookie("username",username,60*60*24*5));response.addCookie(CookieUtils.createCookie("name",name,60*60*24*5));response.addCookie(CookieUtils.createCookie("role",role,60*60*24*5));response.addCookie(CookieUtils.createCookie("photo",photo,60*60*24*5));}//安全退出功能@Overridepublic void loginOut(HttpServletRequest request, HttpServletResponse response) {//删除Cookie里的数据response.addCookie(CookieUtils.createCookie("username","",0));response.addCookie(CookieUtils.createCookie("name","",0));response.addCookie(CookieUtils.createCookie("role","",0));response.addCookie(CookieUtils.createCookie("photo","",0));response.addCookie(CookieUtils.createCookie("password","",0));//删除Session里的数据HttpSession session = request.getSession();session.removeAttribute("username");session.removeAttribute("name");session.removeAttribute("role");session.removeAttribute("photo");session.removeAttribute("password");}//修改密码功能@Overridepublic boolean resetPassword(HttpServletRequest request, HttpServletResponse response) {//获取请求中的数据String username = request.getParameter("username");String password = request.getParameter("password");String newPassword = request.getParameter("newPassword");String role = request.getParameter("role");User user = null;if("student".equals(role)){user = studentMapper.getStudent(username,password);}else if("teacher".equals(role)){user = teacherMapper.getTeacher(username,password);} else if ("admin".equals(role)) {user = adminMapper.getAdmin(username, password);}if(user != null){if("student".equals(role)){studentMapper.update(username,newPassword);}else if("teacher".equals(role)){teacherMapper.update(username,newPassword);} else if ("admin".equals(role)) {adminMapper.update(username,newPassword);}return true;}else{request.setAttribute("msg","修改密码失败 -- 原密码不正确");return false;}}
}
UserController
,前端传过来的路径中带有action=“xxx功能”,然后进行xxx功能的相关业务的跳转
@WebServlet("/user")
public class UserController extends BaseServlet {private UserService userService = new UserServiceImpl();public void doDrawCode(HttpServletRequest request,HttpServletResponse response){userService.drawCode(request,response);}public void doLogin(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {boolean login = userService.login(request, response);if(login){response.sendRedirect("index.jsp");}else{request.getRequestDispatcher("login.jsp").forward(request,response);}}public void doLoginOut(HttpServletRequest request,HttpServletResponse response) throws IOException {userService.loginOut(request, response);response.sendRedirect("welcome.html");}public void doResetPassword(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean resetPassword = userService.resetPassword(request, response);if(resetPassword){request.getRequestDispatcher("user?action=doLoginOut").forward(request,response);}else{request.getRequestDispatcher("resetPassword.jsp").forward(request,response);}}}
2.4 管理员
功能:
1.登录(user里有)
2.修改密码(user里有)
3.管理老师 – 老师列表页面(分页、修改、删除、添加)
4.管理学科 – 学科列表页面(展示所有学科、修改、删除、添加)
5.管理学生 – 学生列表页面(分页、修改、删除、添加)
实体类 Admin 直接继承user类
SQL – admin :username、password
public class Admin extends User{}
AdminMapper
public interface AdminMapper {//获取管理员信息,通过usernamepublic Admin getAdmin(String username);//获取管理员信息,通过username和usernamepublic Admin getAdmin(String username,String password);//更新管理员的密码,通过username和newPasswordpublic void update(String username,String newPassword);
}
AdminMapperImpl
public class AdminMapperImpl implements AdminMapper {@Overridepublic Admin getAdmin(String username) {Admin admin=null;try {admin = DBUtils.commonQueryObj(Admin.class, "select * from admin where username =?", username);} catch (SQLException e) {throw new RuntimeException(e);}return admin;}@Overridepublic Admin getAdmin(String username, String password) {Admin admin=null;try {admin = DBUtils.commonQueryObj(Admin.class, "select * from admin where username =? and password=?", username,password);} catch (SQLException e) {throw new RuntimeException(e);}return admin;}@Overridepublic void update(String username, String newPassword) {try {DBUtils.commonUpdate("update admin set password = ? where username =?", newPassword, username);} catch (SQLException e) {throw new RuntimeException(e);}}
}
AdminService
都是uer里写了的,就没有AdminServiceImpl,controller层也没有,直接在index.jsp跳转就可以了
public interface AdminService {//登录功能public boolean login(HttpServletRequest request, HttpServletResponse response);//修改验证码功能public boolean resetPassword(HttpServletRequest request, HttpServletResponse response);
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head><title>Title</title>
</head>
<body><button οnclick="safeExit()">安全退出</button><h1>详情页面</h1><c:if test="${role eq 'admin'}"><h1>欢迎管理员进入到学生管理系统</h1></c:if><c:if test="${role eq 'student' || role eq 'teacher'}"><h1>欢迎${name}${(role eq "student")?"学员":""}${(role eq "teacher")?"老师":""}进入到学生管理系统</h1><img src="${photo}" width="100px" height="100px"><br/></c:if><a href="resetPassword.jsp">修改密码</a><c:if test="${role eq 'admin'}"><a href="student?action=doGetStudents&curPage=1">管理学生</a><a href="teacher?action=doGetTeachers&curPage=1">管理老师</a><a href="course?action=doGetCourses">管理学科</a></c:if><c:if test="${role eq 'student'}"><a href="student?action=doInitModify&username=${username}">修改信息</a></c:if><c:if test="${role eq 'teacher'}"><a href="teacher?action=doInitModify&username=${username}">修改信息</a><a href="student?action=doGetStudents&curPage=1">查看所有学生</a></c:if><script type="text/javascript">function safeExit(){window.location = "user?action=doLoginOut";}</script>
</body>
</html>
2.5 其他补充
数据库工具类DBUtils
package com.qf.utils;public class DBUtils {private static DruidDataSource pool;private static ThreadLocal<Connection> local;static{Properties properties = new Properties();try {properties.load(DBUtils.class.getClassLoader().getResourceAsStream("DBConfig.properties"));} catch (IOException e) {throw new RuntimeException(e);}String driverClassName = properties.getProperty("driverClassName");String url = properties.getProperty("url");String username = properties.getProperty("username");String password = properties.getProperty("password");int maxActive = Integer.parseInt(properties.getProperty("maxActive"));//初始化数据库连接池pool = new DruidDataSource();//设置参数pool.setDriverClassName(driverClassName);pool.setUrl(url);pool.setUsername(username);pool.setPassword(password);pool.setMaxActive(maxActive);local = new ThreadLocal<>();}/*** 获取连接对象*/public static Connection getConnection() throws SQLException {Connection connection = local.get();//获取当前线程的Connection对象if(connection == null){connection = pool.getConnection();//获取数据库连接池里的连接对象local.set(connection);//将Connection对象添加到local中}return connection;}/*** 关闭资源*/public static void close(Connection connection, Statement statement, ResultSet resultSet){if(resultSet != null){try {resultSet.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(statement != null){try {statement.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(connection != null){try {if(connection.getAutoCommit()){connection.close();local.set(null);}} catch (SQLException e) {throw new RuntimeException(e);}}}/*** 开启事务*/public static void startTransaction() throws SQLException {Connection connection = getConnection();connection.setAutoCommit(false);}/*** 提交事务*/public static void commit() throws SQLException {Connection connection = local.get();if(connection != null){connection.commit();connection.close();local.set(null);}}public static void rollback() throws SQLException {Connection connection = local.get();if(connection != null){connection.rollback();connection.close();local.set(null);}}/*** 更新数据(添加、删除、修改)*/public static int commonUpdate(String sql,Object... params) throws SQLException {Connection connection = null;PreparedStatement statement = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramHandler(statement,params);int num = statement.executeUpdate();return num;}finally {close(connection,statement,null);}}/*** 添加数据 - 主键回填(主键是int类型可以返回)*/public static int commonInsert(String sql,Object... params) throws SQLException {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);paramHandler(statement,params);statement.executeUpdate();resultSet = statement.getGeneratedKeys();int primaryKey = 0;if(resultSet.next()){primaryKey = resultSet.getInt(1);}return primaryKey;}finally {close(connection,statement,resultSet);}}/*** 查询多个数据*/public static <T> List<T> commonQueryList(Class<T> clazz,String sql, Object... params) throws SQLException{Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramHandler(statement,params);resultSet = statement.executeQuery();//获取表数据对象ResultSetMetaData metaData = resultSet.getMetaData();//获取字段个数int count = metaData.getColumnCount();List<T> list = new ArrayList<>();while(resultSet.next()){T t = null;try {t = clazz.newInstance();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}//获取字段名及数据for (int i = 1; i <= count; i++) {String fieldName = metaData.getColumnName(i);Object fieldVal = resultSet.getObject(fieldName);setField(t,fieldName,fieldVal);}list.add(t);}return list;} finally {DBUtils.close(connection,statement,resultSet);}}/*** 查询单个数据*/public static <T> T commonQueryObj(Class<T> clazz,String sql, Object... params) throws SQLException{Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramHandler(statement,params);resultSet = statement.executeQuery();//获取表数据对象ResultSetMetaData metaData = resultSet.getMetaData();//获取字段个数int count = metaData.getColumnCount();if(resultSet.next()){T t = null;try {t = clazz.newInstance();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}//获取字段名及数据for (int i = 1; i <= count; i++) {String fieldName = metaData.getColumnName(i);Object fieldVal = resultSet.getObject(fieldName);setField(t,fieldName,fieldVal);}return t;}} finally {DBUtils.close(connection,statement,resultSet);}return null;}/*** 获取当前表的总条数*/public static int getAllCount(String table) throws SQLException {Connection connection = getConnection();String sql = "select count(1) from " + table;PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery();if(resultSet.next()){int allCount = resultSet.getInt(1);return allCount;}return 0;}/*** 处理statement对象参数数据的处理器*/private static void paramHandler(PreparedStatement statement,Object... params) throws SQLException {for (int i = 0; i < params.length; i++) {statement.setObject(i+1,params[i]);}}/*** 获取当前类及其父类的属性对象* @param clazz class对象* @param name 属性名* @return 属性对象*/private static Field getField(Class<?> clazz,String name){for(Class<?> c = clazz;c != null;c = c.getSuperclass()){try {Field field = c.getDeclaredField(name);return field;} catch (NoSuchFieldException e) {} catch (SecurityException e) {}}return null;}/*** 设置对象中的属性* @param obj 对象* @param name 属性名* @param value 属性值*/private static void setField(Object obj,String name,Object value){Field field = getField(obj.getClass(), name);if(field != null){field.setAccessible(true);try {field.set(obj, value);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}}
其余代码太多,不一一展示
总结
1…MVC
注意:MVC设计模式和服务端分层思想的区别2.MVC版本的学生管理系统
相关文章:

学习java的日子 Day64 学生管理系统 web2.0 web版本
MVC设计模式 概念 - 代码的分层 MVC:项目分层的思想 字母表示层理解MModle模型层业务的具体实现VView视图层展示数据CController控制器层控制业务流程(跳转) 1.细化理解层数 Controller:控制器层,用于存放Servlet&…...

【第14章】Spring Cloud之Gateway路由断言(IP黑名单)
文章目录 前言一、内置路由断言1. 案例(Weight)2. 更多断言 二、自定义路由断言1. 黑名单断言2. 全局异常处理3. 应用配置4. 单元测试 总结 前言 Spring Cloud Gateway可以让我们根据请求内容精确匹配到对应路由服务,官方已经内置了很多路由断言,我们也…...

3、pnpm yarn npm
项目里实际上就只有这些依赖 node module 里却有很多的包 原因: 比如说vue,vue内部有依赖了其余的包。工具又依赖了别的依赖 造成的问题:我可以直接去用这个包,但是这个包在package.json中却没有看到-----幽灵依赖 那如果说别…...
❄️5. Kubernetes核心资源之名称空间和Pod实战
**什么是名称空间Namespace: ** Namespace是k8s系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多用户的资源隔离。默认情况下,k8s集群中的所有的Pod都是可以相互访问的。但是在实际中,可能不想让两个Pod之间进行互…...

锂电池充电板电路设计
写这篇文章的目的主要是个人经验的总结,希望能给开发者们提供一种锂电池充电电路以及电源显示的电路思路。接下来从以下几个方面讲述电路。 设计这款电路的初衷是想用一块硬币大小的锂电池作为供电电源(3.5V-4.2V),降压供给3.3V电…...

工业互联网产教融合实训基地解决方案
一、引言 随着“中国制造2025”战略的深入实施与全球工业4.0浪潮的兴起,工业互联网作为新一代信息技术与制造业深度融合的产物,正引领着制造业向智能化、网络化、服务化转型。为培养适应未来工业发展需求的高素质技术技能人才,构建工业互联网…...

高效批量提取PPT幻灯片中图片的方法
处理包含大量图片的PPT(PowerPoint)幻灯片已成为许多专业人士的日常任务之一。然而,手动从每张幻灯片中逐一提取图片不仅耗时耗力,还容易出错。为了提升工作效率,减少重复劳动,探索并实现一种高效批量提取P…...

怎么在 React Native 应用中处理深度链接?
深度链接是一种技术,其中给定的 URL 或资源用于在移动设备上打开特定页面或屏幕。因此,深度链接可以引导用户到应用程序内的特定屏幕,而不仅仅是启动移动设备上的应用程序,从而提供更好的用户体验。这个特定的屏幕可能位于一系列层…...

el-table自动滚动到最底部
我的需求是这样的,因为我的表格是动态的,可以手动新增行,固定表头,而且需要一屏显示,为了方便用户就需要再新增的时候表格自动向上滚动。 差了官方文档后发现有一个属性可以支持 这个属性正是自己需要的,所…...
小白零基础学数学建模系列-引言与课程目录
目录 引言一、我们的专辑包含哪些内容?第一周:数学建模基础与工具第二周:高级数学建模技巧与应用第三周:机器学习基础与数据处理第四周:监督学习与无监督学习算法第五周:神经网络 二、学完本专辑能收获到什…...
Integer类型比较是 == 还是equals()
在Java编程中,判断两个Integer对象是否相等时,我们经常遇到使用和equals()方法的选择问题。这两个操作符和方法在判断对象相等性时有所不同,理解它们的区别对于编写健壮的代码至关重要。 使用判断Integer相等性 在Java中,操作符…...

七夕情人节送什么礼物?看完这篇你就知道了
在这个充满爱意的时刻,送上一份精心挑选的礼物,不仅能表达你的爱意,更能加深彼此之间的情感联系。然而,选择一份合适的情人节礼物并非易事,因为每个人都有其独特的需求和喜好。如果你还在为情人节送什么礼物而纠结&…...

让B站直接变成一个纯粹的音乐平台的简单小方法
可能在大多数人眼里,B站就是一个内容丰富的高质量视频平台 但实际上B站还是一个“音乐平台”,只不过大多数时候都是以视频的形式呈现,所以你们可能对此没啥感觉。 那么今天给大家分享一款神级插件,让B站变成一个纯粹的音乐平台&a…...

【MySQL 01】在 Ubuntu 22.04 环境下安装 MySQL
文章目录 🌈 1. 说明🌈 2. 卸载不必要的环境🌈 3. 安装 MySQL🌈 4. 启动和关闭 MySQL 服务🌈 5. 临时登录 MySQL🌈 6. 设置 MySQL 密码🌈 7. 配置 MySQL 🌈 1. 说明 在安装与卸载中…...
linux命令 根据某一字段去掉txt中重复的数据
前提: 文档为格式化好的数据。比如一行是一个json。 判断总共有多少行数据: grep No f.txt | wc -l 查询重复数据有多少行: grep No f.txt | sort -u | wc -l 找到重复的那行数据:(如果每行的json数据大,可忽略此操…...

LVS(Linux virual server)
一:环境准备: rhel9 软件:httpd, ipvsadm 四台纯净的rhel9机子:一台LVS调度设备(双网卡),两台webserver(单网卡仅主机),一台客户机 DR模式多…...

End-to-End Object Detection with Transformers(Detection Transformer)翻译
摘要 我们提出了一种新方法,将目标检测视为直接的集合预测问题。我们的方法简化了检测流程,有效消除了对许多手工设计组件的需求,如非极大值抑制过程或锚框生成,这些组件显式编码了我们对任务的先验知识。新框架称为检测变换器&a…...

uniapp打开地图直接获取位置
uniapp官网文档 https://en.uniapp.dcloud.io/api/location/open-location.html <view class"map-content" click.stop"kilometer(item)"><view class"km">{{item.distance||0}}km</view></view>import map from ../../…...
Qt的事件处理机制、信号和槽以及两者之间的区别
Qt的事件处理机制 Qt 的事件处理机制是其框架的核心部分之一,用于处理用户操作、系统事件以及其他各种事件。以下是 Qt 事件处理机制的关键组成部分和流程: 事件对象 (QEvent): 所有事件在 Qt 中都是通过事件对象来表示的。QEvent 是所有事…...

LSTM实战之预测股票
📈 用PyTorch搭建LSTM模型,轻松预测股票价格!🚀 Hey小伙伴们,今天给大家带来一个超级实用的项目教程——如何用PyTorch和LSTM模型来预测股票价格!🌟 🔍 项目背景 我们都知道股市是…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...