servlet ---- Java进阶篇

目录

一、servlet概念及相关接口简介

1.1、什么是servlet?

1.2、什么是Servlet容器

1.3、 相关接口

1.4、servet 执行过程 

 1. 4.1、 编写一个servlet继承HttpServlet类

1.4.2、重写doGet()和doPost()方法

  1.4.3、把servlet程序交给Tomcat运行

1.4.4、 访问URL  :    http://localhost:8082/project06/Demo01

1.5、servlet路径映射

1.5.1、匹配ur-pattern

1.5.2、注意

1.6、缺省servlet

二、servlet生命周期(重点)

2.1、servlet生命周期的四个重要方法

2.2、伪代码演示servlet生命周期

三、Servlet自动加载

四、Servlet线程安全

五、servletConfig对象

5.1、作用

5.2、创建与获得

5.3、servlet初始化参数配置

六、ServletContext对象

6.1、创建于得到Context

6.2、自己可以这样设计设计

6.3、Sun公司设计

6.4、ServletContext对象的核心API(作用)

七、​​​​​​​所有域对象

7.1、转发

7.2、重定向

7.3、转发


​​​​​​​

一、servlet概念及相关接口简介

1.1、什么是servlet?

基于Java技术的web组件,基于java与第三方平台的无关类,是 Spring MVC、Struts、WebWork、SiteMesh等框架的基础,

一般被web服务器编译、加载,运行,生成动态资源的内容

1.2、什么是Servlet容器

  • 典型的servlet容器:Tomcat
  • servlet容器通过servlet的生命周期来管理servlet
  • servlet容器的本质是一个组件,接收客户端/浏览器请求并响应

1.3、 相关接口

  • interface   servlet
  • interface  ServletConfig
  • interface  ServletContext
  • GenericServlet实现Servlet接口

1.4、servet 执行过程 

如何开发一个servlet

     步骤

 1. 4.1、 编写一个servlet继承HttpServlet类

             new = > servlet类

1.4.2、重写doGet()和doPost()方法

 

servlet ---- Java进阶篇_第1张图片

  1.4.3、把servlet程序交给Tomcat运行

           servlet程序的class码拷贝的WEB-INF/classes目录部署项目

           配置web.xml文件




    ServletDemo01

    cn.itcase.servlet.ServletDemo01
  
  

    ServletDemo01

    /Demo01
  

1.4.4、 访问URL  :    http://localhost:8082/project06/Demo01

前提条件:必须启动Tomcat服务器,首先加载webapps下的web.xml文件

http://   http协议:浏览器与服务器之间的数据传输规范

 localhost:访问本地文件   在本地的hosts文件中查找是否存在该域名对应的IP地址  127.0.0.1

 8082:Tomcat的端口号

 /project06:到webapps下查找project06的项目

/Demo01:资源名称(URI)

1. 在project06的web.xml中查找是否有匹配的url-pattern的内容(/Demo01)

2.如果匹配到了url-pattern,则使用当前的servlet-name的名称到web.xml文件中查询是否有相同的servlet配置

3.如果找到,则取出对应的servlet配置信息中的servlet-class内容:

  •  cn.itcase.servlet.ServletDemo01
  • 通过反射:构造ServletDemo01的对象
  • 然后调用Servlet中的方法

 

1.5、servlet路径映射

 

    ServletDemo01

    /Demo01
 

1.5.1、匹配ur-pattern

 

匹配url-name

浏览器输入

精准匹配(完整的url地址)

/ServletDemo01

http://localhost:8082/project06/ServletDemo01

/itcase/Demo01

http://localhost:8082/project06/itcase/Demo01

 

模糊匹配

