Servlet

 

 

替换之后,myeclipse中新建时特别简洁,不需要每次都删除了。

今天内容都特别重要

一、Servlet概述

1、什么是Servlet

Servlet是一个运行在服务器端的Java小程序,通过HTTP协议用于接收来自客户端请求,并发出响应。

2、Servlet中的方法

public void service(ServletRequest req,ServletResponse res)

throws ServletException,java.io.IOException

 

ServletRequest req:代表着请求对象,该对象中有HTTP协议的请求部分的所有内容。它的实现类由服务器提供的,封装数据也是服务器来做的。

ServletResponse res:代表着响应对象,该对象中由我们写数据(HTTP协议的响应部分)进去。它的实现类也是由服务器提供的。

service:由服务器调用,每次请求都会调用一次。服务器采用的是多线程机制。

二、Servlet的编码步骤

1、编写一个类实现javax.servlet.Servlet接口,或者继承javax.servlet.GenericServlet。

 

 

2、编译Servlet的源码

 

 

3、映射Servlet

修改web.xml

 

 

4、把应用部署Tomcat中,访问地址:http://localhost:8080/firstServlet/hello

 

明确:规范 服务器 应用间的关系

 

 

三、Servlet的执行过程

 

 

 

 

1.客户端访问Tomcat访问地址:http://localhost:8080/firstServlet/hello

2.Tomcat解析客户端的访问地址

3.Tomcat找firstServlet应用。

4.找之间先搜索web.xml

5.接着就找到自己的类。

6.执行service

7.给用户看到结果

四、Servlet的编写方式:

1、javax.servlet.GenericServlet:通用的Servlet实现,抽象类

 

(经常用)2、javax.servlet.http.HttpServlet:与HTTP协议有关的,抽象类

继承HttpServlet,然后覆盖掉doGetdoPost方法即可

不要覆盖掉service方法。

 

 

*Servlet规范中的核心接口类图(建议作为桌面)

 

 

Httpservlet(HttpServletRequest、HttpServletResponse)继承GenericServlet(ServletRequest、ServletRespone)、GenericServlet继承Servlet(接口)

 

五、Servlet的生命周期

1、生命周期(必须清晰):诞生--活着--死亡。人有这个过程,内存中的对象也有。

2、Servlet对象的生命周期

  • 诞生:用户第一次访问时,由容器创建他的实例。
  • 活着:一旦创建就驻留内存(单例)。每次用户的访问,容器都会调用sevice方法发出响应(多线程)
  • 死亡:应用被卸载或者Tomcat关闭了

代码实现:

 //用户第一次访问时,只执行一次

 public ServletDemo3(){

  System.out.println("调用了Servlet的默认构造方法");

 }

 

 

 //用户第一次访问时,执行一次。用于对象的初始化

 public void init() throws ServletException {

  System.out.println("调用了Servlet的初始化方法");

 }

 //每次用户访问都执行

 public void doGet(HttpServletRequest request, HttpServletResponse response)

   throws ServletException, IOException {

  System.out.println("执行了Service方法");

 }

 public void doPost(HttpServletRequest request, HttpServletResponse response)

   throws ServletException, IOException {

  doGet(request, response);

 }

 //调用一次。用于清理工作

 public void destroy() {

  System.out.println("调用了Servlet的销毁方法");

 }

结果截图:

 

 

六、Servlet的线程安全

 

 

错误的写法:

 

 

 

 

 

七、Servlet的一些细节

1.一个Servlet可以被映射到多个地址上

 

 

 

 

也可以:

 

 

 

 

2、可以使用地址的通配符

写法一:*.do结尾。必须以*开头  比如*.do

