在学习javaweb时接触到的第一个能处理请求的东西,因为这个东西打开了整个javaee的大门创造无数的可能!
Servlet的生命周期,javax.servlet.Servlet接口中定义了它的生命周期
1.客户端请求该 servlet;
2.加载 servlet 类到内存;
3.实例化、初始化该 servlet;
4.init() 初始化参数;
5.service()(doGet() 或者 doPost());
6.destroy()
废话不多说,先弄一个hello world。
创建一个动态web工程,生成web.xml文件
创建一个类,继承HttpServlet(问题1,为什么变成HttpServlet而不是Servlet)
覆盖父类的service方法(问题2)
基本的架构弄好了
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String nameStr = request.getParameter("name"); System.out.println("前端参数传入→ name:"+nameStr); } }
在web.xml中如下配置
<!-- hello --> <servlet> <servlet-name>/hello</servlet-name><!-- 资源名字--> <servlet-class>cn.peace.servlet.HelloServlet</servlet-class><!-- 资源的权限定名,可以准确的定位到一个Servlet来处理--> </servlet> <servlet-mapping> <servlet-name>/hello</servlet-name><!-- 暴露给外部的资源名称--> <url-pattern>/*</url-pattern><!-- 表示哪些请求将被拦截,/*表示拦截所有--> </servlet-mapping> <!-- 此处的name值必须相同 -->
讲解一次请求的过程:
http://localhost:8080/hello?name=%22wow1%22
当请求资源hello的时候,首先解析url中的被请求的资源名字,此处为hello。
扫描web.xml 找到名字为hello的资源,通过class配置找到对应的Servlet处理本次请求。
问题1:Servlet是一个接口,只能实现,极其不方便,HttpServlet 继承自GenericServlet,而GenericServlet实现了Servlet, ServletConfig,java.io.Serializable这些接口。由此HttpServlet 是线程安全的。
问题2:在HttpServlet 中有doGet(),doPost(),service()等方法,为什么要用service()?
首先对这几个方法做一个说明。
doGet(),处理get请求
doPost(),处理post请求
service(),则对所有的请求都有处理这点在HttpServlet.class中有赘述,相关代码如下
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {//判断请求类型是否为get
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);//调用get方法
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);//调用post方法
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
}
由此可以知道 在一个Servlet中,service方法会先执行,然后才是get或者是post
实验中得到,如果service方法存在,则不会调用get或是post方法
测试代码:
请求URL:http://localhost:8080/hello?name=%22wow1%22
结果
HelloServlet.service()
前端参数传入→ name:"wow1"
在Servlet 3.0后,提供注解版
首先,需要对web.xml文件中
<web-app id="WebApp_9" version="3.0" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3.0.xsd">
修改掉version="2.4"为3.0,而web-app_2.4.xsd也要修改为3.0
只需要在Servlet类上打上注解即可,例:
@WebServlet(name="" urlPatterns="/hello2")//urlPatterns需要保证唯一
ps:标红的为必须有
案例
@WebServlet(urlPatterns="/hello2")//urlPatterns需要保证唯一 public class HelloServlet2anno extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("正在使用注解版Servlet,请等待...."); } }
请求路径:http://localhost:8080/hello2
结果
正在使用注解版Servlet,请等待....