servlet和jsp的区别

jsp作为Servlet技术的扩展,经常会有人将jsp和Servlet搞混。本文,将为大家带来servlet和jsp的区别,希望对大家有所帮助。

servlet和jsp的区别

1、Servlet在Java代码中可以通过HttpServletResponse对象动态输出HTML内容。

2、JSP是在静态HTML内容中嵌入Java代码,然后Java代码在被动态执行后生成HTML内容。

servlet和jsp的各自的特点

1、Servlet虽然能够很好地组织业务逻辑代码,但是在Java源文件中,因为是通过字符串拼接的方式生成动态HTML内容,这样就容易导致代码维护困难、可读性差。

2、JSP虽然规避了Servlet在生成HTML内容方面的劣势,但是在HTML中混入大量、复杂的业务逻辑。

通过MVC双剑合璧

JSP和Servlet都有自身的适用环境,那么有没有什么办法能够让它们发挥各自的优势呢?答案是肯有的,MVC模式就能够完美解决这一问题。

MVC模式,是Model-View-Controller的简称,是软件工程中的一种软件架构模式,分为三个基本部分,分别是:模型(Model)、视图(View)和控制器(Controller):

Controller——负责转发请求,对请求进行处理

View——负责界面显示

Model——业务功能编写(例如算法实现)、数据库设计以及数据存取操作实现

在JSP/Servlet开发的软件系统中,这三个部分的描述如下所示:

1、Web浏览器发送HTTP请求到服务端,然后被Controller(Servlet)获取并进行处理(例如参数解析、请求转发)

2、Controller(Servlet)调用核心业务逻辑——Model部分,获得结果

3、Controller(Servlet)将逻辑处理结果交给View(JSP),动态输出HTML内容

4、动态生成的HTML内容返回到浏览器显示

MVC模式在Web开发中有很大的优势,它完美规避了JSP与Servlet各自的缺点,让Servlet只负责业务逻辑部分,而不会生成HTML代码;同时JSP中也不会充斥着大量的业务代码,这样能大提高了代码的可读性和可维护性。

Spring 中的Servlet与Spring MVC 有什么区别?

ServletSpring MVC都是在Java Web开发中用于处理Web请求的技术,其中Servlet是Java EE规范的一部分,而Spring MVC是Spring Framework的一部分,属于Spring生态系统的一部分。

接下来,我们就来详细的介绍一下二者之间的区别,并且结合底层原理对其进行说明。

Servlet 是 Java EE(现在叫 Jakarta EE)中最核心的组件之一,它是一个接口,主要用于处理HTTP请求。通过实现 javax.servlet.Servlet 接口,来处理客户端发送的请求并生成响应。

其工作流程如下。

  • 第一步、 客户端一般情况下这个客户端通常是指浏览器,发起一个HTTP请求,Servlet会接收到该请求。
  • 第二步、当请求到达Servlet容器(例如Tomcat)之后,Servlet容器会解析请求的URL,并根据映射规则找到相应的Servlet。
  • 第三步、如果Servlet还没有被加载,容器会先实例化它。每个请求会触发Servlet的 service() 方法,该方法会根据HTTP请求类型(GET、POST等)调用相应的doGet()或doPost()等方法。
  • 第四步、Servlet处理完请求后,会将生成的响应数据(通常是HTML或JSON等)返回给客户端。
  • 第五步、当服务器关闭或Servlet不再需要时,容器会调用destroy()方法来销毁Servlet实例。

这也对应了之前的分享中,我们介绍的关于过滤器的操作内容,如下所示。

Servlet要求开发者可以手动处理HTTP请求的各个方面,包括从HttpServletRequest中获取参数,来生成HttpServletResponse响应,以及处理HTTP方法(如GET、POST等)。当然也可以通过转发请求给JSP引擎来渲染动态HTML页面。在默认情况下,Servlet是单实例的,也就是说每个Servlet实例可以处理多个请求,因此需要开发者保证线程安全。

Spring MVC是Spring Framework框架提供的一个基于Servlet实现的Web框架,它遵循MVC(Model-View-Controller)设计模式,其设计的目的就是为了简化Web应用的开发。并且Spring MVC是建立在Servlet API之上,与Servlet的不同就是它提供了更高层次的抽象,并对复杂的Web请求处理提供了更强大的支持。

