第一个Servlet开发步骤

 01_创建一个普通Java类,实现Servlet接口
 02_将写好的Servlet类,还得配置到web.xml文件中去
Demo01.java

编写一个简单的Servlet程序输出英文字符串到浏览器【实现Servlet接口】

    public class Demo01 implements Servlet{
    @Override
    public void destroy() {
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        OutputStream os = servletResponse.getOutputStream();
        os.write("<h1>Hello Servlet</h1>".getBytes());
        os.flush();
        os.close();
    }
}

web.xml

<?xml version="1.0"encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee         http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID"version="2.5">
    <servlet>
        <servlet-name>Demo01</servlet-name>
    <servlet-class>cn.itheima.servlet.Demo01</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo01</servlet-name>
        <url-pattern>/xxx</url-pattern>
    </servlet-mapping>
</web-app>

为什么建议创建Servlet直接继承HttpServlet类呢

 创建Servlet有三种方式,前二种创建的Servlet能处理任意协议的请求,
 但我们做Web开发,大多都是处理Http协议,所有建议直接继承HttpServlet类
 再者,HttpServlet类,也继承与实现了前二种方式的类或接口,且有适合于HTTP协议特点的方法

方式一:编写一个简单的Servlet程序输出英文字符串到浏览器【实现Servlet接口】

编写一个简单的Servlet程序输出英文字符串到浏览器【实现Servlet接口】

public class Demo01 implements Servlet{
    @Override
    public void destroy() {
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        OutputStream os = servletResponse.getOutputStream();
        os.write("<h1>Hello Servlet</h1>".getBytes());
        os.flush();
        os.close();
    }
}
<servlet>
    <servlet-name>Demo01</servlet-name>
<servlet-class>cn.itheima.servlet.Demo01</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Demo01</servlet-name>
    <url-pattern>/Demo01</url-pattern>
</servlet-mapping>

方式二:编写一个简单的Servlet程序输出中文字符串到浏览器【继承GenericServlet类】

编写一个简单的Servlet程序输出中文字符串到浏览器【继承GenericServlet类】

public class Demo02 extends GenericServlet{
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        servletResponse.setContentType("text/html;charset=UTF-8");
        PrintWriter pw = servletResponse.getWriter();
        pw.write("<h2>你好,Servlet,我们今天见面了</h2>");
        pw.flush();
        pw.close();
    }
}

<servlet>
    <servlet-name>Demo02</servlet-name>
<servlet-class> cn.itheima.servlet.Demo02</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Demo02</servlet-name>
    <url-pattern>/Demo02</url-pattern>
</servlet-mapping>

编写一个简单的Servlet程序输出当前时间到浏览器【继承HttpServlet类】

编写一个简单的Servlet程序输出当前时间到浏览器【继承HttpServlet类】

public class Demo03 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter pw = response.getWriter();
        pw.write("<h3>现在时间为:" + new Date().toLocaleString()+"</h3>");
        pw.flush();
        pw.close();
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }
}
   

 <servlet>
        <servlet-name>Demo03</servlet-name>
    <servlet-class>cn.itheima.servlet.Demo03</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo03</servlet-name>
        <url-pattern>/Demo03</url-pattern>
    </servlet-mapping>
如果在浏览器地址栏输入URL后回车,这种方式属于GET请求

什么是Servlet生命周期

 Servlet是运行于Web服务器中的Servlet引擎/容器中,客户端是不能直接调用Servlet的,必须由Servlet引擎/容器才能调用。因此Servlet在引擎/容器中从创建到销毁的全过程,称之为Servlet生命周期

Servlet生命周期分为四个过程,分别是:

     01——构造器(执行一次)
     02——初始化(执行一次)-----------------------------在默认情况下,首次访问该Servlet时执行
     03——doGet/doPost/service(执行多次)----------------------非首次访问该Servlet时执行
     04——销毁(执行一次)
     Servlet是单例的,被多个客户端线程共享,建议不要用实例变量

Servlet运行过程图解

ServletConfig对象有什么作用

当Servlet配置了初始化参数后,Servlet引擎/容器在创建Servlet对象时,
会自动将这些初始化参数封装到ServletConfig对象中,并在调用Servlet的
init(ServletContext)方法时,将ServletConfig对象传递给Servlet。
从而程序员可以通过ServletConfig对象就可以得到当前Servlet的初始化参数信息

常用的API

ServletContext的getInitParameterNames():获取当前Servlet的所有初始化参数
ServletContext的getInitParameter():获取当前Servlet的一个初始化参数 Demo04.java
public class Demo04 extends HttpServlet {
    private ServletConfig config;
    public Demo04() {
    }
    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        /*
        //获取web.xml文件中的servlet初始化参数
        Enumeration<String> enums = config.getInitParameterNames();
        while(enums.hasMoreElements()){
            String key = enums.nextElement();
            String value = config.getInitParameter(key);
            //在控制台显示
            System.out.println(key+"-"+value);
        }
        */
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter pw = response.getWriter();
    Enumeration<String> enums = config.getInitParameterNames();
        while(enums.hasMoreElements()){
            String key = enums.nextElement();
            String value = config.getInitParameter(key);
            //在浏览器中显示
            pw.write(key+"--"+value+"<br/>");
        }
        pw.flush();
        pw.close();
    }
    @Override
    public void destroy() {
    }
}


