Javaweb--实验5 Servlet--期末复盘

实验5 Servlet

需要资料的,文章末尾自提

一、实验目的:

1、理解Servlet的生命周期。
2、熟悉web.xml文件的作用。
3、熟悉ServletConfig接口和SservletContext接口的使用。

二、 实验内容:

1、创建一个Servlet,在浏览器中显示诗歌名。具体要求:
(1)该Servlet在第一次被调用时,初始化一个存储诗歌的数组。
(2)当用户通过浏览器访问Servlet时,如果URL中带参数num,则在浏览器中显示诗歌数组中下标为num的诗歌名,如图1所示;如果URL中不带参数num,则从诗歌数组中随机选择一个诗歌名,如图2所示。

在这里插入图片描述
图1 按照下标的诗歌名输出
在这里插入图片描述
图2 诗歌名的随机输出

【实验步骤】(补全代码)

(1)新建一个Web应用程序,项目名称为“web5”。
(2)在项目中创建“it.entity”包,并在包中创建Poetry类。

package it.entity;

public class Poetry {
    private String artist; //作者
    private String title ; //诗歌名

   //【代码一】带2个参数的构造函数;以及成员变量的getter和setter
}

(3)在项目中创建“it.servlet”包,并在包中创建RandomeServlet类。

package it.servlet;

import it.entity.Poetry;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

