背景
- Servlet是运行在服务器上的Java程序,用来完成B/S架构下,客户请求的响应处理(HTML格式)
- 平台独立,性能优良,能以线程方式运行
- Servlet API为Servlet提供了统一的编程接口
- Servlet在容器中运行,由容器调用接口,常用Tomcat
- TCP/IP参考模型中,只有应用层,没有表示层和会话层,所以,程序员必须自己在应用层实现表示层和会话层
- B/S可看做一种使用超文本作为表示层,HTTP作为会话层的C/S
- cgi隐藏了大多数工作,采用cgi编程时,只需要通过标准输入/输出与web服务器进行数据交互(get/post)
- Servlet是一种面向对象的“cgi”
- 使用 Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页
Web服务器
- 作用:连接客户,提供数据
- IIS:Microsoft的服务器
- Apache:Linux的服务器,c编写,可以运行HTML,PHP
- Tomcat:Apache项目中的一个,java编写,JSP和Servlet的容器
网页
- 静态网页
- 随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了——除非修改页面代码
- 动态网页
- 页面代码虽然没有变,但是显示的内容却是可以随着时间、环境用户操作或者数据库操作的结果而发生改变
- 基本html语法规范与Java、VB、VC等高级程序设计语言、数据库编程等多种技术的融合,以期实现对网站内容和风格的高效、动态和交互式的管理(HTML+高级语言+数据库)
- 网页 URL的后缀不是.htm、.html、.shtml、.xml等静态网页的常见形动态网页制作格式,而是以.aspx、.asp、.jsp、.php、.perl、.cgi等形式为后缀,并且在动态网页网址中有一个标志性的符号——“?”
- 动态网页实际上并不是独立存在于服务器上的网页文件,只有当用户请求时服务器才返回一个完整的网页
- 常用的四种技术
- CGI(Common Gateway Interface):代码中混入HTML
- ASP(Active Server Pages):HTML中混入代码,微软开发,仅用于windows,以进程方式进行,现被ASP.NET替代
- PHP(Personal Home Page):HTML中混入代码
- JSP/Servlet(Java Server Pages):HTML中混入代码,基于java,可跨平台,以线程方式运行
应用
- Servlet部署在web应用上,web应用部署在Tomcat中
- Tomcat是Web应用服务器,是一个Servlet/JSP容器
- Tomcat负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户
- Servlet作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层
- Servlet最常见的用途是扩展Java Web服务器功能
- MVC模型中,Java类是M,JSP是V,Servlet是C
- 前后端分离:后端提供接口及页面模板,JavaScript在浏览器中读取模板和JSON后在浏览器中装配成页面
部署
- 创建java项目(普通项目即可)
- 导入servlet-api.jar包
- 右键点击项目 -> properties -> Java Build Path ->Libraries -> Add External JARs
- 编写HelloServlet类
- 继承HttpServlet,提供doGet()
- 后续直接在浏览器输入 http://127.0.01/hello 即可访问
-
1 package servlet; 2 import java.io.IOException; 3 import java.util.Date; 4 5 import javax.servlet.ServletConfig; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 10 public class HelloServlet extends HttpServlet { 11 public void init(ServletConfig config) { 12 System.out.println("init of Hello Servlet"); 13 } 14 public void doGet(HttpServletRequest request, HttpServletResponse response) { 15 try { 16 response.getWriter().println("<h1>Hello Servlet!!!!</h1>"); 17 response.getWriter().println(new Date().toLocaleString()); 18 } catch (IOException e) { 19 // TODO Auto-generated catch block 20 e.printStackTrace(); 21 } 22 } 23 }
- 配置web.xml
- 创建目录web/WEB-INF
- 创建文件web.xml,提供路径与servlet的映射关系
-
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app> 3 4 <servlet> 5 <servlet-name>HelloServlet</servlet-name> 6 <servlet-class>HelloServlet</servlet-class> 7 </servlet> 8 9 <servlet-mapping> 10 <servlet-name>HelloServlet</servlet-name> 11 <url-pattern>/hello</url-pattern> 12 </servlet-mapping> 13 14 </web-app>
- 指定类文件输出路径
- 创建目录web/WEB-INF/classes
- 把项目的class文件输出由原来的 /bin 设置到 /web/WEB-INF/classes下
- 项目右键->properties->Java Build Path->Source->右下角的 Brower-> 指定位置是 j2ee/web/WEB-INF/classes
- 在ecilpse中默认输出的class是在bin目录,tomcat是WEB-INF/classes
- 配置tomcat的server.xml中的<context
- <Context path="/" docBase="e:\project\j2ee\web" debug="0" reloadable="false" />
- 重启tomcat,访问http://127.0.01/hello
获取参数
- 通过网页,提交用户名、密码
- 创建login.html
- 添加一个form元素
- action="login" 标题会提交到login路径,login路径在后续步骤会映射到LoginServlet
- method="post" post方式表示提交的密码信息在浏览器地址栏看不到
- 两个input元素的name属性分别叫做name和password
- 添加一个form元素
- 创建LoginServlet
- 在web.xml中新增映射
- 重启tomcat,访问 http://127.0.0.1/login.html,提交数据
调用流程
- 访问http://127.0.0.1/login.html,通过form,以post的形式提交数据到/login
- tomcat接受请求http://127.0.0.1/login,到配置文件web.xml进行匹配对应的Servlet类LoginServlet
- tomcat实例化LoginServlet对象,调用doPost(),通过参数request取出账号和密码信息
- Servlet把html字符串设置在response对象上
- tomcat拿到被Servlet修改过的response生成html 字符串,再通过HTTP协议发给浏览器
- 浏览器根据HTTP协议获取这个html字符串,并渲染在界面上
service()方法
- 当浏览器使用get方式提交数据的时候,servlet需要提供doGet()方法
- 当浏览器使用post方式提交数据的时候,servlet需要提供doPost()方法
- 在执行doGet()或者doPost()之前,都会先执行service()
- 直接重写service()方法,在其中提供相应的服务,就不用区分到底是get还是post了
生命周期
- 实例化:用户通过浏览器输入一个路径,路径对应的servlet被调用时,该Servlet被实例化
- 初始化:LoginServlet 继承了HttpServlet,同时也继承了init(ServletConfig),在构造方法执行后执行
- 提供服务:执行service()方法,通过浏览器传递过来的信息进行判断,是调用doGet()还是doPost()方法
- 销毁:关闭tomcat时,调用destroy()
- 被回收:下一次GC时回收
跳转
- 服务端跳转(转发)
- 服务器调用LoginServlet
- LoginServlet发现账号密码正确
- 服务器在内部访问success.html
- 把success.html发送给浏览器
- 客户端跳转(重定向)
- 服务器调用LoginServlet
- LoginServlet发现账号密码错误
- 服务器让浏览器访问fail.html
- 浏览器访问fail.html
- 服务器获取fail.html内容,发送给浏览器
request和response类
- request 常用方法
- request.getRequestURL():浏览器发出请求时的完整URL
- request.getRemoteAddr(): 浏览器所处于的客户机的IP地址
- request.getLocalAddr(): 服务器的IP地址
- request.getHeader() :获取浏览器传递过来的头信息
- response 常用方法
- response.getWriter();:获取一个PrintWriter 对象
- 再通过 println(),append(),write(),format() 等方法设置返回给浏览器的html内容
上传文件
- 准备上传页面upload.html
- 准备 UploadPhotoServlet
- 导入commons-io-1.4.jar和commons-fileupload-1.2.2.jar到WEB-INF/lib下
- 即使用时间戳,避免客户提交的文件名重名
- 读取输入流中的数据,保存在服务端的目录下 e/web/uploaded
- 配置web.xml
- 重启tomcat, 打开http://127.0.0.1/upload.html上传
CRUD
- 准备实体类
- 准备DAO类
- 创建SQL表
- 导入 mysql-jdbc.jar 到 WEB-INF/lib
- 编写 HeroListServlet
- 编写 submit.html
- 配置 web.xml
- 重启 tomcat,访问 http://127.0.0.1/submit.html
弊端
- Servlet编写html代码效率不高,可读性差,难以维护
- 替代方案
- JSP:在html文件里面写html代码,同时又能在里面调用java的变量
参考
servlet教程
https://www.cnblogs.com/whgk/p/6399262.html
servlet菜鸟
https://www.runoob.com/servlet/servlet-intro.html
动态网页(百度百科)
https://www.zhihu.com/people/tom-pareto/answers?page=13
web.xml 中<context-param>与<init-param>的区别与作用