Servlet学习
Servlet技术
- 什么是Servlet
1. Servlet是JavaEE规范之一。规范就是接口。
2. Servlet是JavaWeb三大组件之一。JavaWeb三大组件分别为:Servlet程序,Filter过滤器,Listener监听器。
3. Servlet是运行在服务器上的一个Java小程序,可以接收客户端发来的请求,并响应数据给客户端。 - 手动实现Servlet
1. 编写一个类实现Servlet接口;
2. 实现service方法,处理请求并响应数据;
3. 在web.xml文件中配置servlet程序的访问地址
Servlet程序的实例代码:
public class HelloServlet implements Servlet {
/** service 方法是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
* */
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello Servlet 被访问了");
}
}
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_4_0.xsd"
version="1.0">
<!-- servlet标签用于给Tomcat配置Servlet程序 -->
<servlet>
<!-- Servlet-name标签给Servlet程序起别名,一般是类名 -->
<servlet-name>HelloServlet</serblet-name>
<!-- Servlet-class标签是Servlet程序的全类名 -->
<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
</servlet>
<!-- servlet-mapping标签给serlet程序配置访问位置 -->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
注意:url-pattern标签中配置的访问地址需要以/开头;并且servlet-mapping标签中的servlet-name标签需要与servlet标签中的对应;servlet标签中的servlet-class标签中的全类名须准确无误。
-
Servlet程序的生命周期
- 执行Servlet构造器方法
- 执行init初始化方法(构造器和初始化方法在第一次访问创建Servlet程序时调用)
- 执行service方法,在每次访问时都会调用
- web工程关闭停止时,调用destory方法
-
GET和POST请求的分发处理
在表单提交时,一般会使用GET和POST两种提交方式,如何在Servlet程序中判断表单提交的方式并进行不同的响应操作呢
//以service方法为例介绍
public class HelloServlet implements Servlet(){
public void service(ServletRequest servletRequest,ServletResponse servletResponse) throws IOException , ServletException{
//HttpServletRequest类是ServletRequest的子类,其中的getMethod方法可以返回请求的方法类型
HttpServletRequest httpServletRequest = (HttpServletRequest)ServletRequest;
String method = httpServletRequest.getMethod();
if(method.equals("GET")){
doGet();
}else if(method.equals("POST")){
doPost();
}
}
}
- 在实际项目开发中,一般使用继承HttpServlet类的方式去实现Servlet程序
- 编写一个类继承HttpServlet
- 根据业务的需要重写doGet和doPost方法
- 在web.xml中配置Servlet程序的访问地址
编写类继承HttpServlet
public class HelloServletHttp extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServletHttp2的GET方法");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServletHttp2的POST方法");
}
}
在web.xml中配置Servlet访问地址
<servlet>
<servlet-name>HelloServletHttp</servlet-name>
<servlet-class>com.javis.sevlet.HelloServletHttp</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServletHttp</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
- Servlet的继承体系
类名(接口名) | 说明 |
---|---|
Interface Servlet | Servlet接口只是用于定义Sercvlet程序的访问规范 |
Class GenericServlet | 实现了Servlet接口,对其中的方法做了很多空实现。 并且拥有一个ServletConfig类的引用,对ServletConfig类的使用提供一些方法 |
Class HttpServlet | 继承GenericServlet类,实现了service方法,并且实现了请求的分发处理 |
Class 自定义Servlet程序 | 根据具体的业务需求来编写doGet和doPost方法 |
ServletConfig类
ServletConfig类从类名上看,适用于Servlet程序的配置信息类。
Servlet程序和ServletConfig对象都是有Tomcat负责创建,我们来使用。Servlet程序默认是第一次访问的时候创建,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象。
- ServletConfig类的三大作用
- 可以获取Servlet程序的别名servlet-name的值(即web.xml文件中的配置属性)
- 获取初始化参数init-param
- 获取ServletContext对象
web.xml文件中的配置
<!-- servlet标签给Tomcat配置Sevlet程序 -->
<servlet>
<!-- servletName标签给Servlet程序起一个别名,一般是类名 -->
<servlet-name>HelloServlet</servlet-name>
<!-- 制得是Servlet程序的全类名 -->
<servlet-class>com.javis.sevlet.HelloSevlet</servlet-class>
<!-- init-param是Servlet程序的初始化参数 -->
<init-param>
<param-name>userName</param-name>
<param-value>root</param-value>
</init-param>
<!-- init-param是Servlet程序的初始化参数 -->
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
</servlet>
<!-- servlet-mapping标签给servlet程序配置访问地址 -->
<servlet-mapping>
<!-- servlet-name标签作用是告诉服务器给哪个servlet程序配置地址 -->
<servlet-name>HelloServlet</servlet-name>
<!-- url-pattern标签配置servlet程序访问地址
斜杠表示服务器解析时, http://ip:port/工程路径
/hello 表示地址为 http://ip:port/工程路径/hello
-->
<url-pattern>/hello/hello/hello</url-pattern>
</servlet-mapping>
Servlet程序中的代码
@override
public void init(ServletConfig servletConfig) throws ServletException{
System.out.println("servlet程序的初始化操作");
//1.可以获取Servlet程序的servlet-name属性
System.out.println("Servlet程序的servlet-name别名是" + servletConfig.getServletName());
//2.可以获取Servlet程序的初始化参数init-param
System.out.println("初始化参数userName的值是:" + servletConfig.getInitParameter("userName"));
System.out.println("初始化参数url的值是:" + servletConfig.getInitParameter("url"));
//3.可以获取Servlet程序的servletContext对象
System.out.println("Servlet程序的servletContext对象是" + servletConfig.getServletContext());
}
- 注意,在自定义的Servlet类(即继承了HttpServlet类中),可以在doGet和doPost方法中直接调用servletConfig对象的方法,但是需要注意的是,在重写Servlet程序的init方法时,需要继承HttpServlet(实际上是GenericServlet类)的init方法,否则会出现空指针异常(即类中的ServletConfig引用未指向对象。)
@override
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
//下面是重写的代码
}
ServletContext类
- 什么是ServletContext?
- ServletContext是一个接口,表示Servlet上下文对象
- 一个web工程中只有一个ServletContext对象实例
- ServletContext对象是一个域对象
- ServletContext是在web工程部署启动的时候创建。在web工程停止的时候销毁
- 什么是域对象
域对象服务器在内存上创建的存储空间,用于在不同动态资源(servlet)之间传递与共享数据,它可以像Map一样存取数据。这里的域指的是存取数据的操作范围。域对象是根据key-value键值对来对数据进行存取删除的。
存数据 | 取数据 | 删除数据 | |
---|---|---|---|
Map | put() | get() | move() |
域对象 | setAttribute() | getAttribute() | removeAttribute() |
- ServletContext类的四个作用
- 获取web.xml文件中配置的上下文参数context-param
- 获取当前的工程路径,格式为
/工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
- 像Map一样存取数据
ServletContext类代码
protected void doGet(HttpServletRequest request , HttpServletResponse response) throws IOException , ServletException{
//1.获取web.xml文件中配置的上下文参数context-param
ServletContext context = getServletConfig().getServletContext();
String userName = context.getInitParameter("userName");
String password = context.getInitParameter("password");
//2.获取当前的工程路径
System.out.println("当前工程的路径是:" + context.getContextPath());
//3.获取工程部署后在服务器硬盘上的绝对路径
System.out.println("工程部署的路径是:" + context.getRealPath("/"));
System.out.println("工程下css目录的绝对路径是:" + context.getRealPath("/css"));
System.out.println("工程下imgs目录1.jpg的绝对路径是:" + context.getRealPath("/imgs/1.jpg"));
}
web.xml文件中的配置为:
<!-- context-param是上下文参数(属于整个web工程) -->
<context-param>
<param-name>userName</param-name>
<param-value>context</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>
向ServletContext中存取数据
public class ContextServlet1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletConfig().getServletContext();
//4. ServletContext对象可以像Map一样存取数据
System.out.println("Attr1的值是(未存入):" + servletContext.getAttribute("Attr1"));
servletContext.setAttribute("Attr1","第一个参数");
System.out.println("Attr1的值是:(已存入)" + servletContext.getAttribute("Attr1"));
servletContext.removeAttribute("Attr1");
System.out.println("Attr1的值是:(已删除)" + servletContext.getAttribute("Attr1"));
}
}
在不同的Servlet程序中体现ServletContext对象的公用型
public class ContextServlet2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletConfig().getServletContext();
servletContext.setAttribute("Attr2","第二个参数");
System.out.println("contextServlet2中获取数据Attr2" + servletContext.getAttribute("Attr2"));
}
}
public class ContextServlet3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletConfig().getServletContext();
System.out.println("contextServlet3中获取数据Attr2" + servletContext.getAttribute("Attr2"));
}
}
HTTP协议
-
什么是HTTP协议
协议是指双方或者多方相互约定好,都需要遵守的规则。HTTP协议是指客户端与服务器之间通信时发送的数据需要遵守的规则,HTTP协议中的数据又叫报文。 -
请求的HTTP协议格式
客户端给服务器发送数据叫做请求,服务器给客户端传回数据叫做响应。请求又分为GET和POST请求。- GET请求
- 请求行:由请求的方式(GET)、请求的资源路径[+?+请求参数]、请求协议的版本号(如HTTP/1.1)组成
如:GET/servlet_test/a.html/
- 请求头:由key:value键值对组成,不同的键值对代表不同的含义
- POST请求
- 请求行:由请求的方式(POST)、请求的资源路径[+?+请求参数]、请求协议版本号组成
- 请求头:由key:value键值对组成,不同的键值对代表不同的含义,在请求头后会空出一行。
- 请求体:在请求头空行的下一行,是客户端发送给服务器的数据
- 常用的请求头说明
- Accept:表示服务器可以接受的数据类型
- Accept-Language:表示服务器可以接受的语言类型
- User-Agent:表示客户端浏览器的信息
- Host:表示请求时服务器的ip地址和端口号
- GET请求和POST请求的区分
- GET请求
- form表单中method = get
- a锚点标签
- img标签中添加图片
- link标签引入css文件
- script标签引入js文件
- iframe标签引入html页面
- 在浏览器搜索栏中键入地址后回车
- POST请求
- form表单中method = post
-
响应的HTTP协议
- 相应的HTTP协议格式
- 响应行:分为相应的协议和版本号、响应状态码、响应状态描述符
如:HTTP/1.1 200 OK
- 响应头:由key:value键值对构成,不同的键值对具有不同的含义。响应头后空出一行
- 响应体:在响应头空行后一行开始,代表服务器回传给客户端的数据。
- 常用的响应码说明
- 200 : 表示请求成功
- 302 : 表示请求重定向
- 404 :表示请求服务器已经收到,但是所需数据不存在(即请求地址错误)
- 500 :表示服务器已经收到请求,但是服务器内部产生错误(代码等错误)
-
MIME类型说明
MIME是HTTP协议中的数据类型(多功能Internet邮件扩充服务)。MIME类型的格式是大类型/小类型
,并与某一种文件的扩展名相对应
常见的MIME类型
文件 | MIME类型 |
---|---|
超文本标记语言文本(.html/.htm) | text/html |
普通文本(.txt) | text/plain |
RTF文本(.rtf) | application/rtf |
GIF图形(.gif) | image/gif |
JPEG图形(.jpeg/.jpg) | image/jpeg |
au声音文件(.au) | audio/basic |
avi文件(.avi) | video/x-msivideo |
GZIP文件(.gz) | application/x-gzip |