Java进阶学习第九天——Servlet入门

文档版本 开发工具 测试平台 工程名字 日期 作者 备注
V1.0 2016.04.21 lutianfei none

Servlet开发

Servlet简介

  • Servlet是sun公司提供的一门用于开发动态web资源的技术。
  • Sun公司在其API中提供了一个servlet接口,用户若想要开发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
    • 编写一个Java类,实现servlet接口。
    • 把开发好的Java类部署到web服务器中。

Servlet快速入门

用servlet向浏览器输出“hello servlet”。

  • 步骤如下:

    • 编写一个类,实现Servlet接口,重写5个方法。

      • 编写一个类HelloServlet,继承GenericServlet类,重写一个方法。
public class TestDemo1 implements Servlet {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getServletInfo() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        // TODO Auto-generated method stub

    }

    @Override
    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException {
        res.getWriter().write("hello Miaolu ...");

    }
}
  • 配置文件,配置Servlet信息。
        <!-- 先配置Servlet信息 -->
        <servlet>
            <!-- 配置Servlet名称,名称必须唯一 -->
            <servlet-name>ServletDemo1</servlet-name>
            <!-- 配置Servlet的完全路径(包名+类名) -->
            <servlet-class>cn.itcast.servlet.ServletDemo1</servlet-class>
        </servlet>

        <!-- 配置Servlet映射(访问路径) -->
        <servlet-mapping>
            <!-- 配置Servlet名称,和上面的名称必须相同 -->
            <servlet-name>ServletDemo1</servlet-name>
            <!-- 配置虚拟路径(访问路径) -->
            <url-pattern>/demo1</url-pattern>
        </servlet-mapping>
* 编译(一般用不到)
    * `javac -d . HelloServlet.java`
    * 问题:`HelloServlet.java: 4 : 软件包 javax.servlet 不存在`
    * 解决:`set classpath=%classpath%;servlet-api.jar    `设置临时的环境变量,只对当前的窗口有效。
  • servlet 执行过程


Servlet的生命周期

  • 生命周期:实例被创建,对外提供服务销毁
  • Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。
  • Servlet实例被创建后,调用init方法进行初始化
  • Servlet默认情况下什么时候被创建呢?
    • 第一次访问的时候,实例才被创建。
    • init方法调用几次呢?
      • 只被调用一次。
  • 注意事项:
    • 如果想重写init方法,重写无参数的init方法。
  • 对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
  • 从服务器中移除服务,调用destroy方法。
  • Servlet实例什么时候被销毁呢?
    • 服务器关闭,手动移除。
    • destroy仅调用一次。
  • 针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。

Servlet的关系

  • Servlet接口

    • GenericServlet(重写5个方法)

      • HttpServlet(继承GenericServlet实现了Servlet接口)

        • MyServlet

* 新建servlet模板工程*

  • 新建文件时,选择Servlet
  • 将红框中的勾去掉

  • 将红框中的名字简化成类名

  • 开发步骤(最终)
    • 编写一个类,继承HttpServlet
    • 重写doGet和doPost方法
      • 在doPost方法中调用doGet方法。
      • 表单是get方式,调用doGet
      • 表单是post方法,调用doPost方法
      • doGet和doPost互相调用。代码复用。
  • 修改Servlet模板
    • 先找到MyEclipse的安装路径。

      • \myeclipse10.7\Common\plugins\com.genuitec.eclipse.wizards.xxxx.jar
    • 找到jar包:com.genuitec.eclipse.wizards_9.0.0.me201211011550.jar
      • 千万别解压,右键–选择压缩工具打开
      • 将templates–Servlet.java文件拖到桌面
      • 将Servlet.java文件做如下修改后再拖回压缩包。
      • 拖回去之前,先把MyEclipse关闭。
      • 注:将注释及多余代码全部删掉,并在doPost方法中加入如下doGet方法调用。

Servlet自动加载

  • Servlet默认是第一次访问时候创建实例。通过配置,服务器启动,创建实例。
  • init做初始化的操作,非常消耗时间的。
  • <servlet>标签下:要放在servlet标签内的最后位置。
    • <load-on-startup>3</load-on-startup>
    • 值是正整数
    • 如果值越小,优先级越高。

