我们上一节课写的登陆系统里面,我们在验证用户的时候,只是简单的验证,是指定用户。现在增加到数据库验证用户的功能。
大家应该学习过java文件当中操作数据库,其实servler中操作数据库和普通java文件是完全一样的。
现在我们在LoginCheck.java里面增加这个功能。
大家要注意的一点是使用servlet操作数据库的时候会发生sql注入漏洞,这个大家一定要注意,我也会在后面详细介绍。
当然首先你要在sqlServer当中建立相应的数据库和表
create database spdb1
go
use spdb1
go
create table users (
userId int primary key identity(1,1),--用户id号
username varchar(20),--用户名
passwd varchar(20),--用户密码
email varchar(30),--电子邮件
grade int)--用户的级别
go
insert into users values
('admin','admin','admin@sohu.com',1)
insert into users values
('shunping','shunping','shunping@sohu.com', 1)
insert into users values
('tester1','tester1','tester1@sohu.com',5)
insert into users values
('tester2','tester2','tester2@sohu.com',5)
insert into users values
('tester3','tester3','tester3@sohu.com',5)
insert into users values
('tester4','tester4','tester4@sohu.com',5)
insert into users values
('tester5','tester5','tester5@sohu.com',5)
insert into users values
('tester6','tester6','tester6@sohu.com',5)
insert into users values
('tester7','tester7','tester7@sohu.com',5)
insert into users values
('tester8','tester8','tester8@sohu.com',5)
insert into users values
('tester9','tester9','tester9@sohu.com',5)
insert into users values('tester10','tester10','tester10@sohu.com',5)
insert into users values('tester11','tester11','tester11@sohu.com',5)
insert into users values('tester12','tester12','tester12@sohu.com',5)
insert into users values('tester13','tester13','tester13@sohu.com',5)
insert into users values('tester14','tester14','tester14@sohu.com',5)
--显示用户表
select * from users;
(1)首先要加载驱动包
加载sqlServer2005的驱动包
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
加载sqlServer2000的驱动包
Class.forName(“com.microsoft.jdbc.sqlserver.SQLServerDriver”);
上面会牵涉到SQLException
(2)下一步得到数据库链接
其实就是得到一个Connection 对象
链接sqlServer2005的相关数据库
Connection conn= DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;databaseName=spdb1","sa","admin");
链接sqlServer2000的相关数据库
Connection conn = DriverManager.getConnection(“jdbc:mirosoft:sqlserver://127.0.0.1:1433;databaseName=spdb1”);
(3)获得Statement对象
Statement sm= conn.createStatement();
(4)下面进行查询,会得到一个ResultSet结果集对象
ResultSet rs = sm.executeQuery("select * from users where username='"+u+ "' and passwd='" +p+"'");
在查询的时候要注意
select * from users where username=’ "+u+ " ' and passwd= ' " +p+" ' ";
首先是这个奇葩的组合
然后这样查询其实效率不高,因为我们是要验证登陆
select top 1 返回一条记录这样的效率会更高,如果没有top 1
假设表中有数据100万条,可能你要查询的数据在第一条,但是当查到相应的信息后不会停下来,而是傻傻的继续向下面走,找到第100万条之后,再返回说只找到一个第一条
这样效率很低,但是当加上top 1 当然是在用户名不可能重复的情况下就会很高的提高效率
(5)进行判断
if(rs.next()){
}
(6) 我们在创建Connection Statement ResultSet 的时候会占用很多资源,虽然完成工作后java会自动关闭,但是不如我们自己关闭规范或者说效率更高些(会自动等待一定时间后系统才会自动关闭)。
如果不进行关闭的话就会发现你的代码是不好的代码,是对数据库的一种不负责任的态度。
我们可以把关闭数据库的代码放在finally{
}
里,finally里面的代码的意义在于不管这个程序会抛出异常都会执行的代码。
finally{
try{
if(rs!=null){
rs.close();
}
if(sm!=null){
sm.close();
}
if(ct!=null){
ct.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
这就体现出来为什么要把这些东西定义到外面的必要性
servlet操作数据库的注意事项
需要将连接数据库的jar包放置到Tomcat服务器
具体有两种方放置方法:
(1)将.jar 包拷贝到.common/lib目录下面
(2)或者在你的webapps目录下的WEB-INF文件夹下建立一个lib文件夹,然后把jar包拷贝纸lib文件夹下
两种方法的区别
第一种 所有webapps都可以使用三个jar包(公用lib库)
第二种 只有放到哪个web目录下的才嫩使用
专用 llib库
下面讲述sql注册漏洞
select * from users where username = 'admin' and passwd = 'admin' or 1='1';
会将所有数据都给查询出来 这就是sqlServer 注册漏洞
这样的话无论输入什么密码都会成功
怎么处理呢?
我们可以这样 首先得到用户名
然后查询该用户名匹配的代码是否等于输入密码
//用户验证servlet
package com.tsinghua;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
public class LoginCheck extends HttpServlet{
public void doGet(HttpServletRequest req,HttpServletResponse res){
Connection ct = null;
Statement sm = null;
ResultSet rs = null;
try{
String u = req.getParameter("username");
String p = req.getParameter("password");
//连接数据库
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
//得到链接 Connection对象
ct = DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;databaseName=spdb1","sa","admin");
// 创建statement
sm = ct.createStatement();
//得到结果集
//rs = sm.executeQuery("select top 1 from users where username='"+u+ "' and passwd='" +p+"'");
/*//if(u.equals("sp")&&p.equals("123")){
//if(p.equals("123")){
if(rs.next()){
// 将验证成功的信息写入session
//1:得到session
HttpSession hs = req.getSession(true);
//修改session的存在时间
hs.setMaxInactiveInterval(20);
hs.setAttribute("pass","OK");
res.sendRedirect("welcome?uname="+u+"&upass="+p);
}*/
rs = sm.executeQuery("select top 1 from users where username = '"+u+"'");
if(rs.next()){
//说明用户是存在的
String dbPasswd = rs.getString(1);
if(dbPasswd.equals(p)){
// 将验证成功的信息写入session
//1:得到session
HttpSession hs = req.getSession(true);
//修改session的存在时间
hs.setMaxInactiveInterval(20);
hs.setAttribute("pass","OK");
res.sendRedirect("welcome?uname="+u+"&upass="+p);
// 真的合法
}
}
else{
res.sendRedirect("login");// 里面的内容是写你要跳转servlet的url
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(rs!=null){
rs.close();
}
if(sm!=null){
sm.close();
}
if(ct!=null){
ct.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
public void doPost(HttpServletRequest req,HttpServletResponse res){
this.doGet(req,res);
}
}