2018/12/11 什么是servlet
早上占坑。
servlet概念:
Java web动态网页开发分两种方式servlet和jsp,但是jsp的实现底层也是通过servlet实现的,所以servlet技术是Java web开发的底层实现方式。
servlet实际上是jdk中定义的一个servlet接口,实现了该接口的类可以被tomcat等servlet容器调用,在配置文件中配置servlet和url的映射后,servlet就可以供浏览器访问了。
实际开发中,人们常常将继承了servlet接口的类称为servlet,所以servlet不再单单指servlet接口。但应该明白servlet实际上是一个定义的接口。
大神对servlet的理解:
Servlet是sun公司提供的一门用于开发动态web资源的技术。
Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
1、编写一个Java类,实现servlet接口。
2、把开发好的Java类部署到web服务器中。
按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet
servlet访问过程:比如通过浏览器访问一个servlet开发的服务,http://www.servlet.com/services/test
1.客户端浏览器发送http请求给web服务器,tomcat
2.tomcat解析url,将请求解析到指定的主机host和网站website
3.tomcat通过配置文件的servlet和url的映射配置发现访问的接口为某一个servlet接口
4.如果当前访问是第一次访问该servlet,则创建该servlet实例,调用init()方法。已存在实例则直接下一步。
5.tomcat为该请求创建request实例和response实例,分别封装请求数据和返回数据,(注意,为每个请求创建单独的request和response实例,request实例将请求的数据封装到实例中,且该实例的创建是由tomcat创建的)
6.tomcat调用servlet的service(request,response)方法,将request和response实例当作参数传入service方法中,接下来就是开发者根据自己的业务需求在service中读取request实例的数据,将处理结果返回给response实例
7.service方法执行完毕后,返回response处理结果(根据请求类型的不同,可能直接返回response结果,也可能tomcat根据servlet的控制和返回结果进行动态网页的拼接,将拼接的静态网页给web服务器,然后返回给客户端)
注意:
1.servlet只创建一个实例,所有请求调用的都是同一个实例,
2.但是为每个请求创建单独的request和response实例作为service方法的参数。
3.因为所有的请求共用一个servlet实例,所以定义的servlet类中的属性变量可以被所有请求访问,因此对于servlet类的属性的访问存在线程安全问题,必须考虑。
4.这个servlet的生命周期从web服务器启动,第一次servlet访问,创建servlet实例后直到web服务器关闭。(所以,init方法只调用一次)
5.因为servlet只是一个接口,所以如果直接继承servlet会有很多东西需要自己处理,比如http请求的处理,request实例的创建等,所以Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。
开发者可以直接继承这两个servlet实现类然后重写部分自己需要的方法,service、doPost、doGet等,就可以实现自己的servlet了。(类似于AbstractCollection的作用,使开发者不必从头实现复杂的所有的接口)
(通过servlet的原理,就可以理解.net中controller的request、response等这些属性的来源和属性变量的共享是怎么回事了)
这个过程是简化版的servlet调用过程,可以供理解使用,实际上,有丰富的配置可以供开发者选择,
比如
配置load-on-startup来让tomcat启动时就创建servlet实例,然后调用init方法
配置创建多个servlet实例
配置多个url映射,通配符*url等
配置单线程访问等,这些配置可以后续深入学习时再理解。
关于servlet属性变量的线程安全问题
如果加synchronized锁来实现,这种做法虽然解决了线程安全问题,但是编写Servlet却万万不能用这种方式处理线程安全问题,假如有9999个人同时访问这个Servlet,那么这9999个人必须按先后顺序排队轮流访问。
针对Servlet的线程安全问题,Sun公司是提供有解决方案的:让Servlet去实现一个SingleThreadModel接口,如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。(该接口已过时)
查看Sevlet的API可以看到,SingleThreadModel接口中没有定义任何方法和常量,在Java中,把没有定义任何方法和常量的接口称之为标记接口,
经常看到的一个最典型的标记接口就是"Serializable",这个接口也是没有定义任何方法和常量的,标记接口在Java中有什么用呢?
主要作用就是给某个对象打上一个标志,告诉JVM,这个对象可以做什么,比如实现了"Serializable"接口的类的对象就可以被序列化,还有一个"Cloneable"接口,这个也是一个标记接口,在默认情况下,Java中的对象是不允许被克隆的,就像现实生活中的人一样,不允许克隆,但是只要实现了"Cloneable"接口,那么对象就可以被克隆了。
servlet类和普通类的区别:
Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。
到此处,可以补充servlet容器tomcat起到了什么作用。
tomcat作为容器其实并没有做什么玄学的事情,它仍然是做我们开发常做的事情,调用接口、方法,而已。
动态网页也不玄,所有的开发捅破窗户纸后其实都不玄,很普通,就是定义方法、定义类,调用方法、调用类。高大上如游戏开发也不外乎这样。
实际举例:
配置url Mapping:(web.xml)
<servlet> <servlet-name>ServletDemo1</servlet-name> <servlet-class>gacl.servlet.study.ServletDemo1</servlet-class> </servlet> //注册servlet的名称 <servlet-mapping> <servlet-name>ServletDemo1</servlet-name> <url-pattern>/servlet/ServletDemo1</url-pattern> </servlet-mapping> //配置映射url,映射url支持*通配符,如果url匹配多个,调用最接近的那个。
至此,浏览器就可以通过url访问servlet啦!
补充:控制浏览器如何处理response的数据是由开发者设置的,
比如浏览器用什么编码解析文本,
response.setHeader("content-type", "text/html;charset=UTF-8"); 或
response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
浏览器下载的方式处理发送的资源,
response.setHeader("content-disposition", "attachment;filename="+fileName);
以html方式处理,以图片方式处理,以文件方式处理,,,等等
这些都是可以通过response这个类去进行设置的。要熟练掌握response类。
明天,什么是http协议,它有什么作用,有哪些设置