目录
1Servlet概述
servlet : server applet 服务器的小程序 , 能够被运行的程序
servlet运行在服务器端的java程序。
Servlet是一个接口,一个类要想通过浏览器被访问到,那么这个类就必须直接或间接的实现Servlet接口。
作用:
接收请求,处理请求,生成相应。
2Servlet快速入门
2.1编写步骤
- 定义一个类实现Servlet接口。
- 实现Servlet接口中的所有方法。
- 在web.xml中书写Servlet的配置,让浏览器访问的路径与定义类形成映射关系。
2.2代码书写
在tomcat启动的时候,会加载web.xml中的信息。我们要将这个类的映射书写在其中。
<servlet>表示当前有一个servlet类 主要交给tomcat管理
<servlet-name>别名,在整个web.xml文件中唯一。</servlet-name>
<servlet-class>这个类的全限定名。</servlet-class>
</servlet>
<servlet-mapping>每一个servlet都需要配置映射信息 给每一个类配置入口
<servlet-name>别名</servlet-name>
<url-pattern>当前这个类的访问路径</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.study.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
2.3执行过程
3Servlet的生命周期
init : 初始化方法,当此类第一次被加载时执行。
service : 服务方法,每次请求此路径都会执行。
destroy : 销毁方法,对象销毁时执行。
public class LifeServlet implements Servlet{
@Override
/*
初始化方法
执行时机:默认第一次访问的时候
执行次数:一次
*/
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(555);
}
@Override
/*
服务方法
执行时机:请求来的时候
执行次数:一次请求就会执行一次
*/
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println(666);
}
@Override
/*
销毁方法
执行时机:当servlet从项目中移除的时候或者web服务器关闭的时候
执行次数:一次
*/
public void destroy() {
System.out.println(444);
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
}
4Servlet结构
HttpServlet 继承了 GenericServlet 实现了 Servlet接口。
Servlet 接口
|
GenericServlet 抽象类: 通用的servlet,实现了除service方法之外的所有方法,且也实现servletConfig中的所有方法
|
HttpServlet 抽象类: http servlet,用来处理http请求,实现了servlet的所有方法,且细分了不同请求处理方式
GenericServlet:
public class MyGenericServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("执行了MyGenericServlet的service方法!");
}
}
HttpServlet:
public class MyHttpSelvlet extends HttpServlet {
/*@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("执行了MyHttpSelvlet的service方法!");
}*/
//get请求时走这个方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行了MyHttpSelvlet的doGet方法!");
}
//post请求走这个方法
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行了MyHttpSelvlet的doPost方法!");
}
}
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="4.0">
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.study.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>MyHttpSelvlet</servlet-name>
<servlet-class>com.study.servlet.MyHttpSelvlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyHttpSelvlet</servlet-name>
<url-pattern>/myHttp</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>MyGenericServlet</servlet-name>
<servlet-class>com.study.servlet.MyGenericServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyGenericServlet</servlet-name>
<url-pattern>/myGeneric</url-pattern>
</servlet-mapping>
</web-app>
5页面响应405异常
1.没有重写doGet或者doPost方法
2.调用了父类的doGet 或者 doPost方法
6Servlet底层代码
Servlet:
定义了方法,包括Servlet生命周期的三种方法init、service、destroy
GenericServlet:
实现了Servlet接口。
重写了init方法,将ServletConfig赋值给了成员变量,然后调用自己的init方法。
继续抽象了service方法。
重写了destroy方法,空的。如果我们要使用可以再次进行重写。
HttpServlet:
继承了GenericServlet。
重写了service方法,
将ServletRequest、ServletResponse强转为HttpServletRequest、HttpServletResponse。
获得请求方式并将service方法一分为七,七种http请求方式。
所以,我们定义一个Servlet的时候只需要继承HttpServlet,重写里面的doGet、doPost...(用哪个写那个)即可。
7url-pattern设置详解
作用:将一个请求网络地址和servlet类建立一个映射关系(一对一)
url-pattern : 浏览器访问服务器过程 项目下资源的访问路径
url-pattern 每一个类 url-pattern 都可以书写多个
书写的方式:
1.完全匹配 一模一样的路径 /a/b/c/Servlet 前面的斜杠不能丢 语法: /访问路径
2.不完全匹配(目录匹配) *表示通配符 /a/b/c/* 语法: /内容/*
3.后缀名匹配 *.后缀 没有斜杠 只需要满足后缀名一致即可 语法: *.后缀
4.缺省匹配 以上三种路径都没有匹配成功的时候 默认执行缺省匹配 语法: /
tomcat默认自带缺省匹配
<servlet>
<servlet-name>UrlPatternServlet</servlet-name>
<servlet-class>com.itheima.d_other.UrlPatternServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UrlPatternServlet</servlet-name>
<url-pattern>/a/b/c/myUrl1</url-pattern>
<url-pattern>/a/b/c/*</url-pattern>
<url-pattern>*.abc</url-pattern>
</servlet-mapping>
8load-on-startup标签
默认情况下一个servlet初始化的时机是 第一次被访问的时候 , 希望提前初始化, 项目启动的时候 就需要初始化。<load-on-startup>标签就是提前初始化的标签。
load加载 在xxx时候 startup 启动
<load-on-startup>1-6</load-on-startup> 表示在启动的时候加载servlet
<load-on-startup>数字</load-on-startup>
一般情况数字书写1-6其中一个就够(项目中没有那么多类需要提前加载 一般情况1-2个)
数字越小 加载优先级越高.
建议:如果有设置 一般情况 设置3 设置2 . 可以重复配置 如果数字一样 按照xml顺序执行
<servlet>
<servlet-name>LoadOnStartUpServlet</servlet-name>
<servlet-class>com.itheima.d_other.LoadOnStartUpServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>LoadOnStartUpServlet</servlet-name>
<url-pattern>/loadOnStartUp</url-pattern>
</servlet-mapping>
9Servlet3.0注解开发
9.1注解开发与xml开发的区别
在servlet中有区分版本的 2.5版本 和 3.0以后的版本
2.5 的版本主要是xml开发
3.0以后的版本支持xml和注解开发 : web.xml文件可有可无
注解是用来替换xml
注解:
优点 : 书写简单 , 快速开发
缺点 : 可读性太差 耦合高(直接在java代码中书写的) 修改的时候麻烦
xml:
优点 : 可读性好 , 配置清晰. 解耦(脱离了代码,只需要修改配置文件即可)
缺点 : 配置文件多 配置麻烦
如何创建版本:
只要是3.0以后的版本都可以 支持注解+xml开发 , 支持多线程 (异步), 支持特殊的内容
9.2使用注解开发
通过注解@WebServlet配置Servlet,简化web.xml配置Servlet复杂性,提高开发效率。
/*
@WebServlet(
value = {"/myAnno1","/myAnno2"} 设置访问路径
urlPatterns = {"/myAnno1","/myAnno2"} 设置访问路径
value 和 urlPatterns 只能出现一个
,name ="MyAnnotationServlet" 别名 如果不设置 跟类名一致 可以省略不写
)
*/
//@WebServlet(value="/myAnno")
//如果 属性=数组的情况 如果这个数组有且只有一个成员 花括号可以省略不写
//如果有且只有一个value属性的情况下 value 可省略
//@WebServlet(urlPatterns = {"/myAnno1","/myAnno2"})
@WebServlet(value = {"/myAnno1","/myAnno2"} ,name ="MyAnnotationServlet" )
public class MyAnnotationServlet 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 {
}
}
10ServletContext
10.1介绍
web服务器(tomcat)在启动时,它会为每个web项目创建一个对应的ServletContext对象,它代表当前web项目。
主要作用:
先获得ServletContext
-
域对象(servlet之间可以通过域对象进行通信) - 操作共享数据的过程
-
获取资源在服务器的真实地址 - 管理整个项目的资源
-
获取全局的配置参数
-
获取文件MIME类型
获取ServletContext:
继承HttpServlet后,可以直接调用,当前模块下获得的servletContext对象都是同一个 整个项目启动的过程中有且只有一个对象,对象销毁的时机是服务器关闭。
ServletContext sc = getServletContext();
10.2域对象
域对象 : 区域(Scope) , 在范围内共享数据
在当前项目范围内,共享数据(多个servlet都可以获取)
多个资源共享同一套数据 不能修改只能获得(有线程安全问题)
存储数据
void setAttribute(String name,Object value)
获取数据
Object getAttribute(String name)
删除数据
void removeAttribute(String name)
public class MyServletContext extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获得ServletContext 对象.方法();
ServletContext sc1 = this.getServletContext();
ServletContext sc2 = this.getServletContext();
System.out.println(sc1 );
System.out.println(sc2 );
//往servletContext对象中存数据
//存api
sc1.setAttribute("jiujiu" , "爱java");
//直接获得数据
Object ds = sc2.getAttribute("jiujiu");
System.out.println("oneServlet : " + jiujiu);
}
}
public class MyServletContext2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获得ServletContext 对象.方法();
ServletContext sc1 = this.getServletContext();
ServletContext sc2 = this.getServletContext();
System.out.println(sc1 );
System.out.println(sc2 );
//直接获得数据
//当没有人进行存储的时候 值为null
Object jiujiu= sc2.getAttribute("jiujiu");
System.out.println("twoServlet : " + jiujiu);
//删除数据
sc2.removeAttribute("jiujiu");
}
}
10.3获取资源在服务器的真是地址
getRealPath() 获得项目在本地的真实路径(编译后路径)
getResourceAsStream() 获得项目下的资源文件 转换成流(编译后的)
public class GetResourceServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
/**
* 在java代码中 获得项目的资源 img/1.jpg
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获得ServletContext对象
ServletContext sc = getServletContext();
//2.获得这张图片的真实地址 .get 获得 Real 真实 Path路径 获得项目在本地磁盘的真实路径
//获得的是编译路径 获得最后拼接的路径
String realPath = sc.getRealPath("/img/1.jpg");
System.out.println(realPath);
//File file = new File
//直接获得项目下的文件 并转换成流对象
InputStream is = sc.getResourceAsStream("/img/1.jpg");
System.out.println(is);
}
}
10.4获得全局对象
读取web.xml文件中<context-param>标签信息,实现参数和代码的解耦(多个servlet都可以获取)
web.xml 进行配置
<context-param>
<param-name></param-name>
<param-value></param-value>
</context-param>
api : getInitParameter("key");
在web.xml中全局(项目)配置初始化参数
<context-param>
<param-name>charset</param-name>
<param-value>utf-8</param-value>
</context-param>
public class ParamServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得项目的根对象
ServletContext sc = getServletContext();
//获得根对象中提前设置好的编码
//getInitParameter获得初始化参数
String charset = sc.getInitParameter("charset");
System.out.println("获得根对象中存储的数据:"+charset);
}
}
以上就是Servlet的部分知识点啦,后续会继续补充。各位大佬如发现有知识点错误或者有不同的建议与意见,欢迎评论、私信指正,本人才疏学浅还需向各位大佬学习,还请不吝赐教!在此感谢各位的观看!谢谢!