写法二(比一优先级略高):以/开头,必须*结尾        比如/action/*

 

映射的先后顺序:(例题)

对于如下的一些映射关系:

lServlet1 映射到 /abc/*

lServlet2 映射到 /*

lServlet3 映射到 /abc

lServlet4 映射到 *.do

问题:

l当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应

  Servlet引擎将调用Servlet1。

l当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应

  Servlet引擎将调用Servlet3。

l当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应

  Servlet引擎将调用Servlet1

l当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应

  Servlet引擎将调用Servlet2。

l当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应

  Servlet引擎将调用Servlet2。

3.默认的Servlet

默认的Servlet的映射路径是<url-pattern>/<url-pattern>。不需要大家配,因为默认的Servlet负责处理用户的请求URL找不到匹配的处理工作。

4.应用在启动时就完成Servlet的实例化和初始化

 

 

 

 

 

初始化1被占用了

八、ServletConfigServlet的参数配置

1、ServletConfig:代表看针对当前Servlet的参数配置。

在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。

 

 

 

 

代码实现:

 public void doGet(HttpServletRequest request, HttpServletResponse response)

   throws ServletException, IOException {

  ServletConfig config = getServletConfig(); //使用config了

// method1(config);

  test(config);

 }

 private void test(ServletConfig config) { //得到当前Servlet所有的配置参数

  Enumeration e = config.getInitParameterNames(); //参数的名字

  while(e.hasMoreElements()){

   String paramName = (String)e.nextElement();

   System.out.println(paramName+"="+config.getInitParameter(paramName));

  }

 }

 private void method1(ServletConfig config) { //得到指定名称的参数的值

  String str = config.getInitParameter("encoding"); //得到指定名称的参数值

  System.out.println(str);

 }

2、如何得到ServletConfig对象的应用:在初始化Servlet,由容器产生,并传递给你,

 

 

 

编码和解码:

 

 @Test

 public void test1() throws UnsupportedEncodingException{

  String s = "陈宇超";

  System.out.println(URLEncoder.encode(s,"utf-8"));//编码

 }

 @Test

 public void test2() throws UnsupportedEncodingException{

  String s = "%E9%99%88%E5%AE%87%E8%B6%85";

  System.out.println(URLDecoder.decode(s,"utf-8"));//解码

 }

九、ServletContext

 

1、ServletContext 代表着当前应用。每个应用只有用一个ServletContext对象实例,有容器提供

2、获得ServletContext的实例:ServletConfig.getServletContext();

3、ServletContext的生命周期

        诞生:应用被加载时就有容器创建好

        活着:应用不挂就一直活着

        死亡:应挂了,就挂了

4、域(存活范围)对象:

        ServletContext成为应用范围域对象。

 

 

 

 

 

servletContext 是四大域对象中最大的域对象

 

        【应用1】.多个Servlet通过ServletContext对象实现数据共享

        

      

 

 

    

     注意:运行时,先运行Demo1 在运行Demo2 不然就会出现空指针。

 

 

 

    5、配置应用级的参数web.xml 

     【应用2】、获取WEB应用的初始化参数

    这是个全局配置,具有统一性

 

 

 

    用ServletContext来取

    代码如下:      

  ServletContext sc = getServletContext();

  //获取指定的一个参数

  String s = sc.getInitParameter("encoding");

  System.out.println(s);

  //获取所有的参数

  Enumeration<String> e = sc.getInitParameterNames();

  while(e.hasMoreElements()){

   String contextName = e.nextElement();

   System.out.println(contextName+"="+sc.getInitParameter(contextName));

  }

 

 

    【应用3】实现Servlet的转发。

    代码实现:

        

 

运行Demo4 显示的内容是Demo5

 

 

 

        【应用4】利用ServletContext对象读取资源文件。

        (1)、下载图片:

        

 

 

        (2)读取属性文件

  • properties文件(属性文件)
  • 得到文件路径(ServletContext.getRealPath(),ServletContext.getReaourceAsStream())
  • 思考:如果一个普通类该如何读取配置文件??
  • 读取资源文件的三种方式

    I、代码如下:

public void doGet(HttpServletRequest request, HttpServletResponse response)

   throws ServletException, IOException {

  test4();

 }

 //请不要把Tomcat等服务器装在有空格的目录中

 //1.1.类加载器读取:只能读取classes或者类路径中的任意资源。但是不适合读取特别大的资源。1 2

 private void test4() throws IOException {

  //得到类的字节码文件,在得到类得加载器

  ClassLoader cl = Demo7.class.getClassLoader();

// URL url = cl.getResource("/resources/1.properties");

  URL url = cl.getResource("/2.properties");

  InputStream is = new FileInputStream(url.getPath());

  Properties prop = new Properties();

  prop.load(is);

  System.out.println(prop.getProperty("hello"));

 }

 //1.2.类加载器读取:只能读取classes或者类路径中的任意资源。但是不适合读取特别大的资源。只能读取 1 2

 private void test3() throws IOException{

  ClassLoader cl = Demo7.class.getClassLoader();

  InputStream is = cl.getResourceAsStream("/resources/1.properties");

// InputStream is = cl.getResourceAsStream("2.properties");

  Properties prop = new Properties();

  prop.load(is);

  System.out.println(prop.getProperty("hello"));

 }

 //2.利用ResourceBundle读取:1 2 (文件在classes类路径内),不能读1,只能读取properties的文件

 private void test2(){

// ResourceBundle rb = ResourceBundle.getBundle("2");

  ResourceBundle rb = ResourceBundle.getBundle("resource.1");

  System.out.println(rb.getString("hello"));

 

 }

 //利用ServletContext读取:1 2 3 文件

 //3.可以读取应用中任何位置上的资源。使用限制:只能在web应用中用

 private void test1() throws IOException{

// String realPath = getServletContext().getRealPath("/WEB-INF/classes/resources/1.properties");

// String realPath = getServletContext().getRealPath("/WEB-INF/classes/2.properties");

  String realPath = getServletContext().getRealPath("/3.properties");

  InputStream is = new FileInputStream(realPath);

  Properties prop = new Properties();

  prop.load(is);

  System.out.println(prop.getProperty("hello"));

 }

 

posted on 2016-06-13 15:24  cayman丿2016  阅读(159)  评论(0编辑  收藏  举报

导航