Spring MVC的工作流程包括多个组件,它通过DispatcherServlet作为前端控制器来协调请求处理,其处理流程如下所示。

  • 第一步、和Servlet一样,客户端(浏览器)发送HTTP请求。
  • 第二步、请求首先到达Spring MVC的核心组件DispatcherServlet其本质上也是一个Servlet。
  • 第三步、这个时候DispatcherServlet会使用HandlerMapping来根据URL找到对应的处理器,这个处理器通常是一个控制器Controller。
  • 第四步、DispatcherServlet会调用映射到的控制器中的方法。而控制器方法通常会返回一个 ModelAndView对象这个对象包含视图名和模型数据,用来进行View层的数据渲染展示。
  • 第五步、DispatcherServlet通过ViewResolver来将返回的视图名解析为具体的视图,例如JSP或Thymeleaf模板引擎。
  • 第六步、视图负责渲染最终的HTML或其他格式的响应内容,最后响应返回给客户端。

如下所示,是一个简单的SpringMVC的示例。

Spring MVC主要依靠注解来定义控制器和映射规则,简化了开发。例如我们比较常见的注解有@Controller, @RequestMapping, @GetMapping, @PostMapping等,Spring MVC会自动将HTTP请求中的参数绑定到控制器方法的参数中,不需要手动从 HttpServletRequest 获取。提供了众多(interceptors)、过滤器(filters)等机制,可以方便地进行功能扩展。

通过内置的视图解析机制,可以轻松集成JSP、Thymeleaf等视图技术。支持对表单数据的自动绑定、表单验证和错误处理。

控制器的实现方式

  • Servlet直接实现或继承HttpServlet类来实现的具体操作,我们需要通过重写doGet()、doPost()等方法来处理HTTP请求操作。
  • Spring MVC控制器不需要继承特定类,它通常使用@Controller注解来标记控制类类,然后通过使用@RequestMapping或其他映射注解来定义URL的映射关系。这种方式避免了和具体的Servlet API绑定,使得Spring MVC的使用更加的灵活。

请求处理模型

  • Servlet是单个类对应单个URL映射,处理过程较为手动。需要开发者去处理大量的处理请求参数、构建响应。
  • Spring MVC采用了DispatcherServlet作为中央控制器,将所有的请求经过它来进行处理,然后通过各种策略模式的组件,例如HandlerMapping, HandlerAdapter, ViewResolver等进行分发和处理。这样对于开发者来讲,只需要专注于业务逻辑。而底层的许多重复工作,例如请求参数的处理、视图解析等则是由Spring框架自动完成。

对象和数据管理

  • Servlet处理请求的生命周期较短,主要通过HttpServletRequest和HttpServletResponse传递请求和响应的数据。Servlet则本身只专注于请求和响应的交互,对于状态的管理则需要通过会话Session或者通过上下文Context机制来实现。
  • Spring MVC中的数据传递更加高级,例如通过Model或ModelAndView来传递数据到视图。Spring MVC还整合了@ModelAttribute等注解来处理表单提交的数据绑定和数据校验,减少了手动从请求中获取参数的工作。

扩展性和模块化

  • Servlet本身比较底层,虽然灵活,但很多功能需要手动实现,比如会话管理、跨站请求伪造(CSRF)防护等,开发者必须依赖外部库或者自己实现。
  • Spring MVC提供了大量现成的组件,诸如数据绑定、校验、异常处理、国际化、模板引擎集成等。开发者可以通过扩展HandlerInterceptor、 ControllerAdvice 等类进行扩展,也可以利用Spring生态的众多功能(如Spring Security、Spring Data等)来增强Web应用。

依赖注入和AOP

  • Servlet本身不支持依赖注入,也没有AOP能力。需要结合Java EE中的CDI(Context and Dependency Injection)或手动管理依赖。
  • Spring MVC完全依赖Spring的核心功能即IOC容器和AOP,控制器类的依赖可以通过Spring的自动注入例如 @Autowired来管理,极大简化了组件之间的依赖管理。AOP(Aspect-Oriented Programming)也可以用于控制器中,以处理日志、事务等横切关注点。

