任务5:熟悉Servlet实现验证码的使用
7
李焕贞
开始于 2020-04-20 15:09
0 2 92
已截止

任务尚未发布或者你没有权限查看任务内容。

任务讨论
李焕贞

任务已更新

李焕贞

任务已更新

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

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;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class CodeImageServlet
 */
@WebServlet("/CodeImageServlet")
public class CodeImageServlet extends HttpServlet {
	
	
	
private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
    
    /**
     * 生成一个宽为width, 高为height, 验证码为code的图片
     * @param width 图片的宽
     * @param height 图片的高
     * @param code 验证码字符串
     * @return 返回图片验证码
     */
    public static BufferedImage getImage(int width, int height, String code){
        return getImage(width, height, code, 20);
    }
/**
     * 生成一个宽为width, 高为height, 验证码为code的图片,图片中干扰线的条数为lineCnt
     * @param width 图片的宽
     * @param height 图片的高
     * @param code 验证码字符串
     * @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整
     * @return 返回图片验证码
     */
    public static BufferedImage getImage(int width, int height, String code, int lineCnt){
        return createImage(width, height, code, lineCnt, 0.01);
    }
    /**
     * 生成一个宽为width, 高为height, 验证码为code的图片,图片中干扰线的条数为lineCnt
     * 噪声比为noiseRate,即图片中噪音像素点的百分比
     * @param width 图片的宽
     * @param height 图片的高
     * @param code 验证码字符串
     * @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整
     * @param noiseRate 图片中噪音像素点占总像素的百分比
     * @return 返回图片验证码
     */
    public static BufferedImage getImage(int width, int height, String code, int lineCnt, double noiseRate){
        return createImage(width, height, code, lineCnt, noiseRate);
    }
 /**
     * 
     * 生成一个宽为width, 高为height, 验证码为code的图片,图片中干扰线的条数为lineCnt
     * 噪声比为noiseRate,即图片中噪音像素点的百分比
     * @param width 图片的宽
     * @param height 图片的高
     * @param code 验证码字符串
     * @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整
     * @param noiseRate 图片中噪音像素点占总像素的百分比
     * @return 返回图片验证码
     */
    private static BufferedImage createImage(int width, int height, String code, int lineCnt, double noiseRate){
        int fontWidth = ((int)(width * 0.8)) / code.length();
        int fontHeight = (int)(height * 0.7);
        //为了在任意的width和height下都能生成良好的验证码,
        //字体的大小为fontWdith何fontHeight中的小者,
        int fontSize = Math.min(fontWidth, fontHeight);
        //drawString时要用到
        int paddingX = (int) (width * 0.1);
        int paddingY = height - (height - fontSize) / 2;
 //创建图像
        BufferedImage buffimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //获得画笔
        Graphics g = buffimg.getGraphics();
        //设置画笔的颜色
        g.setColor(getRandColor(200, 255));
        //然后填充一个矩形,即设置背景色
        g.fillRect(0, 0, width, height);
        
        // 设置干扰线
        for (int i = 0; i < lineCnt; i++) {
                //随机获取干扰线的起点和终点
            int xs = (int)(Math.random() * width);
            int ys = (int)(Math.random() * height);
            int xe = (int)(Math.random() * width);
            int ye = (int)(Math.random() * height);
            g.setColor(getRandColor(1, 255));
            g.drawLine(xs, ys, xe, ye);
        }
        // 添加噪点
        int area = (int) (noiseRate * width * height);
        for(int i=0; i<area; ++i){
                int x = (int)(Math.random() * width);
                int y = (int)(Math.random() * height);
                buffimg.setRGB(x, y, (int)(Math.random() * 255));
        }
        //设置字体
        Font font = new Font("Ravie", Font.PLAIN, fontSize);
        g.setFont(font);
        
        for(int i=0; i<code.length(); ++i){
                String ch = code.substring(i, i+1);
                g.setColor(getRandColor(1, 199));
                g.drawString(ch, paddingX + fontWidth * i, paddingY);
        }
        return buffimg;
        
    }
/**
     * 获取随机的颜色,r,g,b的取值在L到R之间
     * @param L 左区间
     * @param R 右区间
     * @return 返回随机颜色值
     */
    private static Color getRandColor(int L, int R){
        if(L > 255)
            L = 255;
        if(R > 255)
            R = 255;
        if(L < 0)
            L = 0;
        if(R < 0)
            R = 0;
        int interval = R - L; 
        int r = L + (int)(Math.random() * interval);
        int g = L + (int)(Math.random() * interval);
        int b = L + (int)(Math.random() * interval);
        return new Color(r, g, b);
    }
  /**
     * 获取随机的颜色,r,g,b的取值在L到R之间
     * @param L 左区间
     * @param R 右区间
     * @return 返回随机颜色值
     */
    private static Color getRandColor(int L, int R){
        if(L > 255)
            L = 255;
        if(R > 255)
            R = 255;
        if(L < 0)
            L = 0;
        if(R < 0)
            R = 0;
        int interval = R - L; 
        int r = L + (int)(Math.random() * interval);
        int g = L + (int)(Math.random() * interval);
        int b = L + (int)(Math.random() * interval);
        return new Color(r, g, b);
    }
 /**
     * 随机生成若干个由大小写字母和数字组成的字符串
     * @param len 随机生成len个字符
     * @return 返回随机生成的若干个由大小写字母和数字组成的字符串
     */
    public static String getRandCode(int len){

	    		double d = Math.random();
	    		int a = (int)(d*10000);
	    		String c = ""+a;
	    		if(a<1000) {
	    			c ="0"+a;
	    		}
        
        return c;
    }
    /**
     * 将图片转为byte数组
     * @param image 图片
     * @return 返回byte数组
     * @throws IOException
     */
    public static byte[] getByteArray(BufferedImage image) throws IOException{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", baos);
        return baos.toByteArray();
    }
	
	
	
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CodeImageServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
        //随机生成字符串,并写入session
        String code = getRandCode(4);
        session.setAttribute("coImage", code);
        
        BufferedImage image = getImage(100,30, code, 5);
        response.setContentType("image/jpg");
        
        OutputStream out =  response.getOutputStream();
        out.write(getByteArray(image));
        out.flush();
        out.close();
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
		response.sendRedirect("login.html");

	}

}
import java.io.IOException;
import java.io.PrintWriter;

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.servlet.http.HttpSession;

/**
 * Servlet implementation class CheckCodeServlet
 */
@WebServlet("/CheckCodeServlet")
public class CheckCodeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CheckCodeServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
HttpSession session = request.getSession();
        String verification = (String)session.getAttribute("coImage");
        String submitVerification = request.getParameter("code");
        PrintWriter pw = response.getWriter();
        if(verification!=null && submitVerification!=null){
            if(verification.toLowerCase().equals(submitVerification.toLowerCase())){
        		pw.print("验证成功");
            }
            else{
            	pw.print("验证失败");
            }           
        }
        else{
        	pw.print("验证失败");
        }
        session.removeAttribute("coImage");//防止用户重复提交表单
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}