Skip to content

五、Servlet

一、介绍

1、ServletServerApplet 的缩写,是的意思。

2、Serviet 本质上也是 Java 类,但要遵循 进行编写,没有main()方法,它的创建、使用、销毁都由 Servlet容器进行管理(如 Tomcat)。

3、提供了 Serviet功能的服务器,叫做 ,其常见容器有很多,如 Tomcat, Jetty, WebLogic Server, Websphere,JBoss 等等。

4、(另外两个是过滤器filter监听器listener)

二、Servlet快速入门

1、导入Servlet依赖

创建web项目,导入Servlet依赖坐标

java
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>maven_web</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
        	<plugin>
            	<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.2</version>
				<configuration>
    				<server>tomcat9</server>
    				<update>true</update>
    				<port>8080</port>
    				<path>/</path>
				</configuration>
			</plugin>
        </plugins>
    </build>
</project>

2、实现Servelt接口

创建:定义一个类,实现Servlet接口,并重写接口中的所有方法,并在service方法中输入一句话

java
package org.example.web;


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

@WebServlet("/demo1")
public class ServletDemo1 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("servlet在tomcat上启动");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

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

    @Override
    public void destroy() {

    }
}

3、配置

配置:在类上使用@WebServlet注解,配置该Servlet的访问路径

java
@WebServlet("/demo1")
public class ServletDemo1 implements Servlet {
}

4、访问

访问:启动Tomcat,浏览器输入URL访问Servlet

bash
http://localhost:8080/demo1

5、出现报错无报错不用看


(1)报错一:“Compilation failure”、“不再支持源选项5,请使用6或更高的版本”

参考csdn链接:https://blog.csdn.net/qq_53253335/article/details/133700923

  • 1、检查maven配置

    maven配置教程:点击此处



  • 2、检查jdk版本

    检查项目jdk

    检查模块jdk

    检查java编译器的jdk


  • 3、运行maven的clean命令和compile命令

    运行项目,此处应该已经成功,如果不成功接着往下看

  • 4、配置项目的pom.xml
    xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    	...
        <properties>
            <maven.compiler.target>17</maven.compiler.target>  <!-- jdk-17 -->
            <maven.compiler.source>17</maven.compiler.source>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        ...
    </project>

三、生命周期

1、加载和实例化

默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象

(1)loadOnStartup

使用 loadOnStartup 参数可以控制 Servlet 的加载行为

java
@WebServlet(urlPatterns = "/demo",loadOnStartup = 1)
  1. 负整数:第一次被访问时创建Servlet对象
  2. 0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高

2、初始化

在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化工作。

该方法只调用一次

3、请求处理

每次请求Servlet时,Servlet容器都会调用Servelt的service()方法对请求进行处理

4、服务终止

当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destory()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收

四、urlPattern配置访问路径

1、规则


(1)精确匹配

  • 配置路径

    java
    @WebServlet("/user/select")
  • 访问路径

    bash
    http://localhost:8080/web-demo/user/select

(2)目录匹配

  • 配置路径

    java
    @WebServlet("/user/*")
  • 访问路径

    bash
    http://localhost:8080/web-demo/user/aaa
    http://localhost:8080/web-demo/user/bbb

(3)扩展名匹配

  • 配置路径

    java
    @WebServlet("/user/*.do")
  • 访问路径

    bash
    http://localhost:8080/web-demo/user/aaa.do
    http://localhost:8080/web-demo/user/aaa.do

(4)任意匹配

  • 配置路径

    java
    @WebServlet("/")
    @WebServlet("/*")
  • 访问路径

    bash
    http://localhost:8080/web-demo/hehe
    http://localhost:8080/web-demo/haha

    建议不要配置这个

五、XML配置访问路径

web.xml文件中配置

xml
<web-app>
    <servlet>
        <servlet-name>demo1</servlet-name>		
        <servlet-class>org.example.web.ServletDemo1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo1</servlet-name>
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>
</web-app>

六、Request

1、获取请求数据

