yanz

response生成验证码

验证码的作用:防止恶意注册、攻击等

网站上看到的验证码,实际上都是一些图片,而这些图片都是程序(Servlet)生成的!

 

package day19.test;

 

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Random;

 

import javax.imageio.ImageIO;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

@SuppressWarnings("all")

public class CheckCodeServlet extends HttpServlet {

   public void doGet(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

      int width = 130, height = 39; // 图片宽度和高度

      // 创建用于保存图片信息的缓冲区对象

      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

      Graphics g = image.getGraphics(); // 获取画笔

      g.setColor(new Color(255, 255, 255)); // 设置画笔颜色

      g.fillRect(0, 0, width, height); // 填充背景颜色

     

      g.setColor(new Color(0, 0, 0)); // 重新设置画笔颜色

      g.drawRect(0, 0, width - 1, height - 1); // 绘制边框

     

      Random r = new Random(); // 创建随机数对象

     

      // 添加干扰线

      for (int i = 0; i < 15; i++) {

        g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255))); // 重新设置画笔颜色

        g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));

      }

     

      // 生成验证码的数据

      String data = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789";

      int length = data.length();

      String capstr = "";

      g.setFont(new Font("宋体", Font.BOLD, 35)); // 设置字体

      for (int i = 0; i < 4; i++) {

        int index = r.nextInt(length);

        String str = data.charAt(index) + "";

        capstr += str;

        g.setColor(new Color(r.nextInt(200), r.nextInt(200), r.nextInt(200))); // 重新设置画笔颜色

        g.drawString(str, 10 + (i * 28), 30); // 将字符写入图片

      }

     

      g.dispose(); // 释放资源

      response.setContentType("image/jpg"); // 设置响应类型

     

      OutputStream strm = response.getOutputStream(); // 输出流

      ImageIO.write(image, "jpg", strm); // 将图片写到输出流

      strm.close(); // 关闭输出流

   }

  

   public void doPost(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

      doGet(request, response);

   }

}

 

文件下载

文件下载分为2种方式:

  1. 使用超链接方式直接下载:服务器自动将请求的资源以流的形式发送给浏览器,浏览器会自动识别并下载到本地
  2. Servlet方式下载:使用输入流读取文件,然后使用response获取输出流对象,将输入流中的数据响应到客户端

 

超链接方式

<a href="1.txt">1.txt</a><br/>

<a href="1.jpg">1.jpg</a><br/>

<a href="1.doc">1.doc</a><br/>

<a href="1.rar">1.rar</a><br/>

<a href="中文.rar">中文.rar</a><br/>

<a href=" .rar"> .rar</a>

 

问题:

  1. 如果下载的文件浏览器能够解析,则会自动显示处来,而不是我们要的下载
  2. 如果下载的资源中,有中文,则提示找不到文件

可以修改tomcat的配置conf/server.xml,编码方式改为UTF-8,不推荐使用

 

Servlet方式

Servlet代码

package web;

 

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.net.URLEncoder;

 

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import sun.misc.BASE64Encoder;

 

@SuppressWarnings("all")

public class DownLoadServlet extends HttpServlet {

   public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

     String filename = request.getParameter("filename");

     // UTF-8浏览器编码 ----> ISO-8859-1服务器解码

     byte[] bytes = filename.getBytes("ISO-8859-1");

     filename = new String(bytes, "UTF-8");

    

     // 获取当前项目在服务器中的真实路径

     // servletContext表示当前的项目对象

     ServletContext servletContext = request.getServletContext();

     // D:\apache-tomcat-7.0.77\webapps\hei26_web10

     //String appPath = servletContext.getRealPath("");

     // D:\apache-tomcat-7.0.77\webapps\hei26_web10\

     //String appPath2 = servletContext.getRealPath("/");

     // D:\apache-tomcat-7.0.77\webapps\hei26_web10\+filename

     String appPath3 = servletContext.getRealPath("/" + filename);

     InputStream is = new FileInputStream(appPath3);

     ServletOutputStream os = response.getOutputStream();

    

     // 获取浏览器类型,通过请求头中的User-Agent来判断

