注意:
- 我把整个前端项目都导入了,在这个登录模块当中实际所需要的只有regist.html和login.html文件
- 相关的Servlet有CheckCode和Regist两个
- 用到的jar包:druid数据库连接池和Dbutils
- 整个模块的代码:
1. 验证码动态获取
通过把请求发给Servlet,Servlet经过处理,再返回一张图片给HTML页面
2. 点击切换验证码
用js在上面注册一个事件就可
<img src="#" onclik="change(this)">
function change(obj) {
obj.src = "/store/CheckCodeServlet?time=" + new Date().getTime();
}
注意:如果js文件不独立一般都把js放在页尾
3.用js写注册的时候的前端验证,比如用户名和密码不能为空。
修改button的类型从submit改成button,并用JS给它注册一个事件,如果通过验证再提交 相关代码如下
function checkData() {
//1.获取用户名, 密码 确认密码
var username = document.getElementById("username");
var pwd = document.getElementById("pwd");
var pwd2 = document.getElementById("pwd2");
//2.判断输入的内容不能为空
if(username.value==""){
alert("请输入用户名");
return;
}
if(pwd.value==""){
alert("请输入密码");
return;
}
if(pwd2.value==""){
alert("请再次输入密码");
return;
}
//3。两次密码是否一样
if(pwd.value == pwd2.value){
//发送请求 form 获取form
var form = document.getElementById("reg_form");
form.submit();//通过js提交表单 执行action
}else{
alert("两次输入的密码不一样");
}
}
4.验证验证码 处理相关的注册逻辑
提交之后发送请求给处理用户名密码的Servlet(RegiesterServelt)
获取刚才生成验证码的具体内容(怎么获取?在CheckCodeServlet生成图片的时候同时把真正的验证码写在域对象当中,这样所有的Servlet就都可以访问了)
如果验证码正确,写入数据库,输出正确,返回登录页面
如果验证码错误,返回验证码错误图片,返回注册界面
相关代码
package com.zzy.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.dbutils.QueryRunner;
import com.zzy.domain.User;
import com.zzy.util.JdbcUtil;
@WebServlet("/RegistServlet")
public class RegistServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取请求参数
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
if (checkCode(request.getParameter("code"))) {
// 写入数据库
// 先把请求参数封装成User对象
// 获取所有请求参数,以键值对存储
Map<String, String[]> parameterMap = request.getParameterMap();
User u = new User();
try {
BeanUtils.populate(u, parameterMap);
} catch (Exception e) {
e.printStackTrace();
}
// 自动生成uid
u.setUid(UUID.randomUUID().toString());
// 现在把信息写入数据库
DataSource ds = JdbcUtil.getDataSource();
QueryRunner qr = new QueryRunner(ds);
String sql = "insert into user values(?,?,?,?)";
try {
qr.update(sql, u.getUid(), u.getUsername(), u.getPassword(), u.getPhonenumber());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 返回正确的提示并跳转
writer.write("注册成功");
response.setHeader("refresh", "3;url=/store/login.html");
} else {
writer.write("验证码错误");
// 返回注册界面
response.setHeader("refresh", "3;url=/store/regist.html");
}
}
/*
* 验证验证码 失败返回false
*/
public boolean checkCode(String code) {
Object obj = new Object();
obj.equals(obj);
// 从域对象中获取内容
ServletContext context = this.getServletContext();
String word = (String) context.getAttribute("checkcode");
return word.equals(code);
}
}
思考:是否能把验证码在生成的时候就发送给前端页面通过前端页面来实现验证码的验证呢?
当然是不行的,因为这样的话攻击人员就完全可以通过分析网页源码来获取验证码,验证码就失去了它本身的意义。