lab06JDBC.docx
- 文档编号:20196100
- 上传时间:2023-04-25
- 格式:DOCX
- 页数:18
- 大小:46.61KB
lab06JDBC.docx
《lab06JDBC.docx》由会员分享,可在线阅读,更多相关《lab06JDBC.docx(18页珍藏版)》请在冰豆网上搜索。
lab06JDBC
Lab06JDBC
实验目标
本实验练习JDBC编程方法,包括JDBCAPI使用、数据持久层设计、数据库连接池、SQL安全性等。
本实验将完成如下任务:
✧为Web应用FileShare系统设计并创建数据库fsdb。
✧将原系统中模拟数据库操作的部分改为实际数据库支持,练习使用SQL语句及存储过程。
✧重构系统,管理数据库连接,使用连接池,用DAO模式并抽象数据持久层。
✧初步进行数据操作安全性考量
实验步骤概要:
1.导入Web项目FileShare3。
2.建立数据库fsdb,设计表结构:
UserInfo、FileInfo等。
3.修改用户登录验证和注册功能中的数据操作。
4.修改文件列表显示、下载等功能中的数据操作。
5.使用数据库连接池。
6.在文件列表页面增加查询功能。
7.思考:
对已有文件如何删除?
如何设计权限?
8.增加用户管理功能。
删除用户时应同时删除其上传的文件。
实验步骤
Step1导入Web工程
File->Import->General->ExistingProjectsintoWorkspace,点击"Next>"
选择项目根路径,Finish。
Step2设计并创建数据库
创建数据库fsdb。
可使用MySql或者SQLServer等任意数据库。
建议使用免费的MySql,本例中使用大家最为熟悉的SQLServer2000。
先从fsdb[SQL2K].sql创建表UserInfo和FileInfo。
如果是MySQL,使用fsdb[MySQL].sql。
添加一些测试数据。
如添加两个用户admin和test。
下载JDBC驱动程序。
下载MySql或SQLServer的JDBC驱动程序。
SQLServer2000的JDBC驱动有3个jar文件。
将驱动程序COPY到WEB应用的“WEB-INF/lib”目录下即可。
如果拷贝到Tomcat安装目录的lib目录下,则部署在其上的所有Web应用都可以使用该驱动。
或者也可以COPY到JRE/lib/ext目录下。
测试一下JDBC连接。
创建SQLServerTester作为测试程序,看是否连接成功。
Step3修改用户登录和注册
修改User.java。
根据数据库模型相应修改。
原来用userId属性表示登录帐户名,现在仍然保留userId,但改为int类型,作为用户唯一标识,对应于表UserInfo中的Id字段;增加loginName表示用户帐户名,对应于表UserInfo中的LoginName字段,并添加Getter/Setter。
为保持命名一致,将register.jsp页面中的userId也改为loginName。
publicclassUser{
privateintuserId;
privateStringloginName;
privateStringuserName;
/**性别:
'1'-男;'0'-女*/
privatecharsex;
privateStringpassword;
/**班级编号*/
privateStringgrade;
/**手机号码*/
privateStringcell;
privateStringemail;
/**角色:
"admin"-管理员;"user"-普通用户*/
privateStringrole;
//Getter/Setter...
}
修改UserDAO.java。
将原有的模拟数据库部分删掉,增加数据库操作,保持接口不变。
publicclassUserDAO{
privateStringdb_url=
"jdbc:
microsoft:
sqlserver:
//localhost:
1433;DatabaseName=fsdb";
privateStringdb_user="sa";
privateStringdb_pwd="sa";
/**
*查询用户
*@paramuserId用户ID
*/
publicUserfindUser(StringuserId){
Connectionconn=null;
try{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
conn=DriverManager.getConnection(db_url,db_user,db_pwd);
if(conn==null)
thrownewException("UserDAO:
无法获得数据库连接!
");
}catch(Exceptionex){
System.out.println("UserDAOError:
"+ex);
}
try{
Stringsql="SELECT*FROMUserInfoWHEREId="+userId;
Statementst=conn.createStatement();
ResultSetrs=st.executeQuery(sql);
if(rs.next()){
Useruser=newUser();
user.setUserId(rs.getInt("ID"));
user.setUserName(rs.getString("UserName"));
user.setLoginName(rs.getString("LoginName"));
user.setSex(rs.getString("Sex").charAt(0));
user.setCell(rs.getString("Cell"));
user.setEmail(rs.getString("Email"));
user.setGrade(rs.getString("Grade"));
user.setRole(rs.getString("Role"));
returnuser;
}
}catch(SQLExceptionex){
System.out.println("UserDAOSQLException:
"+ex);
}finally{
if(conn!
=null){
try{
conn.close();
}catch(SQLExceptione){}
}
}
returnnull;
}
publicUserqueryUser(StringloginName,Stringpassword){
Connectionconn=null;
try{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
conn=DriverManager.getConnection(db_url,db_user,db_pwd);
if(conn==null)
thrownewException("UserDAO:
无法获得数据库连接!
");
}catch(Exceptionex){
System.out.println("UserDAOError:
"+ex);
}
try{
Stringsql="SELECT*FROMUserInfoWHERELoginName='"
+loginName+"'";
if(password!
=null){
sql+="ANDUserPwd='"+password+"'";
}
Statementst=conn.createStatement();
ResultSetrs=st.executeQuery(sql);
if(rs.next()){
Useruser=newUser();
user.setUserId(rs.getInt("ID"));
user.setUserName(rs.getString("UserName"));
user.setLoginName(rs.getString("LoginName"));
user.setSex(rs.getString("Sex").charAt(0));
user.setCell(rs.getString("Cell"));
user.setEmail(rs.getString("Email"));
user.setGrade(rs.getString("Grade"));
user.setRole(rs.getString("Role"));
returnuser;
}
}catch(SQLExceptionex){
System.out.println("UserDAOSQLException:
"+ex);
}finally{
if(conn!
=null){
try{
conn.close();
}catch(SQLExceptione){}
}
}
returnnull;
}
/**
*新增用户
*@paramuser用户对象
*/
publicbooleaninsert(Useruser){
Stringsql="INSERTINTOUserInfo(LoginName,UserName,UserPwd,Sex,Grade,Cell,Email)"+
"VALUES(?
?
?
?
?
?
?
)";
Connectionconn=null;
try{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
conn=DriverManager.getConnection(db_url,db_user,db_pwd);
if(conn==null)
thrownewException("UserDAO:
无法获得数据库连接!
");
conn.setAutoCommit(false);
}catch(Exceptionex){
System.out.println("UserDAOError:
"+ex);
}
PreparedStatementps=null;
intnum=1;
try{
ps=conn.prepareStatement(sql);
ps.setString(num++,user.getLoginName());
ps.setString(num++,user.getUserName());
ps.setString(num++,user.getPassword());
ps.setString(num++,user.getSex()+"");
ps.setString(num++,user.getGrade());
ps.setString(num++,user.getCell());
ps.setString(num++,user.getEmail());
if(ps.executeUpdate()<=0){
thrownewException("插入表UserInfo出错!
");
}
mit();
returntrue;
}catch(Exceptione){
System.err.println("****插入表UserInfo出错!
");
e.printStackTrace();
try{
if(conn!
=null)
conn.rollback();
}catch(Exceptionex){
}
returnfalse;
}finally{
if(conn!
=null){
try{
conn.close();
}catch(SQLExceptione){}
}
if(ps!
=null){
try{
ps.close();
}catch(SQLExceptione){}
}
}
}
/**
*删除用户
*@paramuser用户对象
*/
publicvoiddelete(Useruser){
}
}
修改LoginServlet.java。
将原有的userId相关部分改为loginName(对应于User类及用户表UserInfo的改动)。
登录部分。
修改doPost()方法登录处理如下:
StringloginUrl="/login.jsp";
StringfileUrl="/filelist.jsp";
HttpSessionsession=request.getSession();
StringloginName=request.getParameter("user_name");
Stringpassword=request.getParameter("login_password");
//验证用户ID和密码是否合法
UserDAOuserDao=newUserDAO();
Useruser=userDao.queryUser(loginName,password);
ServletContextcontext=getServletContext();
Stringmessage="用户名或密码错误!
";
if(user==null){
request.setAttribute("message",message);
RequestDispatcherdispatcher=
context.getRequestDispatcher(loginUrl);
dispatcher.forward(request,response);
return;
}
//登录成功,设置session中的属性
session.setAttribute("User",user);
RequestDispatcherdispatcher=context.getRequestDispatcher(fileUrl);
dispatcher.forward(request,response);
注册部分。
修改register()方法如下:
privatevoidregister(...)throws...{
StringloginName=request.getParameter("loginName");
StringuserName=request.getParameter("userName");
StringstrSex=request.getParameter("sex");
charsex=strSex.charAt(0);
Stringpassword=request.getParameter("password");
Stringpassword2=request.getParameter("retype_password");
Stringgrade=request.getParameter("grade");
Stringcell=request.getParameter("cell");
Stringemail=request.getParameter("email");
//验证表单输入数据合法性略...
//验证用户是否存在
Stringmessage="账户名已经存在!
";
StringregUrl="/register.jsp";
UserDAOuserDao=newUserDAO();
Useru=userDao.queryUser(loginName,null);
if(u!
=null){
request.setAttribute("message",message);
RequestDispatcherdispatcher=
getServletContext().getRequestDispatcher(regUrl);
dispatcher.forward(request,response);
return;
}
//验证通过,将用户数据添加到数据库
Useruser=newUser();
user.setLoginName(loginName);
user.setUserName(userName);
user.setSex(sex);
user.setPassword(password);
user.setGrade(grade);
user.setEmail(email);
user.setCell(cell);
if(userDao.insert(user)){
//注册成功,转到文件列表页面
StringfileUrl="/filelist.jsp";
request.getSession().setAttribute("User",user);
RequestDispatcherdispatcher=
getServletContext().getRequestDispatcher(fileUrl);
dispatcher.forward(request,response);
}else{
request.setAttribute("message","注册失败。
");
RequestDispatcherdispatcher=
getServletContext().getRequestDispatcher(regUrl);
dispatcher.forward(request,response);
return;
}
}
Step4重构:
管理数据库连接
修改包名。
首先将包chapter03改为chapter05。
注意web.xml文件和JSP也要相应修改。
新建包chapter05.dao和chapter05.db。
将类UserDAO、CFileDAO移至chapter05.dao中。
统一管理DB连接。
从前面的数据库操作代码中,可以看到有大量重复性的代码,比如:
获取数据库连接等。
下面我们将这一部分抽象出来,用一个新建的类DBHelper进行管理。
将类DBHelper创建在包chapter05.db中。
publicclassDBHelper{
privatestaticfinalStringdriver=
"com.microsoft.jdbc.sqlserver.SQLServerDriver";
privatestaticfinalStringurl=
"jdbc:
microsoft:
sqlserver:
//localhost:
1433;DatabaseName=fsdb";
privatestaticfinalStringuser="sa";
privatestaticfinalStringpwd="sa";
publicstaticConnectiongetConnection(){
Connectionconn=null;
try{
Class.forName(driver);
conn=DriverManager.getConnection(url,user,pwd);
conn.setAutoCommit(false);
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}catch(SQLExceptione){
e.printStackTrace();
}
returnconn;
}
publicstaticvoidclose(Connectionconn){
if(conn!
=null){
try{
conn.close();
}catch(SQLExceptione){}
conn=null;
}
}
publicstaticvoidclose(Statementstmt,ResultSetrs){
if(stmt!
=null){
try{
stmt.close();
}catch(SQLExceptione){}
}
if(rs!
=null){
try{
rs.close();
}catch(SQLExceptione){}
}
}
}
SQL安全性。
在登录页面中,如果用户名和密码都输入:
asdf'or'1'='1,尽管该用户不存在,但仍然可以登录。
这就是SQL注入攻击。
这里只是简单的通过SQL注入完成登录,如果利用复杂一些的SQL注入,可以修改、删除甚至毁掉整个数据库,所以这其实是一个很严重的安全问题。
对于这个问题,我们可以用很简单的方法来解决,那就是,使用PreparedStatement对象。
改写UserDAO类。
代码如下。
/**
*删除用户
*@paramuser用户对象
*/
publicbooleandelete(Useruser){
Stringsql="DELETEFROMUser
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- lab06JDBC