HTTP请求数据总共分为三部分内容,分别是

  1. 请求行

  2. 请求头

  3. 请求体

(1)获取请求行数据

请求行包含三块内容,分别是请求方式请求资源路径HTTP协议及版本

request对象都提供了对应的API方法来获取

  • 获取请求方式: GET
java
String getMethod()
  • 获取虚拟目录(项目访问路径): /request-demo
java
String getContextPath()
  • 获取URL(统一资源定位符): http://localhost:8080/request-demo/req1
java
StringBuffer getRequestURL()
  • 获取URI(统一资源标识符): /request-demo/req1
java
String getRequestURI()
  • 获取请求参数(GET方式): username=zhangsan&password=123
java
String getQueryString()

介绍完上述方法后,咱们通过代码把上述方法都使用下:

java
/**
 * request 获取请求数据
 */
@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // String getMethod():获取请求方式: GET
        String method = req.getMethod();
        System.out.println(method);//GET
        // String getContextPath():获取虚拟目录(项目访问路径):/request-demo
        String contextPath = req.getContextPath();
        System.out.println(contextPath);
        // StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/request-demo/req1
        StringBuffer url = req.getRequestURL();
        System.out.println(url.toString());
        // String getRequestURI():获取URI(统一资源标识符): /request-demo/req1
        String uri = req.getRequestURI();
        System.out.println(uri);
        // String getQueryString():获取请求参数(GET方式): username=zhangsan
        String queryString = req.getQueryString();
        System.out.println(queryString);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

启动服务器,访问http://localhost:8080/request-demo/req1?username=zhangsan&passwrod=123,获取的结果如下:


(2)获取请求头数据

对于请求头的数据,格式为key: value如下:

所以根据请求头名称获取对应值的方法为:

java
String getHeader(String name)

接下来,在代码中如果想要获取客户端浏览器的版本信息,则可以使用

java
/**
 * request 获取请求数据
 */
@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求头: user-agent: 浏览器的版本信息
        String agent = req.getHeader("user-agent");
		System.out.println(agent);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

重新启动服务器后,http://localhost:8080/request-demo/req1?username=zhangsan&passwrod=123,获取的结果如下:

(3)获取请求体数据

  • 如果是纯文本数据:getReader()
  • 如果是字节数据如文件数据:getInputStream()

(4)简化

  • 获取所有参数Map集合

    java
    Map<String,String[]> getParameterMap()
  • 根据名称获取参数值(数组)

    java
    String[] getParametervalues(String name)
  • 根据名称获取参数值(单个值)

    java
    String getParameter(String name)

2、处理中文乱码

  • GET请求

    java
    request.setCharacterEncoding("UTF-8")
  • POST请求(tomcat8.0之后解码方式是UTF-8)

    java
    new String(username.getBytes("ISO-8859-1"),"UFT-8");

3、请求转发

(1)跳转

java
request.getRequestDispatcher("资源路径").forward(request,response)

(2)携带数据

方法名说明
void setAttribute(String name,Object o)存储数据到request域中
Object getAttribute(String name)根据key,获取值
void removeAttribute(String name)根据key,删除键值对

七、Response

1、响应数据格式

响应数据分为3部分

  1. 响应行
  2. 响应头
  3. 响应体

(1)响应行

java
void setStatus(int sc)		//设置响应状态码

(2)响应头

java
void setHeader(String name , String value)		//设置响应偷键值对

(3)响应体

java
PrintWriter getWriter();			//获取字符输出流
ServletOutputStream getOutputStream();	//获取字节输出流

2、重定向

java
String contextPath = request.getContextPath();

response.setStatus(302);
response.setHeader("Location",contextPath + "/resp2");		//虚拟目录

简化

java
String contextPath = request.getContextPath();

response.sendRedirect(contextPath + "/resp2");

3、响应数据

(1)响应字符数据

java
//解决乱码
response.setContentType("text/html;charset=utf-8");

//获取字符输出流
PrintWriter writer = reponse.getWriter();

//设置content-type
//response.setHeader("content-type","text/html");
writer.write("<h1>aaa</h1>");