Servlet(入门)
Servlet : 运行在服务器端的小程序
Servlet就是一个接口,定义了java类被浏览器访问到(tomcat识别)的规则
步骤:
-
创建一个项目
-
定义一个类,并实现接口
public class ServletDemo01 implements Servlet
-
实现接口的抽象方法
-
配置Servlet文件
在web.xml配置文件
<servlet>
<servlet-name>ServletDemo01</servlet-name>
<servlet-class>cn.lsk.Servlet.ServletDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo01</servlet-name>
<url-pattern>/sd</url-pattern>
</servlet-mapping>
执行原理:
- 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径。
- 查找web.xml文件,是否有对应的标签体内容。
- 如果有,则在找到对应的全类名
- tomcat会将字节码文件加载进内存,并且创建其对象
- 调用其方法
Servlet的方法(生命周期)
-
创建 : 执行init方法,只执行一次
Servlet在什么时候被创建呢?
默认情况下,第一次被访问时,Servlet被创建
也可以配置执行Servlet的创建时机(在Web.xml)
如果值为正数在服务器启动的时候就创建
如果为负数在第一次被访问的时候创建
<load-on-startup> -4 </load-on-startup>
Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
多个用户同时访问时,可能存在线程安全问题
解决:尽量不要在Servlet中定义成员变量 如果定义不要修改值
-
提供服务 : 执行Servlet方法,执行多次
每次访问,都会执行一次
-
销毁 : 执行destroy方法,只执行一次
只有服务器正常关闭,才会执行destroy方法
public class ServletDemo02 implements Servlet {
/**
* 初始化方法
* 在Servlet被创建时,执行。只会执行一次
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("我被创建了,我只执行一次");
}
/**
* 获取ServletConfig对象
* ServletConfig: Servlet的配置对象
* /
@Override
public ServletConfig getServletConfig() {
return null;
}
/*
* 提供服务的方法
* 每一次Servlet被访问时,执行。执行多次
*
* */
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello WDNMD");
}
/*
* 获取Servlet的一些信息,版本,作者等等···
*
* */
@Override
public String getServletInfo() {
return null;
}
/*
* 销毁方法
* 在服务器正常关闭时,执行,执行一次
*
* */
@Override
public void destroy() {
System.out.println("GG");
}
}
第一次执行:
如果我们在刷新一下
可以看出 service
又被调用 而 init
初始化方法只执行一次
如果我们正常关闭服务器的话
Servlet注解配置:
步骤:
-
创建项目
-
定义一个类 实现接口
-
复写方法
-
在类上使用@WebServlet注解,进行配置
@WebServlet(“资源路径”)
@WebServlet("/sd3")
public class ServletDemo03 implements Servlet {
/**
* 初始化方法
* 在Servlet被创建时,执行。只会执行一次
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("我被创建了,我只执行一次");
}
/*
* 获取ServletConfig对象
* ServletConfig: Servlet的配置对象
* */
@Override
public ServletConfig getServletConfig() {
return null;
}
/*
* 提供服务的方法
* 每一次Servlet被访问时,执行。执行对此
*
* */
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("注解");
}
/*
* 获取Servlet的一些信息,版本,作者等等···
*
* */
@Override
public String getServletInfo() {
return null;
}
/*
* 销毁方法
* 在服务器正常关闭时,执行,执行一次
*
* */
@Override
public void destroy() {
System.out.println("GG");
}
}
Servlet体系结构
Servlet(接口)
GenericServlet
(抽象类)他实现了Servlet接口
//部分源码
public abstract class GenericServlet implements Servlet,
ServletConfig,
Serializable {
}
HttpServlet(抽象类)它继承了GenericServlet
//部分源码
public abstract class HttpServlet extends GenericServlet {
}
分别来看一下两个抽象类的功能:
我们先不去实现Servlet接口而先去继承GenericServlet
@WebServlet("/sd3")
public class ServletDemo04 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest,
ServletResponse servletResponse)
throws ServletException, IOException {
}
}
进入GenericServlet源代码我们可以看到:(只是部分源码)
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
private static final long serialVersionUID = 1L;
private transient ServletConfig config;
public GenericServlet() {
}
//方法空实现 只有声明
public void destroy() {
}
//方法空实现 只有声明
public void init() throws ServletException {
}
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
}
我们可以看出他把其他的方法做了空实现,只把一个方法抽象化了 就是**service
**方法。 所以我们继承了GenericServlet
只重写 service
方法
HttpServlet
在Servlet方法中有一个service方法 我们以后在service中要干什么呢?
-
判断请求方式
String mehod = request.getMethod();
if(“GET”.equals(mehod )){
// get方式获取数据
doGet();
}else if(“POST”.equals(mehod )){
// post方式获取数据
doPost();
}
-
获取数据
但是我们的HttpServlet 已经把上面的代码帮我们写了
@WebServlet("/sd3")
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
System.out.println("doGet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
System.out.println("doPost");
}
}
通过浏览器请求是get请求
通过表单访问 是Post请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/sd5" method="post">
<input name="username">
<input type="submit" value="提交">
</form>
</body>
</html>
引入注解
-
如果选择Create Java EE 6 annotated class
会创建一个继承
HttpServlet
的Servlet
web.xml:
<servlet>
<servlet-name>ServletDemo06</servlet-name>
<servlet-class>cn.lsk.Servlet.ServletDemo06</servlet-class>
</servlet>
//需要自己编写
<servlet-mapping>
<servlet-name>ServletDemo06</servlet-name>
<url-pattern>/sd6</url-pattern>
</servlet-mapping>