history dedecms charts datagridview jqgrid vue最新版本 vue前端开发 vue数据绑定 npm安装vue vue架构 网赚视频教程 electron教程 在线考试系统代码 jquery选择器找子元素 hadoop特点 matlab图像滤波 destoon python语言入门 python环境安装教程 python连接mysql数据库 python链接mysql数据库 python定义一个变量 python程序实例 java环境 java安装环境 java连接mysql数据库 java语言代码大全 java循环语句 学习java基础 java替换字符 java自学编程入门教程 java怎么编译 java获取数据类型 linux的find 网络电视软件下载 kmservice cmd代码 dll之家 extjs视频教程 cfqq网吧任务
当前位置: 首页 > 学习教程  > 编程语言

超通俗易懂的Servlet入门教程

2020/12/5 10:14:03 文章标签:

不怕千万人阻挡,就怕自己投降。 文章目录01.Servlet快速入门02.Servlet3.0注解配置03.GenericServlet&HttpServlet(Serlvet的体系结构)04.HTTP05.Request对象06.Request案例(登录)07.Response对象Response案例路径…

不怕千万人阻挡,就怕自己投降。

文章目录

  • 01.Servlet快速入门
  • 02.Servlet3.0注解配置
  • 03.GenericServlet&HttpServlet(Serlvet的体系结构)
  • 04.HTTP
  • 05.Request对象
  • 06.Request案例(登录)
  • 07.Response对象
    • Response案例
    • 路径的分类
  • 08.ServletContext对象
  • 09.文件下载案例

概念:运行在服务器端的小程序
servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。将来我们自定义一个类,实现servlet接口,复写方法。 所以servlet就是实现了Servlet接口的类

01.Servlet快速入门

1.创建javaEE项目

2.定义一个类,实现servlet接口
public class servletDemo1 implements servlet

3.实现接口中的抽象方法

4.配置Servlet,在xml中配置。

<servlet>
<servlet-name>demo1</ servlet-name>
<servlet-class>cn.itcast.web. servlet.ServletDemo1</servlet-class>< / servlet>
<servlet-mapping>
<servlet-name>demo1</ servlet-name><url-pattern>/demo1</url-pattern>< / servlet-mapping>

执行原理:
1,当服务器接受到客户端浏览器的请求后,会解析请求uRL路径,获取访问的servlet的资源路径2.查找web.xml文件,足否有对应的<url-pattern>标签体内容。
3.如果有,则在找到对应的<servlet-class>全类名
4. tomcat会将字节码文件加载进内存,并且创建其对象
5,调用其方法。

servlet中的生命周期方法∶
1.被创建:执行init方法,只执行一次
对象被创建后再执行Servlet方法。

servlet什么时候被创建?

默认情况下,第一次被访问时,servlet被创建。可以配置其执行servlet的创建时机。

<servlet>标签下配置

1,第一次被访问时,创建
<load-on-startup>的值为负数。

2.在服务器启动时,创建
<load-on-startup>的值为0或正整数。

Servlet的init方法,只执行一次,说明一个servlet在内存中只存在一个对象,Servlet是单例的。

多个用户同时访问时,可能存在线程安全问题。

解决∶尽量不要在servlet中定义成员变量。即使定义了成员变量,也不要对修改值。

2.提供服务:执行service方法,执行多次。

每次访问Servlet时,Service方法都会被调用一次。

3.被销毁:执行destroy方法,只执行一次。

servlet被销毁时执行,服务器关闭时,Servlet被销毁。

只有服务器正常关闭时,才会执行destroy方法。

destroy方法在servlet被销毁之前执行,一般用于释放资源。

02.Servlet3.0注解配置

java6支持Serlet3.0.

java8支持Serlet4.0.

好处:支持注解配置。

可以不需要web.xml。

步骤:
1.创建JavaEE项目,选择Servelt3.0以上的,可以不创建web.xml。

2.定义一个类,实现Servlet接口。

3.复写方法。

