三、Servlet开发入门

Servlet开发

servlet接口

针对Servlet技术的开发,Sun公司提供了一系列接口和类,其中最重要的是javax.servlet.Servlet接口,Servlet就是一种实现了Servlet接口的类,它是由Web容器负责创建并调用,用于接收和响应应用的请求。
在Servlet接口中定义了5个抽象方法,具体

方法声明功能描述
void init(ServletConfig config)负责Servlet初始化工作。容器在创建好Servlet对象后,就会调用此方法。该方法接收一个ServletConfig类型的参数,Servlet容器通过这个参数向Servlet传递初始化配置信息
ServletConfig getServletConfig()返回容器调用init(ServletConfig config)方法时传递给Servlet的ServletConfig对象
String getServletInfo()返回一个字符串,其中包含关于Servlet的信息,例如,作者,版本和版权等信息
void service(ServletRequest request,ServletResponse response)负责响应用户请求,当容器接收到客户端访问Servlet对象的请求时,就会调用此方法。容器会构造一个表示客户端请求信息的ServletRequest对象和一个用于响应客户端的ServletResponse对象作为参数传递给service()方法。在service()方法中,可以通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息
void destroy()负责释放Servlet对象占用的资源。当Servlet对象被销毁时,容器会调用此方法

手动编译一个Servlet程序

1、编写一个Servlet程序
在目录D:cn/itcast/firstapp/servlet下编写HelloWorldServlet.java,由于直接继承Servlet接口来编写servlet非常不方便。因此可以通过继承Servlet接口的实现类javax.servlet.GenericServlet来实现
在这里插入图片描述

package cn.itcast.firstapp.servlet;
import java.io.*;
import javax.servlet.*;
public class HelloWorldServlet extends GenericServlet{
	public void service(ServletRequest request,ServletResponse response) throws ServletException,IOException{
		PrintWriter out = response.getWriter();
		out.println("Hello World");
	}
}

HelloWorldServlet类只实现了service方法,这是因为除了service之外的方法GenericServlet都实现了。
2、打开命令窗口,进入HelloWorldServlet所在目录,编译
在这里插入图片描述
错误提示没有找到javax.servlet包
3、找到javax.servlet包路径
进入Tomcat安装目录下的lib目录,里面包含许多与Tomcat服务器有关的jar包,其中servlet-api.jar文件就是与Servlet相关的jar文件
在这里插入图片描述
4、通过set classpath命令添加jar路径
在这里插入图片描述
5、重新编译
在这里插入图片描述
在这里插入图片描述
成功得到class文件
6、将servlet应用放置在tomcat下
在Tomcat安装目录的webapps下创建目录chapter04,chapter04为Web应用的名称,然后在chapter04目录下创建\WEB-INF\class目录,将整个包目录复制到其下(\cn…)
在这里插入图片描述
7、配置web.xml
进入目录WEB-INF新建一个web.xml文件
在这里插入图片描述

在这里插入图片描述

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">
   <servlet>
      <servlet-name>HelloWorldServlet</servlet-name>
      <servlet-class>cn.itcast.firstapp.servlet.HelloWorldServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>HelloWorldServlet</servlet-name>
      <url-pattern>/HelloWorldServlet</url-pattern>
    </servlet-mapping>
</web-app>

上面配置文件信息中,元素<servlet>用于注册Servlet,他的两个子元素<servlet-name>和<servlet-class>分别用来指定Servlet名称以及其完整类名。元素<servlet-mapping>用于映射Servlet对外访问的虚拟路径,他的子元素<servlet-name>与servlet元素中的相同,<url-pattern>则是用来指定访问该Servlet的虚拟路径,该路径以(/)开头,代表当前Web应用的根目录。
8、启动Tomcat服务器,使用浏览器访问
使用浏览器访问localhost:8080/chapter04/HelloWorldServlet

在这里插入图片描述
至此第一个Servlet程序实现了。

Servlet生命周期

