案例:用户的注册和登录功能
分类:
IT文章
•
2023-03-13 16:34:09
知识点
①MVC设计模式
②文件上传功能
③验证码的校验
什么是MVC?
JavaWeb开发历程
案例实现
1)环境搭建
用户注册
- 用户信息的保存
- 用户头像的上传
如果注册成功会跳转到登陆页面
创建一个工程
将样式,图片和页面放到webcontent目录下
将需要用到的jar包放到lib目录中
将工程发布到tomcat
2)用户列表初始化
这个案例将账户数据存放在了集合中放到servlet的全局域.
知识点:监听器
domain 实体类:User类
service 接口,用于处理业务逻辑
utils 工具类
listener 监听器:初始化用户信息监听器
servlet servlet类
User.java
1 package com.imooc.domain;
2
3 public class User {
4 private String username;
5 private String password;
6
7 private String path;
8
9 public String getUsername() {
10 return username;
11 }
12
13 public void setUsername(String username) {
14 this.username = username;
15 }
16
17 public String getPassword() {
18 return password;
19 }
20
21 public void setPassword(String password) {
22 this.password = password;
23 }
24
25 public String getPath() {
26 return path;
27 }
28
29 public void setPath(String path) {
30 this.path = path;
31 }
32
33 @Override
34 public String toString() {
35 return "User [username=" + username + ", password=" + password + ", path=" + path + "]";
36 }
37
38
39 }
View Code
监听器
3)注册页面的表单校验
注册页面的form表单
script标签
4)用户信息保存
form表单
接口
注册servlet
5)上传文件功能
原理分析:
但这时接收到的请求参数只有文件名,没有文件
增加enctype属性
原理:拿到请求后,对请求做一个相应的解析
fileload简介:
官网地址:http://commons.apache.org/proper/commons-fileupload/
UploadServlet
1 package com.imooc.servlet;
2
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.util.List;
8
9 import javax.servlet.ServletException;
10 import javax.servlet.annotation.WebServlet;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14
15 import org.apache.commons.fileupload.FileItem;
16 import org.apache.commons.fileupload.FileUploadException;
17 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
18 import org.apache.commons.fileupload.servlet.ServletFileUpload;
19
20 @WebServlet("/UploadServlet")
21 public class UploadServlet extends HttpServlet {
22 private static final long serialVersionUID = 1L;
23
24 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
25
26 // 1.创建磁盘文件项工厂
27 DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
28 // 2.创建核心解析类
29 ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
30 // 3.解析请求对象,将请求分成几个部分(FileItem)
31 try {
32 List<FileItem> list= fileUpload.parseRequest(request);
33 // 4.遍历集合获得每个部分的对象
34 for(FileItem fileItem:list){
35 // 判断是普通项还是文件上传项
36 if(fileItem.isFormField()){
37 // 普通项
38 // 获得普通项的名称:
39 String name = fileItem.getFieldName();
40 // 获得普通项的值:
41 String value = fileItem.getString("UTF-8");
42 System.out.println(name+" "+value);
43 }else{
44 // 文件上传项
45 // 获得文件的名称:
46 String fileName = fileItem.getName();
47 // 获得文件的输入流:
48 InputStream is = fileItem.getInputStream();
49 // 需要将文件写入到服务器的某个路径即可:
50 String path = getServletContext().getRealPath("/upload");
51 System.out.println(path);
52 // 创建输出流 与 输入流进行对接:
53 OutputStream os = new FileOutputStream(path+"\"+fileName);
54 int len = 0;
55 byte[] b = new byte[1024];
56 while((len = is.read(b))!=-1){
57 os.write(b, 0, len);
58 }
59 is.close();
60 os.close();
61 }
62 }
63 } catch (FileUploadException e) {
64 // TODO Auto-generated catch block
65 e.printStackTrace();
66 }
67
68 }
69
70 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
71 doGet(request, response);
72 }
73
74 }
View Code
6)用户头像上传
1 package com.imooc.web.servlet;
2
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10
11 import javax.servlet.ServletException;
12 import javax.servlet.annotation.WebServlet;
13 import javax.servlet.http.HttpServlet;
14 import javax.servlet.http.HttpServletRequest;
15 import javax.servlet.http.HttpServletResponse;
16
17 import org.apache.commons.fileupload.FileItem;
18 import org.apache.commons.fileupload.FileUploadException;
19 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
20 import org.apache.commons.fileupload.servlet.ServletFileUpload;
21
22 import com.imooc.domain.User;
23 import com.imooc.service.UserService;
24 import com.imooc.service.impl.UserServiceImpl;
25 import com.imooc.utils.UploadUtils;
26
27 @WebServlet("/RegistServlet")
28 public class RegistServlet extends HttpServlet {
29 private static final long serialVersionUID = 1L;
30
31 protected void doGet(HttpServletRequest request, HttpServletResponse response)
32 throws ServletException, IOException {
33 // 接收数据
34 // 创建Map集合用于保存数据:
35 Map<String,String> map = new HashMap<String,String>();
36 // 文件上传的代码:
37 // 1.创建磁盘文件项工厂
38 DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
39 // 2.创建核心解析类
40 ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
41 // 3.解析请求对象,将请求分成几个部分(FileItem)
42 try {
43 List<FileItem> list = fileUpload.parseRequest(request);
44 // 4.遍历集合获得每个部分的对象
45 for (FileItem fileItem : list) {
46 // 判断是普通项还是文件上传项
47 if (fileItem.isFormField()) {
48 // 普通项--用户名(username--输入的值) 密码 确认密码
49 // 获得普通项的名称:
50 String name = fileItem.getFieldName();
51 // 获得普通项的值:
52 String value = fileItem.getString("UTF-8");
53 // 保存数据:
54 map.put(name, value);
55 } else {
56 // 文件上传项
57 // 获得文件的名称:
58 String fileName = fileItem.getName();
59 // 获得唯一文件名:
60 String uuidFileName = UploadUtils.getUuidFileName(fileName);
61 // 获得文件的输入流:
62 InputStream is = fileItem.getInputStream();
63 // 需要将文件写入到服务器的某个路径即可:
64 String path = getServletContext().getRealPath("/upload");
65 System.out.println(path);// D:/xxx/ddd/
66 // 显示图片<img src="/regist_login/upload/a.jpg">
67 // 创建输出流 与 输入流进行对接:
68 String url = path + "\" + uuidFileName;
69 map.put("path", request.getContextPath()+"/upload/"+uuidFileName);
70 OutputStream os = new FileOutputStream(url);
71 int len = 0;
72 byte[] b = new byte[1024];
73 while ((len = is.read(b)) != -1) {
74 os.write(b, 0, len);
75 }
76 is.close();
77 os.close();
78 }
79 }
80 } catch (FileUploadException e) {
81 // TODO Auto-generated catch block
82 e.printStackTrace();
83 }
84
85 // 封装数据
86 User user = new User();
87 user.setUsername(map.get("username"));
88 user.setPassword(map.get("password"));
89
90 user.setPath(map.get("path"));
91 System.out.println(user);
92 // 处理数据
93 UserService userService = new UserServiceImpl();
94 // 从ServletContext域中获取用户的集合即可
95 List<User> userList = (List<User>) getServletContext().getAttribute("userList");
96 userService.regist(userList, user);
97 System.out.println(userList);
98 // 显示处理结果
99 response.sendRedirect(request.getContextPath() + "/login.jsp");
100 }
101
102 protected void doPost(HttpServletRequest request, HttpServletResponse response)
103 throws ServletException, IOException {
104 doGet(request, response);
105 }
106
107 }
View Code
7)解决文件名重名问题
1 package com.imooc.utils;
2
3 import java.util.UUID;
4
5 public class UploadUtils {
6
7 public static String getUuidFileName(String fileName){
8 // 解决文件重名的问题:
9 // a.jpg -- 获得后缀名.jpg -- 生成一段随机字符串将a替换掉 xxdfwerw.jpg
10 int idx = fileName.lastIndexOf(".");
11 String exName = fileName.substring(idx);// .jpg
12 // 生成随机字符串:
13 String uuidFileName = UUID.randomUUID().toString().replace("-", "")+exName;
14
15 return uuidFileName;
16 }
17
18 public static void main(String[] args) {
19 System.out.println(UploadUtils.getUuidFileName("a.jpg"));
20 }
21 }
View Code
8)登录功能
用户信息查询
loginservlet
1 package com.imooc.web.servlet;
2
3 import java.io.IOException;
4 import java.util.List;
5
6 import javax.servlet.ServletException;
7 import javax.servlet.annotation.WebServlet;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 import com.imooc.domain.User;
13 import com.imooc.service.UserService;
14 import com.imooc.service.impl.UserServiceImpl;
15
16 @WebServlet("/LoginServlet")
17 public class LoginServlet extends HttpServlet {
18 private static final long serialVersionUID = 1L;
19
20 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
21
22 // 接收数据:
23 String username = request.getParameter("username");
24 String password = request.getParameter("password");
25 // 封装数据:
26 User user = new User();
27 user.setUsername(username);
28 user.setPassword(password);
29 // 处理数据:完成登陆.
30 UserService userService = new UserServiceImpl();
31 // 获得用户列表的集合:
32 List<User> userList = (List<User>)getServletContext().getAttribute("userList");
33 User existUser = userService.login(userList,user);
34 // 显示结果:
35 if(existUser == null){
36 // 登录失败
37 request.setAttribute("msg", "用户名或密码错误!");
38 request.getRequestDispatcher("/login.jsp").forward(request, response);
39 }else{
40 // 登录成功
41 // 将用户信息保存:
42 request.getSession().setAttribute("existUser", existUser);
43 response.sendRedirect(request.getContextPath()+"/index.jsp");
44 }
45 }
46
47 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
48 doGet(request, response);
49 }
50
51 }
View Code
接口实现类
1 package com.imooc.service.impl;
2
3 import java.util.List;
4
5 import com.imooc.domain.User;
6 import com.imooc.service.UserService;
7
8 public class UserServiceImpl implements UserService {
9
10 @Override
11 public void regist(List<User> userList, User user) {
12 // 保存用户信息:
13 userList.add(user);
14 }
15
16 @Override
17 public User login(List<User> userList, User user) {
18
19 for (User existUser : userList) {
20 if(existUser.getUsername().equals(user.getUsername()) && existUser.getPassword().equals(user.getPassword())){
21 return existUser;
22 }
23 }
24
25 return null;
26 }
27
28 }
View Code
首页头部:设置登录成功和失败的样式
1 <c:if test="${ empty existUser }">
2 <li><a href="${pageContext.request.contextPath }/login.jsp">登录</a></li>
3 <li><a href="${pageContext.request.contextPath }/register.jsp">注册</a></li>
4 </c:if>
5 <c:if test="${ not empty existUser}">
6 <li>
7 <img class="profile_item" src="${ existUser.path }">
8 </li>
9 </c:if>
View Code
9)验证码的生成与校验
概述
生成
验证码生成准备工作:
servlet
1 package com.imooc.web.servlet;
2
3 import java.awt.Color;
4 import java.awt.Font;
5 import java.awt.Graphics;
6 import java.awt.Graphics2D;
7 import java.awt.image.BufferedImage;
8 import java.io.IOException;
9 import java.util.Random;
10
11 import javax.imageio.ImageIO;
12 import javax.servlet.ServletException;
13 import javax.servlet.annotation.WebServlet;
14 import javax.servlet.http.HttpServlet;
15 import javax.servlet.http.HttpServletRequest;
16 import javax.servlet.http.HttpServletResponse;
17
18 @WebServlet("/CheckImgServlet1")
19 public class CheckImgServlet1 extends HttpServlet {
20 private static final long serialVersionUID = 1L;
21
22 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
23
24 }
25
26 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
27 doGet(request, response);
28 }
29
30 }
View Code
页面
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
7 <title>Insert title here</title>
8 </head>
9 <body>
10 <form action="" method="post">
11 验证码:<input type="text" name="checkcode"/><img src="${pageContext.request.contextPath }/CheckImgServlet"><br/>
12 <input type="submit" value="提交">
13 </form>
14 </body>
15 </html>
View Code
将内存中图片显示到浏览器
servlet
字母随机旋转一定角度
1 package com.imooc.web.servlet;
2
3 import java.awt.Color;
4 import java.awt.Font;
5 import java.awt.Graphics;
6 import java.awt.Graphics2D;
7 import java.awt.image.BufferedImage;
8 import java.io.IOException;
9 import java.util.Random;
10
11 import javax.imageio.ImageIO;
12 import javax.servlet.ServletException;
13 import javax.servlet.annotation.WebServlet;
14 import javax.servlet.http.HttpServlet;
15 import javax.servlet.http.HttpServletRequest;
16 import javax.servlet.http.HttpServletResponse;
17
18 @WebServlet("/CheckImgServlet1")
19 public class CheckImgServlet1 extends HttpServlet {
20 private static final long serialVersionUID = 1L;
21
22 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
23 int width = 120;
24 int height = 30;
25 // 步骤一:在内存中生成一张图片
26 BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
27 // 步骤二:操作该图片,设置背景色及绘制边框
28 Graphics graphics = bufferedImage.getGraphics();
29 // 设置背景色
30 graphics.setColor(Color.YELLOW);
31 graphics.fillRect(0, 0, width, height);
32 // 绘制边框
33 graphics.setColor(Color.BLUE);
34 graphics.drawRect(0, 0, width-1, height-1);
35
36 // 步骤三:生成随机的四个字母或数字,写入到图片中
37 Graphics2D g2d = (Graphics2D)graphics;
38 g2d.setColor(Color.BLACK);
39 g2d.setFont(new Font("宋体",Font.BOLD,18));//a 4 3 r
40
41 String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
42 Random random = new Random();
43 int x = 10;
44 for(int i=0;i<4;i++){
45 int idx = random.nextInt(words.length());
46 // 获得指定位置的字符
47 char ch = words.charAt(idx);
48 // 旋转的角度 -30 到 30 之间
49 int jiaodu = random.nextInt(60) - 30;
50 // 将角度转化成弧度:
51 double theta = jiaodu * Math.PI / 180;
52 g2d.rotate(theta, x, 20);
53 g2d.drawString(String.valueOf(ch), x, 20);
54 g2d.rotate(-theta, x, 20);
55
56 x+=30;
57 }
58 // 步骤四:将内存中的图片,进行输出
59 ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
60 }
61
62 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
63 doGet(request, response);
64 }
65
66 }
View Code
添加干扰线以及设置字母随机颜色
1 package com.imooc.web.servlet;
2
3 import java.awt.Color;
4 import java.awt.Font;
5 import java.awt.Graphics;
6 import java.awt.Graphics2D;
7 import java.awt.image.BufferedImage;
8 import java.io.IOException;
9 import java.util.Random;
10
11 import javax.imageio.ImageIO;
12 import javax.servlet.ServletException;
13 import javax.servlet.annotation.WebServlet;
14 import javax.servlet.http.HttpServlet;
15 import javax.servlet.http.HttpServletRequest;
16 import javax.servlet.http.HttpServletResponse;
17
18 /**
19 * 生成验证码图片
20 */
21 @WebServlet("/CheckImgServlet")
22 public class CheckImgServlet extends HttpServlet {
23
24 public void doGet(HttpServletRequest request, HttpServletResponse response)
25 throws ServletException, IOException {
26
27 int width = 120;
28 int height = 30;
29
30 // 步骤一 绘制一张内存中图片
31 BufferedImage bufferedImage = new BufferedImage(width, height,
32 BufferedImage.TYPE_INT_RGB);
33
34 // 步骤二 图片绘制背景颜色 ---通过绘图对象
35 Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
36 // 绘制任何图形之前 都必须指定一个颜色
37 graphics.setColor(getRandColor(200, 250));
38 graphics.fillRect(0, 0, width, height);
39
40 // 步骤三 绘制边框
41 graphics.setColor(Color.WHITE);
42 graphics.drawRect(0, 0, width - 1, height - 1);
43
44 // 步骤四 四个随机数字
45 Graphics2D graphics2d = (Graphics2D) graphics;
46 // 设置输出字体
47 graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
48
49 String words =
50 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
51 // String words = "u7684u4e00u4e86u662fu6211u4e0du5728u4ebau4eecu6709u6765u4ed6u8fd9u4e0au7740u4e2au5730u5230u5927u91ccu8bf4u5c31u53bbu5b50u5f97u4e5fu548cu90a3u8981u4e0bu770bu5929u65f6u8fc7u51fau5c0fu4e48u8d77u4f60u90fdu628au597du8fd8u591au6ca1u4e3au53c8u53efu5bb6u5b66u53eau4ee5u4e3bu4f1au6837u5e74u60f3u751fu540cu8001u4e2du5341u4eceu81eau9762u524du5934u9053u5b83u540eu7136u8d70u5f88u50cfu89c1u4e24u7528u5979u56fdu52a8u8fdbu6210u56deu4ec0u8fb9u4f5cu5bf9u5f00u800cu5df1u4e9bu73b0u5c71u6c11u5019u7ecfu53d1u5de5u5411u4e8bu547du7ed9u957fu6c34u51e0u4e49u4e09u58f0u4e8eu9ad8u624bu77e5u7406u773cu5fd7u70b9u5fc3u6218u4e8cu95eeu4f46u8eabu65b9u5b9eu5403u505au53ebu5f53u4f4fu542cu9769u6253u5462u771fu5168u624du56dbu5df2u6240u654cu4e4bu6700u5149u4ea7u60c5u8defu5206u603bu6761u767du8bddu4e1cu5e2du6b21u4eb2u5982u88abu82b1u53e3u653eu513fu5e38u6c14u4e94u7b2cu4f7fu5199u519bu5427u6587u8fd0u518du679cu600eu5b9au8bb8u5febu660eu884cu56e0u522bu98deu5916u6811u7269u6d3bu90e8u95e8u65e0u5f80u8239u671bu65b0u5e26u961fu5148u529bu5b8cu5374u7ad9u4ee3u5458u673au66f4u4e5du60a8u6bcfu98ceu7ea7u8ddfu7b11u554au5b69u4e07u5c11u76f4u610fu591cu6bd4u9636u8fdeu8f66u91cdu4fbfu6597u9a6cu54eau5316u592au6307u53d8u793eu4f3cu58ebu8005u5e72u77f3u6ee1u65e5u51b3u767eu539fu62ffu7fa4u7a76u5404u516du672cu601du89e3u7acbu6cb3u6751u516bu96beu65e9u8bbau5417u6839u5171u8ba9u76f8u7814u4ecau5176u4e66u5750u63a5u5e94u5173u4fe1u89c9u6b65u53cdu5904u8bb0u5c06u5343u627eu4e89u9886u6216u5e08u7ed3u5757u8dd1u8c01u8349u8d8au5b57u52a0u811au7d27u7231u7b49u4e60u9635u6015u6708u9752u534au706bu6cd5u9898u5efau8d76u4f4du5531u6d77u4e03u5973u4efbu4ef6u611fu51c6u5f20u56e2u5c4bu79bbu8272u8138u7247u79d1u5012u775bu5229u4e16u521au4e14u7531u9001u5207u661fu5bfcu665au8868u591fu6574u8ba4u54cdu96eau6d41u672au573au8be5u5e76u5e95u6df1u523bu5e73u4f1fu5fd9u63d0u786eu8fd1u4eaeu8f7bu8bb2u519cu53e4u9ed1u544au754cu62c9u540du5440u571fu6e05u9633u7167u529eu53f2u6539u5386u8f6cu753bu9020u5634u6b64u6cbbu5317u5fc5u670du96e8u7a7fu5185u8bc6u9a8cu4f20u4e1au83dcu722cu7761u5174u5f62u91cfu54b1u89c2u82e6u4f53u4f17u901au51b2u5408u7834u53cbu5ea6u672fu996du516cu65c1u623fu6781u5357u67aau8bfbu6c99u5c81u7ebfu91ceu575au7a7au6536u7b97u81f3u653fu57ceu52b3u843du94b1u7279u56f4u5f1fu80dcu6559u70edu5c55u5305u6b4cu7c7bu6e10u5f3au6570u4e61u547cu6027u97f3u7b54u54e5u9645u65e7u795eu5ea7u7ae0u5e2eu5566u53d7u7cfbu4ee4u8df3u975eu4f55u725bu53d6u5165u5cb8u6562u6389u5ffdu79cdu88c5u9876u6025u6797u505cu606fu53e5u533au8863u822cu62a5u53f6u538bu6162u53d4u80ccu7ec6";
52 Random random = new Random();// 生成随机数
53
54 // 定义x坐标
55 int x = 10;
56 for (int i = 0; i < 4; i++) {
57 // 随机颜色
58 graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
59 .nextInt(110), 20 + random.nextInt(110)));
60 // 旋转 -30 --- 30度
61 int jiaodu = random.nextInt(60) - 30;
62 // 换算弧度
63 double theta = jiaodu * Math.PI / 180;
64
65 // 生成一个随机数字
66 int index = random.nextInt(words.length()); // 生成随机数 0 到 length - 1
67 // 获得字母数字
68 char c = words.charAt(index);
69
70 // 将c 输出到图片
71 graphics2d.rotate(theta, x, 20);
72 graphics2d.drawString(String.valueOf(c), x, 20);
73 graphics2d.rotate(-theta, x, 20);
74 x += 30;
75 }
76
77 // 步骤五 绘制干扰线
78 graphics.setColor(getRandColor(160, 200));
79 int x1;
80 int x2;
81 int y1;
82 int y2;
83 for (int i = 0; i < 30; i++) {
84 x1 = random.nextInt(width);
85 x2 = random.nextInt(12);
86 y1 = random.nextInt(height);
87 y2 = random.nextInt(12);
88 graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
89 }
90
91 // 将上面图片输出到浏览器 ImageIO
92 graphics.dispose();// 释放资源
93 ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
94
95 }
96
97
98 public void doPost(HttpServletRequest request, HttpServletResponse response)
99 throws ServletException, IOException {
100 doGet(request, response);
101 }
102
103 /**
104 * 取其某一范围的color
105 *
106 * @param fc
107 * int 范围参数1
108 * @param bc
109 * int 范围参数2
110 * @return Color
111 */
112 private Color getRandColor(int fc, int bc) {
113 // 取其随机颜色
114 Random random = new Random();
115 if (fc > 255) {
116 fc = 255;
117 }
118 if (bc > 255) {
119 bc = 255;
120 }
121 int r = fc + random.nextInt(bc - fc);
122 int g = fc + random.nextInt(bc - fc);
123 int b = fc + random.nextInt(bc - fc);
124 return new Color(r, g, b);
125 }
126
127 }
View Code
实现验证码看不清更换一张的功能
页面
浏览器有缓存 要更换每次请求的路径 才能实现点击更换图片
校验
checkImgServlet
1 package com.imooc.web.servlet;
2
3 import java.awt.Color;
4 import java.awt.Font;
5 import java.awt.Graphics;
6 import java.awt.Graphics2D;
7 import java.awt.image.BufferedImage;
8 import java.io.IOException;
9 import java.util.Random;
10
11 import javax.imageio.ImageIO;
12 import javax.servlet.ServletException;
13 import javax.servlet.annotation.WebServlet;
14 import javax.servlet.http.HttpServlet;
15 import javax.servlet.http.HttpServletRequest;
16 import javax.servlet.http.HttpServletResponse;
17
18 /**
19 * 生成验证码图片
20 */
21 @WebServlet("/CheckImgServlet")
22 public class CheckImgServlet extends HttpServlet {
23
24 public void doGet(HttpServletRequest request, HttpServletResponse response)
25 throws ServletException, IOException {
26
27 int width = 120;
28 int height = 30;
29
30 // 步骤一 绘制一张内存中图片
31 BufferedImage bufferedImage = new BufferedImage(width, height,
32 BufferedImage.TYPE_INT_RGB);
33
34 // 步骤二 图片绘制背景颜色 ---通过绘图对象
35 Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
36 // 绘制任何图形之前 都必须指定一个颜色
37 graphics.setColor(getRandColor(200, 250));
38 graphics.fillRect(0, 0, width, height);
39
40 // 步骤三 绘制边框
41 graphics.setColor(Color.WHITE);
42 graphics.drawRect(0, 0, width - 1, height - 1);
43
44 // 步骤四 四个随机数字
45 Graphics2D graphics2d = (Graphics2D) graphics;
46 // 设置输出字体
47 graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
48
49 String words =
50 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
51 // String words = "u7684u4e00u4e86u662fu6211u4e0du5728u4ebau4eecu6709u6765u4ed6u8fd9u4e0au7740u4e2au5730u5230u5927u91ccu8bf4u5c31u53bbu5b50u5f97u4e5fu548cu90a3u8981u4e0bu770bu5929u65f6u8fc7u51fau5c0fu4e48u8d77u4f60u90fdu628au597du8fd8u591au6ca1u4e3au53c8u53efu5bb6u5b66u53eau4ee5u4e3bu4f1au6837u5e74u60f3u751fu540cu8001u4e2du5341u4eceu81eau9762u524du5934u9053u5b83u540eu7136u8d70u5f88u50cfu89c1u4e24u7528u5979u56fdu52a8u8fdbu6210u56deu4ec0u8fb9u4f5cu5bf9u5f00u800cu5df1u4e9bu73b0u5c71u6c11u5019u7ecfu53d1u5de5u5411u4e8bu547du7ed9u957fu6c34u51e0u4e49u4e09u58f0u4e8eu9ad8u624bu77e5u7406u773cu5fd7u70b9u5fc3u6218u4e8cu95eeu4f46u8eabu65b9u5b9eu5403u505au53ebu5f53u4f4fu542cu9769u6253u5462u771fu5168u624du56dbu5df2u6240u654cu4e4bu6700u5149u4ea7u60c5u8defu5206u603bu6761u767du8bddu4e1cu5e2du6b21u4eb2u5982u88abu82b1u53e3u653eu513fu5e38u6c14u4e94u7b2cu4f7fu5199u519bu5427u6587u8fd0u518du679cu600eu5b9au8bb8u5febu660eu884cu56e0u522bu98deu5916u6811u7269u6d3bu90e8u95e8u65e0u5f80u8239u671bu65b0u5e26u961fu5148u529bu5b8cu5374u7ad9u4ee3u5458u673au66f4u4e5du60a8u6bcfu98ceu7ea7u8ddfu7b11u554au5b69u4e07u5c11u76f4u610fu591cu6bd4u9636u8fdeu8f66u91cdu4fbfu6597u9a6cu54eau5316u592au6307u53d8u793eu4f3cu58ebu8005u5e72u77f3u6ee1u65e5u51b3u767eu539fu62ffu7fa4u7a76u5404u516du672cu601du89e3u7acbu6cb3u6751u516bu96beu65e9u8bbau5417u6839u5171u8ba9u76f8u7814u4ecau5176u4e66u5750u63a5u5e94u5173u4fe1u89c9u6b65u53cdu5904u8bb0u5c06u5343u627eu4e89u9886u6216u5e08u7ed3u5757u8dd1u8c01u8349u8d8au5b57u52a0u811au7d27u7231u7b49u4e60u9635u6015u6708u9752u534au706bu6cd5u9898u5efau8d76u4f4du5531u6d77u4e03u5973u4efbu4ef6u611fu51c6u5f20u56e2u5c4bu79bbu8272u8138u7247u79d1u5012u775bu5229u4e16u521au4e14u7531u9001u5207u661fu5bfcu665au8868u591fu6574u8ba4u54cdu96eau6d41u672au573au8be5u5e76u5e95u6df1u523bu5e73u4f1fu5fd9u63d0u786eu8fd1u4eaeu8f7bu8bb2u519cu53e4u9ed1u544au754cu62c9u540du5440u571fu6e05u9633u7167u529eu53f2u6539u5386u8f6cu753bu9020u5634u6b64u6cbbu5317u5fc5u670du96e8u7a7fu5185u8bc6u9a8cu4f20u4e1au83dcu722cu7761u5174u5f62u91cfu54b1u89c2u82e6u4f53u4f17u901au51b2u5408u7834u53cbu5ea6u672fu996du516cu65c1u623fu6781u5357u67aau8bfbu6c99u5c81u7ebfu91ceu575au7a7au6536u7b97u81f3u653fu57ceu52b3u843du94b1u7279u56f4u5f1fu80dcu6559u70edu5c55u5305u6b4cu7c7bu6e10u5f3au6570u4e61u547cu6027u97f3u7b54u54e5u9645u65e7u795eu5ea7u7ae0u5e2eu5566u53d7u7cfbu4ee4u8df3u975eu4f55u725bu53d6u5165u5cb8u6562u6389u5ffdu79cdu88c5u9876u6025u6797u505cu606fu53e5u533au8863u822cu62a5u53f6u538bu6162u53d4u80ccu7ec6";
52 Random random = new Random();// 生成随机数
53 // 定义一个字符串,用于保存随机产生的四个字母或数字
54 StringBuffer sb = new StringBuffer();
55 // 定义x坐标
56 int x = 10;
57 for (int i = 0; i < 4; i++) {
58 // 随机颜色
59 graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
60 .nextInt(110), 20 + random.nextInt(110)));
61 // 旋转 -30 --- 30度
62 int jiaodu = random.nextInt(60) - 30;
63 // 换算弧度
64 double theta = jiaodu * Math.PI / 180;
65
66 // 生成一个随机数字
67 int index = random.nextInt(words.length()); // 生成随机数 0 到 length - 1
68 // 获得字母数字
69 char c = words.charAt(index);
70 // 将产生字符存入到StringBuffer中
71 sb.append(c);
72 // 将c 输出到图片
73 graphics2d.rotate(theta, x, 20);
74 graphics2d.drawString(String.valueOf(c), x, 20);
75 graphics2d.rotate(-theta, x, 20);
76 x += 30;
77 }
78 // 将产生的字符串存入到session中:
79 request.getSession().setAttribute("checkCode", sb.toString());
80
81 // 步骤五 绘制干扰线
82 graphics.setColor(getRandColor(160, 200));
83 int x1;
84 int x2;
85 int y1;
86 int y2;
87 for (int i = 0; i < 30; i++) {
88 x1 = random.nextInt(width);
89 x2 = random.nextInt(12);
90 y1 = random.nextInt(height);
91 y2 = random.nextInt(12);
92 graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
93 }
94
95 // 将上面图片输出到浏览器 ImageIO
96 graphics.dispose();// 释放资源
97 ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
98
99 }
100
101
102 public void doPost(HttpServletRequest request, HttpServletResponse response)
103 throws ServletException, IOException {
104 doGet(request, response);
105 }
106
107 /**
108 * 取其某一范围的color
109 *
110 * @param fc
111 * int 范围参数1
112 * @param bc
113 * int 范围参数2
114 * @return Color
115 */
116 private Color getRandColor(int fc, int bc) {
117 // 取其随机颜色
118 Random random = new Random();
119 if (fc > 255) {
120 fc = 255;
121 }
122 if (bc > 255) {
123 bc = 255;
124 }
125 int r = fc + random.nextInt(bc - fc);
126 int g = fc + random.nextInt(bc - fc);
127 int b = fc + random.nextInt(bc - fc);
128 return new Color(r, g, b);
129 }
130
131 }
View Code
loginServlet
1 package com.imooc.web.servlet;
2
3 import java.io.IOException;
4 import java.util.List;
5
6 import javax.servlet.ServletException;
7 import javax.servlet.annotation.WebServlet;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 import com.imooc.domain.User;
13 import com.imooc.service.UserService;
14 import com.imooc.service.impl.UserServiceImpl;
15
16 @WebServlet("/LoginServlet")
17 public class LoginServlet extends HttpServlet {
18 private static final long serialVersionUID = 1L;
19
20 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
21 // 完成验证码的校验:
22 // 获得session中保存的验证码的信息
23 String code1 = (String)request.getSession().getAttribute("checkCode");
24 // 接收前台表单提交的验证码的信息
25 String code2 = request.getParameter("checkCode");
26 if(code2==null || !code2.equalsIgnoreCase(code1)){
27 request.setAttribute("msg", "验证码输入不正确!");
28 request.getRequestDispatcher("/login.jsp").forward(request, response);
29 return;
30 }
31
32 // 接收数据:
33 String username = request.getParameter("username");
34 String password = request.getParameter("password");
35 // 封装数据:
36 User user = new User();
37 user.setUsername(username);
38 user.setPassword(password);
39 // 处理数据:完成登陆.
40 UserService userService = new UserServiceImpl();
41 // 获得用户列表的集合:
42 List<User> userList = (List<User>)getServletContext().getAttribute("userList");
43 User existUser = userService.login(userList,user);
44 // 显示结果:
45 if(existUser == null){
46 // 登录失败
47 request.setAttribute("msg", "用户名或密码错误!");
48 request.getRequestDispatcher("/login.jsp").forward(request, response);
49 }else{
50 // 登录成功
51 // 将用户信息保存:
52 request.getSession().setAttribute("existUser", existUser);
53 response.sendRedirect(request.getContextPath()+"/index.jsp");
54 }
55 }
56
57 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
58 doGet(request, response);
59 }
60
61 }
View Code
Kaptcha验证码的介绍及入门
上面我们自己编写的验证码代码有一定的局限性,当验证码的样式,比如宽高等需要改变时,得更改相应的源代码,不是很方便
这时我们可以用第三方的验证码工具,如Kaptcha
首先我们要将Kaptcha的jar包引入到工程中
然后在web.xml中进行相应的配置
1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
3
4 <servlet>
5 <servlet-name>KaptchaServlet</servlet-name>
6 <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
7
8 <!-- 修改随机的字母或数字的长度 -->
9 <init-param>
10 <param-name>kaptcha.textproducer.char.length</param-name>
11 <param-value>4</param-value>
12 </init-param>
13
14 <!-- 修改字体大小 -->
15 <init-param>
16 <param-name>kaptcha.textproducer.font.size</param-name>
17 <param-value>25</param-value>
18 </init-param>
19 <init-param>
20 <param-name>kaptcha.textproducer.char.space</param-name>
21 <param-value>10</param-value>
22 </init-param>
23
24 <!-- 修改图片的宽高 -->
25 <init-param>
26 <param-name>kaptcha.image.width</param-name>
27 <param-value>120</param-value>
28 </init-param>
29 <init-param>
30 <param-name>kaptcha.image.height</param-name>
31 <param-value>30</param-value>
32 </init-param>
33 </servlet>
34
35 <servlet-mapping>
36 <servlet-name>KaptchaServlet</servlet-name>
37 <url-pattern>/KaptchaServlet</url-pattern>
38 </servlet-mapping>
39
40
41 <welcome-file-list>
42 <welcome-file>index.html</welcome-file>
43 <welcome-file>index.htm</welcome-file>
44 <welcome-file>index.jsp</welcome-file>
45 <welcome-file>default.html</welcome-file>
46 <welcome-file>default.htm</welcome-file>
47 <welcome-file>default.jsp</welcome-file>
48 </welcome-file-list>
49 </web-app>
View Code
配置参数介绍
配置前
配置后
Kaptcha验证码的校验
1 // 获得session中保存的验证码的信息
2 String code1 = (String)request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
3