JavaWeb02

2022/7/1 14:21:58

本文主要是介绍JavaWeb02,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

6. Servlet

6.1 Servlet简介

  • Servlet是sun公司开发动态web的一门技术。
  • Sun在这些API中提供了一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
    1. 编写一个类,实现Servlet接口。
    2. 把开发好的Java类部署到Web服务器中。
  • Servlet项目由一个父项目和众多子项目构成,servlet接口在子项目中实现。

6.2 父项目与子项目

关于父子工程的理解:

  1. 父项目的配置文件中存在如下标签,记录了子项目的个数:
    <modules>
        <module>servlet-01</module>
    </modules>
  1. 相对应的,子项目中存在如下标签,记录了父项目的情况:
    <parent>
        <artifactId>JavaWeb_Servlet</artifactId>
        <groupId>com.zfy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
  1. 父项目中的java,子项目可以直接使用(继承与多态)
son extends father
  1. Servlet接口于子项目中实现。

6.3 Hello Servlet

对于初学者而言,步骤较为复杂,总而言之分为如下几步:

  1. 创建父工程
  2. 创建子工程
  3. 编写一个servlet程序,即在子工程中实现servlet接口
  4. 配置服务器,启动servlet。

6.3.1 父工程的创建

  1. 构建一个普通Maven项目(即不启用Maven模板。详细参考如上节所示)
  2. 删除src文件夹,其余不可删。
  3. 所得到的空工程即为Maven父工程(也称作主工程),可以在此创建众多子工程(即Module)。
  4. 在父工程中导入需要父/子工程需要的依赖,根据需求查询有哪些依赖需要导入。
    以JSP工程为例,在父工程的pom.xml文件中导入如下依赖:
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
        </dependency>
  1. 至此,父工程创建完毕。

6.3.2 子工程的创建

  1. 在父工程文件夹处new一个module
  2. 子项目启用Maven模板创建。
  3. 如图,此处创建的servlet项目为子项目,父项目就是原项目。
  4. 重写子项目web.xml文件,将其改成最新的服务器配置:
    该步骤内容查询自:Tomcat-conf-web.xml,复制粘贴即可。
  5. 在main文件夹下创建:java文件夹和resource文件夹,并标记。以此补子全项目结构(main下面有三个文件夹才算结构齐全)。
  6. 至此,子工程创建完毕。

6.3.3 在子工程中创建servlet程序

  • servlet是一个接口程序,也就是一个java程序,其存放于main-java文件夹中。
  • servlet接口在sun公司有两个默认的实现类:①HttpServlet,②GenericServlet
  1. 在(子项目)java文件中new一个package,并在该package下新建一个class。
  2. 继承HttpServlet类,基于此类实现servlet接口,编写servlet程序。这是通过方法重载实现的。
    (servlet相关class关系说明图)

  3. ctrl+o呼出接口与方法菜单,写入需要重载的方法(继承自HttpServlet)。
  4. 重载的方法原始代码如下:
  5. 方法重载(以Get和Post为例):
    // 由于get或者post只是请求实现的不同方式,因此可以相互调用。二者的业务逻辑是一致的。
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter();  // 响应流
        writer.print("Hello,Servlet!");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

  1. 在子项目网页配置文件web.xml中编写Servlet映射
    为什么需要映射?
    我们写的是java程序,但是要通过浏览器访问,而浏览器需要连接web服务器。
    所以我们需要:
    1. 在web服务器中注册我们的Servlet程序(class类)。
    2. 提供一个浏览器可以访问的路径(mapping映射)
  2. 至此,子项目servlet程序创立完毕。

6.3.4 配置Tomcat服务

  1. Tomcat配置过程如3.4节所述
  2. 启动测试:右上角运行Tomcat9服务器。
  3. Tomcat编译之后产生target文件夹,内容如图所示:

    (生成的target文件夹可以通过Maven-lifecycle-clean清除)
  4. 弹出Tomcat默认的js界面:Hello World!
  5. 输入我们设置的servlet映射地址,即可访问到我们编写的servlet class文件。
  6. 发布并访问一个简单的servlet程序到此结束

6.4 Servlet原理

(一)Servlet总体原理

  • 典型的Servlet业务流程如下所示:
  • 其中我们自己编写的实现类重构service方法。

(二)Mapping问题

