JAVA EE-SERVLET
未来将属于两种人:思想的人和劳动的人。实际上这两种人是一种人,因为思想也是劳动。 —— 雨果
什么是servlet?
- Servlet => Server Applet => 服务器端的小程序(类)
- Servlet技术中的三大组件之一
- Servlet 动态资源
- FIlter 过滤器
- Listener 监听器 - Servlet就是一个接口. 接口中定义了一些方法. 这些方法分为两部分。一部分是生命周期方法。 一部分没啥用。
实现servlet接口的方式?
*实现接口
*继承GenericServlet
*继承HTTPServlet
创建Servlet类–实现Servlet类
/**
* 实现Servlet接口,重写5个方法
* 在web.xml进行配置
* @author Administrator
*
*/
public class ServletDemo1 implements Servlet{
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.getWriter().write("hello demo1...");
}
public void init(ServletConfig config) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
Servlet的生命周期
*Servlet对象创建时机? 第一次访问servlet时.
*Servlet对象创建的特点? 通过只在第一次访问时调用init的现象, 一个servlet实例在服务器中只有一个.
*当请求访问servlet时,service方法会处理请求.
*当服务器将要关闭,服务器会销毁服务器中的Servlet对象,在真正销毁之前调用destory方法.
/**
* 生命周期
* @author Administrator
*
*/
public class ServletDemo2 implements Servlet {
/**
* Servlet实例被创建后,调用init方法进行初始化
* Servlet什么时候被创建呢?
* * 不是服务器一启动时,实例被创建,第一次访问的时候,实例才被创建。
* init方法调用几次呢?
* * 只被调用一次。
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("init...");
}
/**
* service调用几次呢?
* * 有一次请求,调用一次service方法
*/
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
System.out.println("service...");
}
/**
* Servlet实例什么时候被销毁呢?
* * 服务器关闭,手动移除。
* destroy调用几次呢?
* * 一次
*/
public void destroy() {
System.out.println("destroy...");
}
public ServletConfig getServletConfig() {
return null;
}
public String getServletInfo() {
return null;
}
}
通过继承HttpServlet创建Servlet
/**
* 配置servlet启动时加载
* @author Administrator
*
*/
public class ServletDemo5 extends HttpServlet {
/**
* 默认的情况下第一次访问的时候init被调用。
*
*/
public void init() throws ServletException {
System.out.println("init...");
// 初始化数据库的链接
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 写的内容
// 获取表单输入的内容
// 自己逻辑,通过名称查询数据库,把张三的姓名查到了
// 把张三返回浏览器
System.out.println("doGet...");
// 向页面输出内容
response.getWriter().write("hello demo5...");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
关于ServletConfig对象
/**
* ServletConfig对象
* @author Administrator
*
*/
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<String> 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);
}
}
利用response完成重定向
/**
* 和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);
}
}
利用request完成刷新操作
/**
* 页面定时跳转
* @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);
}
}
一个小的Demo,获得某网站被访问的次数
CountServlet
/**
* 统计网站的访问次数
* @author Administrator
*
*/
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("<h3>大爷,欢迎再来哦!!</h3>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
ShowServlet
/**
* 显示网站的访问次数
* @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("<h3>该网站一共被访问了"+count+"次</h3>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
关于ServletContext对象
ServletContext 对象可以看做是web项目的法人.
我们一个WEB项目 有 且只有一个ServletContext .
创建: 随着项目的启动而创建
销毁:随着项目的关闭而销毁
获得:通过ServletConfig对象的 getServletContext方法获得.
功能:
1.可以获得项目参数
2.是Servlet技术中的3个域对象之一
3.获得项目内的资源
//———————————————————————————–
功能详解:
1>获得项目参数
String getInitParameter(String name)
Enumeration getInitParameterNames()
//—————————————————–
2>域功能
Servlet三大域
application
request
session
jsp技术中的域
page
域用于服务器组件之间的通讯(例如:两个servlet之间通讯).
域的实质就是map.
application域 就是在整个项目内共享数据的map.
*操作域的方法:
void setAttribute(String key,Object value);
Object getAttribute(String key);
Enumeration<String> getAttributeNames();
void removeAttribute(String key);
//————————————————————————————–
3>获得项目内资源
// 该方法使用相对路径获得 资源的流 其中 "/" ==> 项目根下 WebRoot
InputStream sc.getResourceAsStream();
// 使用相对路径获得绝对路径
String sc.getRealPath("/student.xml");
获取项目/磁盘下的资源
/**
* 读取资源文件
* @author Administrator
*
*/
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);
}
}
关于路径配置的问题:
默认情况: 第一次访问该servlet时候.
让servlet实例随着服务器的启动而创建:
添加一个配置即可:<load-on-startup></load-on-startup>
在该配置中填入一个整数即可实现.
数字的数值,在有多个servlet需要随着服务器启动而启动时,决定启动顺序.
数字越小优先级越高. 最小就是0. 一般0~5. 3.
如果数字一样,谁先配置谁先创建.
*servlet的路径配置
<url-pattern></url-pattern>
该配置,配置方式有两种
路径匹配: 一定以"/"开头
/AServlet
/ABC/AServlet
/ABC/BCD/AServlet
/ABC/*
/*
/
后缀名匹配: 以*开头
*.do
*.action
*.html
注意:
匹配范围越大,优先级越低.
后缀名匹配和路径匹配不能同一配置中混合使用. 例如: /*.do
一个servlet可以配置多个路径. 直接在<servlet-mapping>元素中添加多个<url-pattern>配置即可.
优先级: /AServlet > /abc/* > *.do > /*