深入理解Servlet原理

本文详细介绍了Servlet的基本概念,包括如何返回网页、Servlet的特征及其在JavaWeb开发中的作用。此外还讲解了Servlet的开发步骤、执行原理及HTTP协议等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Servlet介绍:

1. 如何返回一个网页:

 a. 静态网页

    >新闻页、百度百科

    >服务器保存一份HTML,直接返回给浏览器即可

 b. 动态网页

    >淘宝、QQ空间、微博

    >服务器保存一个组件,通过它动态拼一个HTML

    >在Java中这个组件就是Servlet

2. Servlet特征:

  a. Servlet是服务器端组件,必须保存在服务器上。

  b. Servlet可以动态拼资源(HTML/IMG等),即处理HTTP协议。

  c. Servlet必须满足Sun的规范。

  d. Servlet是什么:Servlet是Sun推出的,用来在服务器端处理HTTP协议的组件。

服务器:

1. 名称:Java 服务器、Java Web 服务器、Servlet 容器;

2. 本质:是一个软件,需要安装在硬件上才能用和浏览器是平级的关系;

3. 举例:Tomcat(Apache)、JBOSS、WebLogic、WebSphere。

Tomcat使用:

1. 启动Tomcat:

   -Linux:打开/tomcat/bin,终端输入命令./startup.sh

   -Windows:打开/tomcat/bin,双击startup.bat

2. 关闭Tomcat:

   -Linux:打开/tomcat/bin,终端输入命名./shutdown.sh

   -Windows:打开/tomcat/bin,双击shutdown.bat

Servlet开发步骤:

1.创建WEB项目

  >目录:webapp/WEB-INF/web.xml

2.导入jar包

  >通过maven导入jar包,搜javaee

  >使用服务器自带的jar包,右键项目->target runtime->勾选tomcat

3.创建Servlet

  >实现Servlet接口

  >也可以继承HttpSevlet,此类已实现了Servlet接口

  >实现/重写service(),在此方法内动态拼HTML

4.注册Servlet

  >注册Servlet,并声明别名

  >通过别名,给此Servlet注册网名(以/开头)

5.部署项目

  >在Servers下选择Tomcat,右键Add and Remove

  >在弹出框内左侧选中项目,双击移动到右侧

  >部署:就是拷贝

6.访问Servlet

  >启动Tomcat

  >浏览器输入地址 http://ip:port/项目名/Servlet网名

7.重新部署

  >修改代码后,需要重新部署并重启Tomcat才有效

  >点击Servers下面的Tomcat7,右键publish

  >可以手动关闭Tomcat,再启动它

  >也可以等待Eclipse自动重启Tomcat(Reloading...)

Servlet执行原理:


HTTP协议:

1. 什么是HTTP协议:它规定了浏览器和服务器如何通信,以及通信时的数据格式。

2. 如何通信:

  >建立连接

  >发送请求

  >接收响应

  >关闭连接

3. 数据格式:

 a. 请求数据包

   >请求行:请求方式、Servlet网名、协议类型

   >消息头:数据的描述信息

   >实体内容:浏览器发送给服务器的数据

 b. 响应数据包

   >状态行:协议类型、状态码、状态

   >消息头:数据的描述信息

   >实体内容:服务器给浏览器发送的数据

4. 对开发的要求

  -通信的方式已经由浏览器和服务器完成;

  -请求数据的打包由浏览器实现;

  -响应数据的打包由服务器实现;

  -开发需要提供浏览器发送给服务器的数据,以及服务器返回的数据;

  -服务器通过request对象接收请求数据;

  -服务器通过response对象向浏览器发送数据;

注册案例:

1. form的action属性要写上Servlet的访问路径(网名);

2. 在表单空间上,使用name属性给该控件的数据命名,可以调用request的getParameter("name的指")来获取值;

3. radio和checkbox需要设置value属性的值,就是要传递给服务器的具体的值;

Servlet原理图:


请求方式:

1. 介绍:浏览器向服务器发送数据的方式;

2. GET:

  >默认情况下所有的请求都是GET请求

  >采用路径传参,即通过路径携带参数

  >传参过程中参数可见,隐私性差

  >因为路径大小有限制,所以能够传递的参数很小

3. POST:

  >method="post"

  >采用实体内容传参

  >在传参的过程中,路径上看不到参数,隐私性好

  >实体内容专门用于传递数据,因此大小不受限制

4. 使用场景:

  >浏览器向服务器索取(查询)数据用GET请求

  >浏览器向服务器提交(保存)数据用POST请求

解决乱码问题:


重定向:

 1. 格式:res.sendRedirect("findEmp");//findEmp是网名

 2. 原理图如下:


项目路径:


URI和URL:

1. 狭义(Java):

   - URI:绝对路径;

   - URL:完整路径;

   - URL包含了URI;

2. 广义(Java/.net/php):

   - URI:资源的名称;

   - URL:资源的真名;

   - URI包含了URL;  

Servlet路径的配置方式及用途:

1. 精确匹配(/test):

    - 只有这唯一的路径可以可以访问此Servlet

    - 该Servlet只能处理一个请求 

