文章目录
- 一、Servlet 目的 ----- 实现动态页面
- 二、编写一个 Servlet 的Hello World
- 2.1 创建项目
- 2.2 处理文件夹
- 2.3 引入依赖
- 2.4 手动创建一些必要的目录/文件
- 2.5 编写代码
- 2.6 打包程序
- 2.7 部署
- 2.8 验证程序是否能正常工作
一、Servlet 目的 ----- 实现动态页面
静态页面 VS 动态页面:静态页面日渐稀少,目前以动态页面为主
- 静态页面:不论处于什么情况下,展示的页面始终不变
- 动态页面:
- 从用户面来看,页面的内容会随着用户输入参数的不同而发生改变
- 从服务器角度来,服务器根据请求,进行一系列运算,动态生成了一个页面
二、编写一个 Servlet 的Hello World
2.1 创建项目
- Build system:构建工具,这里选择Maven
- Maven:Java 中一个常用的“构建工具”。
一个程序在编写过程中,往往要涉及第三方库的依赖和要对这个写好的程序进行打包部署。而Maven可以帮助我们更加方便的进行依赖管理和打包。 - IntelliJ:IDEA 默认的构建工具
- Gradile:主要是安卓里面会用到
- Maven:Java 中一个常用的“构建工具”。
2.2 处理文件夹
创建出来的项目,一般会自动生成一些文件夹
- src:源文件
- main:业务代码
- java:java 代码。里面自动创建的包,如org、example可以删了,后期手动添加。
- resources:放一些依赖的资源面如图片、字体、音频等
- test:测试代码
- main:业务代码
- pom.xml:Maven 项目里最主要的配置文件
- 身份标识:如果要将该程序放到Maven中央仓库上,就需要通过这几个属性来作区分,这三个联合起来,就相当于是一个库的身份标识了
- groupId:所在公司/组织的名称
- artifactId:产品名称
- version:版本号
- properties 配置的属性
- maven.compiler.source:当前的源代码是什么版本,如果是8,表示为Java8版本
- maven.compiler.target:生成的Java文件是什么版本,如果是8,表示为Java8版本
- project.build.sourceEncoding:编码字符集
- 身份标识:如果要将该程序放到Maven中央仓库上,就需要通过这几个属性来作区分,这三个联合起来,就相当于是一个库的身份标识了
2.3 引入依赖
- 为什么要引入依赖:当前代码需要使用Servlet开发,但 Servlet 并不是Java标准库自带的,就需要让 Maven 把 Servle t的依赖获取过来
- 如何引入依赖:
- 找到Maven的中央仓库,仓库链接
- 输入【Java Servlet API】,选择3.1.0版本(如果Tomcat是8版本的话)
注意,Servlet 版本和Tomcat版本是有对应关系的,如果不匹配可能会出现问题 - 把中央仓库的坐标复制在dependencies标签下,不需要下载jar包。此时IDEA就会自动的通过Maven从中央仓库下载这里的依赖。
<dependencies><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency>
</dependencies>
- 如果下载出错/很慢
因为默认Maven源是国外的服务器,比较慢,如果想要提高速度,可以手动修改Maven源,将其改为国内的阿里云源之类的。 - 为什么不像JDBC一样,直接手动下载jar包:
有些依赖可能会间接的依赖其他jar包,而Maven能够把整个依赖链条都搞定。不建议手动下载,因为手动无法保证下载整个依赖链。
2.4 手动创建一些必要的目录/文件
- 为什么要创建这些文件:Tomcat 对于 Servlet 项目,有一些额外的要求,我们需要根据该要求创建出一些特定的目录和文件
- web.xml:
- 作用:告诉 Tomcat 现在这个目录里的东西就是一个webapp,需要加载进来
- 如果出现标红怎么办:一般是第二个标红,该处是一个schema文件
- 不管:注意IDEA只能保证针对java程序的提示是准确的,其他文件仅供参考。而次数的标红,可以不用管。
- 非要处理:Alt + Enter,选择fetch(主动从服务器中获取这个scheme文件)或ignore(忽略这个)
- 内容:内容不能为空,且是固定的,copy即可
- schema文件:
描述了该xml里面的格式是什么样的,一旦拿到这个文件,IDEA就可以针对你的xml,进行自动补全了
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name>
</web-app>
2.5 编写代码
- 步骤:
- 在Java目录下创建一个继承 HttpServlet 的类
- 重写父类的方法,这里重写的是 doGet()
- doGet()方法什么时候会被调用:
不需要程序员手动调用,本质上是一个“回调函数”。当把该方法写好后,就会交给Tomcat。Tomcat在收到一个合适的时机就会自动调用它 - 关于doGet方法被调用的合适时机:请求的方法匹配(Get请求) + 请求的路径匹配
- 为何Servlet不需要main方法也能运行:
一个程序的确是需要main方法作为入口,但是此处我们写的代码并不是独立的代码,而是放到Tomcat上执行的,main方法其实是在Tomcat里。包括doGet()、doPost()都是由Tomcat来调用的 - HttpServletRequest:这次请求的http请求内容
调用doGet方法的时候,Tomcat会解析这次的HTTP请求,生成一个与HTTP协议格式匹配的HttpServletRequest对象(Tomcat帮我们解析请求,不需要再去写一个解析代码了) - HttpServletResponse:这次请求要返回的http响应内容
- Tomcat 会构造出一个空的HttpServletResponse 对象(空不是指null,而是一个new好的,但是没有初始化属性的对象),并且把这个 resp 对象传递到 doGet里面
- 服务器需要根据req不同的参数的细节往resp这个空对象里设置属性。然后Tomcat就会根据这个响应对象,转换成符合HTTP协议的响应报文,然后返回给浏览器。
- 关于父类的doGet方法:要删掉,不然会出错
@WebServlet("/hello") //把当前这个Servlet类和一个请求的路径关联起来了(配置路由)
//这里必须带/,否则不能正确加载
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("Hello Servlet"); //在服务器的日志中打印resp.getWriter().write("hello servlet");//同调getWriter()拿到内置的Writer字符流,使用write()将数据(这里是一个字符串)写到HTTP响应的body中//浏览器拿到body的内容,就可以显示到界面上了}
}
2.6 打包程序
-
为何要打包:因为程序是要放到 Tomcat 上执行的
-
如何打包:使用Maven,点package执行打包操作
- Lifecycle:生命周期
- 打包后会出现一个 【target】目录,包含着我们已经生出的内容,打好的包也会在该目录下
-
包的格式:
- 要什么包:Maven 默认打出来的包是 Jar包,但是Tomcat并不能识别这种格式。为了能让Tomcat识别,我们需要打成war包
- war 包:war 包本质上和 jar 包差不多,但是这里会包含一些前端的代码(HTML、CSS、JS)以及一些Tomcat的配置(web.xml)
-
如何修改 Maven 打出的包的格式:在 pom.xml 里修改,注意重新打出的 war 包也在target目录下
<packaging>war</packaging>
<build><!-- 描述了打的包的名字是什么,不是必须的,可以使用默认的名字 --><finalName>light</finalName>
</build>
- 如何确定打包成功:在打印了一系列日志后,出现了【BUILD SUCCESS】
2.7 部署
- 把写好的war包,拷贝到Tomcat的webapps目录中
- 当拷贝进来后,Tomcat就能识别到有新的webapp来了,就会自动对这个war包解压缩,同时会在服务器上打印出一段日志(发现了新的war包,对war包进行部署),此时Tomcat就能识别出我们新写的程序了
- 再次使用时,需重启Tomcat。
2.8 验证程序是否能正常工作
- 如何做:通过浏览器发起 HTTP 的Get请求,触发刚才 Servlet 的代码
- 关于请求路径:
- 通过第一级路径(context path/application path)确认要去访问哪个webapp,通常就是war包的名字,即解压缩之后的目录名字
- 通过第二级目录说明要访问哪个Servlet代码,与@WebServlet注解是对应的
- 根据请求决定调用的是哪个方法
- 如果出现Tomcat正常运行,但是浏览器一直转圈的情况:可能是cmd的问题,按enter即可解决
当选中了cmd中的某个内容,cmd就会进入“复制”模式,此时按下enter就是完成复制。而进入复制模式的过程中,cmd就会把正在运行的进程给阻塞掉。此时,可以通过按下enter完成复制,把Tomcat的阻塞状态解除