WEB开发中路径的问题

配置虚拟路径(访问路径)

  • 由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。
  • <servlet>元素用于注册Servlet,它包含有两个主要的子元素:<servlet-name><servlet-class>,分别用于设置Servlet的注册名称Servlet的完整类名
  • 一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name><url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。

路径匹配问题

  • 完全路径匹配

    • /开头的。eg:/demo5
    • 访问:http://localhost/day09/demo5
  • 目录匹配
    • /开头的:/*,任意后缀都可以访问。
    • 访问:http://localhost/day09/demo5可以访问
  • 扩展名匹配
    • 不能以/开头的, eg:*.do *.action
    • 访问:http://localhost/day09/demo5.do
  • 优先级完全路径匹配 > 目录匹配 > 扩展名匹配(重点)
  • 练习题:

相对路径

  • 一个文件相对于另一个文件的位置的关系
  • 不能以/开头 写法: ./demo当前目录==demo../demo:表示上级目录。
  • 访问1.html: http://localhost/day09/1.html
  • 访问demo5: http://localhost/day09/demo5
  • 从1.html中去访问demo5:./demo5 demo5
  • 访问2.html: http://localhost/day09/html/2.html
  • 访问demo5: http://localhost/day09/demo5
  • 从2.html访问demo5: ../demo5

绝对路径(推荐使用)

  • /开头的
  • 访问demo5: http://localhost/day09/demo5
  • 从1.html使用绝对路径访问demo5:http://localhost/day09/demo5
  • 简写方式:/day09/demo5
  • 客户端绝对路径
    • /day09/demo5 需要写项目名
  • 服务器绝对路径
    • /demo5 不能写项目名
  • 客户端关于路径问题的编程结论
  • *.html *.jsp : 内都使用绝对路径
  • *.css:内部使用相对路径—- 背景图片
  • *.js:中使用绝对路径

ServletConfig对象和配置文件相关

  • 当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servletinit方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息
  • 配置初始化参数
    • 需要在<servlet> </servlet>标签下配置。
    • 如果要是配置在某个servlet的标签下,那么只能在该servlet中获取初始化参数。
  • 在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数
  • String getServletName() 获取配置文件中servlet的名称
  • String getInitParameter(String name) 获取初始化参数
  • Enumeration getInitParameterNames() 获取初始化参数的所有名称
    <init-param>
        <param-name>username</param-name>
        <param-value>root</param-value>
    </init-param>
public class ServletDemo6 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 测试ServletConfig对象的api
        // 先获取ServletConfig对象
        ServletConfig config = getServletConfig();
        // 获取配置文件中serlvet的名称
        System.out.println("servlet的名称:"+config.getServletName());

        // 获取初始化的参数
        String username = config.getInitParameter("username");
        String password = config.getInitParameter("password");
        System.out.println(username+" : "+password);

        Enumeration<String> e = config.getInitParameterNames();
        while(e.hasMoreElements()){
            String name = e.nextElement();
            String value = config.getInitParameter(name);
            System.out.println(name+" : "+value);
        }

    }

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

}

ServletContext对象(域对象) (重要)

  • WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。

    • 一个WEB应用对应一个ServletContext对象
    • 一个WEB应用下有多个Servlet程序
    • 所有的servlet程序都共享同一个ServletContext对象
  • ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
  • 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象
  • 作用:
    • 获取WEB应用全局初始化参数

      • String getInitParameter(String name)
      • getInitParameterNames()
      • 在web.xml中配置全局初始化参数
            <context-param>
                <param-name>encoding</param-name>
                <param-value>GBK</param-value>
            </context-param>
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 先获取ServletContext对象
        ServletContext context = getServletContext();
        // 获取初始化参数
        String encoding = context.getInitParameter("encoding");
        System.out.println("编码:"+encoding);

        Enumeration<String> e = context.getInitParameterNames();
        while(e.hasMoreElements()){
            String name = e.nextElement();
            // 通过name获取值
            String value = context.getInitParameter(name);
            System.out.println(name+" : "+value);
        }
    }
  • 实现数据的共享(重要)

    • void setAttribute(String name, Object object) : 存入数据
    • void removeAttribute(String name) : 删除数据
    • Object getAttribute(String name) : 获取数据
  • 读取资源文件(重要)
    • InputStream getResourceAsStream(String path) 通过文件的地址获取输入流
    • String getRealPath(String path) 通过文件的地址获取文件的绝对磁盘路径
public class ReadServlet extends HttpServlet {

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

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

    /**
     * 通过ServletContext对象获取文件的绝对磁盘路径
     * 获取src目录下文件
     * @throws IOException
     */
    public void read5() throws IOException{
        // 获取对象
        String path = getServletContext().getRealPath("/WEB-INF/classes/db.properties");
        // System.out.println(path);
        // C:\apache-tomcat-6.0.14\webapps\day09\WEB-INF\classes\db.properties

        // 获取输入流
        InputStream in = new FileInputStream(path);
        print(in);
    }

    /**
     * 获取WebRoot目录目录下db.properties文件
     * @throws IOException
     */
    public void read4() throws IOException{
        // ServletContext读取文件
        InputStream in = getServletContext().getResourceAsStream("/db.properties");
        // 打印方式
        print(in);
    }

    /**
     * 获取包目录下db.properties文件
     * @throws IOException
     */
    public void read3() throws IOException{
        // ServletContext读取文件
        InputStream in = getServletContext().getResourceAsStream("/WEB-INF/classes/cn/itcast/context/db.properties");
        // 打印方式
        print(in);
    }

    /**
     * 获取src目录下db.properties文件
     * @throws IOException
     */
    public void read2() throws IOException{
        // ServletContext读取文件
        InputStream in = getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        // 打印方式
        print(in);
    }

    /**
     * 传统方式读取资源文件
     *     交给服务器处理,相对的位置tomcat/bin
     * @throws IOException
     */
    public void read1() throws IOException{
        // 获取输入流
        InputStream in = new FileInputStream("src/db.properties");
        print(in);
    }

    /**
     * 在控制台打印内容
     * @param in
     * @throws IOException
     */
    public void print(InputStream in) throws IOException{
        Properties pro = new Properties();
        // 加载
        pro.load(in);
        // 获取文件中的内容
        String username = pro.getProperty("username");
        String password = pro.getProperty("password");
        String desc = pro.getProperty("desc");

        System.out.println("用户名:"+username);
        System.out.println("密码:"+password);
        System.out.println("描述:"+desc);
    }

}