2. 通配符(/*):

    - 所有的路径都是可以访问此Servlet

    - 该Servlet可以处理所有请求

3. 后缀匹配(*.test):

    - 所有以.test为后缀的路径都可以访问此Servlet

    - 该Servlet可以处理很多请求

注:

  a. 必须先通过规范约定正确的路径;

  b. 按照规范判断路径,处理请求。对于不满足规范的路径,认为是用户输入的错误路径,统一报错;

Servlet生命周期:

1. 第1、2、4步只能执行一次,第3步可以执行多次;

2. 因为Servlet被Tomcat自动创建一次,因此它在Tomcat内是单例的(只有1个实例),即Servlet满足单例模式;

3. 默认情况下,首次访问Servlet时,Tomcat会创建它,也可以修改配置文件web.xml,使得Tomcat启动时就直接创建Servlet;

4. 启动时创建Servlet,数字1代表创建的次序:<load-on-startup>1</load-on-startup>;


ServletConfig和ServletContext:

1. Context:上下文,理解为环境。环境可以给其内部的个体提供资源。从编程的角度来说可以给内部的对象提供数据;
2. ServletConfig:它是Servlet的私有环境,可以为某一个Servlet提供数据;
3. ServletContext:它是Servlet的公有环境,可以为所有Servlet提供数据;
4. 使用ServletConfig和ServletContext给Servlet预置数据,不用写单独的配置文件,直接使用web.xml即可;另外这两个对象可以在初始化Servlet之前自动读取web.xml中的预置数据;
5. Servlet特殊用法:
    - 可以使用此对象存取一些变量;
    - 即在程序运行阶段随时向此对象存取数据;
    - 获取对象:ServletContext ctx = getServletContext();
    - 取:ctx.getAttribute("user");
    - 存:ctx.setAttribute("user","admin");
 6. 通常在Tomcat启动时,都要调用某Servlet重写init(ServletConfig config)方法,专门用来在此阶段初始化项目所需要的一些变量。

使用案例:

1. ServletConfig案例:
  a. 配置文件web.xml
  <servlet>
  	<servlet-name>login</servlet-name>
  	<servlet-class>web.LoginServlet</servlet-class>
  	<!-- 给当前Servlet预置一个数据 -->
  	<init-param>
  		<param-name>maxOnline</param-name>
  		<param-value>2000</param-value>
  	</init-param>
  </servlet>
  <servlet-mapping>
  	<servlet-name>login</servlet-name>
  	<url-pattern>/login</url-pattern>
  </servlet-mapping>
  b. 在Servlet类中读取参数
	/**
	 * 1.Tomcat在创建此Servlet后,会自动创建ServletConfig对象。
	 * 2.Tomcat会调用此对象,读取web.xml中给当前Servlet所配置的参数。
	 * 3.Tomcat会自动调用init方法,并传入已创建好的ServletConfig对象。
	 * 归纳:调用init方法前,创建config并读取数据。在init及其后面的方法内可以使用config。
	 */
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		String mo = config.getInitParameter("maxOnline");
		System.out.println(mo);
	}

	@Override
	protected void service(
		HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		//从web.xml中读取参数
		ServletConfig cfg = getServletConfig();
		String mo = cfg.getInitParameter("maxOnline");
		System.out.println(mo);
	}

2. ServletContext案例:

  a. 配置文件web.xml

  <!-- 
  	给所有的Servlet预置一个数据。
  	1.Tomcat启动时会自动创建ServletContext对象。
  	2.Tomcat调用context读取此参数。
  	由于这件事是在调用Servlet之前完成的,所以在service()中可以通过context读取参数。
  -->
  <context-param>
  	<param-name>size</param-name>
  	<param-value>10</param-value>
  </context-param>
  
  <servlet>
  	<servlet-name>findDept</servlet-name>
  	<servlet-class>web.FindDeptServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>findDept</servlet-name>
  	<url-pattern>/findDept</url-pattern>
  </servlet-mapping>

  b. 在Servlet类中读取参数

@Override
protected void service(
	HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
	//从web.xml中读取分页条件
	ServletContext ctx = getServletContext();
	String size = ctx.getInitParameter("size");
	//分页查询
	System.out.println(size);
}

线程安全:

1. 成员变量:

    - 成员变量存于堆内;

    - 堆内数据只有一份;

    - 多线程共用一份数据;

    - 存在并发问题;

2. 局部变量:

    - 成员变量存于栈内;

    - 栈内数据是多份;

    - 每个线程都有一份自己的数据;

    - 没有并发问题;

3. 解决方案:

   - 不用成员;

   - 枷锁synchronized (this) {//TODO};

HttpServlet:

1. 自定义的类继承HttpServlet类,重写service方法,Tomcat将HttpServletRequest,HttpServletResponse传入此方法:

public class TestServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		super.service(req, res);
		
	}
	
	//...
}
2. 调用父类,并将HttpServletRequest、HttpServletResponse两个参数传入:

public class HttpServlet {
	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res= (HttpServletResponse) response;
		this.service(req, res);
	}
	public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		String m = req.getMethod();
		if(m.equals("GET")) {
			doGet(req, res);
		}else if(m.equals("POST")) {
			doPost(req, res);
		}
	}		
	private void doPost(HttpServletRequest req, HttpServletResponse res) {
		// TODO
		
	}
	private void doGet(HttpServletRequest req, HttpServletResponse res) {
		// TODO
		
	}
	
	//...
}
3. doGet()和doPost()默认的代码直接抛出了异常,为了强制开发者去重写他们。若要调用它们,就必须重写;

4. service()内去掉super.service()的目的就是不掉用它们,从而避免异常;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值