一、環(huán)境搭建
1、導包
??這個案例中使用的jar包有三個息堂,需要導入到WEB-INF目錄下的lib文件夾中。
2块促、導入工具庫
??本案例使用的工具類是之前用過的JDBCUtils荣堰。
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JDBCUtils {
// 創(chuàng)建一個連接池:但是這個連接池只需要創(chuàng)建一次即可。
private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
/**
* 獲得連接的方法
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
/**
* 獲得數(shù)據(jù)源:
*/
public static DataSource getDataSource(){
return dataSource;
}
}
3竭翠、創(chuàng)建數(shù)據(jù)庫和表
??打開mysql數(shù)據(jù)庫振坚,創(chuàng)建數(shù)據(jù)庫和表,并添加一些記錄斋扰。
create database ajax_test;
use ajax_test;
create table user (
uid int primary key auto_increment,
username varchar(30),
password varchar(20)
);
insert into user(username,password) values ('itheima','123456');
insert into user(username,password) values ('itcast','qwerty');
4渡八、修改配置文件
二啃洋、使用傳統(tǒng)的方式實現(xiàn)案例
1、創(chuàng)建JavaBean
package com.itheima.domain;
import java.io.Serializable;
public class User implements Serializable {
private int uid;
private String username;
private String password;
public User() {
super();
// TODO Auto-generated constructor stub
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2屎鳍、編寫regist.jsp頁面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>注冊頁面</h1>
<form action="${pageContext.request.contextPath}/RegistServlet" method="post">
用戶名:<input type="text" name="username"/>
<br />
密碼:<input type="text" name="password"/>
<br />
<input type="submit" value="注冊"/>
</form>
</body>
</html>
3宏娄、編寫RegisterServlet類
??RegisterServlet類中僅僅實現(xiàn)請求數(shù)據(jù)的獲取和返回響應信息,邏輯放入UserService類中進行判斷逮壁。
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.itheima.domain.User;
import com.itheima.service.UserService;
public class RegisterServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//設置響應類型定和編碼
response.setContentType("text/html;charset:UTF-8");
//獲取輸出流對象
PrintWriter out = response.getWriter();
//獲取表單提交的數(shù)據(jù)
String username = request.getParameter("username");
String password = request.getParameter("password");
//封裝數(shù)據(jù)
User user = new User(null,username,password);
//將數(shù)據(jù)傳入service進行邏輯判斷
UserService service = new UserService();
Boolean flag = service.checkUsername(username);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
4孵坚、編寫UserService類
??UserService類實現(xiàn)對邏輯的判斷,用戶名是否已經被注冊窥淆,但是數(shù)據(jù)庫中數(shù)據(jù)的獲取需要在UserDao類中實現(xiàn)卖宠。
import java.util.List;
import com.itheima.dao.UserDao;
import com.itheima.domain.User;
public class UserService {
public Boolean checkUsername(String username){
//查詢數(shù)據(jù)庫中是否已經有該用戶名
UserDao dao = new UserDao();
User user = dao.findUserByUsername(username);
}
}
5、編寫UserDao類
??在UserDao類中實現(xiàn)對數(shù)據(jù)庫中數(shù)據(jù)的查詢忧饭,查詢數(shù)據(jù)庫中是否有用戶注冊時輸入的用戶名的信息扛伍。
package com.itheima.dao;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import com.itheima.domain.User;
import com.itheima.utils.JDBCUtils;
public class UserDao {
public User findUserByUsername(String username) {
User user = null;
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
try {
user = qr.query("select * from user where username = ?", new BeanHandler<User>(User.class), username);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return user;
}
}
6、完善UserService類
??如果UserDao類中返回的User對象為空词裤,說明這個用戶名沒有被注冊過刺洒,返回一個true,否則返回false亚斋。
package com.itheima.service;
import java.util.List;
import com.itheima.dao.UserDao;
import com.itheima.domain.User;
public class UserService {
public Boolean checkUsername(String username){
//查詢數(shù)據(jù)庫中是否已經有該用戶名
UserDao dao = new UserDao();
User user = dao.findUserByUsername(username);
//如果返回null,說明該用戶名沒有注冊
if(user == null){
return true;
}
return false;
}
}
7攘滩、完善RegisterServlet類
??如果UserService中的service方法返回的是true帅刊,說明用戶名沒有被注冊,返回注冊成功的提示信息漂问;如果返回的是false赖瞒,說明用戶名已經被注冊,設置域對象蚤假,轉發(fā)請求信息栏饮,提示用戶名已經被注冊猬错。
package com.itheima.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.itheima.domain.User;
import com.itheima.service.UserService;
public class RegisterServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//設置響應類型定和編碼
response.setContentType("text/html;charset:UTF-8");
//獲取輸出流對象
PrintWriter out = response.getWriter();
//獲取表單提交的數(shù)據(jù)
String username = request.getParameter("username");
String password = request.getParameter("password");
//封裝數(shù)據(jù)
User user = new User(null,username,password);
//將數(shù)據(jù)傳入service進行邏輯判斷
UserService service = new UserService();
Boolean flag = service.checkUsername(username);
//如果返回true诈铛,說明用戶名沒有被創(chuàng)建水由,可以注冊
if(flag){
out.println("恭喜您物咳!注冊成功魔慷!");
}else{
//如果用戶名已經被注冊了逞敷,則設置域對象必怜,返回提示性信息
request.setAttribute("error", "用戶名已經被注冊了养涮!");
request.setAttribute("user", user);
//將請求轉發(fā)回注冊頁面
request.getRequestDispatcher("/register.jsp").forward(request, response);
return;
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
8逢享、完善注冊頁面
??對注冊頁面進行完善罐监,使用el表達式將用戶名被注冊的信息提示出來,并在用戶名文本框中顯示用戶之前輸入的用戶名瞒爬。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>注冊頁面</h1>
<form action="${pageContext.request.contextPath}/registServlet" method="post">
用戶名:<input type="text" name="username" value="${user.username}"/><span>${error}</span>
<br />
密碼:<input type="text" name="password"/>
<br />
<input type="submit" value="注冊"/>
</form>
</body>
</html>
案例實現(xiàn)結果
輸入數(shù)據(jù)庫中沒有的用戶信息
輸入數(shù)據(jù)庫中已有的用戶信息
三弓柱、使用AJAX方式實現(xiàn)案例
??在上面的案例中沟堡,我們可以發(fā)現(xiàn),當用戶輸入完注冊信息后矢空,點擊注冊按鈕航罗,才會提示用戶名已經被注冊了,并且頁面被刷新了妇多,這樣的頁面用戶體驗較差伤哺。
??現(xiàn)在我們想實現(xiàn):用戶名能夠動態(tài)的進行判斷,如果用戶輸入一個已經被注冊的用戶名者祖,直接就會顯示提示信息立莉;如果用戶點擊用戶名這個文本框后沒有輸入信息,并且又點擊了其他地方七问,會提示用戶沒有輸入用戶名蜓耻;并且在實現(xiàn)這些功能的時候,頁面不會被刷新械巡。
接下來我們對案例進行改寫
對jsp頁面進行修改
??實現(xiàn)三個功能(頁面不刷新):
????(1)用戶名文本框失去焦點的時候刹淌,提示用戶名不能為空
????(2)用戶名重復,提示用戶名已經被注冊了
????(3)用戶名不重復讥耗,提示用戶名可以注冊
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
//為用戶名文本框添加這個方法有勾,在文本框失去焦點以后運行
//就是當用戶填寫完用戶名后,進行下一步填寫的時候古程,異步執(zhí)行這個方法
function checkUsername(){
//獲取用戶名文本框對象
var username = document.getElementsByName("username")[0].value;
//獲取提示信息span對象
var span1 = document.getElementsByTagName("span")[0];
if(username == ""){
span1.innerHTML = "用戶名不能為空蔼卡!";
return;
}
//創(chuàng)建請求對象
var xmlHttp = new XMLHttpRequest();
//設置請求狀態(tài)變化時觸發(fā)的事件
xmlHttp.onreadystatechange = function(){
//如果請求狀態(tài)碼為4,說明請求已經完成挣磨,響應已經就緒
if(xmlHttp.readyState == 4){
//響應狀態(tài)碼為200雇逞,響應完成
if(xmlHttp.status == 200){
//獲取服務器返回的信息
var data = xmlHttp.responseText;
//判斷返回的信息,輸出響應的提示信息
if(data == 0){
//如果返回0茁裙,說明用戶名不重復塘砸,可以使用
span1.innerHTML = "用戶名可以使用!";
}else{
//說明用戶名重復晤锥,不能使用
span1.innerHTML = "用戶名已經被注冊掉蔬!";
}
}
}
}
//創(chuàng)建連接
xmlHttp.open("GET","/web14_test1/RegisterAJAXServlet?username="+username,true);
//發(fā)送請求
xmlHttp.send();
}
</script>
</head>
<body>
<h1>注冊頁面</h1>
<form action="${pageContext.request.contextPath}/RegisterServlet" method="post">
用戶名:<input type="text" name="username" onblur="checkUsername();"/><span></span>
<br />
密碼:<input type="text" name="password"/>
<br />
<input type="submit" value="注冊"/>
</form>
</body>
</html>
創(chuàng)建一個新的RegisterAJAXServlet
??我們可以將RegisterServlet類的代碼復制過來進行修改,返回簡單的提示信息矾瘾,由js方法進行判斷眉踱,所以就不用設置響應編碼,也不用獲取用戶輸入的密碼霜威。
??這里就體現(xiàn)了我們MVC三層架構的好處谈喳,只需要修改servlet,邏輯層和數(shù)據(jù)層都不需要修改戈泼。
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.itheima.domain.User;
import com.itheima.service.UserService;
public class RegisterAJAXServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取輸出流對象
PrintWriter out = response.getWriter();
//獲取表單提交的數(shù)據(jù)
String username = request.getParameter("username");
//將數(shù)據(jù)傳入service進行邏輯判斷
UserService service = new UserService();
Boolean flag = service.checkUsername(username);
//AJAX方式
if(flag){
//如果返回true婿禽,說明用戶名沒有被創(chuàng)建赏僧,可以注冊,返回0
out.println(0);
}else{
//用戶名已經被注冊,返回1
out.println(1);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
AJAX方式實現(xiàn)案例成果
用戶名文本框不輸入內容失去焦點時
用戶名重復時
用戶名不重復時
完成注冊