Servlet笔记

来源:互联网 发布:奥运会标志 知乎 编辑:程序博客网 时间:2024/06/06 03:10

Servlet
1、什么是Servlet
Servlet是在服务器上运行的小程序,也就是一个Java类,Servlet是JavaWeb的三大组件之一(Servlet、Filter、Listener),它属于动态资源。Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:
 接收请求数据;
 处理请求;
 完成响应。
例如客户端发出登录请求,或者输出注册请求,这些请求都应该由Servlet来完成处理。Servlet需要我们自己来编写,每个Servlet必须实现javax.servlet.Servlet接口。Servlet对象驻留在服务器内存中。
2、Tomcat容器等级
Tomcat的容器分为四个等级,Servlet的容器管理Context容器,一个Context对应一个Web工程。

3、实现Servlet的方式
实现Servlet有三种方式:
 实现javax.servlet.Servlet接口;
 继承javax.servlet.GenericServlet类;
 继承javax.servlet.http.HttpServlet类;
自定义Servlet类的继承结构,如下图:

3.1、实现Servlet接口的自定义Servlet
/**
* Servlet中的大部分方法(生命周期方法)都是有Tomcat服务器调用,
* Servlet对象也是由Tomcat服务器创建
*/
public class DemoServlet implements Servlet {

/*生命周期方法
* 在Servlet对象被销毁前调用,并且只执行一次
* 一般用于释放资源操作
*/
public void destroy() {
System.out.println(“destroy…..”);
}
/*用来获取Servlet的配置信息
*/
public ServletConfig getServletConfig() {
System.out.println(“getServletConfig….”);
return null;
}
/* 获取Servlet信息(一般无用)
*/
public String getServletInfo() {
System.out.println(“getServletInfo….”);
return null;
}
/*生命周期方法
* 在Servlet对象创建后立即执行,并且只执行一次
* 一般用于初始化操作
*/
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(“init…..”);
}
/* 生命周期方法
* 每次处理请求都会执行该方法
*/
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
System.out.println(“service….”);
}
}
Servlet生命周期方法:
 void init(ServletConfig) 创建之后被调用(1次)
 void service(ServletRequest request,ServletResponse response)每次处理请求时被调用(多次)
 void destroy()销毁之前被调用(1次)
特性:
 Servlet是单例的,一个类只有一个对象,可以存在多个Servlet类;
 线程不安全的,效率高;
 Servlet由我们自己编写,对象由服务器来创建,由服务器调用相应方法。
3.2、实现第一个Servlet程序
1、重写doGet()或doPost()方法
public class HelloServlet extends HttpServlet {

@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException {    System.out.println("处理get请求。。。。");

//设置输出格式和字符编码
resp.setContentType(“text/html;charset=utf-8”);
//向页面输出内容
PrintWriter out = resp.getWriter();
out.println(“

Hello Servlet

“);
}

@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException {}

}
2、在web.xml中注册Servlet

//url-pattern路径前置的斜杠是代表当前项目

代码示例:

HelloServlet
com.oracle.servlet.HelloServlet


HelloServlet
/servlet/HelloServlet

3、编辑JSP页面
跳转
//url路径为web.xml配置文件中rul-pattern标签内容

4、执行结果

4、Servlet详解
4.1、如何让浏览器访问Servlet
需要给Servlet指定一个路径,让Servlet与该路径绑定在一起;
在浏览器中访问该路径;
这个路径可以在web.xml中进行配置。

Demo
com.demo.DemoServlet


Demo
/demo.html

4.2、在web.xml配置初始化参数
web.xml

Demo
com.demo.DemoServlet

name
tom


password
1234


在Servlet中获取参数和值
public void init(ServletConfig servletConfig) throws ServletException {
//方法一
String name = servletConfig.getInitParameter(“name”);
String pwd = servletConfig.getInitParameter(“password”);
System.out.println(name+”,”+pwd);

    //方法二    Enumeration en = servletConfig.getInitParameterNames();    while(en.hasMoreElements()){        String key = (String) en.nextElement();        String val = servletConfig.getInitParameter(key);        System.out.println(key+","+val);    }

}
4.3、GenericServlet概述
GenericServlet是Servlet接口的实现类(抽象类),我们可以通过GenericServlet来编写自己的Servlet。
模拟GenericServlet类:
public class GServlet implements Servlet{

//声明成员变量configprivate ServletConfig config;public void destroy() {}public ServletConfig getServletConfig() {    return this.config;}public String getServletInfo() {    return null;}public void init(ServletConfig config) throws ServletException {    this.config = config;    init();//调用无参方法,方便子类的初始化操作}//声明无参方法,方便子类中的初始化操作public void init(){}public void service(ServletRequest request, ServletResponse response)        throws ServletException, IOException {}public ServletContext getServletContext(){    return config.getServletContext();}public String getServletName(){    return config.getServletName();}public String getInitParameter(String name){    return config.getInitParameter(name);}

}
GServlet的子类:
public class SonGServlet extends GServlet {

@Overridepublic void init() {    System.out.println("子类中的初始化操作");}@Overridepublic void service(ServletRequest request, ServletResponse response)        throws ServletException, IOException {    String name = getInitParameter("name");    System.out.println(name);}

}
4.4、HttpServlet概述
Tomcat调用service(ServletRequest,ServletResponse)方法,强转两个参数为http协议相关的类型,然后再调用本类的service(HttpServletRequest,HttpServletResponse)。
该service()方法会通过request得到当前请求的请求方式,例如:GET或POST,根据请求的方式再调用doGet()或doPost()方法。doGet()和doPost()是由我们自己来覆盖,如果没有重写doGet或doPost,并且他们被调用了,这时会出现405
演示:
在我们自定义的Servlet中,只重写了doPost方法

