一、什么是Servlet
实际上JSP的底层就是Servlet,但是JSP是嵌在HTML页面中的Java程序段,而Servlet是纯Java程序。
Servlet主要用于业务逻辑处理,Jsp用于展示内容。
二、第一段Servlet程序
1、新建一个Java Web项目,在src文件夹下新建一个类LoginServlet,并使其继承自HttpServlet类,重写类下的doGet和doPost方法,当网页向该Servlet发送请求的方式是以get方式发送的时候将触发doGet方法,当网页向该Servlet发送请求的方式是以post方式发送的时候将触发doPost方法
//让LoginServlet类继承自HttpServlet类,那么LoginServlet就成为了Servlet类
public class LoginServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("我是doGet()方法");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("我是doPost()方法");
}
}
注意这里使用HttpServlet类的前提是需要导入Tomcat安装目录下的lib文件夹里的servlet-api.jar包
2、为该Servlet类配置对外访问的虚拟路径
- 进入web.xml
- 添加如下程序段,将LoginServlet类的对外访问路径配置为http://localhost:8080/Servlet/LoginServlet
<!--给LoginServlet类配置一个对外访问的虚拟路径-->
<servlet>
<servlet-name>LoginServlet</servlet-name>
<!--这里指的是Servlet类的路径,右键点击类,点击copy reference即可获得-->
<servlet-class>cn.java.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--这里的servlet-name必须和上面的一致-->
<servlet-name>LoginServlet</servlet-name>
<!--
对外访问的虚拟路径
"/"代表http://localhost:8080/[在Run/Debug Configurations中配置部署的Application Context]
-->
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
3、为了方便演示,我们修改index.jsp代码,通过一个登录表单来演示我们的Servlet效果
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
//动态获取LoginServlet的访问路径
String basePath = request.getScheme() + "://" + request.getServerName() + ":"
+ request.getServerPort() + request.getServletContext().getContextPath()
+ "/" + "LoginServlet";
System.out.println(basePath);
%>
<html>
<head>
<title>首页</title>
</head>
<body>
<center>
<!--method为get时,点击登录按钮就会触发LoginServlet的doGet方法,反之触发doPost方法-->
<form action="<%= basePath %>" method="post">
<p>用户名:<input type="text" name="username" /></p>
<p>密码:<input type="password" name="password" /></p>
<p>
<input type="submit" value="登录" />
<input type="reset" value="重置" />
</p>
</form>
</center>
</body>
</html>
这时我们打开index.jsp页面,点击登录,就会发现控制台输出了下面这段话,说明LoginServlet类下的doPost方法被成功执行!
http://localhost:8080/Servlet/LoginServlet
我是doPost()方法
三、Servlet生命周期
- init方法只有Servlet第一次被请求的时候会调用
- service方法则是Servlet每次被请求时都会调用
- destory只有在Servlet被销毁时才会调用
让我们用一个实例来理解Servlet的生命周期:
1、创建一个新的Servlet类LifeServlet,重写init、service和destory方法
//通过注解配置该Servlet的对外访问路径为http://localhost:8080/Servlet/LifeServlet,Servlet名称为LifeServlet
//相当于在Web.xml中的配置信息
@WebServlet(name = "/LifeServlet", urlPatterns = "/LifeServlet")
public class LifeServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("Servlet的init方法");
}
@Override
public void destroy() {
System.out.println("Servlet的destroy方法:Servlet被销毁了");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet的service方法:Servlet被请求了");
}
}
2、启动项目,访问LifeServlet,查看控制台输出信息
Servlet的init方法
Servlet的service方法:Servlet被请求了
3、刷新LifeServlet,查看控制台输出信息
Servlet的init方法
Servlet的service方法:Servlet被请求了
Servlet的service方法:Servlet被请求了
4、将改项目从Tomcat服务器中移除,查看控制台输出信息
Servlet的init方法
Servlet的service方法:Servlet被请求了
Servlet的service方法:Servlet被请求了
Servlet的destroy方法:Servlet被销毁了
由此我们可以发现,Servlet的init方法只会在第一次访问的时候触发,而service方法在每次访问Servlet的时候都会触发,destory方法在Servlet从服务器移除的时候触发(注意终止项目运行是无法触发destroy方法的)
JSP就是Servlet,所以JSP内置对象和Servlet中类的对应关系如下
四、请求与响应
五、ServletContext对象和ServletConfig对象
ServletContext
1、新建一个Servlet——Demo1Servlet,向域对象ServletContext中存放数据
/**
* ServletContext对象:表示整个JavaWeb工程
* ServletConfig对象:表示某一个Servlet的配置文件
*/
@WebServlet(name = "Demo1Servlet", urlPatterns = "/Demo1Servlet")
public class Demo1Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取ServletContext对象
//ServletContext对象是一个域对象,可以往某一个域对象中存取数据
ServletContext servletContext = this.getServletContext();
//往ServletContext域对象中存放数据
servletContext.setAttribute("username", "张三");
//从ServletContext域对象中取出数据
Object result = servletContext.getAttribute("username");
//打印取出的数据
System.out.println("Demo1Servlet:" + result);
}
}
2、新建另一个Servlet——Demo2Servlet,在这个Servlet中取出Demo1Servlet中向ServletContext对象里存放的数据
@WebServlet(name = "Demo2Servlet", urlPatterns = "/Demo2Servlet")
public class Demo2Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//从ServletContext域对象中取出在Demo1Servlet中存放的数据
ServletContext servletContext = this.getServletContext();
Object result = servletContext.getAttribute("username");
System.out.println("Demo2Servlet:" + result);
}
}
3、分别访问Demo1Servlet和Demo2Servlet,查看控制台输出信息
Demo1Servlet:张三
Demo2Servlet:张三
这样就说明了ServletContext的域对象的性质,意思就是整个JavaWeb项目里共用一个ServletContext对象,反过来说,ServletContext对象代表的就是这个JavaWeb项目。
ServletConfig
1、新建一个Servlet——Demo3Servlet,并且不使用注解配置该Servlet的配置信息;通过代码获取该Servlet在Web.xml中配置的数据信息
//ServletConfig
public class Demo3Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletConfig对象
ServletConfig servletConfig = this.getServletConfig();
//获取ServletConfig对象中封装的参数信息
String encoding = servletConfig.getInitParameter("encoding");
System.out.println("encoding = " + encoding);
}
}
2、在Web.xml为Demo3Servlet配置数据信息
<servlet>
<servlet-name>Demo3Servlet</servlet-name>
<servlet-class>cn.java.servlet.Demo3Servlet</servlet-class>
<!--为Servlet配置存放的数据信息-->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Demo3Servlet</servlet-name>
<url-pattern>/Demo3Servlet</url-pattern>
</servlet-mapping>
3、访问Demo3Servlet,查看控制台输出信息
encoding = utf-8
这样就说明了一个Servlet在Web.xml中配置的信息是可以通过这个Servlet对应的ServletConfig对象来获取的,与ServletContext不同的是,一个ServletConfig对象只对应一个Servlet。
转发与重定向的区别
重定向不能使用request带数据到跳转的页面,但是转发可以。因此重定向要带数据的话需要使用到ServletContext对象。
- 转发:request.getRequestDispatcher(“/xxx.jsp”).forward(request,response);
- 重定向:response.sendRedirect(request.getContextPath() + “/xxx.jsp”);