1、Servlet简介
1.1、servlet是什么
1、servlet只是java ee里的一个接口API,里面有一些抽象方法,包括 init()、service()、destroy()等
2、作为浏览器、客户端 与 服务器数据库、逻辑层之间的中间层,处理客户端请求
3、servlet本身并不能监听某个端口,不是实现了servlet接口就直接可以处理请求。servlet需要放置在web容器里,比如我们常见的 Apache的tomcat,由tomcat去监听某个端口,当客户端发出请求之后,tomcat根据请求的路径,调用对应项目的servlet,servlet进行init()初始化操作之后,调用service()实现业务逻辑处理,处理之后返回响应。
1.2、servlet作用
servlet作用很明显了,可以接收客户端发来的请求数据,包括http headers、body信息,并做相应的逻辑处理之后,对请求做出相应,并返回给客户端。
1.3、servlet生命周期
servlet最主要包括三个抽象方法, init()、service()、destroy() 这三个也是servlet生命周期主要部分。
init() -->初始化
* servlet第一次调用 或者 可以配置成项目服务启动时候调用,init()被设计成只执行一次的方法.
* 之后用户每次请求servlet都创建一个servlet实例,每个用户请求都会产生一个线程.
* init()简单的创建或者加载一些数据 用于整个生命周期
public void init() throws ServletException { //snipped }
service() -->处理请求
*服务器每接收到一次请求,web容器调用service()方法,处理请求并返回格式化的响应给客户端.
*service()方法检查 http method,并适当时候 移交给 doGet doPost doDelete 等方法处理
*一般service不需要重写,直需要重写真正处理业务逻辑的doGet doPost doDelete等方法
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException{
//snipped }
destory() -->销毁
*destory()方法在servlet生命周期结束之后调用.
*destory()方法可以关闭数据库连接、cookies写入磁盘等清理活动
*servlet 在destory()之后被标记为垃圾回收
2、搭建环境
1、需要搭建JDK环境
2、需要一个servlet容器,我们选择 tomcat
具体搭建不细说,网上很多~
3、发布一个Servlet
1、需要编写一个类实现servlet
// 导入必需的 java 库 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; // 扩展 HttpServlet 类 public class hello extends HttpServlet { private String message; public void init() throws ServletException { // 执行必需的初始化 message = "Hello World"; } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置响应内容类型 response.setContentType("text/html"); // 实际的逻辑是在这里 try (PrintWriter writer = response.getWriter()) { writer.println("<h1>" + message + "</h1>"); } catch(IOException ex) { System.out.println("response error"); } } public void destroy() { // 什么也不做 } }
PS: javax.servlet取自tomcat/lib/servlet-api.jar ,引入项目即可
2、编译编写好的servlet实现类
3、在tomcat容器下面新增如下目录结构(项目结构),并将编译好的hello.class放置进去
test
-WEB-INF
-classes
-hello.class
-web.xml
其中test为新增的一个web项目,我们请求地址为 http://ip:port/test/hello
我们样例里没有添加包,如果有包名,比如:com.test.hello,则需要在classes下新增包名对应的目录
4、关于web.xml部署描述符简单配置
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1" metadata-complete="true"> <display-name>test</display-name> <description>Welcome to Tomcat</description> <!--servlet--> <servlet> <servlet-name>HelloWorld</servlet-name> <servlet-class>hello</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloWorld</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
<web-app>是web.xml根节点.
<display-name>、<description>两节点为描述信息、项目名称
<servlet>节点对应要发布的servlet,每有一个servlet都要新增一个servlet节点,servlet-class 节点为servlet类对应的地址,包名 + 类名
4、一些问题汇总
1、@WebServlet注解不起作用:
servlet3.0开始 在web.xml新增了一个熟悉:metadata-complete,如果为true,则认为xml文件已经配置完全,不需要去扫面类里的注解
false或者不写 默认需要去扫描类里的注解
2、含有包名的类编译
含有包名的类编译时候直接javac xx.java 会在当前目录编译生成xx.class文件,不会形成包名目录,可以添加参数 javac -d . xx.java,这样直接根据包名新增目录编译
3、很蠢的拼写错误
由于我的类文件是在cmd里用命令编译完之后拖进tomcat运行的,项目需要手动添加,添加完毕之后启动一直报404错误,找了好久没发现!
之后发现原来是 目录名称拼写错误 →_→ WEB-INFclasses 这俩 WEB-INF 和 classes 一点不能出错,大小写敏感!!