案例一:发送验证码案例

1、 定义一个 Servlet 用来在内存中生成 二维码图片,并向浏览器页面输出。

 1 import javax.imageio.ImageIO;
 2 import javax.servlet.ServletException;
 3 import javax.servlet.annotation.WebServlet;
 4 import javax.servlet.http.HttpServlet;
 5 import javax.servlet.http.HttpServletRequest;
 6 import javax.servlet.http.HttpServletResponse;
 7 import java.awt.*;
 8 import java.awt.image.BufferedImage;
 9 import java.io.IOException;
10 import java.util.Random;
11 
12 @WebServlet("/checkCodeServlet")
13 public class CheckCodeServlet extends HttpServlet {
14     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
15 
16         // 定义图片的宽高
17         int width = 100;
18         int height = 50;
19 
20         // 1 创建对象,在内存中生成图片(验证码图片对象)
21         BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
22 
23         // 2 修饰图片
24         // 2.1 填充背景色
25         Graphics g = image.getGraphics(); //获取画笔对象
26         g.setColor(Color.pink);  // 设置画笔颜色
27         g.fillRect(0,0,width,height);  // 绘制一个矩形,给定坐标与宽高
28 
29         // 2.2 画边框
30         g.setColor(Color.blue);    // 设置画笔颜色
31         g.drawRect(0,0,width-1,height-1);  // 给图像绘制边框
32 
33         String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
34         //生成随机角标
35         Random ran = new Random();
36 
37         for (int i = 1; i <= 4; i++) {
38             int index = ran.nextInt(str.length());
39             //获取字符
40             char ch = str.charAt(index);//随机字符
41             //2.3写验证码
42             g.drawString(ch+"",width/5*i,height/2);
43         }
44 
45         //2.4画干扰线
46         g.setColor(Color.GREEN);
47 
48         // 随机生成坐标点
49 
50         for (int i = 0; i < 6; i++) {
51             int x1 = ran.nextInt(width);
52             int x2 = ran.nextInt(width);
53 
54             int y1 = ran.nextInt(height);
55             int y2 = ran.nextInt(height);
56             g.drawLine(x1,y1,x2,y2);  // 画干扰线
57         }
58 
59 
60         // 3 将图片输出到页面展示:通过response 的 字符流,将图片输出到浏览器上
61         ImageIO.write(image,"jpg",response.getOutputStream());
62     }
63 
64     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
65         this.doPost(request, response);
66     }
67 }

 

2、 定义一个web页面,用来查看验证码,可以刷新验证码。

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>验证码</title>
 6 
 7     <script>
 8         /*
 9                 点击超链接或者图片,需要换一张
10                 1.给超链接和图片绑定单击事件
11 
12                 2.重新设置图片的src属性值
13 
14          */
15         window.onload = function(){
16             //1.获取图片对象
17             var img = document.getElementById("checkCode");
18             //2.绑定单击事件
19             img.onclick = function(){
20                 //加时间戳
21                 var date = new Date().getTime();
22 
23                 img.src = "/web/checkCodeServlet?"+date;
24             }
25 
26             // 获取超链接对象
27             var a = document.getElementById("change");
28             
29             a.onclick = img.onclick();
30             
31         }
32 
33 
34     </script>
35 
36 
37 </head>
38 <body>
39 
40 
41 <img id="checkCode" src="/web/checkCodeServlet" />
42 
43 <a id="change" href="javascript:;">看不清换一张?</a>
44 
45 </body>
46 </html>

 

3、 效果图

 

案例二: 文件下载案例

1、文件下载需求:

1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载

2、分析过程:

1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
2. 任何资源都必须弹出下载提示框
3. 使用响应头设置资源的打开方式:   content-disposition:attachment;filename=xxx

3、步骤:

1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
2. 定义Servlet
	1. 获取文件名称
	2. 使用字节输入流加载文件进内存
	3. 指定response的响应头: content-disposition:attachment;filename=xxx
	4. 将数据写出到response输出流

4、下载页面:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>文件下载</title>
 6 </head>
 7 <body>
 8 
 9 
10     <a href="/day13/img/狐狸.jpg">图片1</a>
11 
12     <a href="/day13/img/2.jpg">图片2</a>
13 
14     <a href="/day13/img/1.avi">视频</a>
15     <hr>
16 
17 
18     <a href="/day13/downloadservlet?filename=狐狸.jpg">图片1</a>
19 
20     <a href="/day13/downloadservlet?filename=2.jpg">图片2</a>
21 
22     <a href="/day13/downloadservlet?filename=1.avi">视频</a>
23 
24 
25 
26 
27 </body>
28 </html>

 

 

