关于设置验证码代码展示
在我们注册账户,或者登录时经常看到会有验证码,这就是为了防止暴力破解密码以及黑客攻击服务器的情况,那么我们应该如何在代码中设置这些东西呢?
首先,根据mvc设计模式,先把模型,控制层的代码写好,一下就是我的数据层代码
package com.runze.dao;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import com.runze.daomain.User;
public class UserDao {
String path="F:/myeclipse2/day14_1/User.xml";
public User findByUsername(String username){
//按照传入的username去数据库中查询,如果存在就将数据封装成User对象返回,不存在就返回Null
//获取解析器对象
SAXReader s=new SAXReader();
try {
//读取xml文件,回去document对象
Document doc=s.read(path);
//根据传入的Username在doucument中进行查询
Element ele=(Element)doc.selectSingleNode("//user[@username='"+username+ "']");
//如果els为空,就返回null
if(ele==null)return null;
//如果不为空,说明存在存在元素,将元素的属性封装成一个User,返回该User
//创建User对象,用于存储元素的属性
User u=new User();
//根据属性名获取属性值
String name=ele.attributeValue("username");
String word=ele.attributeValue("password");
//将属性值封装到User对象中,将u返回
u.setUsername(name);
u.setPassword(word);
return u;
} catch (DocumentException e) {
//将异常抛出,调用此方法的类不用在进行处理
throw new RuntimeException(e);
}
}
public void add(User u){
//将传入的User对象添加到数据库中
SAXReader saxReader=new SAXReader();
try {
Document document=saxReader.read(path);
//获取根节点
Element root=document.getRootElement();
//添加属性
Element user=root.addElement("user");
user.addAttribute("username", u.getUsername());
user.addAttribute("password", u.getPassword());
try {
//回写
OutputFormat format=OutputFormat.createPrettyPrint();
XMLWriter x=new XMLWriter(new OutputStreamWriter(new FileOutputStream(path),"utf-8"), format);
x.write(document);
x.close();
} catch (Exception e) {
throw new RuntimeException();
}
} catch (DocumentException e) {
throw new RuntimeException();
}
}
}
这部分是JavaBean的代码
package com.runze.daomain;
public class User {
private String username;
private String password;
private String verifycode;
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;
}
public String getVerifycode() {
return verifycode;
}
public void setVerifycode(String verifycode) {
this.verifycode = verifycode;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password
+ ", verifycode=" + verifycode + "]";
}
}
下面是数据层的代码
package com.runze.service;
import com.runze.dao.UserDao;
import com.runze.daomain.User;
public class UserService {
UserDao ud=new UserDao();
//注册,用于校验username是否已经被注册
public void regist(User user) throws UserException{
User u= ud.findByUsername(user.getUsername());
//如果数据库返回的user不为null说明该用户名已经被注册
if(u != null){
throw new UserException("对不起"+user.getUsername()+"已经被注册");
}else {
ud.add(user);
}
}
public User login(User form) throws UserException {
/*
* 步骤:
* 1,通过传入的form的username进行查询,返回一个User对象,
* 如果user为null,则抛出异常 ,错误信息为用户名不存在
* 如果不为Null,那就拿传入的密码与返回的密码比较,
* 不同的话就抛出异常,错误信息是密码错误
* 相同的话就返回user
*/
UserDao ud=new UserDao();
User user=ud.findByUsername(form.getUsername());
if(user==null)throw new UserException("用户名不存在");
if(!form.getPassword().equals(user.getPassword()))throw new UserException("密码错误");
//返回数据库中的user,而不是传入的form,因为user中有所有的信息,而form中只有用户名密码
return user;
}
}
下面是we层的代码,关于响应验证码的Servlet以及登录,注册的Servlet
package com.runze.web.Servlet;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import tools.VerifyCode;
public class VerifyCodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//生成图片
VerifyCode vf=new VerifyCode();
BufferedImage image=vf.getImage();
//将图片上的文本保存到Session域中
request.getSession().setAttribute("text", vf.getText());
//将图片响应给客户端
VerifyCode.output(image, response.getOutputStream());
}
}
package com.runze.web.Servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.commons.CommonUtils;
import com.runze.daomain.User;
import com.runze.service.UserException;
import com.runze.service.UserService;
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset='utf-8'");
/*
* 步骤
* 1,获取表单数据,封装到form中
* 2,调用Service的login()方法,将form穿进去
* 3,如果login()方法没有抛出异常,返回一个User对象
* 有异常:在request域中保存异常信息,保存form,转发到login.jsp
* 无异常:保存返回的对象到session域中,重定向到welcome.jsp
*/
//创建UserService对象
UserService us=new UserService();
//将传入的参数封装成一个User对象
User form=CommonUtils.toBean(request.getParameterMap(), User.class);
try{
//调用us的login()方法
User user=us.login(form);
//无异常:保存返回的对象到session域中,重定向到welcome.jsp
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath()+"/UserJsp/welcome.jsp");
}catch (UserException e) {
//有异常:在request域中保存异常信息,保存form,转发到login.jsp
request.setAttribute("msg", e.getMessage());
request.setAttribute("user", form);
request.getRequestDispatcher("/UserJsp/login.jsp").forward(request, response);
}
}
}
package com.runze.web.Servlet;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.commons.CommonUtils;
import com.runze.daomain.User;
import com.runze.service.UserException;
import com.runze.service.UserService;
public class RegistServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//编码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
UserService us=new UserService();
//将表单请求的信息封装到一个form中
User form=CommonUtils.toBean(request.getParameterMap(), User.class);
/*
* 进行表单提交数据的验证
*/
//首先创建Map集合用于存储错误信息,键是表单中错误的输入框,值是错误信息
Map<String, String> errors=new HashMap<String, String>();
//验证用户名
String username=form.getUsername();
//判断条件,输入的用户名为空或者是
if(username==null||username.trim().isEmpty()){
errors.put("username", "用户名不能为空");
}else if (username.length()>12||username.length()<4) {
errors.put("username", "用户名的长度不能小于4或者是大于12");
}
//验证密码
String password=form.getPassword();
if(password==null||password.trim().isEmpty()){
errors.put("password", "密码不能为空");
}else if (password.length()>12||password.length()<4) {
errors.put("password", "密码的长度不能大于12或者是小于4");
}
//验证验证码
String text=(String)request.getSession().getAttribute("text");
String verifycode=form.getVerifycode();
if(verifycode==null||verifycode.trim().isEmpty()){
errors.put("verifycode", "验证码不能为空");
}else if (verifycode.length()!=4) {
errors.put("verifycode", "验证码的长度是4");
}else if (!verifycode.equalsIgnoreCase(text)) {
errors.put("verifycode", "验证码输入错误");
}
//判断errors是否为空,如果为空,就说明没有错误信息
if(errors!=null&&errors.size()>0){
//将错误信息保存到request域中
request.setAttribute("errors", errors);
//将form保存到request域中,回显
request.setAttribute("user", form);
//转发到regist.jsp
request.getRequestDispatcher("/UserJsp/regist.jsp").forward(request, response);
return;
}
//将form传入到UserService的regist()方法中
try {
//如果不抛出异常,说明数据库中没有相同的username
us.regist(form);
response.getWriter().write(
"<h1>注册成功</h1><a href='"+request.getContextPath()+"/UserJsp/login.jsp"+"'>前去登录</a>");
} catch (UserException e) {
//抛出异常
request.setAttribute("msg", e.getMessage());
//将表单提交的数据保存到request域中,防止一旦出现已注册的情况下,输入的表单里面数据被清空
request.setAttribute("user", form);
//请求转发到注册界面
request.getRequestDispatcher("/UserJsp/regist.jsp").forward(request, response);
}
}
}
其实中重要的就是主界面的jsp,首先当我们申请服务器的jsp页面时,服务器会将jsp页面翻译成客户端浏览器能识别的html页面,当我们第一次向服务器发送请求时,页面会,生成验证码的那个输入框会自动向servlet发送请求,servlet会反馈一张图片回来。
而后,当我们点击换一张的时候,超链接指向的还是生成图片的servlet,就会在生成一张。这就是总体思想了。