什么是servlet
- Servlet其实就一个运行在web服务器上的小的Java程序,用于处理从web客户端发送的请求,并且对请求作出响应。
Servlet技术概述
JavaEE技术有13规范,其中之一就是Servlet规范,本质就是接口
Servlet是JavaEE技术平台的规范,Servlet 运行在服务端的Java小程序只能运行在WEB服务器(Tomcat).
Servlet是JavaWeb三大组件之一(Servlet、Filter、Listener),且最重要。
作用: 接收请求,进行响应
广义的Servlet: Servlet接口所有实现类
狭隘的Servlet: 专门指的是Servlet接口
Servlet程序快速入门
实现Servlet程序入门,Servlet成为Java服务器端程序,由客户端浏览器访问的.
- 实现步骤:
- 定义类实现接口Servlet
- 重写接口中的全部抽象方法(5个)
- 在web.xml中配置Servlet
下面是定义了一个QuickStartServlet类实现接口Servlet:
package com.ccc.servlet;
/*
* 实现Servlet快速入门
* 1、创建一个类实现Servlet接口(Tomcat)
* 2、重写Servlet接口中的所有抽象方法(5个)
* 3、在当前项目的web.xml文件中,对Servlet进行配置
*/
public class QuickStartServlet implements Servlet{
/*
service方法用于接收客户端的请求,给客户端进行响应
ServletRequest:接收客户端的请求
ServletResponse:给客户端进行响应
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Servlet快速入门");
// 参数servletResponse方法getWriter()获取字符输出流
Writer w = servletResponse.getWriter();
//输出流的方法write,数据写到客户端浏览器
w.write("hello world");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
在web.xml中配置这个类
<servlet>
<!--quick这个名字随便起,但要跟下面的<servlet-name>内的名字对应-->
<servlet-name>quick</servlet-name>
<!--这个名字是前面那个实现接口Servlet的类的全路径-->
<servlet-class>com.ccc.servlet.QuickStartServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--quick这个名字随便起,但要跟上面的<servlet-name>内的名字对应-->
<servlet-name>quick</servlet-name>
<!--使用浏览器访问Servlet的虚拟路径-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
访问servlet
http://localhost:8080/day01/hello
这个day01是package com.ccc.servlet这个包所属的模块名称。
Servlet程序执行原理(重要)
Servlet对象生命周期
Servlet生命周期:Servlet对象从创建到销毁的过程。
- Servlet何时被创建又是何时被销毁的?
Servlet中有init,service,destroy方法,这几个方法称为是Servlet生命周期相关的方法。
-
init(ServletConfig config)Servlet对象的初始化方法,对象被创建的时候调用
Servlet对象什么时候被创建
-
Servlet默认第一次访问的时候,对象被创建
-
Tomcat服务器启动的时候创建对象,需要修改web.xml (一般不配置)
<!-- Tomcat服务器启动的时候,自动创建Servlet对象 配置的数字是设置启动的优先级 可以写任意的整数,数字越小,优先级越高 --> <load-on-startup>5</load-on-startup>
-
-
service(request,response)客户端访问一次,执行一次
-
destory()Servlet对象销毁之前调用
-
Servlet对象什么时候被销毁
- 停止Tomcat服务器
- WEB项目从服务器移除
Servlet的启动时加载(了解)
为什么使用启动时加载
Servlet对象是第一次被访问的时候会被创建的,init方法就会执行。假设在init方法中做了一些比较耗时的操作(比如:加载了一些配置文件并且解析可能需要花费3秒钟)。第一个用户第一次访问这个Servlet的时候,需要等待3秒钟。如何使第一个用户在第一次访问的时候不需要花费这么长时间?
什么是启动时加载
Servlet默认是在第一次访问的时候创建的对象,现在通过一个配置将Servlet的实例化的过程放在服务器启动的时候(让服务器启动的时候创建Servlet的对象)。如果现在这样做那么之前花费的时间就会在服务器启动的时候一起花费掉了。对于用户来讲就不需要额外花费这个时间。
配置完成启动时加载
<servlet>
<servlet-name>ServletDemo2</servlet-name>
<servlet-class>com.ccc.servlet.demo1.ServletDemo2</servlet-class>
<!--
Tomcat服务器启动的时候,自动创建Servlet对象
配置的数字是设置启动的优先级
可以写任意的整数,数字越小,优先级越高
-->
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo2</servlet-name>
<url-pattern>/ServletDemo2</url-pattern>
</servlet-mapping>
serlvet的访问路径配置(理解)
Servlet的Web.xml配置
<!--
Servlet的详细配置
-->
<servlet>
<!-- name,定义名字,随意-->
<servlet-name>path</servlet-name>
<!-- class 配置类的全名,反射-->
<servlet-class>com.itheima.servlet.PathServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- name 必须和上面name相同-->
<servlet-name>path</servlet-name>
<!-- url-pattern 配置的是浏览器访问的虚拟路径,需要最后将“\”后的名字输入到浏览器-->
<url-pattern>/path</url-pattern>
</servlet-mapping>
url-pattern的配置
-
1、完全匹配也称精确匹配 :以 / 开始
/abc : 浏览器地址栏必须写 /abc(abc只是方便为了举例)
<url-pattern>/path</url-pattern>
-
2、目录匹配,以 / 开始 需要以 * 结束
/aaa/bbb/* : 浏览器地址栏可以写 /aaa/bbb/任意
-
3、后缀名匹配。以 * 开始的
*.abc : 浏览器地址栏可以写 任意.abc
目录匹配和后缀名匹配不能同时使用
/aaa/bbb/*.abc 冲突
访问的优先级
tomcat获得匹配路径时,访问优先级顺序:完全路径匹配 > 目录匹配 > 扩展名匹配
注意:开发中servlet配置路径选择精确匹配
适用于处理HTTP协议的Servlet的实现关系
基本的实现关系
Servlet接口
|
|
GenericServlet类 通用的Servlet,是一个与协议无关的Servlet
|
|
HttpServlet类 Http专用的Servlet
关系实现的概述
SUN设计之初,是有野心,以后的互联网不仅仅只使用http协议,可以通过GenericServlet实现。HttpServlet是一个与协议相关的Servlet是专门用来处理HTTP协议的请求。通常编写一个Servlet一般都会让这个Servlet继承HttpServlet重写service方法。
- 在service方法内部根据请求方式不同执行不同的doXXX的方法(get请求执行doGet方法,如果是post请求就会执行doPost方法)。
- 所以往往继承了HttpServlet之后不需要重写service方法,只需要重写doGet和doPost方法即可。往往请求要处理的内容的代码都是一致的,所以需要让doGet和doPost相互调用可以简化编程。
继承HttpServlet的代码实现
步骤1 :创建类,继承MyServlet,复写doGet方法
package com.ccc.web;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("get请求将执行");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req,resp);
}
}
步骤2:编写配置文件
<!--配置servlet-->
<servlet>
<!--配置servlet名称-->
<servlet-name>myServlet</servlet-name>
<!--配置servlet类的全路径-->
<servlet-class>com.ccc.web.MyServlet</servlet-class>
</servlet>
<!--配置servlet映射关系-->
<servlet-mapping>
<!--配置关联的servlet名称-->
<servlet-name>myServlet</servlet-name>
<!--配置 访问路径-->
<url-pattern>/my</url-pattern>
</servlet-mapping>
步骤3:浏览器访问
在浏览器地址栏输入:http://localhost:8080/day13/hello
- 浏览器显示空白页面
- 控制打印信息
request接收请求参数
Request接收请求参数的概述
请求参数
方法名 | 描述 |
---|---|
String getParameter(String name) | 获得指定参数名对应的值。如果没有返回null,如果只有多个获得第一个。 例如:username=jack |
Request接收请求参数入门
- 编写form.html表单,提供表单字段:username、password 以post方式提交
<form action="./demo01ParamServlet" method="post">
用户名:<input type="text" name="username" value="jack" /> <br/>
密码:<input type="text" name="password" value="1234" /> <br/>
<input type="submit" value="post提交" />
</form>
- 编写Servlet实现类,使用对应方法获得请求参数
public class ParamServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1 使用参数名获得一个值
//1.1 获得用户名
String username = request.getParameter("username");
//1.2 获得密码
String password = request.getParameter("password");
System.out.println(username + " : " + password);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/* 开发中我们发现,doPost和doGet两个方法编写的内容相同
* 所以常使用一个调用另一个,此处我们使用doPost调用doGet
* 所有的内容之后都编写doGet方法中
*/
doGet(request, response);
}
}
- 编写Servlet配置文件
<servlet>
<servlet-name>paramServlet</servlet-name>
<servlet-class>com.ccc.web.ParamServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>paramServlet</servlet-name>
<url-pattern>/paramServlet</url-pattern>
</servlet-mapping>
IDEA创建Servlet(重要)
public class MyServlet extends HttpServlet {
/**
* doGet方法对应了客户端浏览器的提交方式GET
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().print("MyServlet run");
}
/**
* doPost方法对应了客户端浏览器的提交方式POST
* 无论:是POST提交,还是GET,统一处理,都使用doGet
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//调用doGet
doGet(request,response);
}
}
继承HttpServlet原理
Servlet是JavaEE规范,Servlet接口中的标准方法 service方法
修改Servlet模版(了解)
注意:之前说的提交安全,指的是form表单有两种提交方式get/post。get提交数据的时候,会把表单中数据追加到地址栏,这里只是在浏览器的这方面不安全。而此处调用get、post方法时,数据已经进入到到servlet类里面了。在外界,用户根本就不知道类中有哪些方法。所以在这个类中无论是用get调用post、还是post调用get方法,其实效果是一样的,每什么区别。这个看个人喜好,设置成哪个调用哪个都行。
ServletConfig对象
ServletConfig用来获得Servlet的相关的配置的对象
有一个Servlet程序,就会出现一个对应的ServletConfig对象
-
获取ServletConfig对象
- init方法参数(ServletConfig servletConfig),调用者是Tomcat引擎,ServletConfig对象是由Tomcat引擎创建
- 父类中,定义了方法 ServletConfig getServletConfig()
-
对象能做什么
-
获取Servlet的名字,String getServletName()
<servlet-name>config</servlet-name>
-
获取Servlet的初始化参数,String getInitParameter(“键名”)
<init-param> <param-name>ccc</param-name> <param-value>java</param-value> </init-param>
public class ConfigServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* 使用父类的方法getServletConfig()方法,获取ServletConfig对象 ServletConfig是接口 org.apache.catalina.core.StandardWrapperFacade 接口的实现类(Tomcat重写) */ ServletConfig config = getServletConfig(); System.out.println(config);//org.apache.catalina.core.StandardWrapperFacade@63b85cd //获取Servlet名字 String servletName = config.getServletName(); System.out.println(servletName);//config //获取Servlet初始化参数 String value = config.getInitParameter("ccc"); System.out.println(value);//340 } }
-