/*

http://localhost:8082/project06/任意路径

/itcast/*

http://localhost:8082/day10/itcast/任意路径

*.后缀名                                                   http://localhost:8082/project06/任意路径.do

*.action                                                     http://localhost:8082/project06/任意路径.action

*.html(伪静态)

1.5.2、注意

1.url-pattern要么以 /开头,要么以*开头

  •    *Demo01
  •  /Demo01

2.不能同时使用两种模糊匹配   /itcase/*.html

3.当输入的url有多个servlet匹配时

        精确匹配优先

        以后缀名结尾的模糊url-pattern优先级最低

       

1.6、缺省servlet

 servlet省略路径  格式: 

servlet省略路径是Tomcat内置的一个路径该路径对应的是一个DefaultServlet(缺省Servlet)。这个缺省的Servlet的作用是用于解析web应用的静态资源文件

浏览器输入(URL)    http://localhost:8080/day10/index.html   如何读取资源

    1. 到当前project06应用下的web.xml文件查找是否有匹配的url-pattern         

    2.如果没有匹配的url-pattern,则交给tomcat的内置的DefaultServlet处理

    3.DefaultServlet程序到project06应用的根目录下查找是存在一个名称为index.html的静态文件。

    4.如果找到该文件,则读取该文件内容,返回给浏览器

    5.如果找不到该文件,则返回404错误页面

总结:先找动态资源在找静态资源

 

 

 

二、servlet生命周期(重点)

servlet的生命周期:什么时候创建,什么时候调用什么方法,什么时候销毁

servelt生命周期由serlvet容器控制(Tomcat)

2.1、servlet生命周期的四个重要方法

package cn.itcase.test;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;

public class FlistServlet extends HttpServlet {
	 /*
     * 1.构造方法
     * 创建对象的时候调用
     * 默认情况下第一次访问servlet时候创建servlet对象 只调用1次
     * 证明servlet在Tomcat(servlet容器)是单实例
     * 
     * 单实例:一个对象的实例,在一个应用生命周期中只生成一次,所有的请求(方法调用)都由这个实例处理
     * 多实例:一个对象在应用里生成多个实例,所有的请求可能有不同的实例进行处理
     * 
     * 实例:就是某个类的一个对象  类是抽象的,对象是实在的,所以叫实例
     * 实例变量 也叫 成员变量 、实例域、实例字段
     * 实例方法 也叫 成员方法
     * 
     * 
     * 
     * */
	public FlistServlet(){
		System.out.println("1.创建servlet对象");
		
	}
	/*2.init()方法
	 * 创建完servlet对象后调用,只调用一次
	 * 
	 * */
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("2.init()方法被调用");
	}
	/*3.service()方法
	 * 每次发送请求时调用     调用n次
   */
	
	@Override
	public void service(ServletRequest arg0, ServletResponse arg1)
			throws ServletException, IOException {
		System.out.println("3.service方法被调用");
	}

	
	/*4.destory()方法
	 * 销毁servlet对象的时候调用 。停止服务器或者重新部署web应用时销毁servlet对象
	 * 只调用一次
	 * 
	*/
	@Override
	public void destroy() {
		System.out.println("4.destory()方法被调用");
		
	}
	
}

2.2、伪代码演示servlet生命周期

   tomcat内部代码运行:

          1.通过映射找到servlet-class内容:(字符串)cn.itcase.FilstServlet

         2.通过反射构造FilstServlet对象

            2.1 得到字节码对象

             Class clazz = class.forName("cn.itcase.FilstServlet");

          2.2调用无参数的构造方法来构造对象

                     Object bjo =clazz.newInstance();          1.servelt的构造方法被调用

         3.创建ServletConfig对象,通过反射调用init()方法

              3.1得到方法对象

               Method m = clazz.getDeclareMehtod("init",ServletConfig.class);

              3.2 调用方法

              m.invoke(obj,config);                                       2.servlet的init方法被调用

            4.创建request。response对象,通过反射调用service方法

              4.1得到方法对象

method  m = clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);

             4.2调用方法

        m.invoke(obj,request,response);            3.servlet的service方法被调用

           5.当tomcat服务器停止或web应用重新部署,通过放射调用destroy方法

               5.1得到方法对象

               Method m = clazz.getDeclareMethod("destroy",null);

                5.2调用方法

            m.invoke(obj,null);                 4.servlet的destory方法被调用

 

三、Servlet自动加载

       默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢

 

  把servlet创建对象提前到加载web应用

 

在servlet的配置信息中,加上一个


    FlistDemo01
    cn.itcast.FilstDemo01
    
    1  注意: 整数值越大,创建优先级越低!!
  

有参数与无参数的init方法

有参数的init方法: 该方法是servlet的生命周期方法,一定会被tomcat服务器调用