4.在类上使用@WebServlet注解,进行配置。

因为注解是加在类上的,所以不需要关心类名,只需要关心资源路径。

@WebServlet(urlPatterns="/demo")//可以配置多个路径
public class ServletDemo implement Servlet{
}

或者

@WebServlet("/demo")//可以配置多个路径
public class ServletDemo implement Servlet{
}

IDEA与tomcat的相关配置
1.IDEA会为每一个tomcat部署的项目单独建立一份配置文件.
查看控制台的log : Using CATALINA_BASE:“c: \users\fay.Intelli]Idea2018.1\system\tomcatl_itcast"

2.工作空间项目和 tomcat部署的web项目。

tomcat真正访问的是"“tomcat部署的web项目”",“tomcat部署的web项目"对应着”"工作空间项目”的web目录下的所有资源。

WEB-INF目录下的资源不能被浏览器直接访问。

03.GenericServlet&HttpServlet(Serlvet的体系结构)

GenericServlet是Servlet的子类(子);
HttpServlet是GenericServlet的子类(孙);

问题提出:有时候我们只需要重写Servlet的service方法。然而我们继承Servlet类必须实现Servlet的所有抽象方法。这样就与我们意愿相左。有什么解决办法呢?

解决办法】:GenericServlet为Servlet的子类,并且已经(空)实现了Servlet的4个方法,只有service方法没有实现。

因此我们可以写一个类,继承GenericServlet抽象类。实现service方法即可。

将来我们在定义自己的serlvet类时,可以继承抽象类GenericServlet即可,如果需要使用到其他方法,重些该方法即可。

可以看出,此时代码书写已经很方便,但是我们以后开发并不使用这种方式。

那我们使用哪种方式呢?

【HttpServlet】:为什么要使用这个类呢?
那我们得问自己,我们实现service方法干嘛呢?

我们在写service方法体时,需要判断前端给后台的请求方式,并根据其获取数据。每次都需要判断,有没有一种方式,可以简洁的达到效果呢?
HttpServlet抽象类,帮我们把这些事情都做好了,我们只需要重写HttpServlet对应得方法即可。
如:

doGet(){
//重写部分
};
doPost(){
//重些部分
};

因此我们将来需要屏蔽请求方式的处理逻辑,继承HttpServlet就显得格外好用。

HttpSerlvet:对http协议的一种封装,简化操作
因此我们以后开发:就不再定义类继承GenericServlet实现service方法。而是定义类继承HttpServlet重写doGet(),或doPost()方法。

Servlet的urlpartten配置
因为urlpattten是一个数组,所以可以为其配置多个资源路径

@WebServlet({"/d4","dd4","ff"})
public class ServletDemo extends HttpServlet{
}

一个servlet可以设置多个访问路径。
路径的定义规则

1./xxx

