WEB核心【案例:文件下载,案例:点击切换验证码,几种获取properties资源方式】第十二章

目录

1.文件下载

1.1超链接下载:

1.2自定义servlet下载

1.3小结

2.点击切换验证码

2.1前置只是-验证码生成

2.2分析及代码实现

2.3需求2:点击切换验证码-绕过缓存

3.几种获取preperties资源方式


💟作者简介:大家好呀!我是爱吃豆的土豆    
📝个人主页:【爱吃豆的土豆的博客_CSDN博客-Web知识,spring框架,vue领域博主
🏆博主信息:人必有所执,方能有所成!

🐋希望大家多多支持😘一起进步呀!
🌈若有帮助,还请【关注➕点赞➕收藏】,不行的话我再努力努力呀!💪
⚡版权声明:本文由【爱吃豆的土豆的博客】原创、在CSDN首发、需要转载请联系博主。

1.文件下载

1.1超链接下载:

 

 超链接下载方式

自定义Servlet下载

通过自定义Servlet 完善超链接下载,可以下载中文名资源 

http://localhost:8080/day08_1/download/hello.jpg

浏览器发来的所有请求,都会进行url-pattern.

完全匹配:尝试寻找servlet,路径为download/hello.jpg,寻找不到,进入下一个匹配

目录匹配:尝试寻找servlet,目录路径为/download/*,寻找不到,进入下个匹配

扩展名匹配:尝试寻找servlet,扩展名为:*.jpg,寻找不到,进入最终匹配

缺省匹配:访问DefaultServlet,把当前/download/hello.jpg,对应的资源通过IO流读取到,写出到响应体中。

 

超链接下载资源的本质:依靠DefaultServlet。

DefaultServlet遵循的码表为iso8859-1,使得utf-8编码的中文资源名,被解析为乱码,通过乱码无法定位资源的,导致资源找不到。

本质:模仿DefaultServlet,并且将资源名解决乱码

new String("乱码".getBytes("iso8859-1"),"utf-8");

 

1.2自定义servlet下载

download.html

<h1>自定义Servlet下载</h1>
<a href="/day08_1/dl?method=download&filename=hello.jpg">hello.jpg</a>
<a href="/day08_1/dl?method=download&filename=你好.rar">你好.rar</a>

 DownLoadServlet

@WebServlet({"/dl"})
public class DownLoadServlet extends BaseServlet {
    /**
     * 文件下载
     */
    public void download() throws IOException {
        //1、获取参数filename
        String filename = getRequest().getParameter("filename");
        //2、处理文件名乱码
        String resourceName = new String(filename.getBytes("iso8859-1"), "utf-8");
        //3、设置强制弹出下载窗口
        HttpServletResponse response = getResponse();
        // 传递的文件名应该是原来乱码的filename,这样下载窗口经过解码后,就会解为正常内容
        response.setHeader("Content-Disposition","attachment;filename="+filename);
        //4、读取资源文件
        //4.1、资源的绝对路径
        String filePath = getServletContext().getRealPath("/")+"/download/"+resourceName;
        //4.2、文件流读取
        FileInputStream fis = new FileInputStream(filePath);
        //5、写出响应体
        //5.1、获取响应体字节流
        ServletOutputStream out = response.getOutputStream();
        //5.2、使用工具流复制
        IOUtils.copy(fis,out);
        fis.close();
        //因为out流被tomcat控制的,所以不要手动关闭,由tomcat管理
    }
}

小结:

  1. get乱码处理:  new String("乱码".getBytes("iso8859-1"),"utf-8");
  2. 强制下载响应头,必须位于getOutputStream()之前。
  3. response.getOutputStream();由tomcat控制的,程序员不要手动关闭。

1.3小结

文件下载:服务器把数据传递给浏览器(响应体)

文件下载,默认依赖的是DefaultServlet,因为解码码表为iso8859-1,会导致中文资源名乱码,导致无法找到。

自定义Servlet下载:

强制下载的响应头:response.setHeader("Content-Disposition","attchment;filename="+下载名);

必须位于 getOutputStream()之前,否则失效。

2.点击切换验证码

2.1前置只是-验证码生成

@WebServlet({"/vc"})
public class VerfityCodeServlet extends BaseServlet {
    public void vc() throws IOException {
        //若需要看到指定图片,需要手动设置响应体(必须在响应体操作之前设置)
        getResponse().setContentType("image/jpeg;charset=utf-8");
        //向响应体写出一张图片形式的验证码
        String vc = createVerifyCodeImage();
        System.out.println(vc);
    }
}

