Servlet原理及应用

本文详尽的介绍了servlet的相关知识,包含servlet基础与tomcat相关知识、servlet声明周期原理及其应用、servlet多请求携带数据、以及单个servlet如何处理多请求的相关知识!

一、servlet基础-tomcat

1、Servlet是什么?

  • Servlet是什么
    • servlet 接口定义的是 一套处理网络请求的规范,所有实现servlet的类,都需要实现它的那五个方法,其中最主要的是两个声明周期方法init()和destory(),还有一个处理请求的service()。
  • Servlet请求处理
    • servlet是一个规范,那实现了servlet的类,就能处理请求了吗?
      • 不能
    • 请求是怎么来到servlet的呢?
      • 答案是web服务器,比如我们最常用的Tomcat。servlet都是部署在一个容器中的,不然你的servlet根本不起作用。
    • Tomcat才是与客户端直接打交道的家伙
      • 它监听了端口,请求过来后,根据URL等信息(<url-pattern>),确定要将请求交给哪个servlet去处理,然后调用那个servlet的service方法,service方法返回一个response对象,Tomcat再把这个respond返回给客户端。

2、安装配置tomcat

2.1 tomcat目录结构

  • bin: 该⽬录存放的是可执⾏的⼆进制⽂件(startup.bat⽤于启动Tomcat、shutdown.bat⽤于停⽌Tomcat)
  • conf :存放的是Tomcat的配置⽂件(server.xml可以配置Tomcat的端⼝,web.xml)
  • lib 此⽬录存放了Tomcat服务器运⾏web项⽬所需的基础类库(jar包)
  • logs : 存放Tomcat服务器的运⾏⽇志、记录了服务器启动、运⾏异常及关闭等操作的记录
  • webapps: 存放Tomcat管理的web项⽬的⽬录,此⽬录中默认部署了Tomcat管理器等⼏个web项⽬
  • work: 运行时生成的文件,最终运行的文件都在这里。
    • (当客户端用户访问一个JSP文件时,Tomcat会 通过JSP生成Java文件,然后再编译Java文件生成class文件,生成的java和class文件都会存放到这个目录下。)

2.2 重装Tomcat

  • tomcat 基于jdk运行的

    • java_home
    • classpath
    • path
  • 需要清理操作系统的环境变量 catalina字样 (重新安装时需要清除)

  • 关于服务:ip地址+端口号 端口唯一必须遵守规则

  • tomcat默认端口:8080 代表 tomcat-HOME/webapps/ROOT(没有指定具体项目名时,默认访问ROOT项目)

2.3 部署一个web项目

  • 手工部署一个静态网站
    • 在tomcat/webapps目录下新建应用目录(应用名);
    • 在该目录下建/images、/js、/css
    • 将写好的html文件放置于该目录下
  • 打包war包-项目部署
    • 可以将web程序打包为war包,将其放置到tomcat/webapps
    • 启动tomcat后,即可以进行访问(tomcat会默认将其解压缩为文件夹)

3、Servlet规范的引入

  • jdk版本支持
    • javaEE7支持servlet3.1规范
    • javaEE8支持servlet4.0规范
    • 以前的版本 2.0、2.1\2.2.\2.3\2.4\2.5\3.0\3.1
  • 应用程序中配置文件web.xml 因为规范版本不同,也有不同的设置
  • servlet编写规则也因为选择的servlet规范版本变化
  • 不同版本的tomcat支持的servlet规范不同

4、如何编写一个servlet类

4.1 作用

  • 相比于套接字网络编程,其更方便的处理http请求

4.2 规范

  • 首先,一个Servlet类必须继承HttpServlet(接口或抽象类)

  • 其次,重写其service方法(doGet\doPost)

  • 再次,将servlet在web.xml注册

  • <!--    注册自定义servlet-->
        
        <servlet>
            <servlet-name>my</servlet-name>
    <!--        全限定路径名-->
            <servlet-class>com.xcu.web.MyFirstServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
    <!--        servlet在web容器中的对象名 (必须与上面完全一致)-->
            <servlet-name>my</servlet-name>
    <!--        本servlet对外暴露的请求path-->
            <url-pattern>/login</url-pattern>
        </servlet-mapping>
    

    注意:servlet与servlet-mapping 不能交叉

  • 最后,编写html页面表单 发请求