2./xxx/xxx(多层路径)
(/xxx/*)


3.*.do

04.HTTP

概念:Hyper Text Transfer Protocol超文本协议。
传输协议:定义了,客户端和服务器端通信超时,发送数据的格式。

请求和响应一一对应
无状态:每次请求之间相互独立,不能交互数据。
历史版本:
1.0:每一次请求响应都会建立新的连接(http1.0)
1.1:复用连接(http1.1)。

请求消息数据格式
1.请求行
请求方式 请求url 请求协议/版本
GET /index.html HTTP/1.1

HTTP协议有7种请求方式。
GET
(1.请求参数在请求行中,在url后。
(2.请求的url的长度有限制。
(3.不安全
POST:
(1.请求参数在请求体中。
(2.请求的url的长度没有限制。
(3.相对安全

2.请求头
请求头名称:请求头值
常见的请求头:
主机
User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息,可以获取其信息解决浏览器兼容性问题。

Accept:告诉服务器,我可以解析的格式。

Referer:告诉服务器,当前请求从哪里来。
作用:方式其他人盗链。统计工作。

Connection:表示连接可以复用。

3.请求空行
空行(分割POST的请求头和请求体)
4.请求体
POST才有请求体,封装了POST的请求参数。

响应消息数据格式

1.响应行
协议及版本 响应状态码 状态码描述

状态码:
1xx:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx状态码。
2xx:成功

3xx:302(重定向),304访问缓存
在这里插入图片描述
4xx:客户端错误,405没有对应的方法。(doGet,doPost)

5xx:服务器端错误,500代码错误,505服务器不支持客户端使用的HTTP版本。

2.响应头
头名称:值
常见的响应头:
Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式。
Content-disposition:服务器告诉客户端以什么格式打开响应体数据。
值:in-line默认值,在当前页面内打开。
attachment:以附件形式打开响应体,文件下载。
3.响应空行

4.响应体
传输的数据。

05.Request对象

1.request对象继承体系结构:
ServletRequest —接口
继承
HttpServletRequest —接口
实现
org.apache.catalina.connector.RequestFacade 类(tomcat实现了HttpServletRequest接口)

2.request和response的原理

在这里插入图片描述
1.request和response对象是由服务器创建的。我们只是使用他们。

2.request对象是来获取请求消息,response对象是来设置响应消息。

3.request的功能

3.1获取请求消息数据

获取请求行数据

**1.1获取请求方式**

String getMethod();//了解即可

**1.2获取虚拟目录**

String getContextPath();//重要

**1.3获取Servlet路径:**

String getServletPath();

**1.4获取get方式请求参数:**

String getQueryString();//了解

**1.5获取请求URI**

String getRequestURI(); 如:/day1/demo2

**1.6获取请求URL**

StringBuffer getRequestURL(); 如: http://localhost/day1/demo2

**1.7获取协议及版本**

String getProtocol();

**1.8获取客户机的IP地址**

String getRemoteAddr();

URI:统一资源标识符。(范围更大)
URL:统一资源定位符。
获取请求头数据

String getHeader(String name);//通过请求头的名称获取请求头的值
Enumeration<String>  getHeaderNames();//获取所有的请求头名称
@WebServlet("/ServletTest2")
public class ServletTest2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取所有请求头名称
        Enumeration<String> headNames = request.getHeaderNames();
        //遍历
        while (headNames.hasMoreElements()){
            String name = headNames.nextElement();
            //根据名称获取请求头的值
            String value = request.getHeader(name);
            System.out.println(name+"---"+value);
        }
    }
}

获取请求体数据
步骤:
1.获取流对象

BufferedReader getReader() ;//获取字符输入流,只能操作字符数据
ServletInputStream getInputStream();//获取字节输入流,可以操作所有
类型的数据(文件上传)

2.再从流对象中拿数据

@WebServlet("/ServletTest3")
public class ServletTest3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求参数
        //1.获取字符流
        BufferedReader br = request.getReader();
        //读取数据
        String line = null;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
    }

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

    }
}

3.2.其他功能
1.获取请求参数的通用方式(get和post都可以)

String getParameter(String name):根据参数名获取参数值
String[] getParameterValues(String name):根据参数名获取参数值的数组
(常用于复选框)
Enumeration<String> getParameterNames():获取所有请求参数名称。
Map<String,String[]> getParameterMap():获取所有参数的map集合。

优势:屏蔽了get和post方法的不同,代码只需要写一份,再另一方法中调用另一个已经实现的方法即可,满足get和post请求。

获取请求参数中文乱码的问题处理:
get方式:tomcat8已经将get方式乱码问题解决了。
post方式:会乱码。

解决方案:在获取参数前,设置流的编码。
request.setCharacterEncoding(“utf-8”);

//设置编码
request.setCharacterEncoding("utf-8");
//获取请求参数
String username = request.getParameter("username");

2.请求转发
在这里插入图片描述

一种在服务器内资源跳转的方式。
步骤:

1.通过request对象获取请求转发器对象:
RequestDispatcher getRequestDispatcher(String path)
2.使用RequestDispatcher对象来进行转发:
forward(ServletRequest request,ServletResponse response)

特点
浏览器地址栏路径没有发生变化。

只能访问当前服务器内部资源中。

转发是一次请求,多个资源使用同一个请求。
3.共享数据
在这里插入图片描述

域对象:一个有作用范围的对象,可以在范围内共享数据。
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据。
方法:

setAttribute(String name,Object obj);存储数据
Object getAttitude(String name);通过键获取值

removeAttribute(String name)通过键移除值

例子:

@WebServlet("/ServletTest4")
public class ServletTest4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ServletTest4被访问了");
        //存储数据到request域中
        request.setAttribute("name","MengYangchen");
        RequestDispatcher getquestDispatcher = request.getRequestDispatcher("/ServletTest5");//没有虚拟路径(项目)
        getquestDispatcher.forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
    }
}
@WebServlet("/ServletTest5")
public class ServletTest5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ServletTest5被访问了");
        //获取数据
        Object name = request.getAttribute("name");
        System.out.println(name);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

结果:
在这里插入图片描述

4.获取ServletContext(对象)
返回ServletContext对象

ServletContext getServletContext()  

06.Request案例(登录)

用户登录案例需求:
1.编写login.html登录页面
username &password两个输入框

2.使用Druid数据库连接池技术,操作mysql,day14数据库中user表

3.使用JdbcTemplate技术封装JDBC

4.登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您

5.登录失败跳转到FailServlet展示:登录失败,用户名或密码错误。

07.Response对象

1.请求消息:客户端发送给服务器的数据。
2.服务器端发送给客户端的数据。

功能:设置响应消息。
1.设置响应行。

void setStatus(int sc)  设置状态码

2.设置响应头。

void setHeader(String name, String value)  

3.设置响应体。
获取输出流

PrintWriter getWriter()  字符输出流
ServletOutputStream getOutputStream()  字节输出流

使用输出流,将数据输出到客户端浏览器。

Response案例

1.完成重定向
在这里插入图片描述

@WebServlet("/ServletResponseTest1")
public class ServletResponseTest1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("response1被访问了");
        //重定向,访问ServletResponseTest1,会自动跳转到ServletResponseTest2
        //1.设置状态码302
/*        response.setStatus(302);
        //2.设置响应头location
        response.setHeader("location","/First/ServletResponseTest2");
        */

        //简单重定向方法
        response.sendRedirect("/First/ServletResponseTest2");//有虚拟路径
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
@WebServlet("/ServletResponseTest2")
public class ServletResponseTest2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("response2被访问了");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

转发的特点
1.转发地址栏路径不变。
2.转发只能访问当前服务器下的资源。
3.转发是一次请求。
4.路径不需要带虚拟路径。
重定向的特点
1.地址栏发生改变。
2.重定向可以访问其他站点(服务器)的资源。
3.重定向是两次请求。
4.路径需要虚拟路径。

2.服务器输出字符数据到浏览器
乱码原因:编码解码用的编码不同。
在这里插入图片描述

2.1.获取字符输出流。

//设置输出流编码
response.setCharacterEncoding("utf-8");

//告诉浏览器,服务器发送消息体数据的编码,建议浏览器使用该编码解码
response.setHeader("content-type","text/html;charset=utf-8");

//简单形式,设置编码
response.setContentType("text/html;charset=utf-8");
PrintWrite out = response.getWriter();//tomcat返回的对象[ISO-8859-1]。

2.2输出数据(不需要刷新)
out.write();

3.服务器输出字节数据到浏览器
3.1获取字节输出流

3.2输出数据

response.setContentType("text/html;charset=utf-8");
ServletOutputStream out = response.getOutputStream();
out.writer("你好".getBytes("utf-8"));

4.验证码
1.本质:图片
2.目的:防止恶意表单注册。
随机生成。
后端:servlet:

@WebServlet("/IdentifyingCodeServlet")
public class IdentifyingCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width = 100;
        int height = 50;
        //1.创建一对象,在内存中的图片(验证码图片对象)
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        //2.美化图片
        //2.1填充背景色
        Graphics g = image.getGraphics();
        g.setColor(Color.pink);
        g.fillRect(0,0,100,50);//填充矩形

        //2.2画边框
        g.setColor(Color.yellow);
        g.drawRect(0,0,width-1,height-1);

        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        //生成随机角标
        Random ran  = new Random();

        for(int i=1;i<=4;i++){
            int index = ran.nextInt(str.length());
            char ch = str.charAt(index);//随机字符
            //2.3写验证码
            g.setColor(Color.blue);
            g.drawString(""+ch,width/5*i,height/2);
        }
        //2.4画干扰线,防识别
        //随机生成坐标点
        for(int i=0;i<8;i++){
            int x1 =ran.nextInt(width);
            int x2 =ran.nextInt(width);
            int y1 =ran.nextInt(height);
            int y2 =ran.nextInt(height);
            g.setColor(Color.green);
            g.drawLine(x1,y1,x2,y2);
        }

        //3.将图片输出到页面展示
        ImageIO.write(image,"jpg",response.getOutputStream());
  

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

前端页面:

<body>
<h1>账号注册</h1>
<form action="/First/ServletTest3" method="post">
    <input type="text" placeholder="请输入用户名" name="username"><br>
    <input type="password" placeholder="请输入密码" name="password"><br>
    <input type="submit"  value="注册"><br>
    <img id="checkCode" src="/First/IdentifyingCodeServlet"/>
    <a id="change" href="">看不清换一张</a>
</form>
    <script>
        //1.给超链接或图片绑定单击事件
        //2.重新设置图片的src属性
        window.onload = function () {

            var a  =document.getElementById("change");
            //1.获取图片对象
            var img  = document.getElementById("checkCode");
            //2.绑定单击事件
            img.onclick = function () {
                //加时间戳
                var date = new Date().getTime();

                img.src = "/First/IdentifyingCodeServlet?"+date;//欺骗缓存,因为路径不变,浏览器会自动去找缓存,而不是服务器
            }
            a.onclick = function () {
                var date = new Date().getTime();
                img.src = "/First/IdentifyingCodeServlet?"+date;//欺骗缓存,因为路径不变,浏览器会自动去找缓存,而不是服务器
            }
        }
    </script>
</body>

路径的分类

1.相对路径
如:./index.html
不以/开头,以./开头的路径(可以省略不写)。
规则:找到当前资源和目标资源之间的相对位置关系
./表示当前目录;…/上一级目录。
2.绝对路径
如:http://localhost/First/ServletResponseTest2
简略写法:/First/ServletResponseTest2
以/开头。
规则:判断定义的路径是给谁用的。
1.给客户端浏览器使用:需要加虚拟目录(超链接…项目的访问路径)
2.给服务器端使用(转发…不需要加虚拟目录)
【问题提出】在重定向写路径是我们采用的是直接书写路径,以后一旦更改了虚拟目录。所有代码将需要该过来。

【解决方案】动态获取虚拟目录。

//动态获取虚拟目
String contextPath = request.getContextPath();

//简单的重定向方法
response.sendRedirect(contextPath+"ServletResponseTest2");

前端代码采取jsp获取虚拟目录。

08.ServletContext对象

1.概念:代表整个web应用,可以和程序的容器(服务器)来通信。

2.如何获取ServletContext对象。

1.通过request获取
request.getServletContext();

2.通过HttpServlet获取
this.getServletContext();//因为我们继承了HttpServlet

两者获取的ServletContext是相等的。

2.功能:
获取MIME类型。
MIME类型:在互联网通信过程中定义的一种文件数据类型。
格式:大类型/小类型 text/html

//通过HttpServlet获取
SevletContext context = this.getServletContext();

//定义文件名称
String filename = "a.jpg";

//获取MIME类型
String mimeType = context.getMimeType(filename);
System.out.println(mimeType);

域对象:共享数据。

1.setAttribute(String name,Object value)

2.getAttribute(String name)

3.removeAttribute(String name);

ServletContext对象范围:所有用户所有请求的数据。

@WebServlet("/ServletContextTest")
public class ServletContextTest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过httpServlet获取
        ServletContext context  = this.getServletContext();

        //设置共享数据
        context.setAttribute("name","Is me!");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

@WebServlet("/ServletContextTest2")
public class ServletContextTest2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过httpServlet获取
        ServletContext context  = this.getServletContext();

        //获取共享数据
        Object a = context.getAttribute("name");
        response.setContentType("utf-8");
        PrintWriter out = response.getWriter();
        out.print(a);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

访问http://localhost/First/ServletContextTest2得到结果:
在这里插入图片描述

获取文件的真实路径
在web服务器的真实路径。
在这里插入图片描述

1.方法:String getRealPath(String path)

配置文件所在地方不同,参数书写不同。

String realPath = context.getRealPath("/a.txt");//web目录下资源访问
String realPath = context.getRealPath("/WEB-INF/a.txt");//WEB-IN目录下资源访问

String realPath = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下资源访问
@WebServlet("/ServletContextTest3")
public class ServletContextTest3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String realPath = context.getRealPath("/WEB-INF/classes/a.txt");
        System.out.println(realPath);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

09.文件下载案例

文件下载需求

1.页面显示超链接

2.点击超链接后弹出下载提示框

3.完成图片文件下载。
分析:
1.超链接指向的资源如果能过被浏览器解析,则在浏览器中显示,如果不能解析,则弹出下载提示框。不满足需求。

2.任何资源都必须弹出下载提示框。

3.使用响应头设置资源的打开方式。

步骤:
1.定义页面,编辑超链接href属性,指向servlet,传递资源名称filename

2.定义servlet
2.1获取文件名称
2.2使用字节输入流加载文件进内存.
2.3指定response的响应头:content-disposition:attachment;filename=xxx.2.4将数据写出到response输出流。

前端:

<body><p align="center">优质资源网站</p>
<a href="/First/res/img/1.jpg">表情包(未处理)</a><br>

<a href="/First/ServletDownLoad?filename=1.jpg">表情包</a><br>
<a href="/First/ServletDownLoad?filename=2.jpg">表情包2</a>
</body>
</html>

后端:

@WebServlet("/ServletDownLoad")
public class ServletDownLoad extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取请求参数,文件名称
        String filename = request.getParameter("filename");
        //2.使用字节输入流加载文件进入内存
        //2.1找到文件服务器路径
        ServletContext context = this.getServletContext();
        String realPath = context.getRealPath("/res/img/"+filename);
        //2.2用字节流关联
        FileInputStream fis = new FileInputStream(realPath);

        //3.设置reponse响应头
        //设置响应数据类型:context-type
        String mimeType = context.getMimeType(filename);
        response.setHeader("content-type",mimeType);
        //设置打开方式:content-disposition
        response.setHeader("content-disposition","attachment;filename="+filename);

        //4.将输入流的数据写出到输出流中
        ServletOutputStream sos = response.getOutputStream();
        byte[] buff = new byte[1024*4];
        int len =0;
        while ((len=fis.read(buff))!=-1){
            sos.write(buff,0,len);
        }
        fis.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

中文文件名的问题
【解决思路】
1.获取客户端使用的浏览器版本信息
2.根据不同的版本信息,设置filename不同的编码方式。

//1.获取user-agent请求头
String agent = request.getHeader("user-agenet");

//2.使用工具类方法编码文件名(自己从网上下载工具栏导入在自己创建的工具包)
filename = DownLoadUtils.getFileName(agent,filename);

别害怕顾虑,想到就去做,这世界就是这样,当你把不敢去实现梦想的时候梦想就会离你越来越远,当你勇敢地去追梦的时候,全世界都会来帮你。

在这里插入图片描述
在这里插入图片描述


本文链接: http://www.dtmao.cc/news_show_450182.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?