在浏览器中发送GET请求,服务器会返回405,意思是不支持该请求方式

4.5、Servlet执行流程

4.6、Servlet生命周期

1)初始化阶段,调用init()方法;
2)响应客户请求阶段,调用service()方法,由service()方法根据提交方式选择执行doGet()或者doPost()方法;
3)终止阶段,调用destroy()方法。
4.7、Tomcat装载Servlet的三种情况
1)Servlet容器启动时自动装载某些Servlet,实现它只需要在web.xml文件中的之间添加如下代码:1,数字越小表示优先级别越高。
2)在Servlet容器启动后,客户首次向Servlet发送请求。
3)Servlet类文件被更新后,重新装载Servlet。
Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在Servlet的整个生命周期内,init()方法只被调用一次。

5、Servlet与线程安全
因为一个类型的Servlet只有一个实例对象,那么就有可能会同时出现一个Servlet同时处理多个请求,那么这样Servlet就是线程不安全的,但是Servlet的工作效率很高。
解决方案:
 不要在Servlet中创建成员,创建局部变量即可;
 可以创建无状态成员(无成员);
 可以创建有状态成员,但状态必须为只读的(只有getter方法);
6、让服务器在启动时就创建Servlet
默认情况下,服务器会在某个Servlet第一次收到请求时创建它,也可以在web.xml中对Servlet进行配置,使服务器启动时就创建Servlet。
在标签中,配置,其中给出一个非负整数,当有多个Servlet在服务器启动时创建,那么根据值的大小决定先后顺序,小的在先。可以通过init()方法测试Servlet的创建时机。
在web.xml中配置

Demo
com.demo.DemoServlet
0


A
com.demo.HttpServletDemo
1

7、配置
是的子元素,用来指定Servlet的访问路径,即URL。它必须是以“/”开头。
可以在中给出多个,例如:

DemoServlet
/AServlet
/BServlet

