0x01 实验要求
采用JSP+Servlet+JavaBean+JDBC方式开发一个Web登录程序。
要求:数据库中建一个“用户名-密码”表,用户由页面上输入用户名和密码,单击【登录】按钮提交,程序通过JDBC访问数据库中的表来验证用户,验证通过转到主页并回显欢迎信息,否则跳转至出错页。
0x02 实验步骤
2.1 建立数据库与表
建表
mysql> create table userTable(id int AUTO_INCREMENT PRIMARY KEY,
-> username varchar(20),
-> password varchar(20)
-> );
插入两条数据
mysql> insert into userTable values(1,'v0w','v0wldl123');
Query OK, 1 row affected (0.00 sec)
mysql> insert into userTable values(2,'zz','zz250');
Query OK, 1 row affected (0.00 sec)
mysql> select * from userTable;
+----+----------+-----------+
| id | username | password |
+----+----------+-----------+
| 1 | v0w | v0wldl123 |
| 2 | zz | zz250 |
+----+----------+-----------+
2 rows in set (0.00 sec)
2.2 创建Java EE项目
在MyEclipse 中,选择主菜单【File】→【New】→【Web Project】,填写“Project Name”栏(为项目起名),项目命名为jsp_servlet_javabean_jdbc
2.3 编写jsp程序
本例只须写3个JSP文件:login.jsp(登录页)、main.jsp(主页)和error.jsp(出错页)
login.jsp
<%@ page language="java" pageEncoding="gb2312"%>
<html>
<head>
<title>简易留言板</title>
</head>
<body bgcolor="#E3E3E3">
<form action="mainServlet" method="post">
<table>
<caption>用户登录</caption>
<tr>
<td>用户名:</td>
<td>
<input type="text" name="username" size="20"/>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" name="password" size="21"/>
</td>
</tr>
</table>
<input type="submit" value="登录"/>
<input type="reset" value="重置"/>
</form>
如果没注册单击<a href="">这里</a>注册!
</body>
</html>
main.jsp
<%@ page language="java" pageEncoding="gb2312"%>
<html>
<head> <title>留言板信息</title></head>
<body>
<% out.print(request.getParameter("username"));%>,您好!欢迎登录留言板。
</body>
</html>
error.jsp
<%@ page language="java" pageEncoding="gb2312"%>
<html>
<head> <title>出错</title></head>
<body>
登录失败!单击<a href="login.jsp">这里</a>返回
</body>
</html>
2.4 构造Java类、创建JDBC
在项目src文件夹下建立包org.easybooks.test.model.vo
,其中创建名为UserTable
的Java类;建立包org.easybooks.test.jdbc
,在包下创建SqlSrvDBConn
类(JDBC),并往项目中添加JDBC驱动包。建立包org.easybooks.test.servlet
,在包下创建MainServlet
的Serverlet。
UserTable.java
package org.easybooks.test.model.vo;
public class UserTable {
private Integer id;
private String username;
private String password;
public Integer getId(){
return this.id;
}
public void setId(Integer id){
this.id=id;
}
public String getUsername(){
return this.username;
}
public void setUsername(String username){
this.username=username;
}
public String getPassword(){
return this.password;
}
public void setPassword(String password){
this.password=password;
}
}
SqlSrvDBConn.java
package org.easybooks.test.jdbc;
import java.sql.*;
public class SqlSrvDBConn {
private Statement stmt;
private Connection conn;
ResultSet rs;
//在构造方法中创建数据库连接
public SqlSrvDBConn(){
stmt=null;
try{
/**加载并注册 SQLServer 2008 的 JDBC 驱动*/
//Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
//conn=DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=TEST","sa","123456");
/**加载并注册 MySQL的 JDBC 驱动*/
Class.forName("com.mysql.jdbc.Driver");
String uri = "jdbc:mysql://localhost:3306/test";
conn = DriverManager.getConnection(uri, "root", "root123");//根据自己的数据库密码,自行修改
}catch(Exception e){
e.printStackTrace();
}
rs=null;
}
//执行查询类的SQL语句,有返回集
public ResultSet executeQuery(String sql)
{
try
{
stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
rs=stmt.executeQuery(sql);
}catch(SQLException e){
System.err.println("Data.executeQuery: " + e.getMessage());
}
return rs;
}
//关闭对象
public void closeStmt()
{
try
{
stmt.close();
}catch(SQLException e){
System.err.println("Data.executeQuery: " + e.getMessage());
}
}
public void closeConn()
{
try
{
conn.close();
}catch(SQLException e){
System.err.println("Data.executeQuery: " + e.getMessage());
}
}
}
MainServlet
package org.easybooks.test.model.vo;
public class UserTable {
private Integer id;
private String username;
private String password;
public Integer getId(){
return this.id;
}
public void setId(Integer id){
this.id=id;
}
public String getUsername(){
return this.username;
}
public void setUsername(String username){
this.username=username;
}
public String getPassword(){
return this.password;
}
public void setPassword(String password){
this.password=password;
}
}
(5)编写Servlet
package org.easybooks.test.servlet;
import java.sql.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.easybooks.test.jdbc.SqlSrvDBConn;
import org.easybooks.test.model.vo.UserTable;;
public class MainServlet extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
request.setCharacterEncoding("gb2312"); //设置请求编码
String usr=request.getParameter("username"); //获取提交的用户名
String pwd=request.getParameter("password"); //获取提交的密码
boolean validated=false; //验证成功标识
SqlSrvDBConn sqlsrvdb=new SqlSrvDBConn();
HttpSession session=request.getSession(); //获得会话对象,用来保存当前登录用户的信息
UserTable user=null;
//先获得UserTable对象,如果是第一次访问该页,用户对象肯定为空,但如果是第二次甚至是第三次,
//就直接登录主页而无须再次重复验证该用户的信息
user=(UserTable)session.getAttribute("user");
//如果用户是第一次进入,会话中尚未存储user持久化对象,故为null
if(user==null){
//查询userTable表中的记录
String sql="select * from userTable";
ResultSet rs=sqlsrvdb.executeQuery(sql); //取得结果集
try {
while(rs.next()) {
if((rs.getString("username").trim().compareTo(usr)==0)&&(rs.getString("password"). compareTo(pwd)==0)){
user=new UserTable(); //创建持久化的JavaBean对象user
user.setId(rs.getInt(1));
user.setUsername(rs.getString(2));
user.setPassword(rs.getString(3));
session.setAttribute("user", user); //把user对象存储在会话中
validated=true; //标识为true表示验证成功通过
}
}
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
sqlsrvdb.closeStmt();
sqlsrvdb.closeConn();
}
else{
validated=true; //该用户在之前已登录过并成功验证,故标识为true表示无须再验了
}
if(validated)
{
//验证成功跳转到main.jsp
response.sendRedirect("main.jsp");
}
else{
//验证失败跳转到error.jsp
response.sendRedirect("error.jsp");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException{
doGet(request,response);
}
}
2.5 配置Serverlet的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>jsp_servlet_javabean_jdbc</display-name>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>mainServlet</servlet-name>
<servlet-class>org.easybooks.test.servlet.MainServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mainServlet</servlet-name>
<url-pattern>/mainServlet</url-pattern>
</servlet-mapping>
</web-app>
0x03 踩坑笔记
第一次做稍微复杂一点(需要导入jar包)的项目,这里导入jar包的时候踩了很多的坑,烦到绝望,于是总结一下。
本次实验需要的是jdbc连接mysql的jar包。
mysql-connector-java-5.1.39-bin.jar下载链接
3.1 导入外部jar包
Project->Properties->Java Build Path-> Libraries->Add Extra Jars->选择刚才下载的jar包
之后在 Order and Export 中勾选上刚刚导入的mysql.jar
Apply And Close
3.2 给Tomcat配置上驱动
原本我以为做完3.1的步骤就可以了,但是发现报错。
description The server encountered an internal error that prevented it from fulfilling this request.
exception
java.lang.NullPointerException
org.easybooks.test.jdbc.SqlSrvDBConn.executeQuery(SqlSrvDBConn.java:30)
org.easybooks.test.servlet.MainServlet.doGet(MainServlet.java:24)
org.easybooks.test.servlet.MainServlet.doPost(MainServlet.java:58)
javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
这里我tm踩了大坑,差点没爬出来==、
做完步骤3.1 ,只是在工程中添加了jar包,
但是Tomcat中缺少相应的驱动,导致不能连接数据库,从而导致代码中构造对象运行不了,从而产生指针未初始化的错误。
解决办法
将下载的mysql-xxx.jar复制粘贴到 工程=>Web Content =>WEB-INF=>lib目录下
这下,重启服务器运行jsp,就可以了!!!
0x04 运行结果
login.jsp
输入的用户名密码与数据库中一致,则跳转至main.jsp
不一致,则跳转到error.jsp
由于代码中有一个类似session的标记
else{
validated=true; //该用户在之前已登录过并成功验证,故标识为true表示无须再验了
}
if(validated)
{
//验证成功跳转到main.jsp
response.sendRedirect("main.jsp");
}
else{
//验证失败跳转到error.jsp
response.sendRedirect("error.jsp");
}
}
测试错误页面时,需要重启服务器,或者重新打开一个浏览器。