Servlet

一个Servlet就可以直接处理一个Http请求

在没有框架的时代,Http请求到达Tomcat应用服务器,服务器更具web.xml中配置的servletmapping,也就是关于哪些请求应该找那个servlet来处理。然后直接将这个Http请求交个对应的Servlet类。所以这些负责哪个请求的servlet配置必须得由程序员在xml文件中配置好才行。
在这里插入图片描述
请求处理方式:
1.去掉项目前缀URL,只剩下login
2.根据url匹配找到应该由名为LoginServlet的Servlet来处理
而名为LoginServlet真实对应的类是demo.servlet.LoginServlet
然后就new一个该Servlet来处理这个Http请求,保证了线程安全。

Spring MVC封装Servlet

Spring主要是通过DispatcherServlet实现了Servlet这个接口,又叫前端控制器,来自前端的请求会先到达这里,它负责去后台匹配合适的Handler(也就是真正的执行逻辑(相当于Servlet中的doGet))

比于之前的servlet,它一定程度上简化了开发人员的工作,使用servlet的话需要每个请求都去在web.xml中配置一个servlet节点,而Spring 中的DispatcherServlet他会拦截所有的请求,进一步去查找有没有合适的处理器,一个前端控制器就可以

HttpServlet

Servlet是一个接口,由Servlet容器直接来创建实现了该接口的实例

Servlet有五个方法:
1.init()只初始化一次
2.getServletConfig()
3.service(ServletRequest,ServletResponse):真正的执行
4.getServletInfo()
5.destory():在tomcat关闭或者该web项目被移出时调用

因为Servlet是Java服务端为了实现动态交互的一个接口,而基本上现在交互使用的都是HTTP协议,所以设计了基于HTTP协议的新接口,继承了Servlet接口的HttpServlet抽象类
在这里插入图片描述
然后将原来的service方法直接拆分成6个方法,来适应HTTP的六种不同的请求
• doGet
• doPost
• doPut
• doDelete
• doOptions
• doTrace
开发者只要根据请求方式来重写不同的方法即可
在这里插入图片描述
1、HttpServletRequest
HttpServletRequest接口继承自ServletRequest
因为Request代表请求,所以我们可以通过该对象分别获得HTTP请求的请求行,请求头和请求体
在这里插入图片描述
在service中使用的编码解码方式默认为 :ISO-8859-1编码,但此编码并不支持中文,因此会出现乱码问题,所以我们需要手动修改编码方式为UTF-8编码,才能解决中文乱码问题,下面是发生乱码的具体细节:
在这里插入图片描述
在这里插入图片描述

2、HttpServletResponse
HttpServletResponse接口继承自ServletResponse
在Service API中,定义了一HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。
由于HTTP请求消息分为状态行,响应消息头,响应消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码,响应消息头,响应消息体的方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我们如何自己手写一个servlet

实现Servlet的三种方式:

  1. 实现javax.servlet.Servlet接口,重写接口中的5个方法
public MyServlet implements Servlet {
  
  // 生命周期的4个方法:构造方法、init、service、destroy, service方法每次请求都会被调用,其他三个方法	 //	只会调用一次
  // 生命周期流程:实例化(构造方法) --> 初始化(init) --> 服务(service) --> 销毁(destroy)
  
  // 第一次访问Servlet就创建,单实例
  public MyServle() {
    ...
  }
  
  @Override
  // 第一次访问Servlet就初始化
  // ServletConfig接口实例用于获取Servlet配置信息,该接口提供了4个方法:
  // getServletName()
  // getInitParameter(String name)
  // getInitParameterNames()
  // getServletContext()  注:GenericServlet中有getServletConfig()和getServletContext()方法
  public void init(ServletConfig config) {
    ...
  }
  @Override
  public void service(ServletRequest request, ServletResponse response) {
    ...
  }
  @Override
  // 应用卸载了就销毁
  public void destroy() {
    ...
  }
  @Override
  public String getServletInfo() {
    ...
  }
  @Override
  public ServletConfig getServletConfig() {
    ...
  }
}
  1. 继承抽象类javax.servlet.GenericServlet,重写service方法