Servlet是Java Web开发的底层技术,它是Java EE的一部分,要求开发者手动处理请求、响应、参数等内容。Servlet的API较为原始,虽然功能强大,但并没有提供高级的Web框架功能。Spring MVC是基于Servlet的一个Web框架,它简化了Web开发,通过 DispatcherServlet 提供了更加模块化、可扩展的方式来处理Web请求。Spring MVC 依赖Spring框架的依赖注入和其他组件,极大提升了开发效率,并且集成了大量Web开发中常用的功能。

两者的区别可以类比于“手工打造”与“利用框架搭建”,Spring MVC在Servlet的基础上进行了高度封装,简化了开发流程并增强了扩展性。

Java杂谈(八)--Servlet/Jsp

终于正式进入J2ee的细节部分了,首当其冲的当然是Servlet和Jsp了,上篇曾经提到过J2ee只是一个规范和指南,定义了一组必须要遵循的接口,核心概念是组件和容器。曾经有的人问我Servlet的Class文件是哪里来的?他认为是J2ee官方提供的,我举了一个简单的反例:稍微检查了一下Tomcat5.0里面的Servlet.jar文件和JBoss里面的Servlet.jar文件大小,很明显是不一样的,至少已经说明了它们不是源自同根的吧。其实Servlet是由容器根据J2ee的接口定义自己来实现的,实现的方式当然可以不同,只要都遵守J2ee规范和指南。

上述只是一个常见的误区罢了,告诉我们要编译运行Servlet,是要依赖于实现它的容器的,不然连jar文件都没有,编译都无法进行。那么Jsp呢?Java Server Page的简称,是为了开发动态网页而诞生的技术,其本质也是Jsp,在编写完毕之后会在容器启动时经过编译成对应的Servlet。只是我们利用Jsp的很多新特性,可以更加专注于前后台的分离,早期Jsp做前台是满流行的,毕竟里面支持Html代码,这让前台美工人员可以更有效率的去完成自己的工作。然后Jsp将请求转发到后台的Servlet,由Servlet处理业务逻辑,再转发回另外一个Jsp在前台显示出来。这似乎已经成为一种常用的模式,最初我学习J2ee的时候,大量时间也在编写这样的代码。

尽管现在做前台的技术越来越多,例如Flash、Ajax等,已经有很多人不再认为Jsp重要了。我觉得Jsp带来的不仅仅是前后端分离的设计理念,它的另外一项技术成就了我们今天用的很多框架,那就是Tag标签技术。所以与其说是在学习Jsp,不如更清醒的告诉自己在不断的理解Tag标签的意义和本质。

1. Servlet以及Jsp的生命周期

Servlet是Jsp的实质,尽管容器对它们的处理有所区别。Servlet有init()方法初始化,service()方法进行Web服务,destroy()方法进行销毁,从生到灭都由容器来掌握,所以这些方法除非你想自己来实现Servlet,否则是很少会接触到的。正是由于很少接触,才容易被广大初学者所忽略,希望大家至少记住Servlet生命周期方法都是回调方法。回调这个概念简单来说就是把自己注入另外一个类中,由它来调用你的方法,所谓的另外一个类就是Web容器,它只认识接口和接口的方法,注入进来的是怎样的对象不管,它只会根据所需调用这个对象在接口定义存在的那些方法。由容器来调用的Servlet对象的初始化、服务和销毁方法,所以叫做回调。这个概念对学习其他J2ee技术相当关键!

那么Jsp呢?本事上是Servlet,还是有些区别的,它的生命周期是这样的:

a) 一个客户端的Request到达服务器 ->

b) 判断是否第一次调用 -> 是的话编译Jsp成Servlet

c) 否的话再判断此Jsp是否有改变 -> 是的话也重新编译Jsp成Servlet

d) 已经编译最近版本的Servlet装载所需的其他Class

e) 发布Servlet,即调用它的Service()方法

所以Jsp号称的是第一次Load缓慢,以后都会很快的运行。从它的生命的周期确实不难看出来这个特点,客户端的操作很少会改变Jsp的源码,所以它不需要编译第二次就一直可以为客户端提供服务。这里稍微解释一下Http的无状态性,因为发现很多人误解,Http的无状态性是指每次一张页面显示出来了,与服务器的连接其实就已经断开了,当再次有提交动作的时候,才会再次与服务器进行连接请求提供服务。当然还有现在比较流行的是Ajax与服务器异步通过xml交互的技术,在做前台的领域潜力巨大,我不是Ajax的高手,这里无法为大家解释。

