频道栏目
首页 > 资讯 > Java > 正文

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

16-04-23        来源:[db:作者]  
收藏   我要投稿
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信息。
        
        
            
            ServletDemo1
            
            cn.itcast.servlet.ServletDemo1
        

        
        
            
            ServletDemo1
            
            /demo1
        
* 编译(一般用不到)
    * `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标签内的最后位置。

3 值是正整数 如果值越小,优先级越高。

 

WEB开发中路径的问题

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

由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用元素和元素完成。

元素用于注册Servlet,它包含有两个主要的子元素:,分别用于设置Servlet的注册名称Servlet的完整类名

一个元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:,分别用于指定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配置一些初始化参数

String getServletName() 获取配置文件中servlet的名称

String getInitParameter(String name) 获取初始化参数

Enumeration getInitParameterNames() 获取初始化参数的所有名称

    
        username
        root
    
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 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中配置全局初始化参数
            
                encoding
                GBK
            
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 先获取ServletContext对象
        ServletContext context = getServletContext();
        // 获取初始化参数
        String encoding = context.getInitParameter("encoding");
        System.out.println("编码:"+encoding);

        Enumeration 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("

大爷,欢迎再来哦!!

"); } 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("

该网站一共被访问了"+count+"次

"); } 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状态码 :控制缓存
相关TAG标签
上一篇:[Java] HashMap和HashTable的区别
下一篇:腾讯2016实习生面试经验(已经拿到offer)
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站