该抽象类实现了除service方法以外的4个方法,service方法为抽象方法

  1. 继承抽象类javax.servlet.http.HttpServlet,重写doGet和doPost方法 (开发中最常用)

抽象类HttpServlet实现了全部5个方法,在service方法的实现service(ServletRequest request, ServletResponse response)中,将ServletRequest对象ServletResponse对象分别强转成了HttpServletRequest对象HttpServletResponse对象,然后调用本地的service(HttpServletRequest request, HttpServletResponse response)方法,在本地的service方法中,根据请求方式的不同调用doGet、doPost、doDelete等方法,并且自身也实现了这些方法,但是自己实现的doGet、doPost等方法是返回错误响应码405(不允许此方法 HTTP 1.1)或者400(请求出错 非HTTP 1.1),所以我们选择这种Servlet实现方式时,必须重写doGet和doPost方法

public MyServlet extends HttpServlet {
  @Override
  public void doGet(HttpServletRequest request, HttpServletReposne response) {
    ...
  }
  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response) {
    ...
  }
}

在这里插入图片描述

实现了Servlet之后必须在web.xml中注册

<servlet>
	<servlet-name>Servlet名字</servlet-name>
  	<servlet-class>你编写的Servlet所在的路径</servlet-class>
  	<!-- 这个标签中的值必须为整数,当值>=0时表示在服务器启动时就创建该Servlet,并且值越小,该Servlet启		 动的优先级越高;当值<0时或者没有指定该标签时,则该Servlet在被选择时才加载 -->
  	<load-on-startup>1</load-on-startup>
  	<init-param>
      	<param-name>参数1</param-name>
      	<param-value>参数值1</param-value>
  	</init-param>
  	<init-param>
      	<param-name>参数2</param-name>
      	<param-value>参数值2</param-value>
  	</init-param>
</servlet>
<servlet-mapping>
	<servlet-name>跟上面servlet节点中的servlet名字一致</servlet-name>
  	<url-pattern>路径匹配模式</url-pattern>
</servlet-mapping>

如何在服务器启动时就创建Servlet?<load-on-startup>标签

Servlet的url-pattern匹配模式与Filter相同,但是匹配是有顺序的:先精确匹配,再路径匹配,最后后缀匹配,一次请求只会匹配一个Servlet。

context全局参数配置方式:

<context-param>
	<param-name>参数1</param-name>
  	<param-value>参数值1</param-value>
</context-param>
<context-param>
	<param-name>参数2</param-name>
  	<param-value>参数值2</param-value>
</context-param>

可以通过ServletContext的getInitParameter(String name)方法来获取全局参数值

Servlet三大域对象:

ServletContext:代表整个应用(WEB项目),一个应用只有一个ServletContext对象,单实例

HttpSession:会话范围

ServletRequest:请求范围

// 往ServletContext、HttpSession、ServletRequest中设置属性、更新属性、删除属性
void setAttribute(String name, Object value)
Object getAttribute(String name)
void removeAttribute(String name)

Servlet中请求转发和请求包含

ServletContext application = this.getServletContext();
RequestDispatcher rd = application.getRequestDispatcher("/contextDemo2");
// 请求转发: 由当前Servlet设置响应头,下一个Servlet设置响应头和响应体
// 设置响应头:response.setHeader("aaa", "bbb")
// 设置响应体:response.getWritter().print("Hello World!")
rd.forward(request, response);
// 请求包含: 当前Servlet和下一个Servlet都可以设置响应头和响应体
rd.include(request, response);

请求转发和重定向的区别:

请求转发:一次请求一次响应,地址栏不变,只能转发到本项目其他的Servlet,服务端的行为

重定向:二次请求两次响应,地址栏变化,不只能重定向到本项目的其它Servlet,还能定向到其它项目,浏览器端的行为。重定向用法:response.sendRedirect("url地址")

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值