在这里插入图片描述
图中描述了Servlet的生命周期。按照功能不同,大致可以分为三个阶段。
1、初始化阶段
当客户端向Servlet容器发出http请求要求访问Servlet时,Servlet容器首先会解析请求,检查内存中是否已经有了该Servlet容器,如果有直接使用该Servlet对象,如果没有就创建Servlet实例对象,然后通过调用init()方法实现Servlet的初始化工作。需要注意的是,在Servlet整个生命周期中,他的init()方法只被调用一次。
2、运行阶段
这是Servlet生命周期中最重要的阶段,在这个阶段,Servlet容器会为这个请求创建代表Http请求的ServletRequest对象和代表Http响应的ServletResponce对象,然后将他们作为参数传递给service()方法。在service()方法中,可以通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息。在Servlet整个生命周期中,对于Servlet的每次访问请求,Servlet容器都会调用一次Servlet的service()方法,并且创建新的ServletRequest和ServletResponce对象,也就是说,service()方法在整个生命周期中被多次调用。
3、销毁阶段
当服务器关闭或web应用被移出容器时,Serlet随着Web应用的销毁而销毁。在销毁Servlet之前,Servlet容器会调用Servlet的destroy()方法,以便让Servlet对象释放占用的资源。在整个生命周期中destroy()方法也仅会调用一次。,Servlet对象一旦创建就会驻留在内存中等待客户端的访问,直到服务器关闭,或Web应用被移出容器。
代码演示

package cn.itcast.firstapp.servlet;

import javax.servlet.*;
public class TestServlet01 extends GenericServlet {
	private static final long serialVersionUID = 1L;
    public void init(ServletConfig config)throws ServletException{
    	System.out.println("init methed is called");
    }
    public void service(ServletRequest request,ServletResponse response)throws ServletException{
    	System.out.println("Hello World");
    }
    public void destroy(){
    	System.out.println("destroy methed is called");
    }
}

该Servlet在init被调用时向命令行输出一句init methed is called,在service被调用时向命令行输出一句Hello World,在destroy()被调用时输出destroy methed is called
首次访问Servlet
在这里插入图片描述
表明第一次访问Servlet,Servlet容器调用了init()和service()
之后多次访问Servlet
在这里插入图片描述
之后再次访问,只会调用service()。
在管理平台将servlet移出
在这里插入图片描述

自动加载Servlet程序

有时候我们需要有些Servlet程序随Tomcat启动时启动。例如在启动服务器时,对数据库初始化。这时需要配置web.xml中的<load-on-startup>元素。
<load-on-startup>元素是<servlet>元素的子元素,用于指定Servlet被加载的时机和顺序。在<load-on-startup>元素中,其值必须是一个整数。如果这个值是一个负数或没有设置,那么Servlet会在用户首次请求的时候加载;如果这个值是正整数或0,Servlet容器将在web应用启动时加载并初始化该Servlet并且<load-on-startup>元素的值越小优先级越高。

Servlet高级应用

由于大多数Web应用都是通过HTTP和客户端进行交互的,因此,在Servlet接口中,提供了一个抽象类javax.servlet.http.HttpServlet的子类,专门用于创建应用于HTTP的Servlet应用。

HttpServlet主要有两大功能,
1、根据用户请求方式的不同,定义相应的doXXX()方法处理用户请求。例如与GET请求方式对应的doGet()方法,与POST请求方式对应的doPost()方法。
2、通过service()方法将HTTP请求和响应分别转为HttpServletRequest和HttpServletResponce类型的对象。
在定义的类继承HttpServlet后,只需要根据请求方式修改对应的doXxx方法即可,而不需要重写service()方法。

使用Eclipse工具开发Servlet

之前为了理解Servlet开发过程,我们没有借助开发工具实现了Servlet,其过程相当繁琐。但是实际开发中,通常会使用Eclipse工具完成Servlet的开发,Eclipse不仅会自动编译Servlet还会自动创建web.xml文件,完成Servlet虚拟机路径的映射。
1、新建Web工程
选择工具栏File->New->Other选项
在这里插入图片描述
选择Dynamic Web Project,单击Next
在这里插入图片描述
填写项目名,选择运行环境,单击next
在这里插入图片描述
ecplise会自动将src目录下的文件编译成class文件存放到class目录中,需要注意的是,src目录和class目录都是可以更改的。这里直接使用默认配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2、创建Servlet程序
右击src文件,选择New->Other选项,进入创建Servlet的界面。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Servlet代码
在这里插入图片描述
web.xml
在这里插入图片描述
可以看到这里没有进行虚拟机映射的配置,只是因为,ecplise在servlet代码中进行了配置,不在需要更改web.xml
在这里插入图片描述
部署和访问Servlet
打开servers选项卡,选中应用的Tomcat服务器,右击并选择Add and Remove选项
在这里插入图片描述
选中想部署的Web工程添加到服务器
在这里插入图片描述
启动Esplice中的Tomcat服务器