无参数的init方法:该方法是servlet的编写初始化代码的方法。是Sun公司设计出来专门给开发者进行覆盖,然后在里面编写servlet的初始逻辑代码的方法。

注意:如果要编写初始代码,不需要覆盖有参数的init方法

四、Servlet线程安全

servlet对象在tomcat服务器是单实例多线程的。

因为servlet是多线程的,所以当多个servlet的线程同时访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。

 

解决办法:

   1.把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)

   2.建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里),以避免因为同步而导致并发效率降低。

package cn.itcase.thread;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ThreadDemo extends HttpServlet {
  static int count = 1;  //成员变量  共享信息
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.setContentType("text/html;charest=utf-8");
		
		synchronized(ThreadDemo.class){//锁对象必须唯一,建议使用该类字节码对象
			resp.getWriter().write("您现在是当前网站的第:"+ count + "个访客");
			count++;
		}
	}

}

Servlet学习:

HttpServletRequest  请求对象:获取请求信息

HttpServletResponse 响应对象: 设置响应对象

ServletConfig对象    servlet配置对象

 ServletContext对象; servlet的上下文对象

五、servletConfig对象

5.1、作用

ServletConfig对象: 主要是用于加载servlet的初始化参数。在一个web应用可以存在多个ServletConfig对象(一个Servlet对应一个ServletConfig对象)

5.2、创建与获得

创建时机: 在创建完servlet对象之后,在调用init方法之前创建

得到对象: 直接从有参数的init方法中得到

5.3、servlet初始化参数配置

 
    ConfigDemo
    cn.itcase.config.ConfigDemo
  
    
    	path
    	D:\a.txt
    
  
package cn.itcase.config;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 * 	java.lang.String getInitParameter(java.lang.String name)  根据参数名获取参数值
	java.util.Enumeration getInitParameterNames()    获取所有参数
	ServletContext getServletContext()     得到servlet上下文对象
	java.lang.String getServletName()       得到servlet的名称
 * */
public class ConfigDemo extends HttpServlet {

	/*
	 * tomcat服务器把这些参数会在加载web应用的时候, 封装到ServletConfig对象中
	 * 
	 * tomcat服务器调用init方法传入ServletConfig对象 private ServletConfig config;
	 * 
	 * @Override public void init(ServletConfig config) throws ServletException
	 * { this.config = config; //引用父类成员变量 }
	 */

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//编码格式
		response.setContentType("text/html");
		//输出
		PrintWriter out = response.getWriter();
         //根据参数名获取参数值
		String path = this.getServletConfig().getInitParameter("path");
		File file = new File(path);

		// 读取内容
		BufferedReader br = new BufferedReader(new FileReader(file));
		String str = null;
		while ((str = br.readLine()) != null) {
			System.out.println(str);
		}
		// 查询当前servlet的所有初始化参数
		Enumeration enums = this.getServletConfig()
				.getInitParameterNames();
		while (enums.hasMoreElements()) {
			String paramName = enums.nextElement();
			String paramValue = this.getServletConfig().getInitParameter(
					paramName);
			System.out.println(paramName + "=" + paramValue);
		}
		//得到servlet名称
		String servletName = this.getServletConfig().getServletName();
	    System.out.println(servletName);
	}

}

 

六、ServletContext对象

ServletContext对象 ,叫做Servlet的上下文对象。表示一个当前的web应用环境。一个web应用中只有一 个ServletContext对象

​​​​​​​6.1、创建于得到Context

创建时机:加载web应用时创建ServletContext对象。

得到对象: 从ServletConfig对象的getServletContext方法得到

6.2、自己可以这样设计设计

创建ServletConfig对象

public void init( ServletConfig config,ServletContext context ){  多了一个参数

得到ServletConfig对象

得到ServletContext对象;

       }

6.3、Sun公司设计

package cn.itcase.content;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ContextDemo03 extends HttpServlet {

	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		
		//1.获得文本域对象
		ServletContext context = this.getServletContext();
	   //2.把数据保存到域对象中
		context.setAttribute("student", new Student("jack",20));
	}

}
class Student{
	private String Name;
	private  int Age;
	public Student(String Name, int Age) {
		super();
		this.Name = Name;
		this.Age = Age;
	}
	public String getName() {
		return Name;
	}
	public void setName(String name) {
		Name = name;
	}
	public int getAge() {
		return Age;
	}
	public void setAge(int age) {
		Age = age;
	}
	@Override
	public String toString() {
		return "student [Name=" + Name + ", Age=" + Age + "]";
	}
	
}

 

