servlet 简介

servlet是java提供一个服务端程序的接口,它在javax.servlet包,原代码如下,共有5个接口。

public interface Servlet {
    //初始化
    void init(ServletConfig var1) throws ServletException;
	//获取配置
    ServletConfig getServletConfig();
	//服务
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
	//获取serlvet方法,一般用来写作者之类的,基本没什么
    String getServletInfo();
	//销毁,回收资源
    void destroy();
}

如果我们要写自己的servlet就需要实现javax.servlet这个接口。

servlet例子

我们建立一个maven的web项目,编写一个类来实现servlet接口,代码如下:

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

//Servlet 3.0以上支持的注解式写法
/*
urlPatterns 是映射路径
loadOnStartup 是这个servlet的加载时机设定。默认-1是第一次调用是加载,非负数则在服务器启动时加载,加载优先级根据loadOnStartup值的大小来确定优先级
* */
//urlPatterns 其实是个数组,你可以对应多个地址比如:
//@WebServlet(urlPatterns = {"/demo","/demo1","/demo2"}, loadOnStartup = 1)
@WebServlet(urlPatterns = "/demo", loadOnStartup = 1)
public class servletDemo  implements Servlet {
	private ServletConfig getServletConfig;
    
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.getServletConfig = servletConfig;
        //根据loadOnStartup配置时机来调用init方法,只会被调用一次
        //如果loadOnStartup 不是负数在启用tomcat的时候控制台就有init...的输出,否则第一次调用这个servlet接口才会调用
        System.out.println("init....");
    }

    @Override
    public ServletConfig getServletConfig() {
        //直接return null也行;
        return this.getServletConfig;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //每次访问都会被调用
        System.out.println("service.....");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        //在tomcat正常关闭才能看到,强制关闭tomcat的话这个方法不会被调用
        //和init一样只会被调用一次
        System.out.println("destroy...");
    }
}

编写完我们把项目放在tomcat上运行,假设我们本地tomcat的端口是8080,项目名是servletDemo则访问地址是:http://localhost:8080/servletDemo/demo

servlet 配置

从3.0版本以上servlet可以使用@WebServlet注解来配置,在以前的版本需要在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>
        <!-- servlet名字,随意你起 -->
        <servlet-name>demo</servlet-name>
        <!-- servlet的全限定名 -->
        <servlet-class>com.hyq.servletStudy.servletDemo</servlet-class>
    </servlet>

    <!-- 配置servlet与路径映射 -->


    <servlet-mapping>
        <!-- servlet名字,上边那段配置中你起的名字 -->
        <servlet-name>demo</servlet-name>
        <!-- 路径映射 -->
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>
</web-app>

配置完了再把之前写的servletDemo中@WebServlet(urlPatterns = "/demo", loadOnStartup = 1)给注释掉,再用

http://localhost:8080/servletDemo/demo地址访问一下就好了。

地址要根据你自己配置的映射地址和项目名(或在tomcat插件中配置的path)来组合

urlPatterns 说明

urlPatterns 配置servlet对应的地址,它有以下几种方式配置

  • 精准匹配
  • 目录
  • 扩展名
  • 任意匹配

1.精准匹配

就是我们上边例子中用的/demo,/test/demo这样的明确写好的地址,写法如下

@WebServlet(urlPatterns = "/demo" )

2.目录

目录写法如下,这样写一切/demo目录下的访问都会被这个servlet处理

@WebServlet(urlPatterns = "/demo/*")

3.扩展名

这样一切.do结尾的访问都会被处理,比如http://localhost/123.do,http://localhost/test/123.do

@WebServlet(urlPatterns = "*.do")

扩展名写法一定不能用/开头,只能直接写扩展名

比如/*.do这样是错误的

4.任意匹配

写法有以下2种

@WebServlet(urlPatterns = "/*")
@WebServlet(urlPatterns = "/")

/和/*区别

虽然它们都可以实现任意匹配,但是我们一般使用/*来实现任意匹配。

原因你可以在tomcat的目录下的/conf/web.xml中找到原因,其中有一段

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

	<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- The mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

tomcat自身使用org.apache.catalina.servlets.DefaultServlet 这个默认servlet来处理“/"任意匹配,这个DefaultServlet 同时还处理tomcat静态资源的访问处理。

如果你用自己写的servlet替换了“/",那么你的网站一切静态资源都访问不了(除非你自己写代码去实现),

比如我们项目中在webapp下有一个 hello.html,以前我们可以用http://localhost:8080/test/hello.html访问,替换“/"之后我们访问这就变成404了。

5.优先级问题

如果一个地址同时满足2个或以上的servlet地址匹配规则就按以下的优先级来处理

精准匹配 > 目录 > 扩展名 > 任意