Srevlet的简介和其相关的功能
Sun公司在其API中提供了一个servlet接口,用户若想要开发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
1.编写一个Java类,实现servlet接口。
2.把开发好的Java类部署到web服务器中。
Servlet在web应用中的位置
Servlet的运行过程
Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
1.Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
2.装载并创建该Servlet的一个实例对象。
3.调用Servlet实例对象的init()方法。
4.创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
5.WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
Servlet的生命周期
1.init()方法:服务器调用该方法初始化Servlet
2.service()方法:初始化完毕,服务器调用该方法响应客户的请求
3.destroy()方法:服务器调用该方法消灭servlet对象
其中,init()方法只在Servlet第一次被请求加载的时候被调用一次,当有客户再请求Servlet服务时,Web服务器将启动一个新的线程,在该线程中,调用service方法响应客户的请求
package cn.itcast.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Servlet实例被创建后,使用init方法初始化
* Servlet什么时候被创建
* 不是服务器一启动时,实例被创建.第一次启动的时候才会被创建
* inint
* inint方法只能调用一次
* servlet什么时候被销毁呢
*
* @author liugang
*
*/
public class ServletDemo02 implements Servlet {
@Override
public void init(ServletConfig arg0) throws ServletException {
System.out.println("init....");
}
/**
* 从客户端每发送一次请求,就调用一次service方法
*/
@Override
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
System.out.println("service....");
}
/**
* servlet什么时候被销毁呢
* 服务器关闭的时候,或者当项目被移除的时候
* 只销毁一次
*/
@Override
public void destroy() {
System.out.println("destroy....");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
}
Servlet接口的实现类
Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。
1.HttpServlet指能够处理HTTP请求的servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。
2.HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。
3.http是Generic和httpServlet的子类
两个service底层调用了doGet和dopost
配置Servlet的自动加载
如果在元素中配置了一个元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。
Web开发中的路径问题分析
web开发中的路径问题
- 相对路径:
一个文件相对于另一个文件的位置问题
不能一/开头
写法 在同一级目录./demo demo
在上一级目录 …/demo
访问1.html 在加载到服务器中的时候,默认WebRoot是消失的 -
故访问为http://www.localhost:8080/day_09/1.html
访问demo06时因为是绝对路径
-
则访问为http://www.localhost:8080/day_09/demo06
访问2.html 在加载到服务器中的时候,默认WebRoot是消失的
-
则访问为 http://www.localhost:8080/day_09/html/2.html 若想从2.html跳到demo06故上一级目录.故../demo06
- 绝对路径:
以/开头的
访问demo06: -
http://www.localhost:8080/day_09/demo06
-
/day_09/demo06
- 客户端相对路径
- / day_09/demo06 需要写项目名 由网页端写到后台进行交互的
- 服务器端相对路径
- / day_09 不需要写项目名,后台程序相互调用的时候,比如转化和重定向的时候
public class ServletDemo06 extends HttpServlet {
private static final long serialVersionUID = 1L;
//init()自动加载的功能的时候默认是调用哪些使用时间比较长的.比如数据库的初始化加载
public void init() throws ServletException {
System.out.println("init...........");
}
//当浏览器什么方式都没有写的时候。默认使用提交get方式进行提交
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获得输出流.向页面中添加
response.getWriter().write("hello world");
System.out.println("doGet");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
System.out.println("doPost.....");
}
}
<h1>2.html的相对路径</h1>
<a href="../demo06">demo06</a>
<h1>2.html的绝对路径</h1>
<a href="http://www.localhost:8080/day_09/demo06">demo06</a>
<a href="/day_09/demo06">demo06</a>
init方法中的ServletConfig对象
1.在Servlet的配置文件中,可以使用一个或多个标签为servlet配置一些初始化参数。
2.当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
<!-- 配置全局初始化化参数 -->
<context-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>
ServletConfig config = this.getServletConfig();
//获取config对对象的名称
System.out.println("servlet的名称:"+ config.getServletName());
//获取初始化的参数
String name = config.getInitParameter("username");
String pwd = config.getInitParameter("password");
System.out.println(name +":" + pwd);
@SuppressWarnings("unchecked")
//获取初始化参数们
Enumeration<String> e = config.getInitParameterNames();
while (e.hasMoreElements()) {
String names = e.nextElement();
String value = config.getInitParameter(names);
System.out.println(names + ":" + value);
}
Web应用对象:ServletContext
1.WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用
2.ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象
3.由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象
4.获取WEB应用的全局初始化参数
5.通过ServletContext对象实现数据共享
6.利用ServletContext对象读取资源文件
//获取WEB应用的全局初始化参数
public class ServletContextDemo01 extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取ServletContext对象
ServletContext context = getServletContext();
//获取ServletContext对象的名称
String names = context.getInitParameter("encoding");
System.out.println("编码:"+names);
//获取初始化参数们
@SuppressWarnings("unchecked")
Enumeration<String> e = context.getInitParameterNames();
//循环遍历
while (e.hasMoreElements()) {
//判断是否有没有下一个元素
String str = e.nextElement();
String value = context.getInitParameter(str);
System.out.println(str + ":" +value);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//通过ServletContext对象实现数据共享
public class CountServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void init() throws ServletException {
//获取ServletContext域对象,并为其赋值
getServletContext().setAttribute("count", 0);
}
/**
* 每一次访问,都会执行该方法
* 拿出count对象.值自增.存到域对象中
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获得context对象
ServletContext context = getServletContext();
//获取count的值
Integer count = (Integer) context.getAttribute("count");
//存入到域对象中
context.setAttribute("count", ++count);
//向页面中去输入内容
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<h1>大爷,欢迎下次再来哟!!!</h1>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class ShowServlet extends HttpServlet {
//显示网址被访问的次数,并存在客户端
private static final long serialVersionUID = 1L;
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("<h1>该网址一共被访问了"+count+"次</h1>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
利用ServletContext对象读取资源文件
package cn.itcast.servletcontext;
/**
* ServletConfig取资源文件
*
*/
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ReadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
read2();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
//使用ServletContext域对象
public void read2() throws IOException{
//ServletContext读取文件,此时是服务器端的绝对路径读取
InputStream in = getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
//打印方式
print(in);
}
//传统方法显然无法读取到文件的路径
public void read1() throws IOException{
//获取对象
String path = getServletContext().getRealPath("/WEB-INF/classes/db.properties");
//获取输入流的
InputStream in = new FileInputStream(path);
print(in);
}
//把数据打印到控制台上
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);
}
}
response: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 liugang
*
*/
public class ServletDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
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", "/day_09/1.html");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}