使用浏览器访问servlet
在这里插入图片描述

Servlet的多重映射

Servlet的多重映射是指同一个Servlet可以被映射成多个虚拟路径
web.xml
通过修改web.xml映射,只需要额外添加<servlet-mapping>子元素即可
在这里插入图片描述

  <servlet-name>Ex01</servlet-name>
      <servlet-class>cn.itcast.ex1.servlet.Ex01</servlet-class>
    </servlet>
    <!-- 映射成/Ex01 -->
    <servlet-mapping>
      <servlet-name>Ex01</servlet-name>
      <url-pattern>/Ex01</url-pattern>
    </servlet-mapping>
    <!-- 映射成/myapp -->
    <servlet-mapping>
      <servlet-name>Ex01</servlet-name>
      <url-pattern>/myapp</url-pattern>
    </servlet-mapping>

在这里插入图片描述
或者在servlet-name元素下新增一个url-pattern元素。
在这里插入图片描述

<servlet>
      <servlet-name>Ex01</servlet-name>
      <servlet-class>cn.itcast.ex1.servlet.Ex01</servlet-class>
    </servlet>
    <!-- 映射成/Ex01 -->
    <servlet-mapping>
      <servlet-name>Ex01</servlet-name>
      <url-pattern>/Ex01</url-pattern>
      <url-pattern>/eex01</url-pattern>
    </servlet-mapping>

在这里插入图片描述

@WebServlet
要想启用注解需要检查在web.xml最外层的<web-app>中有没有metadata-complete属性,该属性若为true表示完全依赖描述文件,不再使用注解,该属性的默认值是flase,若有且值为true需要修改掉。
多重映射只需要将输入参数变为{}中间用‘,’隔开。

@WebServlet({"/Ex01","/ex01"})

Servlet映射路径中使用通配符