//db.properities

username=root33
password=12333
desc=haha33
  • 案例:统计显示网站访问次数

  • CountServlet.java
public class CountServlet extends HttpServlet {

    /**
     * 实例被创建,调用init方法进行初始化
     *     在域对象存入一个变量,赋值为0
     */
    public void init() throws ServletException {
        // 获取ServletContext对象
        getServletContext().setAttribute("count", 0);
    }

    /**
     * 每一次访问,都会执行该方法。
     * 拿出count的变量,值自增,存入到域对象中
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 先获取ServletContext对象
        ServletContext context = getServletContext();
        // 获取count的值,自增
        Integer count = (Integer) context.getAttribute("count");
        // 存入到域对象中
        context.setAttribute("count", ++count);

        // 向页面输出内容
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("<h3>大爷,欢迎再来哦!!</h3>");
    }

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

}
  • ShowServlet.java
/**
 * 显示网站的访问次数
 * @author Administrator
 *
 */
public class ShowServlet extends HttpServlet {

    /**
     * 获取网站的访问次数,输出到客户端
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Integer count = (Integer) getServletContext().getAttribute("count");
        // 向页面输出
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("<h3>该网站一共被访问了"+count+"次</h3>");
    }

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

}
  • HTTP的协议
  • 响应报头:location 与302 重定向应用
package cn.itcast.http;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 和location和302一起完成重定向
 * @author Administrator
 *
 */
public class ServletDmo1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 向页面输出内容
        response.setContentType("text/html;charset=UTF-8");
        // response.getWriter().write("向班长借钱...");
        // 我没钱
        response.setStatus(302);
        // 告诉我富班长的地址
        response.setHeader("location", "/day09/1.html");
    }

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

}

  • 响应头: refresh 页面定时跳转
package cn.itcast.http;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 页面定时跳转
 * @author Administrator
 *
 */
