一、servlet的基本介绍
- 是一种Web服务端编程技术
- 是实现了特殊接口(HttpServlet)的Java类
- 由支持Servlet的Web服务器(Tomcat)调用和启动运行
- 一个Servlet负责对应的一个或一组URL访问请求,并返回相应的相应内容
现在对于服务器运行代码有了一些认知
现在知道只要写一个MyServlet一个java类 集成一个抽象类之后,实现代码就能完成请求响应的一个逻辑
package xyz.kxq; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // super.service(req, resp); resp.getWriter().write("first web project"); System.out.println("my first web project"); } }
服务器具体是怎么执行的?
请求8080是请求的Tomcat, 通过请求路径映射到Myservlet类,那怎么会知道要执行service方法,这是怎么做到的,
public void test(Hello hello){ hello.service(); } /* 这个service方法逻辑代码是我们写的,举一个test的例子,这时候是调用hello里面的一个service,service方法具体是哪一个子类的,不能确定,Tomcat也不需要知道,但是必须要规定某一个客户端/浏览器发送过来的请求必须要能调用service方法, 那意味着类对象要先定义好, 意味着先定义好接口 如果先发送一个请求,会先找到web.xml文件,映射会找到 <url-patter>/first</url-patter> 然后找到servlet名称, 继续找到上面servlet标签下servlet名称, 通过反射的方式,找到Myservlet, 就会调用里面的service方法 实际上就是面向对象多态的一个基本实现 有一个继承关系 子类重写了父类方法 父类对象指向子类引用,调用的就是子类里面的方法 */
1、实现使用简述
- 创建一个普通java文件
- java文件的类名实现HttpServlet
- 重写service方法
- 在WEB-INF下的web.xml中添加请求与servlet类的映射关系
二、servlet的访问流程
http://localhost:8080/FirstWeb/first
- http://localhost:8080 请求服务器的地址及端口号
- FirstWeb Tomcat中有一个目录是webapps, 写好的web项目放到这个地方 Eclipse是能看到项目名称的
- IDEA做了一个优化, 不放在webapps下了, 项目中会出现一个out目录
-
-
虚拟项目名称
改变后浏览器访问的虚拟项目名也要随之改变
- first 对应web.xml. 配置servlet的别名,同时在servlet-class配置项中添加servlet类的完全限定名(报名+类名), 配置servlet跟请求的映射关系
三、servlet的生命周期
新建一个java文件,- 自动创建
web.xml
<servlet> <servlet-name>life</servlet-name> <servlet-class>xyz.kxq.ServletLife</servlet-class> </servlet> <servlet-mapping> <servlet-name>life</servlet-name> <url-pattern>/life</url-pattern> </servlet-mapping>
ServletLife.java
package xyz.kxq; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; @WebServlet(name = "ServletLife", value = "/ServletLife") public class ServletLife extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write("servlet life"); System.out.println("learn servlet life"); } }
会按照完全限定名反射后生成一个对象, 当接收到客户端请求的时候才会创建这个对象
可以验证一下.
我现在把class文件删除掉, 会影响程序运行吗
发送请求并不影响
当前类对象已经创建好了, 那它什么时候创建的ServletLife类对象
停掉服务,重启启动
访问报错
找不到类文件xyz.kxq.ServletLife, 实例化ServletLife类异常, 刚刚把class文件删除掉了
意味着创建对象的时机是接收客户端请求的时候时才创建对象
这里是空的可以删除掉, 会重新自动创建
代码中加入
// 完成servlet对象的初始化工作 @Override public void init() throws ServletException { System.out.println("init"); }
重新运行代码
发现并没有打印"init"
重新发送请求后打印
init
learn servlet life
意味着在servlet接收到第一次请求的时候创建对象, 只执行一次init方法
那么思考Servlet对象什么时候销毁呢?
代码中加入
@Override public void destroy() { System.out.println("被销毁了"); }
Tomcat停止时被销毁
生命周期: 从第一次接收请求开始到服务器关闭之后销毁
web.xml
<servlet> <servlet-name>life</servlet-name> <servlet-class>xyz.kxq.ServletLife</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>life</servlet-name> <url-pattern>/life</url-pattern> </servlet-mapping>
开启Tomcat服务时, 开启自动对象的创建过程, 中间的数值表示优先级的意思
init会在启动服务器时执行, 关闭服务器会销毁
四、Service、doGet、doPost方法的区别
新建一个Servlet,名为MethodServlet,把勾去掉,自动生成完全限定名
web.xml文件
<servlet> <servlet-name>MethodServlet</servlet-name> <servlet-class>xyz.kxq.MethodServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MethodServlet</servlet-name> <url-pattern>/method</url-pattern> </servlet-mapping>
通过jsp模拟发送GET、POST请求
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="method" method="get"> 用户名: <input type="text" name="name" value=""><br> 密码: <input type="text" name="pwd", value=""><br> <input type="submit" value="登陆"> </form> </body> </html>
1、Service方法
不管是get还是post请求方式, 如果service方法存在, 则优先执行service方法
模拟get请求
method.jsp
<body> <form action="method" method="get"> 用户名: <input type="text" name="name" value=""><br> 密码: <input type="text" name="pwd", value=""><br> <input type="submit" value="登陆"> </form> </body>
MethodServlet
public class MethodServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("我是service"); } }
打印结果:
/* 我是service */
发送post请求同样打印如上结果
Servlet类中可以由service方法, 用来接收get或者post请求
2、doGet方法
在没有service的情况下,如果是get请求,调用doGet方法
3、doPost方法
在没有service的情况下,如果是post请求,调用doPost方法
五、servlet的常见错误
1、404
访问资源不存在
1、 没有method2 这映射关系,请求路径跟web.xml中填写的请求不一致
2、请求路径的项目虚拟名称填写错误
2、405
请求的方式跟servlet中支持的方式不一致
MethodServlet.
public class MethodServlet extends HttpServlet { // @Override // protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // System.out.println("我是get"); // } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("我是post"); } // @Override // protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // System.out.println("我是service"); // } }
method.jsp
<body> <form action="method" method="get"> 用户名: <input type="text" name="name" value=""><br> 密码: <input type="text" name="pwd", value=""><br> <input type="submit" value="登陆"> </form> </body>
3、500
服务器内部错误
1、web.xml中把完全限定名改一个不存在的
<servlet> <servlet-name>MethodServlet</servlet-name> <servlet-class>xyz.kxq.MethodServlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>MethodServlet</servlet-name> <url-pattern>/method</url-pattern> </servlet-mapping>
2、代码逻辑错误