     String ua = request.getHeader("User-Agent");

     boolean IE_LT11 = ua.contains("MSIE"); // IE11以下版本

     boolean IE11 = ua.contains("rv:11.0) like Gecko"); // IE11

     boolean Edge = ua.contains("Edge"); // win10自带的Edge浏览器

     // 如果是微软的浏览器,直接进行UTF-8编码

     if (IE_LT11 || IE11 || Edge) {

        filename = URLEncoder.encode(filename, "UTF-8");

        // java的编码方式和浏览器有略微的不同:对于空格,java编码后的结果是加号,

        // 而浏览器的编码结果是%20,因此将+替换成%20, 这样浏览器才能正确解析空格

        filename = filename.replace("+", "%20");

     }

     // 标准浏览器使用Base64编码

     else {

        BASE64Encoder encoder = new BASE64Encoder();

        filename = encoder.encode(filename.getBytes("utf-8"));

        // =?utf-8?B?文件名?= 是告诉浏览器以Base64进行解码

        filename = "=?utf-8?B?" + filename + "?=";

     }

    

     // 告诉浏览器,不要解析文件,要以附件的形式下载

     response.setHeader("Content-Disposition", "attachment;filename=" + filename);

    

     byte[] buf = new byte[1024];

     int len = 0;

     while ( ( len = is.read(buf) ) != -1  ) {

        os.write(buf, 0, len);

     }

     is.close();

     os.flush();

     os.close();

   }

 

   public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

     doGet(request, response);

   }

  

   public static void main(String[] args) throws UnsupportedEncodingException {

     String url = "AAhttp://127.0.0.1:8080/hei26_web10/download?filename=1.txtZZ";

     BASE64Encoder encoder = new BASE64Encoder();

     url = encoder.encode(url.getBytes("utf-8"));

     System.out.println(url);

   }

}

 

 

download.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

<script type="text/javascript" src="jquery-1.8.3.js"></script>

<script type="text/javascript">

   $(function() {

      // 给超链接绑定单击事件:e:事件对象,可以获取左键还是右键?是按下了键盘上的哪个键?

      $("div a").click(function(e) {

        // 获取要下载的文件名

        var href = $(this).attr("href");

        // 将文件名赋给隐藏域:目的是为了利用表单的特性:提交时会对数据进行UTF-8编码

        $("#filename").val(href);

        // 提交表单:在事件方法中,如果指定函数,则表示事件绑定,如果没有参数,表示调用相应的事件

        $("#dForm").submit();

        // 元素的默认动作: 点击超链接会发生跳转、点击下拉框会展开选项、点击复选按钮会选中... 这些就是元素的默认动作

        e.preventDefault(); // 阻止元素的默认动作

      });

   });

</script>

</head>

<body>

<div>

<a href="1.txt">1.txt</a><br/>

<a href="1.jpg">1.jpg</a><br/>

<a href="1.doc">1.doc</a><br/>

<a href="1.rar">1.rar</a><br/>

<a href="中文.rar">中文.rar</a><br/>

<a href=" .rar"> .rar</a>

</div>

<a href="thunder://QUFodHRwOi8vMTI3LjAuMC4xOjgwODAvaGVpMjZfd2ViMTAvZG93bmxvYWQ/ZmlsZW5hbWU9MS50

eHRaWg==">1.txt--迅雷下载</a>

<form id="dForm" action="/hei26_web10/download">

   <input type="hidden" id="filename" name="filename" />

</form>

 

<!-- <a href="/hei26_web10/download?filename=1.txt">1.txt</a><br/>

<a href="/hei26_web10/download?filename=1.jpg">1.jpg</a><br/>

<a href="/hei26_web10/download?filename=1.doc">1.doc</a><br/>

<a href="/hei26_web10/download?filename=1.rar">1.rar</a><br/>

<a href="/hei26_web10/download?filename=中文.rar">中文.rar</a><br/>

<a href="/hei26_web10/download?filename= .rar"> .rar</a> -->

</body>

</html>

 

 

转载于:https://my.oschina.net/u/3892666/blog/3070738

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值