Servlet
1、简介:
Servlet(Server Applet)是用Java编写的服务器端程序。
狭义上来说,Java API中提供一个接口叫做Servlet,因此,我们把实现了Servlet接口的Java程序叫做Servlet。
2、作用:
Servlet主要用于处理客户端发来的HTTP请求,并返回一个HTTP响应。
3、开发步骤:
(1)自己编写一个类,来实现servlet接口。
(2)把开发好的Java类部署到web服务器上。
■ 使用Tomcat自带的示例,开发第一个Servlet程序。
(1)创建一个maven-webapp项目。
IDEA创建maven项目时,如果maven太慢,需要配置
archetypeCatalog=internal
(2)在项目中添加java和resource目录。
(3)然后新建一个Create new Servlet,如果在new中找不到【Create new Servlet】的选项,需要在Project Structure中配置本Module的Source Roots。h
(4)在maven中引入servlet依赖。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>
如果不配置依赖的,会默认把jar包发布,可能会跟容器里的jar包冲突,scope如果要用provided,由容器提供,则不会发布。
scope可以使用5个值:
compile,缺省值,适用于所有阶段,会随着项目一起发布。
provided,类似compile,期望JDK、容器会提供这个依赖。如servlet.jar。
runtime,只在运行时使用,如JDBC驱动,适用运行和测试阶段。
test,只在测试时使用,用于编译和运行测试代码。不会随项目发布。
system,类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找
(6)修改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"
metadata-complete="true">
<display-name>Welcome to Tomcat</display-name>
<description>
Welcome to Tomcat
</description>
</web-app>
(7)创建FServlet:
写入代码doGet(request, response);
和要打印的内容
(8)配置web.xml
<servlet>
<servlet-name>FServlet</servlet-name>
<servlet-class>cn.sdcit.FServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FServlet</servlet-name>
<url-pattern>/f</url-pattern>
</servlet-mapping>
(9)访问FServlet
详细创建配置Servlet:https://blog.csdn.net/qq_53520822/article/details/115023148
解决tomcat控制乱码:
乱码有两种:
1、tomcat日志编码
tomcat日志编码解决:apache-tomcat-9.0.19\conf\logging.properties 文件中设置java.util.logging.ConsoleHandler.encoding = UTF-8
2、idea的日志显示控制台编码解决:
在idea安装目录中,idea64.exe.vmoptions文件中,最后添加一句:
-Dfile.encoding=utf-8
4、Servlet原理
针对Servlet接口,Java提供了两个默认的实现类:HttpServlet和GenericServlet。
(1)GenericServlet是一个抽象类。该类为Servlet接口提供了部分实现,但是没有实现HTTP请求的处理。
(2)HttpServlet类为HTTP请求中的GET、POST等类型的请求提供了操作方法。
5、Servlet的生命周期
Servlet生命周期是Servlet从创建到毁灭的整个过程。
三个阶段:
1、初始化阶段,Servlet容器会创建一个Servlet实例并调用init()方法;
2、处理客户端请求阶段,每收到一个客户端请求,Servlet容器就会产生一个新的线程,调用 service() 方法来处理客户端的请求。
3、终止阶段,调用destroy()方法终止。
最后,Servlet 是由 JVM 进行垃圾回收。
6、验证Servlet的生命周期
★设置servlet代码模板
【按Ctrl+o】快捷键
(1)创建LiveServlet类
(2)重写init()和destory()方法。
package cn.sdcit;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "FServlet")
public class FServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("客户端请求FServlet");
}
@Override
public void destroy() {
super.destroy();
System.out.println("FServlet销毁");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("FServlet初始化");
}
}
配置web.xml
<servlet>
<servlet-name>FServlet</servlet-name>
<servlet-class>cn.sdcit.FServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FServlet</servlet-name>
<url-pattern>/f</url-pattern>
</servlet-mapping>
运行,然后访问两次,再关闭
拓展➡自动加载Servlet
在web.xml中对<servlet>
中的<load-on-startup>
进行设置,可以让Servlet随着web应用而自动启动,不用等到第一次访问Servlet时才启动。
<load-on-startup>
设置为一个正整数(顺序),可以在tomcat启动时,按顺序加载它。正整数值越小,就越优先加载。
配置web.xml
<servlet>
<servlet-name>FServlet</servlet-name>
<servlet-class>cn.sdcit.FServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>FServlet</servlet-name>
<url-pattern>/f</url-pattern>
</servlet-mapping>
7、使用Post请求提交表单 ,创建register.jsp
reg.jsp代码:
(注意:表单的action路径要加上web应用的名称,比如本项目是day04)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册页面</title>
</head>
<body>
<div>
<form action="/day04/CServlet" method="post">
用户名:<input type="text"name="username"></br>
密码:<input type="password"name="password"></br>
爱好:<input type="checkbox"value="足球"name="hobby">足球
<input type="checkbox" value="音乐" name="hobby">音乐
<input type="checkbox" value="舞蹈" name="hobby">舞蹈</br>
<div>
<input type="submit"value="提交注册">
</div>
</form>
</div>
</body>
</html>
创建CServlet
package cn.sdcit;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
@WebServlet(name = "CServlet")
public class CServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//在从request在取出数据之前,应先设置数据的编码方式UTF-8
request.setCharacterEncoding("utf-8");
//使用getParameter()方法从request体中取出数据
String username = request.getParameter("username");
String password =request.getParameter("password");
//获取爱好
String[] hobbies =request.getParameterValues("hobby");
System.out.println( Arrays.toString(hobbies));
//测试是否从reg中取出了数据
System.out.println("username = " +username);
System.out.println("password =" +password);
//将注册数据回显到客户端的浏览器
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println("<h1>您注册的用户名是"+username+"</h1>");
out.println("<h1>请牢记密码"+password+"</h1>");
out.println("<h2>你的爱好是:</h2>");
out.println("<ul>");
for (String hobby :hobbies) {//增强循环快捷键iter
out.println("<li>"+hobby+"</li>");
}
out.println("</ul>");
}
}
配置web.xml
<servlet>
<servlet-name>CServlet</servlet-name>
<servlet-class>cn.sdcit.CServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CServlet</servlet-name>
<url-pattern>/CServlet</url-pattern>
</servlet-mapping>
<servlet>
运行,进入reg.jsp ➡填信息➡提交注册
跳转至CServel
8、Mapping(Servlet虚拟路径映射)
1)虚拟路径:
在web.xml文件中,一个<servlet-mapping>
元素用于映射某个Servlet的访问路径,该路径称之为“虚拟路径”。
创建好的Servlet只有映射好虚拟路径,客户端才能对其进行访问。
2)Servlet虚拟路径的多重映射
多重映射是指,对同一个Servlet映射多个虚拟路径。也就是说,客户端可以通过多个不同的路径对同一个Servlet进行访问。
方法一:配置多个<servlet-mapping>
代码:
package servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class TestServlet01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<h1>访问TestServlet01</h1>");
}
}
在web.xml配置多个<servlet-mapping>
的路径
<servlet>
<servlet-name>TestServlet01</servlet-name>
<!-- 这里路径是自己的文件夹和名字-->
<servlet-class>servlet.TestServlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet01</servlet-name>
<url-pattern>/test1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TestServlet01</servlet-name>
<url-pattern>/test01</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TestServlet01</servlet-name>
<url-pattern>/test001</url-pattern>
</servlet-mapping>
方法二:在一个中配置多个
web.xml:
<servlet>
<servlet-name>TestServlet01</servlet-name>
<!-- 这里路径是自己的文件夹和名字-->
<servlet-class>servlet.TestServlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet01</servlet-name>
<url-pattern>/test1</url-pattern>
<url-pattern>/test11</url-pattern>
<url-pattern>/test111</url-pattern>
</servlet-mapping>
★注意
特别注意的是url-pattern要么以 / 开头,要么以 * 开头,其他形式都非法。
例如,合法的:
/test/*
.do
例如,非法的:
/test
(1)一个Servlet可以指定一个映射路径
(2)一个servlet可以指定多个映射路径
(3)默认请求路径(仅有“/”字符时)
(4)一个servlet可以指定通用的映射路径(使用通配符)
如果请求的URL地址能够匹配多个虚拟路径,那么Tomcat将采用“最具体匹配”原则查找虚拟映射路径。
Servlet映射路径中使用通配符
匹配优先级:
精确匹配 > 路径匹配(长路径>短路径)> 扩展名匹配 > 默认servlet(/)
■Servert路径匹配案例