public class RandomServlet implements Servlet {
    Poetry[] poetrys ;
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        poetrys = new Poetry[]{
                new Poetry("泰戈尔", "太阳颂"),
                new Poetry("泰戈尔", "生如夏花"),
                new Poetry("泰戈尔", "飞鸟集"),
                new Poetry("泰戈尔", "太阳颂"),
                new Poetry("泰戈尔", "园丁集"),
                new Poetry("泰戈尔", "吉檀迦利"),
                new Poetry("泰戈尔", "闲暇")};
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        String numString = servletRequest.getParameter("num");
        servletResponse.setContentType("text/html;charset=UTF-8");
        //当没有传num参数时,随机显示一首诗歌名
        if (/*【代码一】*/) {
            int random = (int) (Math.random() * poetrys.length);
            servletResponse.getWriter().println("今天的诗:"+/*【代码二】*/);
            return;
        }
        //判断num的值是否在诗歌数组的下标范围内,
        //如果是,则显示诗歌数组中下标为num的诗歌名
        int num = Integer.parseInt(numString);
        if (/*【代码三】*/) {
            servletResponse.getWriter().println("今天的诗:"+poetrys[num].getTitle());
        } else {
            servletResponse.getWriter().println("<h1>Error!</h1><br/>");
            servletResponse.getWriter().println("num的值应在0~" + (poetrys.length - 1) + "之间");
        }
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

(4)在web.xml文件中,实现Random类和“/random”的映射。例如:
在这里插入图片描述

(5)设置项目的Application Context为“/web5”。启动tomcat,部署项目,查看结果。

2、完善第1题的应用。诗歌信息以如下格式存储在“poetry.txt”文件中,读取该文件,以完成诗歌数据的初始化。
在这里插入图片描述

【实验步骤】
(1)将“poetry.txt”文件拷贝到“web5”项目的“WEB-INF”节点下。

(2)在“web5”项目的“it.servlet”包中新建“RandomServlet2”类。

package it.servlet;

import it.entity.Poetry;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

@WebServlet("/random2")
public class RandomServlet2 implements Servlet {
    ArrayList<Poetry> poetryList = new ArrayList<>();
    //通过字符串的解析,实现诗歌对象的添加
    void addPoetry(String lineToParse) {
        String[] tokens = lineToParse.split("/");
        poetryList.add(new Poetry(tokens[0], tokens[1]));
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        try {
            //获取poetry.txt的实际路径
            File file = new File(servletConfig.getServletContext().getRealPath("/WEB-INF/poetry.txt"));
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line = null;
            while ((line = reader.readLine()) != null) {
                addPoetry(line);
            }
            System.out.println("诗歌数组初始化完毕!");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
   }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        String numString = servletRequest.getParameter("num");
        servletResponse.setContentType("text/html;charset=UTF-8");
        //当没有传num参数时,随机显示一首诗歌名
        if (numString == null) {
            int random = (int) (Math.random() * poetryList.size());
            servletResponse.getWriter().println("今天的诗:"+/*【代码一】*/);
            return;
        }
        //判断num的值是否在诗歌数组的下标范围内,
        //如果是,则显示诗歌数组中下标为num的诗歌名
        int num = Integer.parseInt(numString);
        if (/*【代码二】*/) {
            servletResponse.getWriter().println("今天的诗:"+poetryList.get(num).getTitle());
        } else {
            servletResponse.getWriter().println("<h1>Error!</h1><br/>");
            servletResponse.getWriter().println("num的值应在0~" + (poetryList.size() - 1) + "之间");
        }
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

3、登录功能的实现。其中,初始化的用户名与密码存储于web.xml配置文件中。LoginServlet类读取web.xml文件中的初始化的用户名与密码,如果用户输入的用户名与密码正确,则显示“***,欢迎您!”,否则显示“用户名或密码错误”。
【实验步骤】
(1)在“web5”项目中新建“HTML”文件,命名为“login”。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="login" method="post">
        用户名:<input type="text" name="username"><br/>
        密码:<input type="password" name="userpass"><br/>
        <input type="submit" value="提交">
        <input type="reset" value="清空">
    </form>
</body>
</html>

(2)在“it.servlet”包中新建java类“LoginServlet”。LoginServlet类实现Servlet接口,并判断用户输入的用户名与密码是否与web.xml文件中的用户名与密码一致,如果一致,显示“***,欢迎您”,否则输出“用户名或密码错误”。

package it.test;
import java.io.IOException;
import javax.servlet.*;
public class LoginServlet implements Servlet {
	//请填写代码


    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.servletConfig = servletConfig;
    }

    @Override
    public ServletConfig getServletConfig() {
        return servletConfig;
    }

    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        PrintWriter out = response.getWriter();

        // 获取web.xml中配置的用户名和密码
        String correctUsername = servletConfig.getInitParameter("username");
        String correctPassword = servletConfig.getInitParameter("userpass");

        // 获取用户输入的用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("userpass");

        if (username != null && password != null && username.equals(correctUsername) && password.equals(correctPassword)) {
            // 用户名和密码正确
            out.println(username + ",欢迎您");
        } else {
            // 用户名或密码错误
            out.println("用户名或密码错误");
        }
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        // 清理资源
        System.out.println("服务器重重启或关闭,资源已清除!!!");
    }
}

(3)在web.xml文件中,实现LoginServlet与/login的绑定,并指定初始的用户名与密码。
在这里插入图片描述

4、创建一个Servlet,实现网站访问次数的统计,效果如图3所示。
在这里插入图片描述
图3 网站访问次数统计

【实验步骤】
在“it.servlet”包中新建java类“CountServlet”。当浏览器通过“/count”访问该类时,能在浏览器中输出网站的访问次数。

package it.servlet;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/count")
public class CountServlet implements Servlet {
 private ServletConfig servletConfig;
    @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 {
    //请填写代码 
      
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

三、具体实现

//第一题
package it.entity;

public class Poetry {
    private String artist; //作者
    private String title ; //诗歌名

   //【代码一】带2个参数的构造函数;以及成员变量的getter和setter
public Poetry(String artist, String title) {
        this.artist = artist;
        this.title = title;
    }

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
    
}
package it.servlet;

import it.entity.Poetry;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

public class RandomServlet implements Servlet {
    Poetry[] poetrys ;
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        poetrys = new Poetry[]{
                new Poetry("泰戈尔", "太阳颂"),
                new Poetry("泰戈尔", "生如夏花"),
                new Poetry("泰戈尔", "飞鸟集"),
                new Poetry("泰戈尔", "太阳颂"),
                new Poetry("泰戈尔", "园丁集"),
                new Poetry("泰戈尔", "吉檀迦利"),
                new Poetry("泰戈尔", "闲暇")};
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        String numString = servletRequest.getParameter("num");
        servletResponse.setContentType("text/html;charset=UTF-8");
        //当没有传num参数时,随机显示一首诗歌名
        if (numString == null || numString.isEmpty()/*【代码一】*/) {
            int random = (int) (Math.random() * poetrys.length);
            servletResponse.getWriter().println("今天的诗:"+ poetrys[random].getTitle()/*【代码二】*/);
            return;
        }
        //判断num的值是否在诗歌数组的下标范围内,
        //如果是,则显示诗歌数组中下标为num的诗歌名
        int num = Integer.parseInt(numString);
        if (num >= 0 && num < poetrys.length/*【代码三】*/) {
            servletResponse.getWriter().println("今天的诗:"+poetrys[num].getTitle());
        } else {
            servletResponse.getWriter().println("<h1>Error!</h1><br/>");
            servletResponse.getWriter().println("num的值应在0~" + (poetrys.length - 1) + "之间");
        }
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}
//第二题
package it.servlet;

import it.entity.Poetry;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

@WebServlet("/random2")
public class RandomServlet2 implements Servlet {
    ArrayList<Poetry> poetryList = new ArrayList<>();
    //通过字符串的解析,实现诗歌对象的添加
    void addPoetry(String lineToParse) {
        String[] tokens = lineToParse.split("/");
        poetryList.add(new Poetry(tokens[0], tokens[1]));
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        try {
            //获取poetry.txt的实际路径
            File file = new File(servletConfig.getServletContext().getRealPath("/WEB-INF/poetry.txt"));
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line = null;
            while ((line = reader.readLine()) != null) {
                addPoetry(line);
            }
            System.out.println("诗歌数组初始化完毕!");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
   }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        String numString = servletRequest.getParameter("num");
        servletResponse.setContentType("text/html;charset=UTF-8");
        //当没有传num参数时,随机显示一首诗歌名
        if (numString == null) {
            int random = (int) (Math.random() * poetryList.size());
            servletResponse.getWriter().println("今天的诗:"+ poetryList.get(random).getTitle()/*【代码一】*/);
            return;
        }
        //判断num的值是否在诗歌数组的下标范围内,
        //如果是,则显示诗歌数组中下标为num的诗歌名
        int num = Integer.parseInt(numString);
        if (num >= 0 && num < poetryList.size()/*【代码二】*/) {
            servletResponse.getWriter().println("今天的诗:"+poetryList.get(num).getTitle());
        } else {
            servletResponse.getWriter().println("<h1>Error!</h1><br/>");
            servletResponse.getWriter().println("num的值应在0~" + (poetryList.size() - 1) + "之间");
        }
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}
//第三题
package it.test;
import java.io.IOException;
import javax.servlet.*;
public class LoginServlet implements Servlet {
	//请填写代码
private ServletConfig servletConfig;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.servletConfig = servletConfig;
    }

    @Override
    public ServletConfig getServletConfig() {
        return servletConfig;
    }

    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        PrintWriter out = response.getWriter();

        // 获取web.xml中配置的用户名和密码
        String correctUsername = servletConfig.getInitParameter("username");
        String correctPassword = servletConfig.getInitParameter("userpass");

        // 获取用户输入的用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("userpass");

        if (username != null && password != null && username.equals(correctUsername) && password.equals(correctPassword)) {
            // 用户名和密码正确
            out.println(username + ",欢迎您");
        } else {
            // 用户名或密码错误
            out.println("用户名或密码错误");
        }
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        // 清理资源
        System.out.println("服务器重重启或关闭,资源已清除!!!");
    }
}
//第四题
package it.servlet;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/count")
public class CountServlet implements Servlet {
 private ServletConfig servletConfig;
    @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 {
    //请填写代码 
        // 获取ServletContext对象
        ServletContext context = servletRequest.getServletContext();

        Integer visitCount = (Integer) context.getAttribute("visitCount");
        //包装类的好处:解决第一次未null值的时候不会报空指针问题

        if(visitCount == null)
            visitCount =1;
        else
            visitCount ++;
		// 将访问次数存储回ServletContext中
        context.setAttribute("visitCount", visitCount); 

		servletResponse.setContentType("text/html;charset=UTF-8");
        servletResponse.getWriter().println("访问次数: " + count);      
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

四、资料自提

链接:https://pan.baidu.com/s/1a0D9tsHb3B5CYFosJBI0Bw?pwd=v8ui
提取码:v8ui

<think>嗯,用户想了解Excel中的VLOOKUP函数的用法和参数含义。首先,我需要回忆一下VLOOKUP的基本结构。VLOOKUP是垂直查找函数,用于在表格的首列查找指定的值,然后返回该行中指定列的数据。它的四个参数分别是查找值、表格范围、列索引号和匹配模式。 接下来,我得确认每个参数的具体作用。第一个参数是lookup_value,也就是用户要查找的值,比如产品ID或者姓名。第二个参数是table_array,即查找的范围,这里要注意的是,查找值必须位于这个范围的第一列,否则函数无法正确工作。第三个参数是col_index_num,也就是用户想要返回的数据在表格范围中的第几列,这个列数是从表格范围的第一列开始算起的,不是整个工作表的列。第四个参数是range_lookup,决定是精确匹配还是近似匹配,通常用FALSE或0来指定精确匹配,避免错误。 然后,用户可能需要一个具体的例子来理解如何使用。比如,假设有一个产品价格表,用户想根据产品ID查找对应的价格。这时候,VLOOKUP就可以在ID列查找,然后返回价格列的数据。同时,要提醒用户注意表格范围最好使用绝对引用,比如$A$2:$C$100,这样在拖动公式时范围不会变化。 可能遇到的问题也需要考虑。比如,如果查找值不在表格的第一列,或者列索引号超过了表格的列数,函数会返回错误。此外,数据格式不一致也可能导致问题,比如查找值是数字,而表格中是文本格式的数字,这时候需要统一格式。还有,当出现#N/A错误时,可能是查找值不存在,或者匹配模式设置不正确,需要检查参数是否正确。 用户可能还会问到如何避免常见的错误,比如部分数据匹配出错的情况。这时候需要检查是否有多余的空格,或者数据格式不一致,或者表格范围没有锁定导致拖动时偏移。此外,XLOOKUP作为VLOOKUP的升级版,可能在某些情况下更方便,比如可以向左查找或者返回多列数据,这也是可以提及的内容。 最后,整理步骤,从基础语法到参数说明,再到具体案例,逐步引导用户理解如何使用VLOOKUP函数。同时,提供常见错误和解决方法,帮助用户在实际应用中避免问题。如果有必要,还可以比较VLOOKUP和其他查找函数的区别,比如HLOOKUP或XLOOKUP,但根据用户的问题,主要集中在VLOOKUP本身即可。</think>### Excel VLOOKUP函数详解 #### 一、基础语法与参数说明 VLOOKUP函数的语法为: $$=VLOOKUP(lookup\_value, table\_array, col\_index\_num, [range\_lookup])$$ 包含4个参数: 1. **lookup_value**(必填):要查找的值(如单元格引用或具体值) 2. **table_array**(必填):包含数据的表格范围(必须包含查找列和返回列) 3. **col_index_num**(必填):返回值所在列的序号(从table_array第一列开始计数) 4. **range_lookup**(可选):匹配类型 - `TRUE`/`1`:近似匹配(默认值,需数据升序排列) - `FALSE`/`0`:精确匹配(常用选项) [^1][^2] #### 二、使用步骤演示(工资表查询案例) 假设需要根据员工编号查询工资: 1. 建立查询单元格(如`B12`) 2. 输入公式: ```excel =VLOOKUP(A12, $A$2:$D$100, 4, 0) ``` - `A12`:待查询的员工编号 - `$A$2:$D$100`:锁定数据区域(绝对引用) - `4`:返回第4列(工资列) - `0`:精确匹配 [^2][^3] #### 三、常见错误与解决方法 | 错误现象 | 原因 | 解决方案 | |---------|------|---------| | #N/A | 查找值不存在 | 检查数据源或改用`IFERROR`容错 | | #REF! | 列序号超出范围 | 确认col_index_num ≤ 表格列数 | | 部分匹配失败 | 数据格式不一致 | 统一数值/文本格式 | | 结果错位 | 表格未锁定 | 使用`$`符号固定区域引用 | [^3][^4] #### 四、进阶技巧 1. **多条件查询**: 使用辅助列合并多个条件字段 ```excel =VLOOKUP(A2&B2, $D$2:$F$100, 3, 0) ``` 2. **通配符匹配**: `"*"`匹配任意字符,`"?"`匹配单个字符 ```excel =VLOOKUP("张*", $A$2:$C$100, 3, 0) ``` 3. **跨表查询**: 引用其他工作表数据 ```excel =VLOOKUP(A2, Sheet2!$A$2:$D$100, 4, 0) ``` [^1][^4]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-Z_Nuyoah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值