JavaWeb学习二(Servlet入门)

来源:互联网 发布:点对点传输软件 编辑:程序博客网 时间:2024/04/27 04:54

在学习前我们的先准备先东西,比如javaEE的API:
java ee 帮助文档

一.Servlet概述

1.Servlet概述

  • Servlet是javaweb的三大组件之一 它属于动态资源
  • Servlet的作用是处理请求 服务器会接收到的请求交给Servlet来处理
  • 在Servlet中通常需要:
    • 接收请求数据
    • 处理请求
    • 完成响应

2.实现Servlet

  • 实现 javax.servlet.Servlet接口
  • 继承 javax.servlet.GenericServlet
  • 继承 javax.servlet.http.HttpServlet类
    注意:通常我们会去继承 HttpServlet类来完成我们的Servlet

Servlet中的方法大多数不由我们来调用 而是由Tomcat来调用,并且Servlet的对象也不由我们创建,也是由Tomcat来创建

如何让浏览器访问Servlet?

  • 给Servlet指定一个Servlet路径!(让Servlet与一个路径绑定在一起),给Servlet配置Servlet路径!这需要在web.xml中对Servlet进行配置
  • 浏览器访问Servlet路径

web.xml

<servlet>       <servlet-name>XXX</servlet-name>       <servlet-class>cn.st.web.servlet.Aservlet</servlet-class></servlet><servlet-mapping>          <servlet-name>XXX</servlet-name>             <url-pattern>/Aservlet</url-pattern></servlet-mapping>

3.Servlet生命周期

public class BServlet implements Servlet{    @Override    public void destroy() {        System.out.println("destroy...");    }    /*     * 获取servlet配置信息     */    @Override    public ServletConfig getServletConfig() {        // TODO Auto-generated method stub        return null;    }    /*     * 获取servlet的信息     */    @Override    public String getServletInfo() {        // TODO Auto-generated method stub        return null;    }    @Override    public void init(ServletConfig arg0) throws ServletException {        System.out.println("init..");    }    @Override    public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {        System.out.println("service...");    }}

服务器开启,访问这个servlet,我们会发现会打印出以下信息

init..service...

而我们再次访问这个servlet时,它会继续打印出service…
当我们关闭服务器时,控制台就会打印出destroy…
总结:
对于生命周期方法:
* void init(ServletConfig):出生之后(1次)
* void service(ServletRequest request,ServletResponse response):每次处理请求时都会被调用
* void destroy():临死之前(1次)

Servlet特性

  • 单例,一个类只有一个对象,当然可能存在多个Servlet类
  • 线程不安全,所以效率高
  • Servlet类我们写 但对象由服务器来创建 并且由服务器来调用相应的方法

二.ServletConfig概述

  • 1个ServletConfig对象,对应一段web.xml中Servlet的配置信息!

这里写图片描述
这里写图片描述

查看API发现ServletConfig中有四个方法
这里写图片描述

