雷丰阳JavaWeb学习笔记(五):Servlet
1、Servlet简介
API上的介绍:A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
一个servlet就是一个小的java程序,servlets运行在web服务器,servlet接收和响应来自客服端的请求,通过http
1.1、什么是Servlet
●从广义上来讲,Servlet规范是Sun公司制定的一套技术标准,包含与Web应用相关的一系列接口,是Web应用实现方式的宏观解决方案。而具体的Servlet容器负责提供标准的实现。
●从狭义上来讲,Servlet指的是javax.servlet.Servlet接口及其子接口,也可以指实现了Servlet接口的实现类。
●Servlet作为服务器端的一个组件,它的本意是“服务器端的小程序”。Servlet的实例对象由Servlet容器负责创建;Servlet的方法由容器在特定情况下调用;Servlet容器会在Web应用卸载时销毁Servlet对象的实例。
1.2、为什么要用Servlet
①生活中的例子
②Web应用运行模式
即专门用来处理Web请求的一组接口,用来连接前端与后端数据传输的Java代码,可以提现如下作用:
- 接收请求
- 处理请求
- 完成响应
1.3、如何使用Servlet
操作步骤
①搭建Web开发环境
②创建动态Web工程
③创建javax.servlet.Servlet接口的实现类:com.atguigu.servlet.MyFirstServlet
继承Servlet接口后,需要实现的方法:
④在service(ServletRequest, ServletResponse)方法中编写如下代码,输出响应信息:
public class MyFirstServlet implements Servlet{
//初始化
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
//获取Servlet配置信息
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
//服务
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
//service来处理来自客户端的请求
System.out.println("我是第一个Servlet");
//ServletResponse res给浏览器发送一个响应
//获取一个写数据对象
PrintWriter writer = res.getWriter();
writer.write("helloworld");
}
//获取Servlet信息
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
//销毁
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
⑤在web.xml配置文件中注册MyFirstServlet
<!-- 声明一个Servlet -->
<servlet>
<!-- 为Servlet指定一个名称,以便于引用 -->
<servlet-name>MyFirstServlet</servlet-name>
<!-- 注册Servlet实现类的全类名 -->
<servlet-class>com.atguigu.servlet.MyFirstServlet</servlet-class>
</servlet>
<!-- 建立一个从虚拟路径到Servlet之间的映射关系 -->
<servlet-mapping>
<!-- 引用Servlet名称 -->
<servlet-name>MyFirstServlet</servlet-name>
<!-- 映射到Servlet的虚拟路径:“/hello” -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
其中:
<url-pattern>/MyFirstServlet</url-pattern>
⑥在WebContent目录下创建index.html
⑦在index.html中加入超链接
<a href="MyFirstServlet">To Servlet</a>
⑧点击超链接测试Servlet
运行时分析
用户在浏览器地址栏输入:http://localhost:8011/08.Servlet/hello时,会在相应位置找是否有对应的静态资源hello,当没有对应的静态资源hello时,回到web.xml下找响应的动态资源,此时会找到如下
知道后,就知道对应调用在它之前声明的servlet别名所对应的servlet方法。
1.4、Servlet的声明周期
Servlet是跑在Tomcat服务器上 Tomcat–》Servlet容器,Servlet对象是Servlet容器创建的,生命周期方法都是由容器调用的。
生命周期:从出生到死亡
Servlet的生命周期:从创建到销毁
当我们第一次访问HelloServlet
1)创建Servlet对象
2)调用init方法 init()初始化Servlet
3)调用service方法 service()处理请求
以后请求:
4)只调用service方法 整个运行期间只创建一个servlet对象Servlet是单例多线程
当项目从服务器上卸载
5)服务器调用destroy方法,销毁Servlet
2、Servlet中使用的接口的类
2.1、ServletConfig接口
- ServletConfig接口封装了Servlet配置信息,这一点从接口的名称上就能够看出来。但同时,代表当前Web应用的ServletContext对象也封装到了ServletConfig对象中,使ServletConfig对象成为了获取ServletContext对象的一座桥梁。
- 一个Servlet对应一个ServletConfig,所以ServletConfig类也只能获取对应Servlet的配置信息
- ServletConfig对象的主要功能
①获取Servlet别称 :getServletName()
②获取Servlet初始化参数:getInitParameter(),getInitParameterNames()
③获取ServletContext对象:getServletContext()
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
// TODO Auto-generated method stub
//2.ServletConfig的功能
// 1)获取Servlet的别名:getServletName()
String name = config.getServletName();
System.out.println(name);//ConfigServlet
// 2)获取Servlet初始化参数:getInitParameter()
String username = config.getInitParameter("username");
System.out.println("初始化参数:username="+username);//初始化参数:username=chenyanzhe
// 3)获取ServletContext对象,代表当前Servlet的上下文,代表当前web项目信息:getServletContext()
ServletContext servletContext = config.getServletContext();
System.out.println(servletContext); //org.apache.catalina.core.ApplicationContextFacade@3665f736
}
2.2、ServletContext接口
ServletContext代表Servlet上下文,也就是当前Web应用,一个Wed应用对应一个ServletContext
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
//获取ServletConfig对象
ServletConfig servletConfig = this.getServletConfig();
//使用ServletConfig获取ServletContext
ServletContext servletContext = servletConfig.getServletContext();
//研究ServletContext对象
//1、ServletContext是什么:一个web应用对应一个ServletContext,即ServletContext代表整个web项目(相当于代表08.Servlet)
//2.功能
1)可以获取web项目的配置信息,获取web项目的初始化参数:getInitParameter()
String user = servletContext.getInitParameter("user");
System.out.println(user);//root
String username = servletContext.getInitParameter("username");
System.out.println(username);//null
2)可以获取web项目路径:getContextPath(),虚拟路径
String path = servletContext.getContextPath();
System.out.println(path);///08.Servlet
3)可以获取资源的真实路径:getRealPath()
//虚拟路径:网络访问使用虚拟路径,每个虚拟路径对应一个实际的资源
//真实路径:文件在磁盘中的存储路径
String realPath = servletContext.getRealPath("/index.html");
System.out.println(realPath);//F:\JAVA\TomCatServer\wtpwebapps\08.Servlet\index.html
4)可以作为最大的域对象共享数据,application
域对象:在不同的Web资源中共享数据,
4大域对象:pageContext request session application
}
虚拟路径和真实路径:
3、Eclipse中自动创建Servlet
直接点解eclipse中的new,可以创建servlet,自动生成代码如下,以为自动在web.xml中添加相应的设置。
专门处理http请求
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 HelloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;
public HelloWorld() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
2.1、继承实现结构
自动生成的servlet的类自动继承了HttpServlet,并只用实现其两个方法:doGet()与doPost(),并没有直接实现Servlet接口中的service(),下面的他们之间的关系图:
自己创建的类继承了HttpServlet类,HttpServlet类又继承了GenericServlet类,GenericServlet实现了Servlet接口,但GenericServlet并没有实现service()方法,而是在HttpServlet类中实现了service()方法,并根据不同的报文根式,设置不同的处理方法。但其实doGet()与doPost()基本是只实现一个就可以,相互调用即可。
2.3、HttpServletReques、HttpServletResponse接口
在创建的servlet的方法中,服务器会传进来两个参数
HttpServletRequest request, HttpServletResponse response
- HttpServletRequest接口
①该接口是ServletRequest接口的子接口,封装了HTTP请求的相关信息,由Servlet容器创建其实现类对象并传入service(ServletRequest req, ServletResponse res)方法中。以下我们所说的HttpServletRequest对象指的是容器提供的HttpServletRequest实现类对象。
②HttpServletRequest对象的主要功能有
●获取请求参数。
●在请求域中保存数据。
●将请求转发给另外一个URL地址。
●获取项目虚拟路径。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//HttpServletRequest request代表浏览器发给服务器的请求信息
//http请求:请求首行 请求头 空行 请求体(封装的数据-post)
//get将参数放在url后面
1.获取请求数据
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
// System.out.println(username);
// String aihao = request.getParameter("aihao");
// System.out.println(aihao);
String[] aihao2 = request.getParameterValues("aihao");
if(aihao2!=null){
for(String a : aihao2){
System.out.println(a);
}
System.out.println(username+"爱好:"+aihao2);
}
2.获取请求头信息
String userAgent= request.getHeader("User-Agent");
System.out.println(userAgent);
3.转发页面、资源
//先获取一个请求转发器
RequestDispatcher dispatcher = request.getRequestDispatcher("success.html");
//将请求转发出去
dispatcher.forward(request, response);
4、作为域对象共享数据 4个:application request
}
- HttpServletResponse接口
①该接口是ServletResponse接口的子接口,封装了HTTP响应的相关信息,由Servlet容器创建其实现类对象并传入service(ServletRequest req, ServletResponse res)方法中。以下我们所说HttpServletResponse对象指的是容器提供的HttpServletResponse实现类对象。
②主要功能
●使用PrintWriter对象向浏览器输出数据
●实现请求重定向。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//HttpServletRequest request, HttpServletResponse response
//HttpServletRequest request代表就是封装浏览器请求信息的对象
//HttpServletResponse response代表是要发给浏览器的响应对象,封装响应信息
1.可以给浏览器响应字符串
PrintWriter writer = response.getWriter();
writer.write("Hello HttpServlet");
2.可以重定向到一个页面或者其它资源。重定向就是服务器告诉浏览器重新请求别的资源
response.sendRedirect("success.html");
}
4、请求的转发与重定向
4.1、请求的转发
①Servlet接收到浏览器端请求后,进行一定的处理,先不进行响应,而是在服务器端内部“转发”给其他Servlet程序继续处理。在这种情况下浏览器端只发出了一次请求,浏览器地址栏不会发生变化,用户也感知不到请求被转发了。
②转发请求的Servlet和目标Servlet共享同一个request对象。
③实现转发的API
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//1.使用RequestDispatcher对象封装目标资源的虚拟路径
//2.调用RequestDispatcher对象的forward()方法“前往”目标资源
request.getRequestDispatcher("/index.html").dispatcher.forward(request, response);
//[注意:传入的参数必须是传递给当前Servlet的service方法的
//那两个ServletRequest和ServletResponse对象]
}
4.2、请求的重定向
①Servlet接收到浏览器端请求并处理完成后,给浏览器端一个特殊的响应,这个特殊的响应要求浏览器去请求一个新的资源,整个过程中浏览器端会发出两次请求,且浏览器地址栏会改变为新资源的地址。
②重定向的情况下,原Servlet和目标资源之间就不能共享请求域数据了。
③实现重定向的API
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//1.调用HttpServletResponse对象的sendRedirect()方法
//2.传入的参数是目标资源的虚拟路径
response.sendRedirect("index.html");
}
转发 | 重定向 | |
---|---|---|
浏览器地址栏 | 不改变 | 改变 |
发送请求次数 | 1 | 2 |
位置 | 服务器内部 | 浏览器中完成 |
能否共享request对象数据 | 能 | 不能 |
目标资源 | 必须是当前web应用中的资源 | 不局限于当前web应用 |
WEB-INF下的资源 | 能访问 | 不能访问 |