Servlet是运行在Web服务器上的程序,它担当Web浏览器或其它http客户端发出的请求,与http服务器上的数据库或应用程序之间的中间层.它们的工作是执行如下所示的任务:
- 读取客户程序发送的显式数据
- 读取浏览器发出的隐式http请求数据
- 生成结果
- 向客户发送显式数据(即文档)
- 发送隐式的http响应数据
这5个工作步骤看起来比较抽象,我们举个具体的例子来说明.
我们知道一个Servlet可以对应处理某个链接请求,当我们用浏览器请求某个链接时(以GET请求为例),浏览器实际上会发送这些东西到Web服务器:
GET /lifecycle/welcome?username=liangyudong HTTP/1.1
Host: localhost:8082
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: Hm_lvt_82116c626a8d504a5c0675073362ef6f=1585269393,1585357421,1586488037,1586738782
这就是一个标准的http请求的格式.
假设Web服务器是你编写的,那么你的服务器为了处理这个请求,是不是要解析这段http请求内容,这个http请求的method是什么,协议是什么,都有哪些请求参数,有哪些头字段,有哪些cookie等等.当你解析完这些内容时,是不是要提供一个标准的方式让人可以访问拿到这些信息.
当我们想明白这些,就可以清楚知道Servlet是什么了,它其实就是一些Java接口,定义了操纵这些数据的规范.所有的Java Web服务器开发商都遵循这个规范来开发Web服务器,这样我们就可以用统一的规范来编程了.
我们先来编写一个简单的Servlet,可以看到HttpServletRequest对象就代表了http请求内容,这其实就是一个接口,定义了访问http请求内容的规范.
具体的解析http请求内容的工作由Web服务器完成,然后暴露HttpServletRequest对象给我们,这样我们就可以做自己的事情了.
HttpServletResponse对象则代表了http响应内容,这其实也是个接口,定义了生成http响应内容的规范.当然,具体的实现细节也是Web服务器完成的.
public
请求这个Servlet的http响应内容是这样的,可以看到这就是一个标准的http响应的格式,Web服务器添加了隐式的http响应数据,而动态的html网页内容则是由我们在Servlet里生成:
HTTP/1.1 200
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 155
Date: Sat, 09 May 2020 07:29:56 GMT
Keep-Alive: timeout=20
Connection: keep-alive
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>welcome</title>
</head>
<body>
<h1>liangyudong welcome!</h1>
</body>
</html>
用浏览器请求的的展示效果是这样的:
通过这个例子,是不是能很好理解Servlet的5个工作步骤了.
那么JSP又是什么呢?
通过前面的例子,我们可以看到html网页内容需要我们在Servlet里去一个标签一个标签去生成,如果一个页面超级复杂,特别是现在html页面动不动几千行代码,那这个Servlet的代码就会十分庞大臃肿,可读性可维护性都非常差.
这时候怎么办呢?sun公司很早就意识到了这个问题,便倡导很多公司一块来创建了一种能够动态生成html的新技术,于是JSP便应运而生,有效的解决了上面Servlet所出现的问题.
上述例子的JSP版本:
Servlet代码,业务逻辑均在此处理(HelloJspServlet.java):
public
JSP代码,页面展示(welcome.jsp):
<%@ page contentType="text/html" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>welcome</title>
</head>
<body>
<h1>${requestScope.username} welcome!</h1>
</body>
</html>
该JSP页面会先被翻译成Servlet文件(翻译工作由Web服务器完成),然后在被编译成class文件.我们可以可以看看翻译后的Servlet文件是怎样的(welcome_jsp.java):
public
所以说JSP只是Servlet的一种特殊形式,每一个JSP页面就是一个Servlet实例,通俗一点的话来说:JSP就是Servlet,只不过Servlet把一些业务功能剥离开来交给了或者是形成了JSP.总的来说:Servlet侧重于业务处理,而JSP侧重于页面展示.
关于Servlet和JSP的介绍就到这里.另外我关注到有很多人有这样的观点:认为Servlet和JSP过时了,所以可以不用学了,这个观点我非常不赞同.目前来说Servlet编程仍然是Java Web编程的核心,不管是springMVC框架,还是struts框架,其底层用的还是Servlet,因此掌握Servlet仍然是Java程序员的必备技能之一.
而对于JSP,其作为曾经一度火爆的技术,目前还是有大量的公司遗留项目的表现层技术用的是JSP,而这些遗留项目还是在继续维护中的,我们在公司里不可避免的需要维护和更新这些项目,所以JSP还是需要理解的,但不需钻研太深.
现在的主流开发趋势是前后端分离.前后端分离其实就是后端工程师只关注于后端业务逻辑的开发,不再处理前端问题.前端工程师只关注于自己的页面开发.当需要数据交互的时候,两者会有一份接口文档.这种趋势的流行真正让JSP走向没落.
最后想深入学习Servlet的,推荐此书:
<<Servlet与JSP核心编程>> 美Marty Hall, Larry Brown著
源码github地址:
https://github.com/jufeng98/java-mastergithub.com