使用idea创建web项目
第一种方式:使用原型创建web项目,
Archetype的选择如下图:
创建完成:
第二种方式:不使用原型创建web工程
点击new,选择tomcat的bin的上一级目录
创建完毕
使用:
再webapp目录下创建静态资源(html文件)
这是demo2.html的代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>哈哈</h1> </body> </html>
设置:
选择edit configurations
把Application context的内容修改成"/"
运行
运行成功
为什么开始的页面是Hello World!
再tomcat的conf文件夹中
有web.xml文件
里面的内容
是按照这个三个文件的顺序来执行开始页面的,所以我们可以创建一个index.html文件,看看会发生什么
可以发现开始页面已经发生变化
Servlet
之前我们使用的都是使用浏览器访问的静态资源即html,web资源除了静态资源还有动态资源,即数据可以实现变化,并且前端浏览器通过动态资源可以实现数据的交互。那么如果想实现客户端访问服务器的动态资源,需要我们在后端中直接定义类或者间接实现Servlet接口
实现Servlet
第一步创建web项目
第二步在pom.xml文件中导入servlet依赖
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency>
第三步在创建的web项目中自定义类实现Servlet接口
第四步:重写Servlet接口的所有方法
注意:导入 的是javax.servlet,而不是变成了tomcat10的jakarta.servlet,不然会出现HTTP状态 500 - 内部服务器错误
import javax.servlet.*; import java.io.IOException; //在创建的web项目中的自定义类实现Servlet public class FirstServlet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("servlet入门"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
第五步:在Servlet接口的service的方法书写代码处理业务逻辑
第六步:在web.xml中配置访问Servlet的路径
代码
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0"> <!-- 配置访问的servlet路径--> <!-- 1.<servlet>标签配置浏览器要访问的servlet类 2.<servlet-class>com.hhh.servlet.FirstServlet</servlet-class> 通过该标签配置要访问的servlet类的全路径(包名.类名)tomcat底层通过反射技术创建FirstServlet类的对象 class c=Class.forName("com.hhh.servlet.FirstServlet"); FirstServlet fs=c.newInstance();//调用FirstServlet类的无参构造方法 最后通过对象调用service方法 3.<servlet-name>FirstServlet</servlet-name> 给FirstServlet类起别名FirstServlet --> <servlet> <servlet-name>FirstServlet</servlet-name> <servlet-class>com.hhh.servlet.FirstServlet</servlet-class> </servlet> <!-- 4.<servlet-mapping>表示配置的映射路径,映射到com.hhh.servlet.FirstServlet 5.<servlet-name>FirstServlet</servlet-name>的文本值必须与<servlet>的子标签 <servlet-name></servlet-name>文本值一样 6. <url-pattern>/hello</url-pattern>浏览器通过该标签文本访问FirstServlet类 http://localhost:8080/hello --> <servlet-mapping> <servlet-name>FirstServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
注意: <url-pattern>/hello</url-pattern>的文本值一定要加"/"
第七步:启动tomact
第八步:在浏览器访问servlet类
没有内容则成功
接着回到idea中的终端中
发现输出了我们servlet入门,这样我们就算成功了
Servlet的执行原理
1.<servlet>标签配置浏览器要访问的servlet类
2.<servlet-class>com.hhh.servlet.FirstServlet</servlet-class>
通过该标签配置要访问的servlet类的全路径(包名.类名)tomcat底层通过反射技术创建FirstServlet类的对象
class c=Class.forName("com.hhh.servlet.FirstServlet");
FirstServlet fs=c.newInstance();//调用FirstServlet类的无参构造方法
最后通过对象调用service方法service方法的代码作用
1.接收浏览器客户端请求
2.处理业务逻辑(与后端交互)
3.响应数据给浏览器
相当于service层
3.<servlet-name>FirstServlet</servlet-name>
给FirstServlet类起别名FirstServlet4.<servlet-mapping>表示配置的映射路径,映射到com.hhh.servlet.FirstServlet
5.<servlet-name>FirstServlet</servlet-name>的文本值必须与<servlet>的子标签
<servlet-name></servlet-name>文本值一样
6. <url-pattern>/hello</url-pattern>浏览器通过该标签文本访问FirstServlet类
http://localhost:8080/hello
Servlet的生命周期
1.谁创建Servlet对象
tomcat使用反射技术创建对象
2. 何时创建Servlet对象
第一次访问Servlet类的时候创建Servlet对象,调用无参构造方法创建对象,使用对象立刻调用init方法进行初始化,init方法只执行一次。然后调用service方法处理业务逻辑
3.创建对象之后再次访问Servlet类的时候只会执行service方法
4.关闭tomcat服务器的时候,关闭之前使用Servlet类的对象调用destroy方法销毁资源
实现服务器启动就创建Servlet对象
现在是访问映射路径时才创建Servlet对象(http//localhost:8080/hello)
我们要实现实现服务器启动就创建Servlet对象
方法: 使用<servlet>的子标签<load-on-startup>
<servlet> <servlet-name>FirstServlet</servlet-name> <servlet-class>com.hhh.servlet.FirstServlet</servlet-class> <!-- 服务器启动创建Servlet对象,文本默认值是-1表示第一次访问时才创建Servlet对象,如果文本值>0,表示tomcat启动时创建对象 如果多个servlet都配置了该标签,那么文本值越小创建Servelt对象的优先级越高。 --> <load-on-startup>1</load-on-startup> </servlet>
服务器启动创建Servlet对象,文本默认值是-1表示第一次访问时才创建Servlet对象,如果文本值>0,表示tomcat启动时创建对象
如果多个servlet都配置了该标签,那么文本值越小创建Servelt对象的优先级越高。
实现Servlet方式二:自定义类继承GenericServlet
好处:只需要开发者重写service方法
public class SecondServlet extends GenericServlet { //</editor-fold> @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("利用GenericServlet实现Servlet"); } }
使用快捷键ctrl + alt + u查看一个类的继承关系图
GenericServlet是一个抽象类
接着在web.xml中部署映射关系
<servlet> <servlet-name>SecondServlet</servlet-name> <servlet-class>com.hhh.servlet.SecondServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>SecondServlet</servlet-name> <url-pattern>/second</url-pattern> </servlet-mapping>
实现Servlet方式三:自定义类继承抽象类HttpServlet
好处:处理http协议的(请求和响应),根据不同的请求方式做出不同的处理
重写父类的方法:ctrl+o
public class ThirdServlet extends HttpServlet { //post请求执行的方法 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("利用HttpServlet实现Servlet...post"); } //get请求执行的方法 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("利用HttpServlet实现Servlet...get"); } }
<servlet> <servlet-name>ThirdServlet</servlet-name> <servlet-class>com.hhh.servlet.ThirdServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ThirdServlet</servlet-name> <url-pattern>/Third</url-pattern> </servlet-mapping>
结果:
利用HttpServlet实现Servlet...get继承关系:
Servlet的常见问题
1.HTTP 500异常
服务器代码异常
根据报错找代码问题
2.404 not found 找不到服务器资源
原因:自己的操作问题
是我们访问的资源在服务器中不存在
解决:
1.修改访问地址
2.在服务器中创建资源
3.访问的资源必须在target中,如果没有就执行clean命令,然后重新部署web项目
3.405
原因:调用父类HttpServlet中的doGet,doPost方法(如super.doGet())
4.启动服务器报错
注意:只要启动服务器报错基本都是路径问题
路径没有写 /
一个Servlet类映射多个路径
<servlet> <servlet-name>ThirdServlet</servlet-name> <servlet-class>com.hhh.servlet.ThirdServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ThirdServlet</servlet-name> <url-pattern>/Third</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ThirdServlet</servlet-name> <url-pattern>/third</url-pattern> </servlet-mapping>
Servlet映射路径配置规范
1.完全路径匹配
就是在 <url-pattern>/Third</url-pattern>标签文本中配置什么,那么浏览器地址栏就访问什么
如 http://localhost:8080/Third
2.目录匹配
/xx/*
在浏览器地址栏输入的路径只要以xx开头都会访问对于的Servlet类
<servlet-mapping> <servlet-name>ThirdServlet</servlet-name> <url-pattern>/user/*</url-pattern> </servlet-mapping>
后缀名匹配
*.xx 注意:在web.xml文件中开头不能写 /
那么在浏览器地址栏只要以xx结尾的路径都会访问对应的Servlet类
<servlet-mapping> <servlet-name>ThirdServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
Servlet路径优先级由高到低:
完全路径匹配>目录匹配>后缀名匹配如果又是以/user开头,又以.do结尾,会执行/user的Servlet类