Servlet
最近在学习Servlet,以我的理解:servlet就是运行在服务器端的一个程序,在需要时(如客户端输入某个url时),web容器自动调用某个servlet实现某个功能。我用Servlet实现了一个网站的验证码dome,给大家分享一下。
这是前端的html代码,这里用了下Bootstrap的框架,有想了解这个框架的小伙伴请去官网参考,下载下来将其css和js文件引入就行了。其中写的js脚本中的函数是用来实现:点击验证码图片,重新请求servlet程序,生成不同的验证码。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<title>验证码生成</title>
<script type="text/javascript">
function changeImg(img) {
img.src=img.src+"?"+(new Date().getDate())
}
</script>
</head>
<body>
<form action="login.do" method="post">
姓名:<input type="text" name="username" > <br/><br/>
密码:<input type="password" name="pwd"><br/>
验证码:<input type="text" name="yanzhenma">
<img id="conform_img" src="/MyFristWebApp/login.do" onclick="changeImg(this)">
<br/>
<input type="submit" value="login">
</form>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.min.js" ></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
</body>
</body>
</html>
这是Servlet后台代码:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/login.do")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static int WIDTH=200;
private static int HEIGHT=50;
private static BufferedImage image;
public MyServlet() {}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("image/jpeg");
generateComfirImg();
fillNumber(4);
preventImgRec();
//输出到客户端
ImageIO.write(image, "jpg", response.getOutputStream());
}
private void generateComfirImg() {
//创建图片对象
image=new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_3BYTE_BGR);
Graphics graphics=image.getGraphics();
//填充图片背景色
graphics.setColor(new Color(240,255,240));
graphics.fillRect(0, 0, WIDTH, HEIGHT);
//填充图片边框颜色
graphics.setColor(new Color(187,255,255));
graphics.drawRect(1, 1, WIDTH-2, HEIGHT-2);
}
//向图片中插入count个字符
private void fillNumber(int count) {
//旋转图片中的文字需要Graphics2D对象
Graphics2D graphics=(Graphics2D) image.getGraphics();
graphics.setColor(new Color(100,149,237));
graphics.setFont(new Font("Times New Roman", Font.BOLD+ Font.ITALIC, 30));
//备选字符集
final String string="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
Random random=new Random();
//向图片写入字符的开始位置
int x=20,y=40;
//便于改变生成验证码的个数
int move=(WIDTH-20)/count;
for (int i = 0; i < count; i++) {
//从所有的字符集中随机选择一个字符
int pos=random.nextInt(string.length());
int degree=random.nextInt()%25; //随机-25~25度数
graphics.rotate(degree*Math.PI/180, x, y); //将度数转化为弧度
graphics.drawString(string.charAt(pos)+"",x , y);
graphics.rotate(-degree*Math.PI/180, x, y); //每次旋转后恢复
//x坐标向右移动
x+=move;
}
}
//防止图片识别技术
private void preventImgRec() {
Graphics graphics=image.getGraphics();
graphics.setColor(new Color(100,149,237));
graphics.setFont(new Font("Times New Roman", Font.BOLD+ Font.ITALIC, 30));
int n=3;
Random random=new Random();
int startX,startY;
int endX,endY;
for (int i = 0; i < n; i++) {
startX=random.nextInt(WIDTH);
endX=random.nextInt(WIDTH);
startY=random.nextInt(HEIGHT);
endY=random.nextInt(HEIGHT);
graphics.drawLine(startX, startY, endX, endY);
}
}
}