作用:增强系统的安全性
涉及的知识点:图形的绘制,Session会话的使用,JS
图形的绘制API:
BufferedImage 缓冲图片(保存在内存中的图片)
创建方法:new BufferedImage(图片的类型,宽,高)
Graphics 图形
创建方法:Graphics 图片对象.getGraphics()
主要方法:
setColor(Color color) 设置颜色
setFont(Font font) 设置字体
fillRect(横坐标,纵坐标,宽,高) 填充矩形
drawLine(横坐标,纵坐标,横坐标,纵坐标) 绘制线条
drawString(String text,横坐标,纵坐标) 绘制文字
验证码实现的过程:
1.controller层的验证码具体实现
@WebServlet("/code.do")
public class CodeServlet extends HttpServlet {
private static final String CODES="QWERTYUIOPLKJHGFDSAZXCVBNMqazwsxedcrfvtgbyhnujmkloi1234567890";
private static final int WINDTH=90;
private static final int HEIGHT=30;
private static final int FONT_SIZE=20;
private static final Color[] COLORS={Color.BLACK,Color.blue,Color.cyan,Color.PINK};
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
BufferedImage image=new BufferedImage(WINDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics graphics=image.getGraphics();
//设置背景颜色
graphics.setColor(Color.GRAY);
graphics.setFont(new Font("宋体",Font.PLAIN,FONT_SIZE));
graphics.fillRect(0, 0, WINDTH, HEIGHT);
Random random=new Random();
StringBuilder strb=new StringBuilder();
for(int i=0;i<4;i++){
graphics.setColor(COLORS[random.nextInt(COLORS.length)]);
char c = CODES.charAt(random.nextInt(CODES.length()));
strb.append(c);
graphics.drawString(String.valueOf(c), 10+FONT_SIZE*i, 20);
graphics.setColor(COLORS[random.nextInt(COLORS.length)]);
graphics.drawLine(random.nextInt(WINDTH), random.nextInt(HEIGHT), random.nextInt(WINDTH), random.nextInt(HEIGHT));
}
req.getSession().setAttribute("code",strb.toString());
//通过io流向浏览器发送图片
ImageIO.write(image, "PNG", resp.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
验证码实现的过程:
1)选取4个随机的字母或数字
2)创建缓冲图片
3)创建绘图对象
4)使用绘图对象绘制随机的字母或数字
5)使用输出流将图片发送给浏览器
6)把生成验证码字符串保存到Session中
7)在登录页面中显示验证码 <img src=”Servlet地址”>
8)实现JS点击图片切换验证码
9)登录时将用户填写的验证码和Session中的验证码进行比较
2.controller层的登录的实现
@WebServlet("/login.do")
public class UserLoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
UserService userService=new UserServiceImpl();
req.setCharacterEncoding("UTF-8");
String userName=req.getParameter("username");
String userPass=req.getParameter("userpass");
String code=req.getParameter("code");
// 不懂
String code2 = (String) req.getSession().getAttribute("code");
System.out.println(code);
UserEntity login = userService.login(userName, userPass);
if(login==null){
req.setAttribute("error", "用户名,密码错误");
req.getRequestDispatcher("login.jsp").forward(req, resp);
}else{
if(login.getUsername().equals(userName)&&login.getUserpass().equals(userPass)){
resp.sendRedirect("list.do");
// if(code.equals(code2)){
// }else{
重定
// req.setAttribute("error", "验证码错误");
// req.getRequestDispatcher("login.jsp").forward(req, resp);
// }
}else{
req.setAttribute("error", "用户名,密码错误");
req.getRequestDispatcher("login.jsp").forward(req, resp);
}
}
}
}
3.视图层的登录实现
<script type="text/javascript">
function changeCode(){
document.getElementById("img").src="code.do?x="+Math.random();
}
</script>
</head>
<body>
<span style="color:red">${error}</span>
<form action="login.do" method="post">
<input type="text" name="username" placeholder="请输入用户名" ><br>
<input type="password" name="userpass" placeholder="请输入密码"><br>
<input type="text" name="code" placeholder="请输入验证码"><br>
<img id="img" src="code.do" onclick="changeCode()"><br>
<input type="submit" value="login">
</form>
<a href="register.jsp"><button>注册</button></a>
</body>