  • String getServletName():获取的是<servlet-name>中的内容
<servlet>     <servlet-name>BServlet</servlet-name>     <servlet-class>cn.st.web.servlet.BServlet</servlet-class>     <init-param>           <param-name>p1</param-name>           <param-value>v1</param-value>     </init-param>     <init-param>           <param-name>p2</param-name>           <param-value>v2</param-value>     </init-param>  </servlet>
public class BServlet implements Servlet{    @Override    public void destroy() {        System.out.println("destroy...");    }    /*     * 获取servlet配置信息     */    @Override    public ServletConfig getServletConfig() {        // TODO Auto-generated method stub        return null;    }    /*     * 获取servlet的信息     */    @Override    public String getServletInfo() {        // TODO Auto-generated method stub        return null;    }    @Override    public void init(ServletConfig servletConfig) throws ServletException {        System.out.println("init..");        System.out.println(servletConfig.getServletName());     }    @Override    public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {        System.out.println("service...");    }}

访问这个servlet控制台打印出

init..BServletservice...
  • String getInitParameter(String name):通过名称获取指定初始化参数
@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("init..");System.out.println(servletConfig.getServletName());System.out.println(servletConfig.getInitParameter("p1"));}

再次访问这个servlet控制台打印

init..BServletv1service...
  • Enumeration getInitParameterNames():获取所有初始化参数的名称
@Override    public void init(ServletConfig servletConfig) throws ServletException {        System.out.println("init..");        System.out.println(servletConfig.getServletName());        System.out.println(servletConfig.getInitParameter("p1"));        Enumeration<String> enumeration = servletConfig.getInitParameterNames();        while(enumeration.hasMoreElements()) {                System.out.println(enumeration.nextElement());        }    }

再次访问servlet控制台打印

init..BServletv1p1p2service...
  • ServletContext getServletContext():获取Servlet上下文对象

三.ServletRequest概述

这里写图片描述

四.GenericServlet概述

这里写图片描述

对于GenericServlet的理解我们可以通过一个例子来理解,如下:

public class BServlet implements Servlet{    private ServletConfig config;    @Override    public void destroy() {        System.out.println("destroy...");    }    /*     * 获取servlet配置信息     */    @Override    public ServletConfig getServletConfig() {        return this.config;    }    /*     * 获取servlet的信息     */    @Override    public String getServletInfo() {        return "我是一个快乐的Servlet";    }    @Override    public void init(ServletConfig config) throws ServletException {        this.config=config;        init();    }    public void init() {    }    @Override    public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {        System.out.println("service...");    }    public ServletContext getServletContext() {           return config.getServletContext();    }    public String getServletName() {         return config.getServletName();    }    public String getInitParameter(String arg0) {         return config.getInitParameter(arg0);    }}

web.xml仍然同上的写法

public class CServlet extends BServlet {       @Override    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {              String name=getInitParameter("p1");    }}

这样写并没有什么问题,但向下面的写法呢?

public class CServlet extends BServlet {    @Override    public void init(ServletConfig config) throws ServletException {        System.out.println("快乐与我servlet同在!!!");    }       @Override    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {              String name=getInitParameter("p1");    }}

由于你重写了父类的带参init方法,导致参数config并未被初始化,最后访问这个CServlet会在BServlet的getInitParameter报空指针错误
那么怎么解决这个问题呢???我们可以在BServlet上的带参init方法做点修改

@Override    public void init(ServletConfig config) throws ServletException {        this.config=config;        init();    }    //注意这个init不是生命周期方法!!!    public void init() {    }

之后我们就可以在CServlet重写无参的init

public class CServlet extends BServlet {    @Override    public void init() {        System.out.println("快乐与我servlet同在");    }       @Override    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {              String name=getInitParameter("p1");    }}

一访问CServlet就打印出了

快乐与我servlet同在

当然你也可以这样写,不过这样写有点麻烦,就相当于多写了很多没必要的代码了

public class CServlet extends BServlet {    private ServletConfig config;    @Override    public void init(ServletConfig config) throws ServletException {        this.config=config;        init();    }    @Override    public void init() {        System.out.println("快乐与我servlet同在");    }       @Override    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {              String name=config.getInitParameter("p1");    }}

我们可以来看下GenericServlet的源码结构:

   public void destroy() {    } public String getInitParameter(String name) {        ServletConfig sc = getServletConfig();        if (sc == null) {            throw new IllegalStateException(                lStrings.getString("err.servlet_config_not_initialized"));        }        return sc.getInitParameter(name);    }public Enumeration getInitParameterNames() {        ServletConfig sc = getServletConfig();        if (sc == null) {            throw new IllegalStateException(                lStrings.getString("err.servlet_config_not_initialized"));        }        return sc.getInitParameterNames();    }     public ServletConfig getServletConfig() {    return config;    }  public ServletContext getServletContext() {        ServletConfig sc = getServletConfig();        if (sc == null) {            throw new IllegalStateException(                lStrings.getString("err.servlet_config_not_initialized"));        }        return sc.getServletContext();    }  public void init(ServletConfig config) throws ServletException {    this.config = config;    this.init();    } public void init() throws ServletException {    } public String getServletName() {        ServletConfig sc = getServletConfig();        if (sc == null) {            throw new IllegalStateException(                lStrings.getString("err.servlet_config_not_initialized"));        }        return sc.getServletName();    } public abstract void service(ServletRequest req, ServletResponse res)    throws ServletException, IOException;

我们可以来试试了继承GenericServlet形成Servlet,如下

public class DServlet extends GenericServlet {    @Override    public void init() throws ServletException {        System.out.println("快乐与我servlet同在");    }    @Override    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {         String name=getInitParameter("p1");        System.out.println(name);    }}

是不是很像上边的例子呀???

五.HttpServlet概述

1.HttpServlet的API

这里写图片描述

2.HttpServlet的大致结构

这里写图片描述

3.HttpServlet内部执行顺序

这里写图片描述

4.例子

public class EServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        System.out.println("get...");    }}

直接访问EServlet就会打印出

get...
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body>          <form action="/javaweb1/FServlet" method="post">                 <input type="text"><br/>                 <input type="submit" value="提交">          </form></body></html>

通过jsp表单更改提交方式为post到FServlet去,控制台打印出

post...

END!!!!!!!!!!!

1 0
原创粉丝点击