5.难点

  • servlet中的处理方法
    • 方法名固定:doGet、doPost、service
    • 方法的入参固定: 第一个参数类型:HttpServletRequest对象;第二参数类型:HttpServletResponse对象
    • 方法的抛出异常:ServletException 和IOException
    • 方法的返回值是:void

二、Servlet生命周期原理及其应用

1、servlet处理请求的流程

  1. 启动工程,系统会使用该工程的web.xml初始化此项目(包括外部访问url,创建一个servlet对象的名称的引用(句柄))
  2. 当浏览器访问本服务器上的应用时,应用会自动调用默认的欢迎页面呈现客户
  3. 用户点击欢迎页面提交表单按钮(以添加新用户信息为例)
  4. 浏览器会调用该表单的onsubmit方法(进行校验) ,并向由( url地址 +form.action组成)的新url(ip:端口/应用名/请求path)发出请求
  5. tomcat服务器接收请求,并解析它,
  6. 在web.xml的servlet-mapping中查找和请求path路径匹配的 url-pattern节点
  7. 再继续找url-pattern的兄弟 servlet-name的值(对象名)
  8. 如果servlet-name所指的对象不存在,则再去servlet节点中查找同名项的兄弟节点servlet-class
  9. 拿到servlet-class的文本值 使用反射创建此对象,并将其以servlet-name 对象名
  10. 系统再调用其service方法处理请求,并响应之;
  11. 如果第二次对此服务path进行请求,则因为以servlet-name为名称的对象已存在(唯一实例),则直接调用其service方法处理请求;