Mapping即路径映射,是提供一个访问Servlet程序的路径,其规则如下:

  1. 一个Servlet程序可以指定任意个映射路径(一个或者多个)
  2. 一个Servlet可以指定通用的(通配符*)映射路径:
  <servlet-mapping>
    <!-- servlet的内部名称,与上面的保持一致-->
    <servlet-name>hello</servlet-name>
    <!-- servlet的访问路径.hello/* ,*为通配符,代表*号位置的任意输入都可以访问到该映射 -->
    <url-pattern>/hello/*</url-pattern>
  </servlet-mapping>
  1. 可以指定一些后缀或者前缀作为映射路径(正则式)
  <servlet-mapping>
    <!-- servlet的内部名称,与上面的保持一致-->
    <servlet-name>hello</servlet-name>
    <!-- servlet的访问路径,*为通配符,.zfy为后缀。代表*号位置的任意输入+.zfy后缀都可以访问到该映射 -->
    <url-pattern>*.zfy</url-pattern>
  </servlet-mapping>

6.5 ServletContext(对象)

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,该对象代表了当前的web应用。
ServletContext对象是凌驾在所有Servlet程序之上的,同一个web应用的servlet程序共用同一个ServletContext对象。

6.5.1 Context对象实现数据共享

在任意Servlet中保存的数据,通过Context对象,可以在另一个Servlet中拿到。

  1. 在第一个Servlet文件中,通过在ServletContext对象中创建键值对保存信息:
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        this.getInitParameter();  初始化参数
//        this.getServletConfig();  初始化配置
//        this.getServletContext();  获取Context对象,即上下文对象。

        //  ①获取ServlContex对象
        ServletContext context = this.getServletContext();

        //  ②创建一个Servlet02中的对象(数据)
        String username = "青梧成林";  
        //  ③将该数据保存在了ServlContex对象中,以键值对的形式保存。
        context.setAttribute("username", username);  
        
        System.out.println("Hello!");
    }
}
  1. 在另一个Servlet文件中取出刚才保存的信息:
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // ①获取Context对象
        ServletContext context = this.getServletContext();

        // ②将另一个servlet程序保存在Context对象中的键值对取出,这里输入键名即可。
        // 键值对中保存的是object类型,将其强转为String对象。
        String username = (String) context.getAttribute("username");

        // ③将取到的值在网页上输出
        resp.setContentType("text/html");  // 设置文本格式
        resp.setCharacterEncoding("utf-8");  // 设置中文编码格式
        resp.getWriter().print("username: " + username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
  1. 给两个Servlet文件配置相关映射路径:

  2. 测试.先访问Servlet1文件,再访问Servlet2文件:

6.5.2 Context对象获取初始化参数

  1. web.xml中可能存在一些网页初始化所需要的参数:
  <!-- 配置一些web应用初始化参数 -->
  <!-- 数据库框架连接参数 -->
  <context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
  </context-param>
  1. 使用ServletContext对象获取初始化参数
public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();

        String url = context.getInitParameter("url");  // 获得web初始化参数,这是配置在web.xml里面的
        System.out.println("url: " + url);  // Sout输出只能在idea后台给出,无法在网页中输出。
        resp.getWriter().print(url);  // resp对象的getWriter()方法获取网页输出对象,再用print()方法打出。
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
  1. 注册Servlet,并测试访问。
    网页测试结果,顺利拿到了初始化参数url:

6.5.2 Context对象请求转发

(1)请求转发:

  • 访问A网页,A网页将请求转发到C网页。结果:路径为A,实际访问页面为C(即A拿到了C)。
  • 请求转发的状态码为:200
    (2)重定向:
  • 访问A,A刷新路径为C,改为访问C。访问路径发生改变。
    请求转发的实现:
  1. 编写Servlet程序,context.getRequestDispatcher 实现转发
@Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      ServletContext context = this.getServletContext();
      // 请求转发分成两步来写
//        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");  // 转发的请求路径
//        requestDispatcher.forward(req, resp);  // 调用forward实现请求转发
      //合成一步来写:
      context.getRequestDispatcher("/gp").forward(req,resp);

  }
  1. 网页测试

6.5.2 Context对象读取资源文件

  1. main-resource文件夹下新建配置文件,命名为db.properties:
  2. 创建Servlet程序.通过编译后的资源地址获取Properties资源:
public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // ①流通过资源地址获取properties对象
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classer/db.properties");

        // ②将资源读出,赋予对象
        Properties prop = new Properties();
        prop.load(is);
        String user = prop.getProperty("username");
        String pwd = prop.getProperty("password");

        // ③在网页上写出
        resp.getWriter().print("username: " + user +", " + "password: " + pwd);
        
    }
  1. web注册并测试:
    成功拿到资源:

6.6 HttpServletResponse对象

Z. 本章遇到的错误

1. MAVEN子工程发布在tomcat上时没有lib文件夹

问题描述:发布在tomcat上后,子工程的target中文件夹内仅有war文件,其余文件均缺失,而父工程中的target中会出现classes文件夹,其中包含有对应的class文件。

排错1:让子工程中的target中出现正常的文件夹分布。
解决办法:
在tomcat配置中找Before launch,把里面的全删除,然后加号选择Run Maven Goal ,目录选择父文件目录,命令为:clean packgae,之后重启tomcat

此步之后子工程target文件分布正常:

排错2:
此时index.jsp可以正常访问,但是servlet跳转依旧提示错误404.原因为WEB-INF中没有lib文件夹,即子工程中jar包未能发布到tomcat上。
经过查找,在父工程的pom中,对添加依赖的jar包添加了scope标签,导致子工程在发布到tomcat时无法获取到父工程中jar包的信息。
解决办法:
将父项目pom.xml中依赖的provided删除或者注释掉。

<!--  <scope>provided</scope>  -->
<!-- 设置作用域为provided,表明该包旨在编译和测试时使用,会导致子工程发布到tomcat时无法获取父工程jar包信息。-->

参考链接:https://blog.csdn.net/x2027290/article/details/118718710



这篇关于JavaWeb02的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程