从零开始学习JavaWeb-15
目录
从零开始学习JavaWeb-15
一、数据库安全与防注入实战
1. SQL 注入原理与危害
攻击本质:利用输入漏洞篡改 SQL 语义,例如:
SELECT * FROM users WHERE username = 'admin' OR '1'='1' -- AND password = 'xxx'
OR '1'='1'
导致条件永真,绕过密码验证。危害:数据泄露(用户隐私)、越权操作(删库)、服务瘫痪。
2. 防御方案
预编译(PreparedStatement):强制分离指令与参数
String sql = "SELECT * FROM users WHERE username = ? AND password = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, inputUser); // 参数视为值而非代码 ps.setString(2, inputPass);
输入校验:正则过滤特殊字符(如
'
、--
)if (!inputUser.matches("[a-zA-Z0-9_]+")) { throw new InvalidInputException("用户名含非法字符"); }
最小权限原则:数据库账号仅授权必要操作(禁用
DROP
、DELETE
)。
3. 存储过程与ORM框架
存储过程:封装 SQL 逻辑,减少动态拼接(但需防内部注入)
ORM 框架(如 MyBatis):
<select id="getUser" resultType="User"> SELECT * FROM users WHERE username = #{user} <!-- #{} 自动预编译 --> </select>
二、MySQL 深度优化策略
1. 索引优化与慢查询分析
索引类型 | 适用场景 | 优化效果 |
---|---|---|
B+树索引 | 等值查询(= )、范围查询(> ) | 减少全表扫描,速度提升 10-100 倍 |
哈希索引 | 精确匹配(无范围查询) | O(1) 查询,但不支持排序 |
慢查询日志:
-- 启用慢查询日志 SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2; -- 阈值2秒
分析工具:
mysqldumpslow
、Percona Toolkit。
2. 事务隔离级别选择
级别 | 脏读 | 不可重复读 | 幻读 | 适用场景 |
---|---|---|---|---|
READ UNCOMMITTED | ✓ | ✓ | ✓ | 极少使用 |
READ COMMITTED | ✗ | ✓ | ✓ | Oracle 默认 |
REPEATABLE READ | ✗ | ✗ | ✓ | MySQL 默认 |
SERIALIZABLE | ✗ | ✗ | ✗ | 强一致性(金融系统) |
代码设置:
// JDBC 设置事务隔离级别
conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
三、数据库连接池调优
1. 核心参数配置(以 Druid 为例)
参数 | 推荐值 | 作用 |
---|---|---|
initialSize | CPU核心数 | 启动时初始化连接数 |
maxActive | 50 | 最大连接数(防数据库过载) |
minIdle | 5 | 最小空闲连接(应对突发流量) |
maxWait | 3000 | 获取连接超时时间(ms) |
validationQuery | SELECT 1 | 心跳检测 SQL |
监控集成:
<!-- 启用 Druid 监控 -->
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
访问 http://localhost:8080/druid
查看 SQL 执行效率、慢查询统计。
四、综合实战:用户管理系统安全优化
1. 架构分层设计
graph TB
A[View] --> B[Controller]
B --> C[Service]
C --> D[DAO]
D --> E[MySQL]
F[Filter] -->|全局安全控制| B
- Filter 层:统一防 XSS 攻击(过滤请求参数)。
- Service 层:事务管理 + 密码加密(BCrypt)。
2. 关键代码实现
密码加密存储:
public String encryptPassword(String rawPassword) { return BCrypt.hashpw(rawPassword, BCrypt.gensalt()); } // 验证密码 public boolean checkPassword(String rawPassword, String hashedPassword) { return BCrypt.checkpw(rawPassword, hashedPassword); }
防 XSS 过滤器:
@WebFilter("/*") public class XssFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { HttpServletRequest request = (HttpServletRequest) req; XssRequestWrapper wrappedRequest = new XssRequestWrapper(request); // 包装请求,过滤参数 chain.doFilter(wrappedRequest, res); } }
五、高并发场景解决方案
1. 读写分离(MySQL Replication)
角色 | 作用 | 配置示例 |
---|---|---|
Master | 写操作(INSERT/UPDATE) | binlog-do-db = appdb |
Slave | 读操作(SELECT) | replicate-do-db = appdb |
代码路由:
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return TransactionSynchronizationManager.isCurrentTransactionReadOnly()
? "slave" : "master";
}
}
2. 缓存优化(Redis)
- 缓存穿透:布隆过滤器拦截非法查询。
- 缓存雪崩:随机过期时间 + 熔断降级。
// 查询优化:先查缓存,未命中再查库
public User getUserById(int id) {
String key = "user:" + id;
User user = redisTemplate.opsForValue().get(key);
if (user == null) {
user = userDao.findById(id); // 数据库查询
redisTemplate.opsForValue().set(key, user, 30, TimeUnit.MINUTES);
}
return user;
}
六、总结与知识图谱
模块 | 核心技术点 | 企业级实践 |
---|---|---|
数据库安全 | 预编译 + 输入校验 + 权限控制 | 防御 SQL 注入/XSS 攻击 |
MySQL 优化 | B+树索引 + 慢查询分析 + 事务隔离 | 提升查询效率至毫秒级 |
连接池调优 | 参数配置 + 实时监控 | 支撑 5000+ TPS 并发 |
高并发架构 | 读写分离 + Redis 缓存 | 应对百万级用户请求 |
学习路线图:
graph LR
A[基础] --> B[Servlet/JSP]
B --> C[JDBC/连接池]
C --> D[会话管理]
D --> E[安全防护]
E --> F[高并发架构]
“安全是系统的生命线,性能是用户体验的基石”
动手实践:
- 注入防御测试:尝试攻击自己的系统(如输入
' OR 1=1 --
),验证防护有效性。- 慢 SQL 优化:通过
EXPLAIN
分析查询计划,添加复合索引。- 压力测试:用 JMeter 模拟 1000 并发用户,优化连接池参数。
扩展挑战:
- 整合 Spring Security 实现 RBAC 动态权限控制。
- 使用 ShardingSphere 实现分库分表。