有时候我们希望某个目录下的所有路径都可以访问同一个Servlet,这样我们可以使用统配符,具体有两种格式:
1、格式*.拓展名,例如*.do匹配以.do结尾的所有url地址。
2、格式/*,例如/abc/*匹配以/abc/开始的所有url地址
需要注意的是,这两种通配符格式不能混合使用,例如,/abc*.do就是不合法的映射路径,另外,如果请求的url地址能够匹配多个虚拟路径,那么Tomcat将采取最具体匹配原则查找与请求url最接近的虚拟映射路径。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

默认Servlet

如果某个Servlet的映射路径仅仅是一个正斜线,那么这个Servlet就是当前Web应用的默认Servlet。Servlet服务器在接收到访问请求时,如果在web.xml文件中找不到匹配的<servlet-mapping>元素的url,就会将访问请求交给默认Servlet处理,也就是说,默认Servlet用于处理其他Servlet不处理的访问请求。
在这里插入图片描述

在这里插入图片描述
也可以在conf/web.xml中配置全局默认Servlet
在这里插入图片描述

ServletConfig接口

在运行Servlet运行期间,经常需要一些辅助信息,例如,文件使用的编码,这些信息可以在web.xml文件中使用一个或多个<init-pararm>进行配置。当Tomcat初始化一个Servlet时,会将该Servlet的配置信息封装到一个ServletConfig对象中,通过调用init方法将ServletConfig对象传递给Servlet。ServletConfig定义了一系列获取配置信息的方法,

String getInitParameter(String name)初始化参数名返回对应的初始化参数值
Enumeration getInitParameterNames()返回一个Enumeration对象,其中包括所有的初始化参数名
ServletContext getServletContext()返回一个代表当前Web应用的ServletContext对象
String getServletName()返回Servlet的名字,即web.xml中<servlet-name>元素的值

1、在web.xml文件中为Servlet配置一些参数信息
在这里插入图片描述

<servlet>
      <servlet-name>Ex01</servlet-name>
      <servlet-class>cn.itcast.ex1.servlet.Ex01</servlet-class>
      <init-param>
      	<param-name>encoding</param-name>
      	<param-value>UTF-8</param-value>
      </init-param>
    </servlet>
    <!-- 映射成/Ex01 -->
    <servlet-mapping>
      <servlet-name>Ex01</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>

2、编写Ex01

package cn.itcast.ex1.servlet;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Ex01 extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out=response.getWriter();
		ServletConfig config=this.getServletConfig();
		String param=config.getInitParameter("encoding");
		out.println("encoding="+param);
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

在这里插入图片描述

ServletContext接口

1、获取Web应用程序的初始化参数
在web.xml文件中,不仅可以配置Servlet的初始化信息,还可以配置整个web应用的初始化信息。Web应用初始化参数的配置方法

  <context-param>
  	<param-name>companyName</param-name>
  	<param-value>itcast</param-value>
  </context-param>
  <context-param>
  	<param-name>address</param-name>
  	<param-value>beijing</param-value>
  </context-param>

<context-param>元素位于根元素<web-app>中,它的子元素<param-name>和<param-value>分别用来指定参数的名字和参数值。
2、编写Ex01

package cn.itcast.ex1.servlet;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Ex01 extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		ServletContext context=this.getServletContext();
		Enumeration<String>paramNames=context.getInitParameterNames();
		//out.print("all the paramName and paramValue are following:");
		while(paramNames.hasMoreElements()){
			String name=paramNames.nextElement();
			String value=context.getInitParameter(name);
			out.println(name+":"+value);
			out.println("<br>");
		}
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

在这里插入图片描述

实现多个Servlet对象共享数据

由于一个web应用下的所有Servlet共享一个ServletContext对象,因此Servlet-Context对象的域属性可以被该Web应用中的所有Servlet访问。再ServletContext接口中定义了分别用于增加、删除、设置ServletContext域属性的4个方法

Enumeration getAttributeName()返回一个Enumeration对象,该对象包含存放再ServletContext的所有属性域
Object getAttibute(String name)根据参数指定的属性名返回一个与之匹配的属性域
void removeAttibute(String name)根据参数指定的域属性名,从ServletContext中删除匹配的域属性
void setAttibute(String name.Object obj)设置ServletContext的域属性,其中name是域属性名,obj是域属性值

save.java

package cn.itcast.ex1.servlet;

import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet("/save")
public class save extends HttpServlet {
	private static final long serialVersionUID = 1L;
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext context=this.getServletContext();
		context.setAttribute("data", "this servlet save data");		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

在这里插入图片描述
在这里插入图片描述
getdata.class获得了sava.class存储的字符串。

读取Web应用下的资源文件

Set getResourcePaths(String path)返回一个Set集合,集合中包括资源目录中子目录和文件的路径名称。参数path必须以正斜线开始,指定匹配资源的部分路径
String getRealPath(String path)返回资源文件在服务器文件系统上的真实路径。参数path代表资源文件的虚拟路径,它应该以正斜线开始,表示当前Web应用的根目录,如果Servlet容器不能将虚拟路径转换为文件系统的真实路径,则返回null
URL getResource(String path)返回映射到某个资源文件的URL对象。参数path必须以正斜线开始,“/”表示当前Web应用的根目录
InputStream getResourceAsStream(String path)返回映射到某个资源文件的InputStream输入流对象。参数path传递规则和getResource()方法完全一致

1、新建一个资源文件
右击src目录,选择New->Other选项,进入创建页面
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
2、编写读取itcast.properties资源文件的Ex02

package cn.itcast.ex1.servlet;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet("/Ex02")
public class Ex02 extends HttpServlet {
	private static final long serialVersionUID = 1L;


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		ServletContext context=this.getServletContext();
		PrintWriter out=response.getWriter();
		InputStream in=context.getResourceAsStream("/WEB-INF/classes/itcast.properties");
		Properties pros=new Properties();
		pros.load(in);
		out.println("Company="+pros.getProperty("Company")+"<br>");
		out.println("Company="+pros.getProperty("Address")+"<br>");
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

在这里插入图片描述
3、有时候我们需要调用资源绝对路径
我们可以通过getRealPath(String path)方法
编写Ex03
在这里插入图片描述

package cn.itcast.ex1.servlet;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet("/Ex03")
public class Ex03 extends HttpServlet {
	private static final long serialVersionUID = 1L;


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		ServletContext context=this.getServletContext();
		PrintWriter out=response.getWriter();
		String path=context.getRealPath("/WEB-INF/classes/itcast.properties");
		InputStream in=new FileInputStream(path);
		Properties pros=new Properties();
		pros.load(in);
		out.println("Company="+pros.getProperty("Company")+"<br>");
		out.println("Company="+pros.getProperty("Address")+"<br>");
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值