实现一个java 无论用的的什么框架,都离不开servlet,那servlet是什么?
最开始学习java的时候,老师只告诉我这是用来写java web用的;工作一段时间之后,没有注意过servlet。为什么呢? 一方面是因为项目框架不会让我来配置;另外一方面是项目都集成了各种框架,servlet都没有明显使用了。
那什么是servlet是什么呢?
servlet
servlet是处理请求和响应的;然而这句话说明不了什么。
下面是我写的一个简单的servlet:
public class HelloServlet extends HttpServlet {
@Override
protected void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
}
@Override
protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
@Override
public void destroy () {
System.out.println("servlet 销毁");
super.destroy();
}
@Override
public void init () throws ServletException {
System.out.println("servlet 初始化");
super.init();
}
}
在idea中向上查找继承的类或者实现的接口,最终找到:
public abstract class GenericServlet
implements Servlet, ServletConfig, java.io.Serializable
{}
这个类实现Servlet、ServletConfig、java.io.Serializable,见名知意,Servlet是servlet接口,ServletConfig是配置接口,Serializable是序列化,只要看servlet即可。servlet内容如下:
从截图上可以看到,servlet内容非常的简单,初始化、销毁、执行、以及获取配置等方法。
通常对接第三方接口的时候,都规定了请求头、请求类型、参数等内容,这些东西又被称为api规范;servlet也可以认为是规范,只不过servlet是对容器而言,例如tomcat、weblogic等。
我们实现servlet的时候并不会实现操作socket和端口,socket都是web容器实现的,它们会把接收到的请求处理之后,调用合适的servlet实现,这些实现就是自己实现的servlet。
使用
上面啰嗦了那么多,只是想说明servlet只是一个简单的接口,没有什么特别深奥的内容。
实现了一个servlet,只有使用了才有意义;在Java web中,servlet通常被配置在web.xml中(最近了解到,配置在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="4.0">
<display-name>simpleweb</display-name>
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.learn.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
最开始学习的时候,总是觉得奇怪,为什么一定要这样配置,为什么写其它标签不行;现在我对这个问题有一定的了解,大多数的xml配置文件,基本都被xml配置的使用方限制了配置的标签,这些限制大多都是通过xsd或者dtd来描述,比如,在浏览器中发开http://xmlns.jcp.org/xml/ns/javaee这个路径,会打开一个网页,如下:
打开图中的web-app_4_0.xsd,在这个文件中定义了web.xml中常用的标签,有兴趣的这里看看。
servlet配置
配置可以分为两方面:
- 拦截配置
- 初始化参数配置
拦截配置
servlet是用来处理请求,处理那些请求由拦截规则决定,常见的配置方式:
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.learn.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>*.do</url-pattern> // 此处匹配请求
</servlet-mapping>
常见的匹配方式:
- 精确匹配
- 路径匹配
- 后缀匹配
- /
- /*
精确匹配, 路径必须完全一致才会匹配,例如:
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/role/addRole</url-pattern>
</servlet-mapping>
路径匹配,p匹配以user开头的请求,例如:
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/role/*</url-pattern>
</servlet-mapping>
后缀匹配,例如:
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
/* ,匹配所有的请求(包含jsp、js、html等),spring mvc多采用这种配置,例如:
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
/,匹配所有请求(包含各种资源文件,但不包含jsp),例如:
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
不匹配jsp是经过测试的,原因还不知道。
匹配规则
上面匹配大致可以概括为精确匹配、路径匹配、后缀匹配,三种方式不可在一个servlet中混合使用,比如很容易想到错误匹配方式:
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/role/*.action</url-pattern>
</servlet-mapping>
但是这种混合使用是可以的:
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/role/*.action</url-pattern>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
这样也可以:
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/role/*.action</url-pattern>
<url-pattern>/</url-pattern>// /*也可以
</servlet-mapping>
总而言之不能在一个【url-pattern】中混合使用。
上面是一个基本的规则,满足上面的条件,有多个servlet的话,陪陪规则如下:
- 匹配到一个servlet,就不匹配其它的servlet
- 优先级:精确匹配 >> 路径匹配 >> 后缀匹配 >> (/*和/)
虽然精确匹配优先级高,但是实际项目中一般都是使用/*和/这两种匹配方式。
初始化参数配置
初始化参数配置方式:
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.learn.servlet.HelloServlet</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>nyl</param-value>
</init-param>
</servlet>
获取初始化参数也很容易, 在实现的servlet中,这样写:
ServletConfig config = getServletConfig();
String name = config.getInitParameter("name");
System.out.println("name====" +name);
总结
servlet的配置并不复杂,只需要详细的了解一下就知道怎么回事。