声明:请勿利用本公众号文章内的相关技术、工具从事非法测试,如因此造成一切不良后果与文章作者及本公众号无关! |
-
JavaWeb之HTTP、Tomcat、Servlet -
JavaWeb之Request请求和Response响应 -
JavaWeb之JSP、会话技术(Cookie、Session) -
JavaWeb之Filter、Listener组件
通过这四篇的分享,基本掌握了javaweb主要的基础知识,本篇通过一个综合案例把这四个知识点柔和到一起,做一个简单的增删改查+登录验证的案例。加深大伙对javaweb的理解,有开发基础的师傅可以跳过了
目录:
0x01,整体效果
0x02,项目介绍
-- 基础环境准备
-- 核心功能
0x03,项目完整代码
0x01,整体效果
登录:
查看全部门派:
查看全部英雄:
增加和修改:
0x02,项目介绍
基础环境准备
-
创建项目模块,并添加必要目录和maven依赖
-
创建数据库表结构
-
导入mybatis.xml核心配置文件
-
准备项目结构(三层架构)和pojo实体类
-
准备mapper代理接口和mapper映射文件
项目结构如下:
一共三张表,门派表:
-- auto-generated definition
create table sects
(
id int unsigned auto_increment comment '主键ID'
primary key,
name varchar(100) not null comment '门派名称',
create_time datetime not null comment '创建时间',
update_time datetime not null comment '修改时间',
introduction varchar(200) null comment '简介',
constraint name
unique (name)
)
comment '门派表';
英雄表:
-- auto-generated definition
create table heroes
(
id int unsigned auto_increment comment 'ID'
primary key,
username varchar(20) not null comment '用户名',
password varchar(32) default '123456' null comment '密码',
name varchar(100) not null comment '英雄姓名',
kongfu varchar(50) null comment '代表武功',
gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
image varchar(300) null comment '图像',
level tinyint unsigned null comment '职位, 说明: 1 神级,2 绝顶, 3 一流, 4 准一流, 5 二流',
birthdate datetime null comment '出生日期',
sect_id int unsigned null comment '门派ID',
create_time datetime not null comment '创建时间',
update_time datetime not null comment '修改时间',
constraint username
unique (username)
)
comment '英雄豪杰表';
管理员表(登录用):
-- auto-generated definition
create table user
(
id int auto_increment
primary key,
username varchar(20) null,
password varchar(20) null,
isAdmin tinyint unsigned not null comment '性别, 说明: 1 管理员, 0 普通用户',
isEnable tinyint unsigned not null comment '性别, 说明: 1 启用, 0 禁用'
);
核心功能
主要有以下几个重要功能:
-
门派和英雄的增删改查(查询所有、根据id查询、删除、更新、添加)
-
管理员登录/注销功能:
-
用户登录和会话技术
-
图形验证码功能
-
登录过滤器
-
在线人数统计
-
Listener监听器统计在线人数
-
头像上传
-
为了后续上传webshell准备
门派的增删改查mapper代理接口:
package com.nvyao.mapper;
import com.nvyao.pojo.Sect;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface SectMapper {
/**
* 查询所有门派
* @return
*/
"select * from sects") (
"sectResultMap") (
List<Sect> selectAll();
/**
* 添加门派
* @param sect
*/
"insert into sects values (null, #{name}, #{createTime}, #{updateTime}, #{introduction})") (
void add(Sect sect);
/**
* 根据门派id删除门派
* @param id
*/
"delete from sects where id = #{id}") (
void deleteById(int id);
/**
* 根据门派id查询
* @param id
* @return
*/
"select * from sects where id = #{id}") (
"sectResultMap") (
Sect selectById(int id);
/**
* 更新门派信息
* @param sect
*/
"update sects set name = #{name}, introduction = #{introduction}, update_time = #{updateTime} where id = #{id}") (
void update(Sect sect);
}
管理员登录/注销的mapper代理接口:
package com.nvyao.mapper;
import com.nvyao.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
/**
* 根据用户名和密码查询用户对象
* @param username
* @param password
* @return
*/
User select( String username, String password);
/**
* 根据用户名密码查询用户列表,为了sql注入
* @param username
* @param password
* @return
*/
List<User> selectAll( String username, String password);
/**
* 根据用户名查询用户对象
* @param username
* @return
*/
User selectByUsername( String username);
/**
* 添加用户
* @param user
*/
void add(User user);
}
登录逻辑:
package com.nvyao.web;
import com.nvyao.pojo.User;
import com.nvyao.service.UserService;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
"/loginServlet") (
public class LoginServlet extends HttpServlet {
private final UserService service = new UserService();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1、接收用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//获取复选框-是否记住密码
String remember = request.getParameter("remember");
//获取用户输入的验证码:
String checkCode = request.getParameter("checkCode");
//获取服务端生成的验证吗
HttpSession session = request.getSession();
String checkCodeGen = (String) session.getAttribute("checkCodeGen");
//校验验证码
if(!checkCodeGen.equalsIgnoreCase(checkCode)){
//不允许注册
request.setAttribute("register_msg","验证码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
//2、调用service去查询
User user = service.login(username, password);
//3、判断
if(user != null){
//判断用户的状态是否是启用
if (user.getIsEnable() == 0) {
// 用户被禁用,提示用户已禁用
request.setAttribute("login_msg", "用户已被禁用,请联系管理员");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
//判断用户是否勾选记住我
if("1".equals(remember)){
//勾选了,发送cookie
//1、创建cookie对象
Cookie c_username = new Cookie("username",username);
Cookie c_password = new Cookie("password",password);
//设置cookie存活时间
c_username.setMaxAge(60 * 60 * 24 * 7);
c_password.setMaxAge(60 * 60 * 24 * 7);
//2、发送
response.addCookie(c_username);
response.addCookie(c_password);
}
//将登录成功的user对象,存储到session
// 改了这里这里这里
session.setAttribute("user",user);
String contextPath = request.getContextPath();
//登录成功
response.sendRedirect(contextPath + "/selectAllHeroesServlet");
}else{
//登陆失败
request.setAttribute("login_msg","用户名或密码错误");
//跳转到login.jsp
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
生成图形验证码:
package com.nvyao.web;
import com.nvyao.utils.CheckCodeUtil;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
"/checkCodeServlet") (
public class CheckCodeServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//生成验证码
ServletOutputStream os = response.getOutputStream();
String checkCode = CheckCodeUtil.outputVerifyImage(100, 60, os, 4);
System.out.println("当前图形验证码:" + checkCode);
//存入session中
HttpSession session = request.getSession();
session.setAttribute("checkCodeGen", checkCode);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
登录过滤器逻辑:
package com.nvyao.web.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* 登录验证过滤器
*/
"/*") (
public class LoginFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("LoginFilter被执行....");
HttpServletRequest req = (HttpServletRequest) request;
//判断访问资源路径是否和登录注册相关
String[] urls = {"/login.jsp","/imgs/","/css/","/loginServlet","/register.jsp","/registerServlet","/checkCodeServlet"};
//获取当前访问的资源路径
String url = req.getRequestURL().toString();
System.out.println("当前url是:" + url);
//循环判断
for (String u : urls) {
if(url.contains(u)){
//找到了,放行
chain.doFilter(request, response);
return;
}
}
//1、判断session中是否有user
HttpSession session = req.getSession();
Object user = session.getAttribute("user");
//2、判断user是否为null
if(user != null){
//登录,放行
chain.doFilter(request, response);
}else{
//未登录,存储提示信息,跳转到登录页面
req.setAttribute("login_msg","您尚未登录");
req.getRequestDispatcher("/login.jsp").forward(req, response);
}
}
public void destroy() {
}
}
监听器代码(统计在线人数):
package com.nvyao.web.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class SessionCounterListener implements HttpSessionAttributeListener {
private static int activeSessions = 0;
public void attributeAdded(HttpSessionBindingEvent event) {
// 获取 ServletContext 对象
if ("user".equals(event.getName())) { // 如果添加的属性名为"user",表示有用户登录
activeSessions++;
System.out.println("User logged in. Total active sessions: " + activeSessions);
}
}
public void attributeRemoved(HttpSessionBindingEvent event) {
if ("user".equals(event.getName())) { // 如果移除的属性名为"user",表示有用户登出
if (activeSessions > 0) {
activeSessions--;
}
System.out.println("User logged out. Total active sessions: " + activeSessions);
}
}
public void attributeReplaced(HttpSessionBindingEvent event) {
}
public static int getActiveSessions() {
return activeSessions;
}
}
还有文件上传,本来不想做这个功能,但是为了后面可以上传webshell就做了:
//处理文件上传
String appPath = request.getServletContext().getRealPath("");
String savePath = appPath + SAVE_DIR;
System.out.println(savePath);
Part filePart = request.getPart("image");
String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
try (InputStream fileContent = filePart.getInputStream()) {
Files.copy(fileContent, Paths.get(savePath, fileName));
} catch (IOException e) {
e.printStackTrace();
}
String imagePath = request.getContextPath() + SAVE_DIR + "/" + fileName;
System.out.println(imagePath);
0x03,项目完整代码
tianlong-javaweb
https://github.com/bansh2eBreak/tianlong-javaweb
请师傅们指教~~,尽情期待最后一片内存马专题
原文始发于微信公众号(安全随笔):JavaWeb之综合案例(天龙八部管理系统)
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论