5、DownLoadServlet 类

 1 import javax.servlet.ServletContext;
 2 import javax.servlet.ServletException;
 3 import javax.servlet.ServletOutputStream;
 4 import javax.servlet.annotation.WebServlet;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 import java.io.FileInputStream;
 9 import java.io.IOException;
10 
11 @WebServlet("/downloadservlet")
12 public class downloadservlet extends HttpServlet {
13     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
14         //1获取请求参数,文件名称
15         String filename = request.getParameter("filename");
16 
17         //2使用字节输入流加载文件进内存
18         // 2.1 找文件服务器路径
19         ServletContext servletContext = this.getServletContext();
20         String realPath = servletContext.getRealPath("/img/" + filename);
21 
22         //2.2 使用字节流关联
23         FileInputStream fis = new FileInputStream(realPath);
24 
25         //3 设置 response 的响应头
26         // 3.1 设置响应头类型:content-type
27         String mimeType = servletContext.getMimeType(filename);
28         response.setHeader("content-type",mimeType);
29         // 3.2 设置响应头打开方式:content-disposition
30 
31         response.setHeader("content-disposition","attachment;filename="+filename);
32 
33 
34         // 4. 将输入流的数据写出到输出流中
35         ServletOutputStream sos = response.getOutputStream();
36 
37         byte[] buff = new byte[1024*8];
38         int len = 0;
39 
40         while((len = fis.read(buff)) != -1) {
41             sos.write(buff,0,buff.length);
42         }
43 
44         // 关闭流对象
45         fis.close();
46     }
47 
48     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
49         this.doPost(request, response);
50     }
51 }

  上面的案例中发现,当下载的文件名字是中文的时候,下载的时候会出现乱码。

 

6、文件名中文乱码问题

  解决思路:

    (1)获取客户端使用的浏览器版本信息

    (2)根据不同的版本信息,设置 filename 的编码方式不同

  编码工具类:

  使用 Base64 编码,需要导入 commons-codec-1.13.jar 包。

 1 package cn.itcast.download;
 2 
 3 
 4 import org.apache.commons.codec.binary.Base64;   
 5 
 6 import java.io.UnsupportedEncodingException;
 7 import java.net.URLEncoder;
 8 
 9 
10 public class DownLoadUtils {
11 
12     public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
13         if (agent.contains("MSIE")) {
14             // IE浏览器
15             filename = URLEncoder.encode(filename, "utf-8");
16             filename = filename.replace("+", " ");
17         } else if (agent.contains("Firefox")) {
18             Base64 base64Encoder = new Base64();
19             // 火狐浏览器
20             //BASE64Encoder base64Encoder = new BASE64Encoder();
21             filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
22         } else {
23             // 其它浏览器
24             filename = URLEncoder.encode(filename, "utf-8");
25         }
26         return filename;
27     }
28 }

 

 

7、DownLoadServlet 类(改进):

 1 package cn.itcast.download;
 2 
 3 import javax.servlet.ServletContext;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.ServletOutputStream;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 import java.io.FileInputStream;
11 import java.io.IOException;
12 
13 @WebServlet("/downloadservlet")
14 public class downloadservlet extends HttpServlet {
15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
16         //1获取请求参数,文件名称
17         String filename = request.getParameter("filename");
18 
19         //2使用字节输入流加载文件进内存
20         // 2.1 找文件服务器路径
21         ServletContext servletContext = this.getServletContext();
22         String realPath = servletContext.getRealPath("/img/" + filename);
23 
24         //2.2 使用字节流关联
25         FileInputStream fis = new FileInputStream(realPath);
26 
27         //3 设置 response 的响应头
28         // 3.1 设置响应头类型:content-type
29         String mimeType = servletContext.getMimeType(filename);
30         response.setHeader("content-type",mimeType);
31         // 3.2 设置响应头打开方式:content-disposition
32 
33         // 3.3 解决中文文件名问题
34           // 1 获取 user-agent 请求头
35         String agent = request.getHeader("user-agent");
36         // 2 使用工具类方法编码文件即可
37         filename = DownLoadUtils.getFileName(agent, filename);
38 
39         response.setHeader("content-disposition","attachment;filename="+filename);
40 
41 
42         // 4. 将输入流的数据写出到输出流中
43         ServletOutputStream sos = response.getOutputStream();
44 
45         byte[] buff = new byte[1024*8];
46         int len = 0;
47 
48         while((len = fis.read(buff)) != -1) {
49             sos.write(buff,0,buff.length);
50         }
51 
52         // 关闭流对象
53         fis.close();
54     }
55 
56     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
57         this.doPost(request, response);
58     }
59 }

 

posted on 2021-08-19 10:02  格物致知_Tony  阅读(84)  评论(0编辑  收藏  举报