JAVA WEB之登录案例
一、前期准备工作
1. 建立一个web项目
idea -> Java Enterprise, 勾选Web Application,不创建web.xml,Application Server选择Tomcat服务器
2.导入jar包和配置加载资源
在src目录下创建一个资源(右键->New->Resourse Bundle),名称为druid.properties,这个资源用来获取连接数据库,配置资源内容如下:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///数据库名
username=用户名
password=密码
#初始化连接数
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000
在web目录下,创建文件夹WEB-INF,在WEB-INF目录下创建文件夹lib,这个文件夹用来存放项目所需要的资源
右键lib -> Add as Library ->Level Moudle Livrary
3.修改Tomcat配置
将/java_war_exploded修改为/project
4.创建web页面
在web目录下创建 登录页面 login.html,此时form表单的提交地址先不填,因为要验证用户名和密码是否正确,因此,表单提交后,应该跳转到一个用来验证用户名和密码是否正确的Servlet页面,因此我们开始编写后台的逻辑验证功能
二、后期工作
0.准备工作
先来了解一下dao、domain、servlet的理解,详见慕容囧囧这篇文章
dao domain的理解
了解了dao domain 的大致内容后,我们先来创建这两个个包,创建好这两个个包后,就可以开始分析该如何写代码了。
分析
首先思考第一个问题:
在前端提交用户信息后,后端需要完成什么工作?
因为前台发送的是一个用户登录的请求,那么我们就需要去判断用户的请求是否正确,即验证前端用户提交的用户名和密码是否与数据库中已存的用户信息匹配,如果匹配,就给用户一个请求成功的响应,如果不匹配,就给用户一个请求失败的响应。至此,我们知道我们需要三个servlet页面。
验证用户请求的LoginServlet,
请求成功的SuccessServlet,
请求失败的FailServlet。
接着再来思考第二个问题:
验证用户请求的LoginServlet如何去实现,实现的前提是什么?
验证用户请求,无非需要两个东西,一是用户提交的信息,二是数据库中的信息。
我们可以用获取请求参数的方法来获取用户提交的信息,而数据库中的信息该如何获取呢?
我们再来思考一下,用户会通过登录页面给我们提交用户名和密码。
假设我们的数据库中现在有一张User表,这张表含有三个字段:id 、username、 password,那么我们只需要根据用户提交的信息去查询User表,看是否存在这样一个用户名和密码相匹配用户,这个用来查询User表并返回查询结果的操作,我们把它封装为一个UserDao类。将查询到的结果返回并封装为一个User类。这个User类中有id,username,password三个变量,分别对应User表里的id,username,password。
查询到的结果无非有两种情况,一种是查无此人,查询结果为null,另一种就是确有此人,给我们返回user信息。而对于我们的验证来说,我们其实不需要知道user信息具体是什么,我们只需要知道有这么一个user即可,换句话说,我们在验证用户请求时,我们不需要知道用户是谁,我们只需要根据结果知道有这么一个人或者没有这么一个人就行。
因此,如果返回null,我们给用户一个请求失败的响应;返回结果不是null,我们给用户一个请求成功的响应。
至此,我们知道了,我们除了需要前面提到的三个servlet外,还需要一个用户实体类User,并且需要一个查询数据库表的类UserDao
最后再来补充两个问题,一个是我们在进行数据库查询操作前,需要连接数据库,在这里我们使用druid连接池编写一个JDBC工具类来连接数据库。在一个就是我们在编写完UserDao类后,需要一个UserDaoTest测试类去提前测试一下我们的UserDao类是否编写正确。而如何去测试我们的UserDao类是否正确呢?我们可以根据返回结果来测试,如果可以返回一条用户数据,说明我们的UserDao没有问题,可以继续完成项目。
至此,我们将我们分析的结果做一个总结:
第一步:我们需要使用druid连接池编写一个JDBC工具类连接数据库
第二步:我们需要编写一个用户实体类User
第三步:我们需要编写一个操作数据库表并返回操作结果的类UserDao
第四步:我们需要编写一个测试UserDao的测试类UserDaoTest
第五步:我们需要编写一个用来验证用户请求的Servlet,LoginServlet
第六步:我们需要编写请求成功的SuccessServlet和请求失败的FailServlet
接下来,我们对每一步进行具体的实现
1.JDBC工具类的编写
在src目录下,创建一个util包,在util包创建一个JDBCUtils类。
定义工具类:
JDBCUtils提供一个静态代码块用来加载资源和初始化连接,再分别提供三个方法,分别为获取连接,释放资源和获取连接池对象
定义成员变量
private static DataSource ds;
静态代码块:
static {
try {
//1.加载配置文件
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//2.获取DataSource
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
获取连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
释放资源
public static void close(Statement stmt,Connection conn){
close(null,stmt,conn);
}
public static void close(ResultSet rs, Statement stmt, Connection conn){
if( rs != null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if( stmt != null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if( conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
获取连接池对象
/**
* 获取连接池方法
*/
public static DataSource getDataSoucre(){
return ds;
}
这样,我们就定义好了一个工具类。我们可以写一个JDBCUtils测试类来检查下工具类写的是否有问题。
JDBCUtilsTest
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
//1.获取连接
conn = JDBCUtils.getConnection();
//2.定义sql
String sql = "insert into user values(null,?,?)";
//3.获取pstmt对象
pstmt = conn.prepareStatement(sql);
//4.给?赋值
pstmt.setString(1,"lisi");
pstmt.setString(2,"123456");
//5.执行sql
int i = pstmt.executeUpdate();
System.out.println(i);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JDBCUtils.close(pstmt,conn);
}
}
2.用户实体类User
数据库表里有多少个属性,就定义多少个变量。
定义set,get,toString方法
public class User {
private int id;
private String username;
private String password;
/*
光标移动到变量上Alt+Enter
*/
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
3.操作数据库表类UserDao
第一步:创建JDBCTemplate对象
第二部:定义login方法验证登录
public class UserDao {
//1.创建JDBCTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSoucre());
//2.login方法验证登录
public User login(User loginUser){
try {
String sql = "select * from user where username = ? and password = ?";
User user = template.queryForObject(sql,
new BeanPropertyRowMapper<User>(User.class),
loginUser.getUsername(), loginUser.getPassword());
return user;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
定义好UserDao类后,先不急着进行下一个步骤,先测试一下我们的UserDao类是否有问题。
UserDaoTest
public class UserDaoTest {
@Test
public void tsetLogin(){
User loginuser = new User();
loginuser.setUsername("gaoyuxin");
loginuser.setPassword("123456");
UserDao dao = new UserDao();
dao.login(loginuser);
User user = dao.login(loginuser);
System.out.println(user);
}
}
4.Servlet页面
4.1 LoginServlet
- 设置页面编码
- 获取请求参数
- 封装User对象
- 调用login方法验证登录
- 判断验证结果
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
request.setCharacterEncoding("utf-8");
//获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password");
//封装User对象
User loginuser = new User();
loginuser.setUsername(username);
loginuser.setPassword(password);
//调用login方法
UserDao dao = new UserDao();
User user = dao.login(loginuser);
//判断结果
if (user==null){
//请求失败
request.getRequestDispatcher("/failServlet").forward(request,response);
}else{
//请求成功
//存储数据
request.setAttribute("user",user);
request.getRequestDispatcher("/successServlet").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
4.2SuccessServlet
@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取request域*享的user对象
User user = (User)request.getAttribute("user");
if(user!=null){
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("登陆成功!"+user.getUsername()+",欢迎您");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
4.3FailServet
@WebServlet("/failServlet")
public class FailServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("登录失败,用户名或密码错误");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
注意:在编写三个Servlet时,要注意修改@WebServlet里的地址
最后,我们编写一个简易的登录界面,登录界面中需要注意的是,form表单栏里的地址填写,和设置发送方法为post。地址填写格式如果错误,会直接导致项目运行失败。
地址栏的填写与tomcat服务器的地址有关,比如说我这里tomcat服务器的地址是如下设置
那么from表单里的action路径就写为 “/project/loginServlet”
至此,一个初步的登录逻辑变编写完成。后面学习了更多的东西,再来做笔记。