package cn.itcase.content;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 1.创建ServletContext对象  ServletContext  context = new ServletContext()
 2. 创建ServletConfig对象   ServetConfig config = new ServletConfig();
 config.setServletContxt(context);
 lass  ServletConfig{
 ServletContext context;
 public ServletContext getServletContxt(){
 return contxt;
 }

   }
  public void init( ServletConfig config ){
  得到ServletConfig对象
     从ServletConfig对象中得到ServletContext对象
 SerlvetContext context = config.getServletContext();
      }
 */
public class ContextDemo04 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");

		// 1.得到域对象 域对象可以理解为web.xml文件
		ServletContext context = this.getServletContext();
		// 2.从域对象中取出数据
		Student student = (Student) context.getAttribute("student");
		System.out.println(student);
	}

}

 

6.4、ServletContext对象的核心API(作用)

package cn.itcase.content;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*java.lang.String getContextPath()   --得到当前web应用的路径

java.lang.String getInitParameter(java.lang.String name)  --得到web应用的初始化参数
java.util.Enumeration getInitParameterNames()  

void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法
java.lang.Object getAttribute(java.lang.String name)  
void removeAttribute(java.lang.String name)  

RequestDispatcher getRequestDispatcher(java.lang.String path)   --转发(类似于重定向)

java.lang.String getRealPath(java.lang.String path)     --得到web应用的资源文件
java.io.InputStream getResourceAsStream(java.lang.String path)  */

public class Demo01 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		
		//1.得到servletContext(对象域)的几种方式
		
		//方式一:
		//ServletContext context = this.getServletConfig().getServletContext();
         
		//方式二:推荐使用这种方式
		ServletContext context = this.getServletContext();
		
		//2.得到web应用路径   project02
		String contextPath = context.getContextPath();
	    System.out.println(contextPath);
	
	 //3.案例:应用请求重定向
	    response.sendRedirect(contextPath + "/index.html");
	}
	

}

 域对象:作用是用于保存数据,获取数据。可以在不同的动态资源之间共享数据

注意:servletContext域对象:作用范围在整个web应用中有效   

 

、​​​​​​​所有域对象

HttpServletRequet 域对象       ServletContext域对象   HttpSession 域对象    PageContext域对象

7.1、转发

 RequestDispatcher getRequestDispatcher(java.lang.String path)

7.2、重定向

package cn.itcase.forwrad;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Demo02 extends HttpServlet {

	/*
	重定向			
	1.地址栏会改变,变成重定向到地址。
	2.重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。
	3.不能再重定向的过程,把数据保存到request中。
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
  //保存数据到request域对象
		request.setAttribute("name","rose");
		
		//重定向
		response.sendRedirect("project02/GetDataServlet");
		
	}

}

 

7.3、转发

package cn.itcase.forwrad;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Dmeo01 extends HttpServlet {

	/*
	 
	转发  RequestDispatcher getRequestDispatcher(java.lang.String path)
	1.地址栏不会改变
	2.转发只能转发到当前web应用内的资源
	3.可以在转发过程中,可以把数据保存到request域对象中
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		
		/*保存数据到域对象*/
		request.setAttribute("name", "rose");
	
	  /*转发
	   * 注意:不能转发到当前web应用以外的资源
		*/
		
		this.getServletContext().getRequestDispatcher("/GetDateServlet").forward(request, response);
	}

}
package cn.itcase.forwrad;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class GetDateServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
        //获取文本域中的对象
		String name = (String)request.getAttribute("name");
		System.out.println("name="+name);
/*
 保存数据:void setAttribute(java.lang.String name, java.lang.Object object)
获取数据: java.lang.Object getAttribute(java.lang.String name)
删除数据: void removeAttribute(java.lang.String name
 * */
	}

}

结论:如果要使用request域对象进行数据共享,只能用转发技术

你可能感兴趣的:(java进阶篇)