Servlet创建时间

    在默认情况下,Servlet是客户端首次访问时,Servlet引擎/容器才创建并对其初始化,
有时我们希望Servlet创建与初始化的时间能够提前到Web服务器启动时,这样客户
端首次访问时,就不用创建与初始化Servlet了,提高了访问速度,我们可以用自动
加载Servlet来完成任务
    配置的数值越小,越先创建与初始化,只限于0,1,2,3等等,负数与没有配置效果一样
如果配置负数,必须用户首次访问时才创建与初始化该Servlet


    web.xml
<servlet>
    <servlet-name>Demo04</servlet-name>
    <servlet-class> cn.itheima.servlet.Demo04</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Demo04</servlet-name>
    <url-pattern>/Demo04</url-pattern>
</servlet-mapping>


什么是Servlet虚拟路径

      一个在web.xml文件中,可供外界能访问Web服务器中Servlet的字符串
即<url-pattern>/xxx这个就是Servlet虚拟路径</url-pattern>
   为什么要配置Servlet虚拟路径
      Servlet位于Servlet引擎/容器中,Servlet引擎/容器又位于Web服务器中,
客户端是不可能知道Servlet的名字的,但Servlet毕竟要处理客户端提交的请求,
就必须让客户端访问,那么要访问Servlet,就必须给客户端一个有效的访问路径,
又不能暴露Servlet真实保存在服务器中的位置,于是就只能配置Servlet虚拟路径
    如何配置Servlet虚拟路径
      Servlet虚拟路径的配置是在web.xml文件中,一个Servlet可以配置在一个或多个虚拟路径上,
也可以使用*.xx或者是/xx通配符形式来配置Servlet路径通配符
      不能出现/*.do的情况,只能分成二个url-pattern来书写
      当一个真正的index.html与一个虚拟路径为index.html同时存在时,
以虚拟路径为主

web.xml
<servlet>
    <servlet-name>Demo05</servlet-name> <servlet-class>cn.itheima.servlet.Demo05</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Demo05</servlet-name>
    <url-pattern>/Demo05</url-pattern>
    <url-pattern>/xx</url-pattern>
    <url-pattern>/yy</url-pattern>
    <url-pattern>/index.html</url-pattern>
    <url-pattern>/*</url-pattern>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>


什么是缺省Servlet

  如果某个Servlet的映射的虚拟路径为一个正斜杠(/),那么这个Servlet就成为 当前Web应用程序的默认Servlet

默认Servlet有什么作用 ----专用于处理其它正常Servlet不处理的客户端请求 Servlet读取硬盘中的图片
Tomcat中就有默认Servlet

 在Tomcat/conf/web.xml文件中,注册了一个名称为DefaultServlet的Servlet, 并将这个Servlet设置

为了缺省Servlet,像404,500,等页面,就是由这个DefaultServlet
来响应给客户端的,当程序员有一个缺省Servlet时,Tomcat又有一个缺省Servlet时, 以程序员为主。
项目中,我们以Tomcat中的缺省Servlet为主,即程序员不用写缺省Servlet

 Demo06.java
public class Demo06 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //输入流指向图片
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("../../images/girl1.jpg");
        //输出流指向浏览器
        OutputStream os = response.getOutputStream();
        //读取图片并输出到浏览器
        byte[] buf = new byte[2048];
        int len = 0;
        while((len=is.read(buf))>0){
            os.write(buf,0,len);
        }
        //关闭流
        os.close();
        is.close();
    }
}
<servlet>
    <servlet-name>Demo06</servlet-name>
    <servlet-class>cn.itheima.servlet.Demo06</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Demo06</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
关于路径问题:
/webapps
        /day11
             /images/girl_1.jpg
                  /WEB-INF/classes/Demo06.class
                                /lib
                                /web.xml       
 
 

ServletContext对象

ServletContext对象有什么作用

Tomcat启动时,会为每个部署在Tomcat中的Web应用程序都创建一个对应的ServletContext对象,
它代表当前Web应用。即一个Web应用程序对应着一个ServletContext对象。
一个Web应用程序中可以有很多Servlet,这些Servlet都共享同一个ServletContext对象,我们经常
将ServletContext对象叫域对象。

常用的API

 ServletConfig的getServletContext():获取ServletContext对象
    ServletContext的setAttribute():向ServletContext对象绑定数据
    ServletContext的getAttribute():从ServletContext对象取出数据
    ServletContext的getInitParameter():获取当前Web应用的初始化参数
    ServletContext的getResourceAsStream():获取资源文件,返回流
    ServletContext的getRealPath():获取资源文件,返回路径
    
Demo07.java
public class Demo07 extends HttpServlet {
     public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
         System.out.println("Demo07::doGet()");
         String filePath = this.getServletContext().getRealPath("/images/girl_3.png");
         System.out.println(filePath);
         InputStream is = new FileInputStream(filePath);
         OutputStream os = response.getOutputStream();
         byte[] buf = new byte[1024*2];
         int len = 0;
         while((len=is.read(buf))>0){
              os.write(buf,0,len);
         }
         os.close();
         is.close();
     }
}



万灰灰
1 声望0 粉丝

Debug The World !