2. Tag标签的本质

我之前说了,Jsp本身初衷是使得Web应用前后台的开发可以脱离耦合分开有效的进行,可惜这个理念的贡献反倒不如它带来的Tag技术对J2ee的贡献要大。也许已经有很多人开始使用Tag技术了却并不了解它。所以才建议大家在学习J2ee开始的时候一定要认真学习Jsp,其实最重要的就是明白标签的本质。

Html标签我们都很熟悉了,有 <html> 、 <head> 、 <body> 、 <title> ,Jsp带来的Tag标签遵循同样的格式,或者说更严格的Xml格式规范,例如 <jsp:include> 、 <jsp:useBean> 、 <c:if> 、 <c:forEach> 等等。它们没有什么神秘的地方,就其源头也还是Java Class而已,Tag标签的实质也就是一段Java代码,或者说一个Class文件。当配置文件设置好去哪里寻找这些Class的路径后,容器负责将页面中存在的标签对应到相应的Class上,执行那段特定的Java代码,如此而已。

说得明白一点的话还是举几个简单的例子说明一下吧:

<jsp:include> 去哪里找执行什么class呢?首先这是个jsp类库的标签,当然要去jsp类库寻找相应的class了,同样它也是由Web容器来提供,例如Tomcat就应该去安装目录的lib文件夹下面的jsp-api.jar里面找,有兴趣的可以去找一找啊!

<c:forEach> 又去哪里找呢?这个是由Jsp2.0版本推荐的和核心标记库的内容,例如 <c:if> 就对应在页面中做if判断的功能的一断Java代码。它的class文件在jstl.jar这个类库里面,往往还需要和一个standard.jar类库一起导入,放在具体Web项目的WEB-INF的lib目录下面就可以使用了。

顺便罗唆一句,Web Project的目录结构是相对固定的,因为容器会按照固定的路径去寻找它需要的配置文件和资源,这个任何一本J2ee入门书上都有,这里就不介绍了。了解Tag的本质还要了解它的工作原理,所以大家去J2ee的API里找到并研究这个包:javax.servlet.jsp.tagext。它有一些接口,和一些实现类,专门用语开发Tag,只有自己亲自写出几个不同功能的标签,才算是真正理解了标签的原理。别忘记了自己开发的标签要自己去完成配置文件,容器只是集成了去哪里寻找jsp标签对应class的路径,自己写的标签库当然要告诉容器去哪里找啦。

说了这么多,我们为什么要用标签呢?完全在Jsp里面来个 <% %> 就可以在里面任意写Java代码了,但是长期实践发现页面代码统一都是与html同风格的标记语言更加有助于美工人员进行开发前台,它不需要懂Java,只要Java程序员给个列表告诉美工什么标签可以完成什么逻辑功能,他就可以专注于美工,也算是进一步隔离了前后台的工作吧!

3. 成就Web框架

框架是什么?曾经看过这样的定义:与模式类似,框架也是解决特定问题的可重用方法,框架是一个描述性的构建块和服务集合,开发人员可以用来达成某个目标。一般来说,框架提供了解决某类问题的基础设施,是用来创建解决方案的工具,而不是问题的解决方案。

正是由于Tag的出现,成就了以后出现的那么多Web框架,它们都开发了自己成熟实用的一套标签,然后由特定的Xml文件来配置加载信息,力图使得Web应用的开发变得更加高效。下面这些标签相应对很多人来说相当熟悉了:

<html:password>

<logic:equal>

<bean:write>

<f:view>

<h:form>

<h:message>

它们分别来自Struts和JSF框架,最强大的功能在于控制转发,就是MVC三层模型中间完成控制器的工作。Struts-1实际上并未做到真正的三层隔离,这一点在Struts-2上得到了很大的改进。而Jsf向来以比较完善合理的标签库受到人们推崇。

今天就大概讲这么多吧,再次需要强调的是Servlet/Jsp是学习J2ee必经之路,也是最基础的知识,希望大家给与足够的重视!

想要了解更多Java知识那就来关注我们吧! 精彩内容多多哦!不从错过哦!

多多关注

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。