小结:

验证码本质是一张图片,以响应体的方式传递给浏览器(文件下载)

为了让浏览器打开解析,需要在响应体操作之前,设置响应体类型:

getResponse().setContentType("image/jpeg;charset=utf-8")

2.2分析及代码实现

 

login.html

<img src="/day08_1/vc?method=vc"/>

 VerifyCodeServlet已经在前置知识完成了。

2.3需求2:点击切换验证码-绕过缓存

用户默认开启缓存,存在缓存问题:

因为每次路径都是/day08_1/vc?method=vc ,第一次访问时,该路径就在浏览器上有一张图片了。

缓存理解为一个map集合:

Key                                               value

Url路径                                         该路径的资源

/day08_1/vc?method=vc              验证码图片

下次再准备发请求时,发现该路径在浏览器有缓存,直接使用浏览器缓存,而不去请求服务器。

解决方案:

绕过缓存,只需要让缓存的地址(key)不同,参数列表,只需要让参数列表每次不同,缓存的地址不同

可以用随机数

可以用毫秒值

<script>
   //页面加载完成时,为图片绑定点击事件
   $(function () {
      $("#vcimg").click(function () {
         this.src="/day08_1/vc?method=vc&t="+new Date().getTime();
      });
   });
</script>

小结:

因为用户端访问时存在缓存问题。

为了绕过缓存,需要让每次URL访问路径不同。

让URL最后加入随机的参数列表就可以。

 

3.几种获取preperties资源方式

目标:掌握ServletContext方式获取properties资源方式

public void run1() throws IOException {
    //类加载器获取资源:SE方式(不启动服务器也能正常执行)
    InputStream is = this.getClass().getClassLoader().getResourceAsStream("com/p/d1.properties");
    Properties p1 = new Properties();
    p1.load(is);
    System.out.println(p1);
    //ServletContext获取资源:EE方式(必须先启动服务器才能正常执行)
    InputStream is2 = getServletContext().getResourceAsStream("/WEB-INF/classes/com/p/d1.properties");
    Properties p2 = new Properties();
    p2.load(is2);
    System.out.println(p2);
    //ResourceBundle获取:SE方式(不启动服务器也能正常执行)
    ResourceBundle bundle = ResourceBundle.getBundle("com.p.d1");
    System.out.println(bundle.getString("uname"));
}

 

 

小结:

建议使用的是ServletContext的getResourceAsStream,该方式的出发目录是发布目录的根目录,不仅能够获取properties,而且还能获取其他资源。

其他两种方

注意:

1、以上三种获取资源方式,获取的是 发布目录下的资源。

2、ResourceBundle相同路径文件在服务器启动期间,为了防止重复加载浪费内容,会加载一次

(重新加载,默认关闭服务器,服务器关闭时会卸载内存)

式,出发目录都是 发布目录的/classes 目录

最后:

        如果文章对您有帮助,就拿起小手赶紧给博主点赞💚评论❤️收藏💙 一下吧! 

       愿我们在未来的日子里。熠熠生辉!!!

 

  • 95
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 179
    评论
当下载文件时,报TypeError: Cannot read properties of undefined (reading 'content-type')的错误通常是因为在下载文件的过程中,尝试读取未定义的属性'content-type'。这可能是由于以下几个原因引起的: 1. 未正确设置HTTP响应头:在下载文件时,服务器需要正确设置HTTP响应头,包括Content-Type字段。如果服务器未正确设置Content-Type字段,那么在客户端尝试读取该字段时就会报错。 2. 服务器返回的响应不包含Content-Type字段:有时服务器可能会返回一个不包含Content-Type字段的响应。这可能是由于服务器配置错误或者其他原因导致的。在这种情况下,客户端尝试读取Content-Type字段时会报错。 3. 客户端代码错误:如果你是自己编写的下载文件的代码,那么可能是你的代码中存在错误导致了该错误。请检查你的代码,确保正确地处理了HTTP响应头。 为了解决这个问题,你可以尝试以下几个步骤: 1. 检查服务器端设置:确保服务器正确设置了Content-Type字段,并且在下载文件时返回正确的响应头。 2. 检查客户端代码:如果你是自己编写的下载文件的代码,检查你的代码中是否正确处理了HTTP响应头。确保在读取Content-Type字段之前先检查它是否存在。 3. 使用其他工具或库:如果以上步骤都没有解决问题,你可以尝试使用其他下载文件的工具或库,看看是否能够避免这个错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 179
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃这么好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值