那么这说明Servlet绑定两个URL,无论访问/AServlet还是/BServlet,访问的都是DemoServlet。
还可以在中使用通配符,所谓通配符就是星号“*”,星号可以匹配任何URL前缀或后缀,使用通配符可以命名一个Servlet绑定一组URL,例如:
 /servlet/*:/servlet/a、/servlet/b,都匹配;
 *.do:/abc/def/ghi.do、/a.do,都可以匹配;
 /*:匹配所有URL
注意:通配符要么为前缀,要么为后缀,不能出现在URL中间位置,也不能只有通配符。例如:/.do就是错误的,因为星号出现在URL的中间位置了。.*也是不对的,因为一个URL最多只能有一个通配符。
通配符是一种模糊匹配URl的方式,如果存在更具体的,那么访问路径会去匹配具体的。
8、设置初始化参数
在web.xml中配置Servlet时,可以配置一些初始化参数。而在Servlet中可以通过ServletConfig接口提供的方法来取得这些参数。
在web.xml配置文件中初始化参数信息

HelloServlet
com.oracle.servlet.HelloServlet

username
admin


pwd
1234



HelloServlet
/servlet/HelloServlet

在Servlet类中的init()方法内接收初始化信息
public class HelloServlet extends HttpServlet {
private String username;
private String pwd;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}

@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException {    resp.setContentType("text/html;charset=utf-8");    PrintWriter out = resp.getWriter();    out.println("<h2>"+getUsername()+"</h2>");    out.println("<h2>"+getPwd()+"</h2>");}@Override                                                                    public void init() throws ServletException {                                     this.setUsername(this.getInitParameter("username"));                             this.setPwd(this.getInitParameter("pwd"));                             }

}

前端访问效果

9、web.xml文件的继承
每个完整的JavaWeb应用中都需要有web.xml,在
$[CATALINA_HOME]\conf\web.xml中的内容,相当于写到了每个项目的web.xml中,它是所有web.xml的父文件。
10、ServletContext概述
一个项目只有一个ServletContext对象,服务器会为每个应用创建一个ServletContext对象,我们可以在N多个Servlet中来获取这个唯一的对象,使用它可以给多个Servlet传递数据,与Tomcat同生同死。
 ServletContext对象的创建是在服务器启动时完成的;
 ServletContext对象的销毁是在服务器关闭时完成的。
ServletContext对象的作用是在整个Web应用的动态资源直接共享数据。例如在AServlet中向ServletContext对象中保存一个值,然后在BServlet中就可以获取这个值,这就是数据共享。
获取ServletContext
在Servlet中获取ServletContext对象:
 在void init(ServletConfig config)中:
ServletContext context = config.getServletContext();
public class DemoServlet implements Servlet {
public void init(ServletConfig config) throws ServletException {
ServletContext context = config.getServletContext();
}
}
 在GenericServlet或HttpServlet中获取ServletContext对象:
GenericServlet类有getServletContext()方法,所以可以直接使用this.getServletContext()类获取。
public class HttpServletDemo extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletContext context = this.getServletContext();
}
}
 HttpSession中也可以通过getServletContext()方法来获得
11、域对象的功能
ServletContext是JavaWeb四大域对象之一:
 PageContext
 ServletRequest
 HttpSession
 ServletContext
所有域对象都是有存取数据的功能,因为域对象内部有一个Map,用来存储数据,下面是ServletContext对象用来操作数据的方法:
 void setAttribute(String name,Object val):用来存储一个对象,也可以成为存储一个域,参数分别为域的属性名和属性值,如果多次调用该方法,并且使用相同的name,那么就会覆盖上一次的值,这一特性与Map相似。
 Object getAttribute(String name):用来获取ServletContext中的数据,当前在获取之前需要先存储。
 void removeAttribute(String name):用来移除ServletContext中的域属性,如果参数name不存在,那么该方法什么都不做。
 Enumeration getAttributeNames():获取所有域属性的名称。
12、获取应用初始化参数
Servlet也可以获取初始化参数,但它是局部的参数,即一个Servlet只能获取自己的初始化参数,不能获取别人的。可以设置公共的初始化参数,为所有Servlet而用,这需要使用ServletContext才能使用。
web.xml文件配置

context_name
123


AServlet
com.demo.AServlet


AServlet
/AServlet

在AServlet类中获取参数
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = getServletContext();
String name = context.getInitParameter(“context_name”);
System.out.println(name);
}
}

13、获取资源相关方法

public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

    //获取带有盘符的路径    String path = this.getServletContext().getRealPath("/a.txt");    //获取资源路径后,再获取输入流对象    InputStream is = this.getServletContext().getResourceAsStream("/a.txt");    //获取当前路径下的所有资源路径    Set<String> paths = this.getServletContext().getResourcePaths("/WEB-INF");}

}
14、练习:统计网站访问量
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

    /*     * 获取ServletContext对象,并从该对象中获取名为“count”的属性     * 第一次访问时,该属性不存在,就创建该属性     * 以后每次访问,对该属性的值做累加     */    ServletContext app = this.getServletContext();    Integer count =  (Integer) app.getAttribute("count");    if(count == null){        count=1;        app.setAttribute("count", count);    }else{        app.setAttribute("count", ++count);    }    //向页面输出内容    //设置服务器响应的格式和编码    response.setContentType("text/html;charset=utf-8");    PrintWriter out = response.getWriter();    out.println("<h1>您当前是第<font color=\'red\'>" + count +            "</font>位访问者</h1>");}

}
15、获取类路径下资源
类路径对一个JavaWeb项目而言,就是/WEB-INF/classes和/WEB-INF/lib/每个jar包。
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

    /*     * 先得到Class,在得到ClassLoader     * 得到的是当前项目下的a.txt     */    ClassLoader cl = this.getClass().getClassLoader();    InputStream is = cl.getResourceAsStream("a.txt");    //把资源文件放到与当前类同目录下的访问路径    InputStream is2 = cl.getResourceAsStream("com/demo/a.txt");    //相对.class文件所在目录    Class c = this.getClass();    InputStream in = c.getResourceAsStream("a.txt");    //相对于classes    c.getResourceAsStream("/a.txt");    //获取index.jsp资源    c.getResourceAsStream("/../../index.jsp");    //使用Struts的commons-io-xx.jar    String s = IOUtils.toString(is);    System.out.println(s);}

}

16、MVC架构
16.1、什么是MVC模式
MVC是一种目前广泛流行的软件设计模式,它把应用程序分为三个核心模块:模型(Model)、视图(View)、控制器(Controller),它们各自处理自己的任务。旨在分离模型、控制、视图。是一种分层思想的体现。
模型(Model)代表应用程序的数据和用于控制、访问和修改这些数据的业务规则;
视图(View)用来组织模型的内容,它从模型那里获得数据,并指定这些数据如何表现;
控制器(Controller)定义了应用程序的行为,它负责对来自视图的用户要求进行解释,并把这些要求映射成相应的行为,这些行为由模型负责实现。
16.2、MVC的处理过程
1)浏览器发送一次请求,被控制器(Controller)接收,在Java Web开发中,充当控制器角色的就是Servlet
2)由Servlet实例化一个模型层的对象,通常使用Javabean来充当模型层,由Javabean去调用数据库并获得数据,再返回给控制层,同时也可以被视图层直接访问
3)控制层获得模型层返回的数据,再将数据传给视图层,通常使用jsp充当视图层

模型2

原创粉丝点击