zoukankan      html  css  js  c++  java
  • 轻装上阵,安卓工程师之路---day06(HTTP & Servlet)

    01 HTTP协议入门

    HTTP协议是Web客户端和Web服务端通信的规则,用于定义客户端与web服务器通迅的格式,它是一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程

    HTTP协议分类二个版本:

    1_HTTP1.0版本

      客户端请求服务器后,服务器响应信息后,立即断开,且只能请求和响应一个资源

      缺点:客户端创建连接不容易,需要消耗大量的时间和资源,这时服务器就只响应一个资源就断开,下次客户端再请求,又要创建创建新的连接

    2_HTTP1.1版本

      客户端请求服务器后,服务器响应信息后,不会立即断开,且在一定时间可可请求和响应多个资源

      优点:客户端请求服务器后,得到了响应,在一定时间内,这个连接还是保留的,

            在规则的时间内,客房端再次访问服务器,就不需要创建新的连接了

    目前,Web应用都采用HTTP1.1协议规则,例如:GET(请求方式) /(请求资源) HTTP/1.1(协议名和版本)

    开发最佳建议:在开发中要尽量减少客户端向WEB服务器发送HTTP请求数量,借此来提高客户端访问速度

    面试题:

    一个web页面中,使用img标签引用了三幅图片,当客户端访问服务器中的这个web页面时,客户端总共会访问几次服务器,即向服务器发送了几次HTTP请求。

    通过软件的观察,总共有发送了四次请求,1次为文本请求,3次为图片请求。

    体验:

    1_IE浏览器去访问www.baidu.com回车

    2_HttpWatch软件观察本次回车,浏览器共发送了多少个HTTP请求

    02 HTTP请求

    一个完整的HTTP请求,分为三部份:

    1_请求行

      请求方式 请求内容 协议名和版本

    不管POSTGET,都用于向服务器请求某个WEB资源,这两种方式的区别主要表现在数据传递上,客户端通过这两种方式都可以带一些数据给服务器:

    如请求方式为GET方式,则可以在请求的URL地址后以?的形式带上交给服务器的数据,多个数据之间以&进行分隔,例如:

    GET /mail/1.html?name=abc&password=xyz HTTP/1.1

    GET方式的特点:在URL地址后附带的参数是有限制的,其数据容量不能超过1K

    如请求方式为POST方式,则可以在请求的实体内容中向服务器发送数据,例如:

    POST /servlet/ParamsServlet HTTP/1.1

    Host:

    Content-Type: application/x-www-form-urlencoded

    Content-Length: 28

    name=abc&password=xyz

    Post方式的特点:传送的数据量无限制,如文件上传

    2_请求头

      有很多key:value键值对组成的内容,每次请求都不相同

      

    Accept: text/html,image/*  浏览器可以接收什么类型的响应数据  

    Accept-Charset: GBK 浏览器可以接收什么类型的编码方式

    Accept-Encoding: gzip,compress 浏览器可以接收gzipcompress格式的压缩数据,即浏览器收到这些压缩数据后会自动解压

    Accept-Language: en-us,zh-cn 浏览器可以接收什么类型的语言

    Host: www.itheima.com:80 浏览器请求的主机是www.itheima.com,使用80端口号

    If-Modified-Since: Tue, 11 Jul 2014 18:23:51 GMT(缓存时间浏览器收到数据后,可缓存时间

    Referer: http://www.itheima.com/index.html(来自哪请求来源于哪个URL地址

    User-Agent:Mozilla/4.0 (compatible; MSIE 9; Windows NT 5.0) 浏览器的类型和版本

    Cookie:后面细讲 浏览器缓存服务器响应的信息

    Connection: close/Keep-Alive 浏览器与服务器的连接是打开还是关闭   

    Date: Tue, 11 Jul 2014 18:23:51 GMT(访问时间浏览器请求服务器的时间,这个时间不是中国时间

    3_请求体或实体内容

      请求头与请求内容有一个空行的间隔

      不是每次请求都有内容的,

      GET方式请求体是没有内容的,因为内容都在请求行中

      POST方式请求体是有内容的,例如:文件上传,表单以POST方式提交

    03 HTTP响应

    一个完整的HTTP响应,分为三部份:

    响应行用于描述服务器,对请求的处理结果。

    响应头用于描述服务器的基本信息,以及数据的描述,服务器通过这些数据的描述信息,可

    以通知客户端如何处理等一会儿它回送的数据

    实体内容,代表服务器向客户端回送的数据

    1_响应行

     协议名和版本 响应状态码 响应状态码的英文描述

    2_响应头

    有很多key:value组成的内容,每次响应都不相同

    Location: http://www.itheima/index.html 服务器要求浏览器访问的URL地址

    Server:apache tomcat 服务器通知浏览器服务器的名字

    Content-Encoding: gzip 服务器通知浏览器需要接收的压缩数据类型

    Content-Length: 80 服务器通知浏览器需要接收的响应内容的字节数

    Content-Language: zh-cn 服务器通知浏览器需要接收的语言类型

    Content-Type: text/html; charset=GBK 服务器通知浏览器需要接收的类型和使用什么方式解码

    Last-Modified: Tue, 11 Jul 2014 18:23:51 GMT 服务器通知浏览器浏览器访问的请求最近一次修改的时间

    Refresh: 1; url=http://www.itheima.com 服务器通知浏览器1秒钟后刷新,并且访问指定的URL页面

    content-Disposition: attachment; filename=aaa.zip(下载文件服务器通知浏览器以下载方式打开资源

    Transfer-Encoding: chunked(分块传递数据到客户端)服务器通知浏览器以分块方式下载文件的浏览器指定的目录   

    Set-Cookie:SS=Q0=5Lb_nQ; path=/search 服务器通知浏览器需要接收数据缓存到浏览器

    Expires: -1//3种禁止缓存的头字段 以下三个响应头都表示服务器要求浏览器不要缓存来自服务器的web页面

    Cache-Control: no-cache  

    Pragma: no-cache   

    Connection: close/Keep-Alive 服务器通知浏览器之间的连接是否已以关闭或者打开的  

    Date: Tue, 11 Jul 2014 18:23:51 GM 服务器通知浏览器的时间

    如果上述头中,请求也有,响应也用,我们叫其通用头,ConnectionDate就是通用头

    3_响应体或实体内容

    响应体和响应头之间有一个空行  

    实体内容包含各种数据,音乐,文件,网页等等

    响应状态码是服务器对这次响应设置的一人唯一编号,

    每个编码都有其特定的含义,常见的响应编号有:

    200:表示服务器响应正确

    302:客户端请求一台服务端的资源,该服务端并没有这个资源,服务器要求客户端自已去另一台服务端找资源,这种情况下叫做重定向

    307:客户端请求一台服务端的资源,该服务端并没有这个资源,服务器自已去另一台服务端找资源,这种情况下叫做转发

    304:客户端请求服务端的资源,服务器没有修改过,且已经缓存到了客户端,要求客户端去其缓存中获取即可

    404:客户端请求服务端的URL出错了

    405: 服务端无法找到该servletdoGET方法或doPOST()方法,此错误一般都是方法确实引起的

    500:客户端请求服务端的URL正确,但服务器处理资源出错了

    04 Servlet入门

    JavaEE系统结构分为三大块

    1_客户层

    2_JavaEE服务层

      2_1_Web/表现层,例如:Servlet&Jsp

      2_2_商业逻辑层

    3_EIS企业信息系统层,例如:数据库,第三方系统

    什么是Servlet

    A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol. 

    Servlet是运行于Web服务器中的一个特殊的Java应用程序,Servlet能够接收来自每个客户端的请求,并做之响应,双方遵循HTTP协议

    Servlet将来在企业中能做哪些工作呢?

    1_能够接收客户端HTTP请求,并做以不同的响应,即动态响应

    2_能做一些需要动态显示的Web资源内容,例如:下载,上传,权控显示,用户注册,用户登录。。。

    总之,Servlet中做动态Web应用的核心技术之一

    第一个Servlet开发步骤:

    1_创建一个Demo01A类,实现Servlet接口,重写service()方法

    public class Demo01A implements Servlet {

    public void destroy() {

    }

    public ServletConfig getServletConfig() {

    return null;

    }

    public String getServletInfo() {

    return null;

    }

    public void init(ServletConfig arg0) throws ServletException {

    }

    public void service(ServletRequest req, ServletResponse res)throws ServletException, IOException {

    //向浏览器输出一短英文字符串

    //从响应对象的获取输出流

    //who访问me, 响应对应就指向who

    //即然响应对象指向who,那么从响应对应中获取的输出流,自然指向who

    PrintWriter pw = res.getWriter();

    pw.write("<font style='color:red;font-size:111px'>HAHA</font>");

    }

    }

    2_/WEB-INF/web.xml文件中配置上述Servlet相关的信息,例用外界访问

    <servlet>

    <servlet-name>Demo01A</servlet-name>

    <servlet-class>cn.itcast.android.servlet.Demo01A</servlet-class>

    </servlet>

    <servlet-mapping>

    <servlet-name>Demo01A</servlet-name>

    <url-pattern>/Demo01A</url-pattern>

    </servlet-mapping>

    3_部署该web应用到web服务器,通过浏览器访问,地址如下:

      http://127.0.0.1:8080/itcast-day06_http_servlet/Demo01A回车

    创建Servlet方式有三种

    1_普通类实现Servlet接口,并重写service()方法,每次请求服务器都调用service()方法,请求N次,调用Nservice()

      缺点:不必要的方法我们必须得实现  

    2_普通类继承GenericServlet实,并重写service(),每次请求服务器都调用service()方法,请求N次,调用Nservice()

      缺点:不能够区分不同的请求方式

    3_普通类继承HttpServlet,并重写doGet()doPost(),每次请求服务器都调用doXxx()方法,请求N次,调用NdoXxx()

    ctrl+shift+F格式化代码

    ServletRequest是父接口,既能处理http协议,也能处理非http协议

    HttpServletRequest是子接口,只能处理Http协议

    web中,通常是http协议,所以我们建议用HttpServletRequest

    05 Servlet生命周期

    生命周期:Servletweb服务器中,从出现到消失到整个过程

    为什么在Web中,要基于接口编程呢?

    如果你基于tomcat服务器中的具体类来编程的话,那么将来你的Servlet只能部署到tomcat服务器中才能运行部署到其它web服务器,例如:weblogic的话,就失败了;返之,我基于原SUN公司提供的接口编程,实现类都是由不同web服务器来完成,那么将来我的Servlet即可以在tomcat中运行成功,也可以在其它web服务器中运行成功,这样我的程序可移植性就强了

    无参构造器()   

    通过调用的无参构造获取字节码文件的Class对象,通过反射newIntance构造出一个新的对象,该对象只会构造一次。

    init()

    含有servletconfig对象,可以调用xml文件的初始化参数

    doGet/Post() 

    属于service来调拨的方法

    destory()

    服务器正常关闭时会执行,或者重新启动时也会执行,一个servlet生命周期中只会执行一次

    默认情况下第一次访问会依次执行:无参构造器()->init()->doGet()/Post()---都只执行一次

    第二次,第N次执行:doGet()/Post()---都只执行多次

    重新部署时:destory()---都只执行一次

    始终只有一个Servlet为所有客户端服务,即Servlet是单例的

    非单列又叫多例

    06 ServletConfig对象祥解

    servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servletinit方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

    通过ServletConfig读取web.xml文件中为该Servlet配置的初始化参数

    <servlet>

    <servlet-name>Demo06</servlet-name>

    <servlet-class>cn.itcast.android.servlet.Demo06</servlet-class>

    <init-param>

    <!-- Servlet初始化参数名 -->

    <param-name>email</param-name>

    <!-- Servlet初始化参数值 -->

    <param-value>runsin0723@163.com</param-value>

    </init-param>

    <init-param>

    <param-name>location</param-name>

    <param-value>东圃</param-value>

    </init-param>

    </servlet>

    ServletConfig API,并举例说明该对象的作用:

    getInitParameterNames();

    getInitParameter();

    getServletName();

    07 配置Servlet自动加载

    在默认情况下,Servlet必须要首次访问时,方可创建并初始化

    那有没有方式将Servlet的创建和初始化提前到web服务器启动时呢?

    通常<load-on-startup>配置>=0的整数,如果配置<0的数和没配一样,即在首次访问Servlet时创建和初始化

    当有多个Servlet时,数值越小,越先创建和初始化

        <servlet>

         <servlet-name>Demo07A</servlet-name>

         <servlet-class>cn.itcast.android.servlet.Demo07A</servlet-class>

         <!-- 配置Servlet自动加载 -->

         <load-on-startup>1</load-on-startup>

       </servlet>

    08 提倡创建Servlet直接继承HttpServlet

    因为:

    1_我们在企业中,处理的web请求,大多是HTTP协议的,正好HttpServlet类是符合HTTP协议规则的

    2_HttpServlet类,继承了GenericServlet类,也实现了Servlet接口,不光有祖先的功能,也有自已独特的操作

    3_HttpServlet类可以根据客户端提交的方法来处理,例如:get请求,doGet()方法,通常不用去重写service()方法

    4_虽说HttpServlet类无init()init(ServletConfig)方法,我们也可以获取web.xml文件中对servlet配置的初始化参数

      this.getServletConfig()方法来获取ServletConfig对象

    09 Servlet的运行过程

    参见图解

    注意:客户端不能直接请求Servlet

          Servlet也不能直接响应客户端,中间必须经过Web服务器或容器

    Servlet接口定义了Servlet生命周期

    init()方法

    服务器调用该方法初始化Servlet

    service()方法

    初始化完毕,服务器调用该方法响应客户的请求

    destroy()方法

    服务器调用该方法消灭servlet对象

    注意:init()方法只在Servlet第一次被请求加载的时候被调用一次,当有客户再请求Servlet服务时,Web服务器将启动一个新的线程,在该线程中,调用service方法响应客户的请求整个过程,Servlet只创建了一次,即单例模式

    10 配置Servlet虚拟路径

    配置Servlet映射路径有二种类型的格式:

    1_   /*

         表示访问当前web应用下的所有资源都由同一个Servlet来处理

    2_   *.do(do可以换成其它)

    <servlet-mapping>

    <servlet-name>Demo08</servlet-name>

    <url-pattern>/*</url-pattern>

    <url-pattern>*.do</url-pattern>

    </servlet-mapping>

    Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。

    总结:

    1、只能使用 或 开头

    2和 *. 不能同时存在,即/*.do绝对会报错;

    3或 /* 表示任意

    4*表示通配符

    5.  /* 的优先级大于 *.do

    [包含符号:/a-z*.]

    11 缺省Servlet

    项目的,将<url-pattern>/</url-pattern>Servlet,叫缺省Servlet

    缺省Servlet通常做一些其它Servlet不处理的HTTP请求

    缺省Servlet程序员不用去编写,因为每个web服务器中都由缺省Servlet,

    例如:404页面就是由缺省Servlet来输出的

    如果有二个缺省Servlet,只要访问的是当前web应用,就由当前web应用的缺省Servlet处理;

    如果访问的不是当前web应用,则由tomcat中的缺省Servlet处理

    所在当前web应用可以没有缺省Servlet,但tomcat必须有缺省Servlet

    开发工具中的src目录,部署到tomcat中,就变成了/WEB-INF/classes目录

    关于缺省Servlet

    如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。 

    凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。Tomcat默认存在一个缺省Servlet,报错的404页面就是例子,单若项目中含有缺省值文件,就会优先执行项目中的缺省servlet,忽视Tomcat默认处理界面。

    12.配置Servlet自动加载

    如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。正整数有效,数字越低,优先级越高。

    Day06 重点代码

    HTTP部分:

    HTTP请求与响应练习

    /**

     * 禁止浏览器缓存Demo01这个web页面

     */

    具体类

    public class Demo01 extends HttpServlet {

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

    //禁止浏览器缓存Demo01这个web页面,因为每个浏览器不同,要针对所有浏览器进行设置

    WebUtil.setIeNoCache(response);

    //服务器向浏览器输出中文,text/html;charset=UTF-8就是响应头

    response.setContentType("text/html;charset=UTF-8");

    //以字符流方式输出

    response.getWriter().write("<font style='font-size:111px;color:red'>哈哈</font>");

    }

    }

    /**

     * 工具类

     */

    public class WebUtil {

    /**

     * 不要外界创建

     */

    private WebUtil(){}

    /**

     * 禁止浏览器缓存web页面

     */

    public static void setIeNoCache(HttpServletResponse response){

    //禁止浏览器缓存Demo01这个web页面,因为每个浏览器不同,要针对所有浏览器进行设置

    response.setDateHeader("expires",-1);

    response.setHeader("cache-control","no-cache");

    response.setHeader("pragma","no-cache");

    }

    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    /**

     * 通知浏览器3秒后跳到url指定的web页面

     */

    public class Demo02 extends HttpServlet {

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

    response.setHeader("Refresh","3;url=http://127.0.0.1:8080");

    }

    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    /**

     * 下载文件

     */

    public class Demo03 extends HttpServlet {

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

    //响应头

    //content-disposition表示下载响应头 

    //attachment表示浏览器会打开一个下载提示框

    //filename=abc.jpg表示浏览器打开的下载提示框中显示的下载文件名

    //今天下载的文件是假的

    //如果是中文文件名的话,一定要进行URL编码,各个浏览器做URL解码

    String filename = "中文.jpg";

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

    response.setHeader("content-disposition","attachment;filename="+filename);

    }

    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    编写Servlet的三种方式:

    方法一:实现Servlet接口

    public class Demo01A implements Servlet {

    public void destroy() {

    }

    public ServletConfig getServletConfig() {

    return null;

    }

    public String getServletInfo() {

    return null;

    }

    public void init(ServletConfig arg0) throws ServletException {

    }

    public void service(ServletRequest req, ServletResponse res)throws ServletException, IOException {

    //向浏览器输出一短英文字符串

    //从响应对象的获取输出流

    //who访问me, 响应对应就指向who

    //即然响应对象指向who,那么从响应对应中获取的输出流,自然指向who

    PrintWriter pw = res.getWriter();

    pw.write("<font style='color:red;font-size:111px'>HAHA</font>");

    }

    }

    方法二:继承GenericServlet抽象类,注意,GenericServlet该抽象类是一个空实现,仅仅为了快速编写servletservice方法

    /**

     * 创建Servlet程序的方式二

     * GenericServlet类已对Servlet接口的中的所有方法做了空实现,即方法体无内容

     */

    public class Demo01B extends GenericServlet {

    public Demo01B(){

    System.out.println("创建Demo01B");

    }

    @Override

    public void service(ServletRequest req, ServletResponse res)throws ServletException, IOException {

    //通知浏览器需要接收一个html页面,其中字符串用UTF-8的方式进行解码

    res.setContentType("text/html;charset=utf-8");

    //获取指向每个浏览器的字符输出流

    PrintWriter pw = res.getWriter();

    //向浏览器输出一段中文字符串

    pw.write("<font style='font-size:111px;color:red'>Servlet是做动态Web技术之一</font>");

    }

    }

    方法三:推荐使用,继承HTTPServlet类,该类是GenericServlet类的具体实现,service方法不用覆盖,作为中转方法,转到doGETdoPOST方法上

    /**

     * 创建Servlet程序的方式三

     */

    public class Demo01C extends HttpServlet {

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

    System.out.println(request);

    System.out.println(response);

    //通知浏览器接收类型和解码方式

    response.setContentType("text/html;charset=UTF-8");

    //从响应对应的中获取字符输出流

    PrintWriter pw = response.getWriter();

    //以下代码输出一个登录表单

    pw.write("<form action='#' method='POST'>");

    pw.write("<table border='2' align='center'>");

    pw.write("<caption><h2>用户登录</h2></caption>");

    pw.write("<tr><th>姓名</th><td><input type='text' name='username'/></td></tr>");

    pw.write("<tr><th>密码</th><td><input type='password' name='password'/></td></tr>");

    pw.write("<tr><td colspan='2' align='center'><input type='submit' value='提交'/></td></tr>");

    pw.write("</table>");

    pw.write("</form>");

    }

    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    /**

     * 演示Servlet生命周期中各方法的执行情况 通过多次的点击,发现除了首次执行空参构造与init方法外,其余点击都是执行service,而且地址值得hascode都相同,所以证明servlet是单例模式

     *每次执行访问都创建新的httpservletrequest对象与httpservletreaonse对象

     */

    public class Demo05 extends HttpServlet {

    public Demo05() {

    System.out.println("Demo05()::" + this.hashCode());

    }

    public void init() throws ServletException {

    System.out.println("init()::" + this.hashCode());

    }

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

    System.out.println("doGet()::" + this.hashCode());

    }

    public void destroy() {

    System.out.println("destroy()::" + this.hashCode());

    }

    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    init初始化方法能获取在servlet加载时设定在web.xml的初始化对象,ServletConfig类对象还有很多好方法,请查看API

    /**

     * 通过init(ServletConfig对象)方法获取web.xml文件中Servlet配置的初始化参数

     * 单例

     */

    public class Demo06 extends HttpServlet {

    /**

     * ServletConfig对象做成实例变量

     * 被所有客户端共享,只能做读操作,如果做写操作的话,非常危险

     */

    private ServletConfig config;

    public Demo06(){

    System.out.println("Demo06()");

    }

    /**

     * 读取web.xml文件中的servlet初始化参数

     */

    @Override

    public void init(ServletConfig config) throws ServletException {

    //为实例变量ServletConfig设置值

    this.config = config;

    }

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

    response.setContentType("text/html;charset=UTF-8");

    PrintWriter pw = response.getWriter();

    //一次性获取servlet的所有初始化参数名,初始化参数存放于web.xml文件中

    Enumeration<String> enums = config.getInitParameterNames();

    //迭代

    while(enums.hasMoreElements()){

    //获取初始化参数名,例如:emaillocation

    String name = enums.nextElement();

    //根据实始化参数名获取对应的参数值,例如:"xxxx""yyyy"

    String value = config.getInitParameter(name);

    //在浏览器在显示

    pw.write(name+":"+value+"<br/>");

    }

    //获取Servlet名字,即在web.xml文件中<servlet-name>

    pw.write(config.getServletName()+"<br/>");

    }

    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    load-on-startup:正整数,数字越小优先级越高,0的优先级最高

    <servlet>

    <servlet-name>Demo07A</servlet-name>

    <servlet-class>cn.itcast.android.servlet.Demo07A</servlet-class>

    <!-- 配置Servlet自动加载 -->

    <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet>

    <servlet-name>Demo07B</servlet-name>

    <servlet-class>cn.itcast.android.servlet.Demo07B</servlet-class>

    <load-on-startup>2</load-on-startup>

    </servlet>

    ---------------------------------------------------------------------------------------------------------------------------------------

    /**

     * 写一个Servlet,用于读取E:/下的图片,响应给所有浏览器

     * 注意:文件若不是文本文件,只能采用字节流方式读取,不然会乱码,打不开

     */

    public class Demo09 extends HttpServlet {

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

    System.out.println("Demo09");

    //字节输入流,路径要看tomcat中,不是看开发工具中

    InputStream is = this.getClass().getClassLoader().getResourceAsStream("../../images/广州地铁规划图.jpg");

    //字节输入流

    OutputStream os = response.getOutputStream();

    //以下是通过循环读取文件内容,并输出到浏览器中

    byte[] buf = new byte[1024];

    int len = 0;

    while((len=is.read(buf))>0){

    os.write(buf,0,len);

    }

    os.close();

    is.close();

    }

    }

  • 相关阅读:
    linux时间同步,ntpd、ntpdate
    重启HPE管理芯片ILO5的5种方法(Reset ilo)
    Linux内核SPI支持概述
    linux 查看CPU详情命令
    高可用
    NFS的介绍
    SELINUX
    error: undefined reference to 'android::hardware::details::return_status::~return_status()'
    errors collectiions
    大型分布式架构设计与实现-第三章互联网安全架构
  • 原文地址:https://www.cnblogs.com/canceler/p/4681613.html
Copyright © 2011-2022 走看看