public class RefreshServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("访问到了...");
        // 页面5秒会跳转
        response.setHeader("refresh", "5;url=/day09/1.html");
    }

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

}
  • 响应报头last-modefied-since 和304状态码 :控制缓存

时间: 2024-10-10 07:12:05

Java进阶学习第九天——Servlet入门的相关文章

Java进阶学习(2)——log4j的学习和使用

Java进阶学习(2)--log4j的学习和使用 简介Loj4j Log4j的组成 Log4j主要由三大组组件构成: Logger: 负责生成日志,并能够对日志信息进行分类筛选,通俗的讲就是决定什么日志信息应该被输出,什么日志信息应该被忽略. Appender: 定义了日志信息输出的目的地,指定日志信息应该被输出到什么地方,这些地方可以是控制台.文件或网络设备等. Layout: 指定日志信息的输出格式. 说明: 一个Logger可以有多个Appender,这意味着日志信息可以被输出到多个设备上

java进阶学习计划

断断续续使用java也已经有两年了,算是最熟悉的开发工具了.但写的代码都是以项目为导向,追求work around,还需要打好基础才能长远发展. 大致的进阶学习计划, 阶段1:深究java语法,阅读常用库的jdk源码,了解jvm机制; 阶段2:阅读基于java的开源框架源码,各种framework,container. 希望可以坚持下来,经常更新技术博客. java进阶学习计划

Java:进阶学习(1)——网络编程

Java:进阶学习(1)--网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket方法 getInetAddress();    远程服务端的IP地址 getPort();    远程服务端的端口 getLocalAddress()    本地客户端的IP地址 getLocalPort()    本地客户端的端口 getInputStream();   

Java进阶学习第二十二天——上传与下载

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.06.05 lutianfei none Servlet规范中 servlet有初始化参数 Filter有初始化参数 Listener没有初始化参数,要使用,在开发中一般使用<context-param> servletContext的初始化参数. 文件上传 问题:什么是文件上传?为什么使用文件上传? 就是将客户端资源,通过网络传递到服务器端. 就是因为数据比较大,我们必须通过文件上传才可以完成将数据保存到服务器端操

Java Web学习(29): Servlet学习(二)

Servlet生命周期 先来看看一个Servlet执行的流程图: 再来看看我们所说的HttpServlet的上下文: 一个Servlet的执行过程: Servlet的生命周期 Servlet生命周期可被定义为从创建直到销毁的整个过程.servlet生命周期阶段包括初始化.加载.实例化.服务 和销毁. 以下是Servlet遵循的过程: 1)初始化阶段:Servlet通过调用init()方法进行初始化. 2)响应客户端请求阶段:Servlet调用service()方法来处理客户端的请求:由servi

Java Web学习(30): Servlet学习(三)

Servlet获取JSP九大内置对象 Servlet与JSP九大内置对象对应关系: Servlet与表单 Servlet如何获取表单数据呢? 我们就不再一一讲解,具体的可以参考:http://www.runoob.com/servlet/servlet-form-data.html 实例:获取表单数据 实体类Users代码: package com.entity; import java.util.Date; /**  * 用户实体类  * @author Administrator  * @d

java web 学习五(servlet开发1)

一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤: 1.编写一个Java类,实现servlet接口. 2.把开发好的Java类部署到web服务器中. 按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet 二.Servlet的运行过程 Servlet程序是由WEB

Java Web学习(31): Servlet学习(四)

Servlet路径 绝对路径:一个资源的完整路径: 相对路径:相对于当前资源的路径: 在进行路径说明的时候首先声明一点,如果新建的项目工程中带有WebRoot目录,那么js.css.img都应该放 到WebRoot目录下,否则访问会有问题.千万不要放在WEB-INF下,因为WEB-INF下的内容只有服务器转发可以访 问到,处于安全考虑:如果新建的项目工程中不带有WebRoot目录,那么可以放在WEB-INF外面建立的文件夹中. 那么使用Eclipse创建的Web工程项目是下面的目录结构: JSP

Java Web学习(32): Servlet学习(五)

获取初始化参数 在web.xml中配置Servlet时或者在注解中配置Servlet时,可以配置一些初始化参数,而在Servlet中可以通过 ServletConfig接口提供的方法来取得这些参数. 例子: ServletDemo: package com.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet