主要目录
Servlet技术
1、Servlet概述
1.1 什么是servlet?
运行在web服务器的一个java小程序,通俗来讲,它就是一个java类,在使用servlet时,需要导入javax.servlet下的jar包。比如:tomcat服务器提供了servlet的servlet-api.jar包,所以在开发时用tomcat服务器就不需要再导入servlet的jar包。
servlet是一个资源,是用来被用户访问的资源,同时也是一个动态资源。
1.2 Servlet的作用
它是基于Http协议的,主要是用来接收客户端发送的请求,处理请求,把数据响应给客户端,
2、Servlet的入门
2.1 Servlet的接口和实现类
Servlet是一个接口,在javax.servlet包下面。
2.1.1 五个方法
(1)destory():执行这个方法,销毁了servlet对象
(2) init(ServletConfig config): 在web服务器创建servlet对象以后,执行这个初始化方法
(3)service(ServletRequest req, ServletResponse res): 服务方法,用来接收客户端发送的请求,并且响应数据到客户端。
(4)getServletConfig()
(5)getServletInfo(): servlet的信息,比如作者、版本和版权,开发中不用
2.1.2 GenericServlet
是一个类,实现了Servlet接口
HttpServlet,是一个类,实现了Servlet接口,同时继承了GenerciServlet
2.2 创建servlet三种方式
直接实现Servlet接口
继承GenericServlet类
继承HttpServlet类
一般在开发中,创建servlet,通常去继承这个HttpServlet
比如:class MyServlet extends HttpServlet(重写所需要的方法)
2.3 servlet的继承关系
HttpServlet继承GenericServlet
GenericServlet实现Servlet接口
3、实现第一个Servlet程序
(1)自己动手创建Servlet,通过Dos命令窗口编译Servlet,把编译好的class文件部署到tomcat服务器运行。
(2)通过Eclipse创建Servlet,部署到tomcat服务器,然后就可以访问所需要的Servlet。
步骤:
创建HelloWordServlet,继承GenericServlt。
重写父类GenerciServlet的service方法。
在服务方法里面,处理客户端的请求后,把数据响应给客户端。
如果没有对应的包,则要先导入jar包:先拷贝对应的jar包,放到WebContent下面的WEB-INF下面的lib文件夹下面。jar的图标就变成小奶瓶。
访问Servlet,提供servlet的访问路径:
例如:
/**
*自己创建Servlet, 继承GenericServlet
*重写它的服务方法:service
*
**/
public class HelloWordService extends GenericServlet{
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException{
//处理客户端发送的请求,并且把数据响应给客户端
System.out.println("接收了客户端的请求------------");
//把数据响应给客户端 ,与浏览器绑定的输出流,作用向浏览器输出数据
PrintWriter pw = response.getWriter();
pw.print("Hello World");
}
}
在xml文件中写入
<!--配置/hello,访问的servlet-->
<servlet>
<servlet-name>helloWorld</servlet-name>
<servlet-class>cn.itcast.firstmyapp.servlet.HelloWordServlet</servlet-class>
</servlet>
<!--配置浏览器访问servlet的路径-->
<servlet-mapping>
<servlet-name>helloWorld</servlet-name>
<url-pattern>hello</url-pattern>
</servlet-mapping>
访问:
http://localhost:8080/webFirst/hello
就找到对应的HelloWorldServlet,把数据响应给浏览器
4、Servlet的生命周期:
4.1 生命周期(自然界人从出生到最终走向西方极乐世界)
从servlet对象被创建,经过使用servlet对象被销毁,整个过程就是servlet的生命周期。
4.2 生命周期相关的三个方法
(1)init(ServletConfig config) 初始化方法: 首次访问这个Servlet, Servlet对象会被创建,执行初始化方法。
(2)service(ServletRequest req, ServletResponse res) 服务方法:每次访问servlet时,服务方法都会被执行。
(3)destroy()销毁方法:在服务器正常关闭时,会执行销毁方法,执行一次。
4.3 例子
public class LifeServlet extends GenericServlet{
//初始化方法
@Override
public void init(ServletConfig config) throws ServletException{
System.out.println("首次访问LifeServlet时,会执行这个初始化方法。。。");
}
//servlet的服务方法
@Override
public void service (ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException
{
System.out.println("每次访问LifeServlet时,都会执行这个服务方法。。。");
}
//销毁方法
@Override
public void destroy(){
System.out.println("在服务器关闭时,会执行销毁方法。。。");
}
}
在web.xml文件上面配置访问路径
<servlet>
<servlet-name>lifeServlet</servlet-name>
<servlet-class>cn.itcast.firstmyapp.servlet.LifeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>lifeServlet</servlet-name>
<url-pattern>/life</url-pattern>
</servlet-mapping>
5、Servlet应用~HttpServlet
在开发中,通常浏览器访问web服务器端的资源,是带有协议的访问,比如说http协议、https协议等,所以在创建servlet时,需要使用带有协议的servlet,那么程序员在创建servlet时,通常用继承HttpServlet的方式来实现。
5.1 查看HttpServlet的源码
在HttpServlet里面重写service方法时,一般情况下不会重写service方法,因为在service方法里面,最终调用doGet或者doPost方法,所以说在重写服务方法时,直接重写doGet和doPost方法。
在客户端发送get请求,在服务器端就用doGet方法接收,
在客户端发送Post请求,在服务器端就用doPost方法接收。
过程:
浏览器发送的是get请求到服务端,服务端中的
service{
1.获取请求方式 String method=-----
2.根据请求方式判断执行什么方法
doGet(request,response);
}
浏览器发送的是post请求到服务端,服务端中的
service{
1.获取请求方式 String method=-----
2.判断请求方式是什么,执行对应的方法
doGet(request,response);
}
举个例子
先创建表单页面,主要内容如下:
<form action="固定的url地址" method="get">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="psw"/><br/>
<input type="submit" value="get请求方式"/>
</form>
<form action="固定的url地址" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="psw"/><br/>
<input type="submit" value="post请求方式"/>
</form>
然后创建servlet文件
主要内容如下
public class MyHttpServlet extends HttpServlet{
/**
*接收客户端发送的get请求
*/
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
String method = req.getMethod();
System.out.println(method);
System.out.println("这是发送的get请求");
}
/**
*接收客户端发送的post请求
*/
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
String method = req.getMethod();
System.out.println(method);
System.out.println("这是发送的post请求");
}
}
再写对应的.xml文件的路径
<servlet>
<servlet-name>java文件名</servlet-name>
<servlet-class>src包名+该java文件名 </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>java文件名</servlet-name>
<url-pattern>java文件名</url-pattern>
</servlet-mapping>
5.2 在开发中,注意的细节
1、在使用对象时,使用带有协议的请求和响应对象HttpServletRequest和HttpServletResponse
2、在开发时,继承HttpServlet是,直接重写doGet和doPost方法,而不是重写service方法
访问servlet的具体执行过程
<servlet>
<servlet-name>helloWorld</servlet-name>
<servlet-class>cn.itcast.firstmyapp.servlet.HelloWordServlet</servlet-class>
</servlet>
<!--配置浏览器访问servlet的路径-->
<servlet-mapping>
<servlet-name>helloWorld</servlet-name>
<url-pattern>hello</url-pattern>
</servlet-mapping>
在浏览器的地址栏:
http://localhost:8080 访问tomcat服务器
http://localhost:8080/webFirst/hello
上面的路径在访问时,会去找webFirst项目下的web.xml配置文件
首先访问 /hello
然后跳到helloWorld
再从helloworld跳到cn.itcast.firstmyapp.servlet.HelloWordServlet
6、在Eclipse开发工具中创建servlet
通过开发工具创建servlet有两种方式:
6.1 第一种方式
先创建一个普通的java类,需要去实现Servlet接口,或者继承对应的HttpServlet(GenericServlet)类,普通的java类就具有了service功能,所以需要手动在web.xml配置文件中添加访问servlet的路径信息。
6.2 第二种方式
直接创建servlet,会自动在web.xml文件中添加访问servlet的路径信息。
步骤:
(1)新建web项目:
比如:创建一个web项目名称:chapter01
(2)创建一个servlet程序
比如:先创建一个包,名称cn.itcast.servlet, servlet的名称:TestServlet01
(3)部署和访问servlet:
通过开发工具部署web项目,如chapter01,访问下面的servlet资源:
访问的地址:http://localhost:8080/chapter01/testServlet01
注意:一般情况下,为了简化开发,会在doPost方法里面调用doGet方法。
具体见以下代码:
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
int sum=0;
for(int i=0;i<=100;i++)
{
sum=sum+i;
}
System.out.println(sum);
}
/**
*接收客户端发送的post请求
*/
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
this.doGet(request, response);
}
7、实现Servlet的虚拟路径映射
7.1 Servlet的多重映射:一个Servlet,可以对应多个访问路径。
比如:一个servlet对应的访问路径:/test02 或者 /test03
<servlet-mapping>
<servlet-name>TestServlet01</servlet-name>
<url-pattern>/test02</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TestServlet01</servlet-name>
<url-pattern>/test03</url-pattern>
</servlet-mapping>
7.2 Servlet的映射路径可以使用通配符
servlet的映射路径有三种方式:
完全目录匹配: 比如 /hello
目录匹配: 比如 /abc/* 或者 /*
扩展名匹配: *.do, .action 注意:/.do这种写法是错误的
优先级:完全目录匹配 > 目录匹配 > 扩展名匹配
7.3 缺省Servlet
什么是缺省Servlet:它的映射路径"/", 代表这是一个缺省的servlet.
缺省的servlet作用:处理请求的资源找不到的问题 (404 代表请求的资源找不到)
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
response.setContentType("text/html;charset=utf-8");
response.getWriter().print("缺省的servlet处理请求资源找不到的问题,在浏览器地址栏输入的路径写错了-----");
}
/**
*接收客户端发送的post请求
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
this.doGet(request, response);
}
8、ServletConfig接口
8.1 什么是ServletConfig
它是servlet的配置对象,作用就是获取与servlet的初始化参数。
它的子类是GenericServlet和HttpServlet
它被实例化通过web服务器实现的。
8.2 ServletConfig常用的方法
(1)获取servlet的初始化参数:getInitParameter(String name) //根据encoding获取utf-8
(2)获取servlet初始化参数的名称:getInitParameterNames() //获取encoding和username等名称
(3)得到servletContext对象:getServletContext()
(4)获取servlet的名称:getServletName() //对应web.xml里面TestServlet02
先在web.xml配置文件里进行servlet初始化参数的配置
<!--servlet初始化参数的配置-->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>TestServlet02</param-name>
<param-value>test02</param-value>
</init-param>
然后创建对应的servlet文件
主要内容如下:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//1.得到servletConfig对象
ServletConfig config = this.getServletConfig();
//2.获取servlet的名称,对应web.xml里面<servlet-name> TestServlet02</servlet-name>
String servletName = config.getServletName();
System.out.println("servlet的名称:"+servletName);
//3.获取servlet的初始化参数
String value=config.getInitParameter("encoding");
System.out.println("初始化参数的值:"+ value);
//4.获取servlet的初始化参数的名称
Enumeration<String> er=config.getInitParameterNames();
while(er.hasMoreElements()){
//获取初始化参数的名称
String name = er.nextElement();
//根据初始化参数的名称,获取对应的值
String value1=config.getInitParameter(name);
System.out.print("初始化参数的名称:"+name);
System.out.println("该名称对应的值:"+value1);
}
}
/**
*接收客户端发送的post请求
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
this.doGet(request, response);
}
9、ServletContext接口
9.1 ServletContext接口是什么?
ServletContext对象是在web服务器启动时就创建了,是web服务器创建的servletContext对象。
每一个web项目只有一个ServletContext对象。
ServletContext对象的作用:获取web应用程序的初始化参数,在web应用程序获取web项目下的资源文件。
得到ServletContext对象:
(1)通过ServletConfig对象:config.getServletContext()
(2)直接得到: getServletContext();
9.2 获取web应用程序的初始化参数(web应用程序就是web项目)
(1)获取全局初始化参数:getInitParameter(String name)
(2)获取全局初始化参数的名称:getInitParameterNames()
在web.xml配置文件中如下进行配置
<!--配置全局的初始化参数-->
<context-param>
<param-name>AAA </param-name>
<param-value>aaa</param-value>
<context-param>
<context-param>
<param-name>BBB</param-name>
<param-value>bbb</param-value>
<context-param>
然后创建java文件,内容如下
public class TestServlet03 extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//1.得到ServletContext对象
ServletContext context = this.getServletContext();
//2.获取全局的初始化参数
Enumeration<String> er=context.getInitParameterNames();
while(er.hasMoreElements()){
//获取初始化参数的名称
String name = er.nextElement();
//根据初始化参数的名称,获取对应的值
String value=context.getInitParameter(name);
System.out.print("初始化参数的名称:"+name);
System.out.println("该名称对应的值:"+value1);
}
}
/**
*接收客户端发送的post请求
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
this.doGet(request, response);
}
}
9.3 实现多个servlet对象之间共享数据
因为一个Web项目只有一个ServletContext对象。
ServletContext对象就是域对象:域对象在一定范围内能存值和取值
域对象相关的方法:
存值:void setAttribute(String key,Object obj);
取值:Object obj = getAttribute(key);
删除值:void removeAttribute(key);
比如:在TestServlet04里面存值,在TestServlet05里面获取值
public class TestServlet04 extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//1.得到ServletContext对象
ServletContext context = this.getServletContext();
//2.存值
context.setAttribute("key","servlet04里面存的值唯一")
}
/**
*接收客户端发送的post请求
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
this.doGet(request, response);
}
}
public class TestServlet05 extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//1.得到ServletContext对象
ServletContext context = this.getServletContext();
//2.从ServletContext取值
Object obj = context.getAttribute("key");
String value = obj.toString();
response.setContentType("text/html;charset=utf-8");
response.getWriter().print(value);
}
/**
*接收客户端发送的post请求
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
this.doGet(request, response);
}
}
9.4 获取web下面的资源文件
通过ServletContext对象能够获取Web项目下面文件的字节输入流,或者文件的绝对路径。
路径问题:
(1)普通java项目:直接使用jdk编译java文件,所以说文件的路径是相对于工作空间。
public class Demo{
public static void main(String[] args)
{
//1.Property对象加载properties文件
Properties por = new Properties();
InputStream inStream = new FileInputStream("src/config.properties");
por.load(inStream);
String value = por.getProperty("key");
System.out.println(value);
}
}
(2)web项目:运行在tomcat服务器上面的,所以说文件的路径是相对于tomcat服务器。
服务器端是没有src这个目录,写路径不能写src,必须相对于tomcat服务器端的路径。
public class TestServlet06 extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
ServletContext context = this.getServletContext();
String path = context.getRealPath("/WEB-INF/classes/config.properties")
System.out.println(path);
}
/**
*接收客户端发送的post请求
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
this.doGet(request, response);
}
}
(3)获取文件的自己输入流:路径是相对于tomcat服务器的路径
public class TestServlet07 extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//获取文件的字节输入流
ServletContext context = this.getServletContext();
String path="/WEB-INF/classes/config.properties";
InputStream in = context.getResourceAsStream(path);
Properties pro = new Properties();
pro.load(in);
//获取配置文件的值
String v1 = pro.getProperty("Company");
String v2 = pro.getProperty("Address");
response.getWriter().print("company name" + v1 + "company address:" + v2);
}
/**
*接收客户端发送的post请求
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
this.doGet(request, response);
}
}
获取文件的绝对路径:路径是相对于服务器端的路径
String realPath = getRealPath(path);
比如:
public class TestServlet08 extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//获取文件的字节输入流
ServletContext context = this.getServletContext();
//获取文件的绝对路径
String path="/WEB-INF/classes/config.properties";
//调用getRealPath
String realPath = context.getRealPath(path);
System.out.println(realPath);
InputStream in = new FileInputStream(realPath);
Properties pro = new Properties();
pro.load(in);
//获取配置文件的值
String v1 = pro.getProperty("Company");
String v2 = pro.getProperty("Address");
response.getWriter().print("company name" + v1 + "company address:" + v2);
}
/**
*接收客户端发送的post请求
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
this.doGet(request, response);
}
}