2、servlet对象产生过程

  • servlet对象由web容器(tomcat、weblogic、websthere、jboss)负责产生
  • 使用load-on-startup节点可以设置servlet创建的时机,含有load-on-startup节点则在服务器启动时创建servlet对象;如果不含有,则会在首次请求时创建对象
  • 再由容器调用init方法初始化servlet对象
  • 容器调用service方法提供服务(如果没有(重写)service,则实际是执行父类的service方法(子类继承过来的service方法),在其中会根据请求的method调用doGet或doPost方法服务(实际上调用的是子类的)
  • 下次,请求来时,直接对外提供服务,不会创建servlet对象(唯一实例)
  • 最后,当容器关闭时,容器会先调用servlet的destroy方法再关闭

3、servlet处理请求多个场景

  • 请求数字

    • 所有的表单提交的数据均是字符。因此,必须要进行类型转换(常见的有Integer.parseInt\Doble.parseDouble\Long.parseLong\Float.parseFloat)
    • 需要判空,应为“”或null无法转数字(可以使用三元运算符)
  • 请求日期

    • <input type="datetime-local" name="birthday" />
    • 服务端获取日期字符串,需要使用SimpleDateFormat类的函数转换
  • 请求中文

    • req.setCharacterEncoding(“UTF-8”); //上行编码
    • resp.setContentType(“text/html;charset=UTF-8”);//下行转码
    • 请求的method=POST
  • 在不同请求模式下中文转码

    • get请求乱码必须使用String构造手动转码

4、响应方式

  • 请求转向
    • 携带数据,整个过程只有一次浏览器请求
    • 由req进行处理req.getRequestDispatcher("页面或servlet").forward(req,resp);
  • 重定向
    • 不携带数据,整个过程有两次浏览器请求
    • 由resp进行处理resp.sendRedirect("页面或servlet");
    • servlet经过重定向告诉浏览器一个新地址,浏览器重新请求新地址(地址栏发生变化)
  • 注意事项:
    • 在添加、修改、删除之后只能是重定向,不能使用请求转发,否侧刷新时会重复执行上一步操作(可能会抛出异常)
    • 原因(以插入servlet转向查询servle为例):
      • 使用重定向在整个业务流程中会触发两次浏览器请求,刷新时只会出触发后一次查询的浏览器请求
      • 请求转发在整个业务流程中只会触发一次浏览器请求,刷新时会触发整个业务流程(包括插入和查询)

5、EL表达式与JSTL表达式特性

1. EL表达式特性

  • EL表达式取数据自动探空
  • EL表达式只简化了输出,没有提供任何逻辑代码功能(if、for、while都不含有)

2. JSTL表达式特性

  • 自动类型转换
  • 自动探空
  • 提供任何逻辑代码功能(if、for、while都含有,常配合EL表达式配合使用)

6、浏览器请求注意事项

  • 浏览器会将页面所有标签,按照层级将其构成一个对象树,每一个标签节点时一个对象,其每个对象还有属性和方法,js可以对其进行操作
  • 表单提交的任何数据都是string类型(eg: text文本框提交的数据是string类型)
  • get请求会将地址后携带的值清除,并携带自己本身的表单值

三、Servlet进阶应用

1、jsp-servlet 处理逻辑

请添加图片描述

2、get-post携带数据请求

  • 代码示例:
	<form action="teacher?method=addTeacher" method="post">
        姓名:<input type="text" name="tname" /><br/>
        性别:<input type="radio" name="gender" value="" /><input type="radio" name="gender" value=""/><br/>
        入职日期:<input type="text" name="workDate"/><br/>
        教授年级:<input type="text" name="workGrade"/><br/>
        <input type="submit" value="添加"/>
    </form>
  • 请求:
    • 表单属性action="teacher?method=addTeacher"的请求url携带参数,可以看作是get方式请求,而其属性method="post"提交方式为post请求,所以此种请求方式可以看作是get-post携带数据请求
  • 数据获取:
    • get-post携带数据请求的方式,在被请求的servlet中无论是url后携带的参数(get请求携带参数),还是通过post请求携带参数(请求体中携带的参数),均可以使用getParamter("xxx")获取参数

3、一个servlet处理多个请求

  • 核心思想

    • 在请求的url后携带参数method=xxx,并在所请求的servlet中编写相同参数值名称的方法,处理相应的请求
    • 在后端的servlet的service方法中获取method参数值,并通过反射获取到方法对象
    • 通过反射调用执行相应的方法
  • 示例

  1. 请求
 <form action="teacher?method=addTeacher" method="post">
      姓名:<input type="text" name="tname" /><br/>
      性别:<input type="radio" name="gender" value="" /><input type="radio" name="gender" value=""/><br/>
      入职日期:<input type="text" name="workDate"/><br/>
      教授年级:<input type="text" name="workGrade"/><br/>
      <input type="submit" value="添加"/>
  </form>
  1. 反射获取方法对象
  @Override
  protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1.设置编码格式
      req.setCharacterEncoding("UTF-8");
      resp.setContentType("text/html;charset=UTF-8");

//        利用反射执行对应的请求方法
      String methodName = req.getParameter("method");
      try {
          Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//        执行方法
          method.invoke(this, req, resp);
      } catch (NoSuchMethodException e) {
          e.printStackTrace();
      } catch (InvocationTargetException e) {
          e.printStackTrace();
      } catch (IllegalAccessException e) {
          e.printStackTrace();
      }

  }

  1. 处理请求对应的方法

//    增加
  private void addTeacher(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //        2.
      String tname = req.getParameter("tname");
      String gender = req.getParameter("gender");
      String workDate = req.getParameter("workDate");
      String workGrade = req.getParameter("workGrade");

      Teacher teacher=new Teacher(0,tname,gender,workDate,workGrade);
//        3.
      TeacherService teacherService=new TeacherServiceImpl();
      boolean b = teacherService.addTeacher(teacher);
//        4.
      if (b){
          resp.sendRedirect("teacher?method=findAll");
      }else {
          resp.sendRedirect("error.jsp");
      }
  }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340