JavaWeb开发中的Servlet与DispatchServlet解析

在 做java Web 开发一定躲不开的是 Servlet。但是因为现在Spring系列框架的封装,我们已经感受不到Servlet的存在,因此对javaweb的底层并不了解,本文给大家详细介绍一下java Servlet相关技术的来龙去脉。

servlet

Servlet 是一套用于处理 HTTP 请求的 API 标准。我们可以基于 Servlet 实现 HTTP 请求的处理。但是 JavaEE 当中只提供了 Servlet 的标准,要真正运行 Servlet,需要使用 Servlet Container。

这层抽象让 Servlet 可以跑在任何一个 Container 当中,隔绝了对 Runtime 环境的依赖。

JavaEE 本身没有提供 Servlet Container,比较常用支持 Servlet Container 的 Server 软件有 Apache Tomcat,Glassfish,JBoss,Jetty 等等

Servlet 是 Java Web 开发的事实标准,不过也不代表所有 Java Web 框架都一定要使用或者兼容 Servlet。不使用 Servlet 也可以进行 Java Web 开发,例如 Play Framework,就是完全自立门户的一个框架。

创建一个自己的Servlet

public class MyFirstServlet implements Servlet {
 public void init(ServletConfig config) throws ServletException {
 System.out.println("Init");
 }
 public void service(ServletRequest request, ServletResponse response)
 throws ServletException, IOException {
 System.out.println("From service");
 PrintWriter out = response.getWriter();
 out.println("Hello, Java Web.");
 }
 public void destroy() {
 System.out.println("Destroy");
 }
 public String getServletInfo() {
 return null;
 }
 public ServletConfig getServletConfig() {
 return null;
 }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <servlet>
 <servlet-name>MyFirstServletName</servlet-name>
 <servlet-class>com.skyline.MyFirstServlet</servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet-name>MyFirstServletName</servlet-name>
 <url-pattern>/hello</url-pattern>
 </servlet-mapping>
</web-app>

web.xml 的作用是告诉 Servlet容器,这里用的Tomcat,我们想使用哪个 Servlet 来处理对应的请求。Tomcat 通过 web.xml 找到对应的 Servlet 完成请求以及响应过程。

HttpServlet

使用 Servlet 我们就可以生成简单的网页了,例如:

public class MyFirstServlet extends HttpServlet {
 protected void doGet(HttpServletRequest request,
 HttpServletResponse response)
 throws ServletException, IOException {
 response.getWriter().write("<html>");
 response.getWriter().write("<body>");
 response.getWriter().write("<h2>");
 response.getWriter().write(LocalDateTime.now().toString());
 response.getWriter().write("</h2>");
 response.getWriter().write("</body>");
 response.getWriter().write("</html>");
 }
}

注意我们使用了 HttpServlet 而不是前一个例子中的 Servlet,它是一个更高级的封装类。

可以看到,虽然我们可以输出网页了,但是这种写法实在是让人崩溃。所以后面出现了JSP技术。JSP,全称 JavaServer Pages。JSP 可以理解成一种高度抽象的 Servlet。事实上 JSP 在运行期间会被编译成 Servlet,因此 JSP 和 Servlet 可以认为没有本质上的差异,只不过写起来容易了很多。当然,现在JSP技术也已经过时了。

DispatchServlet

是SpringMvc中对请求进行分发的servlet。就是根据请求的URL,按照配置的规则,转发给处理该请求的Controller

通过第一个Servlet的例子,我们处理某个请求,就在web.xml中配置处理它的servlet。然而对于真实的项目来说,如果加一个(或一类)请求就配置一下,这就是个灾难。所以在Spring框架中,就有了这个DispatchServlet,在Servlet之上做了一层分发逻辑。

一般我们使用SpringMVC时,web.xml会这样配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <servlet>
 <servlet-name>MyFirstServletName</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
 <servlet-name>MyFirstServletName</servlet-name>
 <url-pattern>/*</url-pattern>
 </servlet-mapping>
</web-app>

通过/*将所有请求交给Spring的DispatcherServlet处理

另外要注意<load-on-startup>1</load-on-startup>配置,在Container启动的时候就要加载这个Servlet,而不是等到请求过来的时候再加载。

这样,在我们之后编写Controller,使用@RequestMapping描述了处理的url后。spring会根据注解解析自动获得将哪个请求分发给哪个Controller处理的逻辑

Servlet 3

Spring 本身逐渐从 XML 转向了基于 Annotation 的配置,与之类似的,Servlet API 从 3.0 开始也支持了基于 Annotation 的配置。

在 Servlet 3 中,我们可以继承 ServletContainerInitializer 来实现替代 web.xml 的作用。Servlet 3 要求在 deploy 目录中加入 META-INF/services/javax.servlet.ServletContainerInitializer 文件,来指示 ServletContainerInitializer 的实现者,用于 Servlet 的初始化。

SpringMVC 已经帮我们做了这件事情,在 spring-web-4.3.9.RELEASE 这个 jar 里我们可以找到 javax.servlet.ServletContainerInitializer 这个文件,里面的内容是:

org.springframework.web.SpringServletContainerInitializer

同时 SpringMVC 暴露出了自己的接口,名为 WebApplicationInitializer,通过这个接口我们可以进行类似 web.xml 的配置。

注意这一层封装,实际上是想把 Servlet API 和 Spring API 隔离开,在 SpringBoot 框架中我们会有更加深刻的体会。

创建一个新类 MyWebApplicationInitializer:

import javax.servlet.*;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.servlet.DispatcherServlet;
public class MyWebApplicationInitializer implements WebApplicationInitializer {
 @Override
 public void onStartup(ServletContext container) {
 ServletRegistration.Dynamic registration = container.addServlet("MyFirstServletName", new DispatcherServlet());
 registration.setLoadOnStartup(1);
 registration.addMapping("/");
 }
}

注意我们配置的内容,实际上和之前用过的 web.xml 是可以对应的:

<servlet>
 <servlet-name>MyFirstServletName</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
 <servlet-name>MyFirstServletName</servlet-name>
 <url-pattern>/*</url-pattern>
</servlet-mapping>

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

热门产品

php编程基础教程.pptx|php编程培训,php,编程,基础,教程,pptx
php编程基础教程.pptx

历史上的今天:05月01日

热门专题

云南开放大学|云南开放大学报名,云南开放大学报考,云南开放大学,什么是云南开放大学,云南开放大学学历,云南开放大学学费,云南开放大学报名条件,云南开放大学报名时间,云南开放大学学历,云南开放大学专业
云南开放大学
外贸网站建设|外贸网站建设,英文网站制作,英文网站设计,美国主机空间,外贸建站平台,多语言网站制作
外贸网站建设
安徽开放大学|安徽开放大学报名,安徽开放大学报考,安徽开放大学,什么是安徽开放大学,安徽开放大学学历,安徽开放大学学费,安徽开放大学报名条件,安徽开放大学报名时间,安徽开放大学学历,安徽开放大学专业
安徽开放大学
大理科技管理学校|大理科技管理中等职业技术学校,大理市科技管理中等职业技术学校
大理科技管理学校
安徽中源管业有限公司|安徽中源管业有限公司,安徽中源管业有限公司介绍,安徽中源管业有限公司电话,安徽中源管业有限公司地址,安徽中源管业有限公司厂家,安徽中源管业有限公司电力管,安徽中源管业有限公司管材
安徽中源管业有限公司
云南网站建设|云南网站制作,网站建设,云南网站开发,云南网站设计,云南网页设计,云南网站建设公司,云南网站建设
云南网站建设
一年制中专|中专学历,中专是什么学历,中专是什么,中专有什么专业,中专升大专,一年制中专
一年制中专
综合高中|云南综合高中,昆明综合高中,综合高中能考本一吗,综合高中和普通高中的区别,综合高中是什么意思,综合高中能参加全国统一高考吗,综合高中可以考哪些大学,综合高中的学籍是什么
综合高中

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部