jsp+servelt+mysql+tomcat 四六级单词查询系统

java 专栏收录该内容
5 篇文章 0 订阅

0.具体要求

  1. 要求建立大学四级、 六级词汇表(可从网上找来)放到 MYSQL 数据库中;
  2. 完善上周发布的网站,实现一个单词查询的页面,能够根据拼写、词性、难度范围(四级 or 六级)等信息查出所需要单词的释义。网页可参照金山词霸、汉典、有道等的风格;
  3. 反查:能依据释义内容,模糊查出对应的单词;
  4. 统计:实现对单词表中 a,b,c 到 z 开头单词个数的统计,结果以表格输出到网页上;
  5. 学习如何在网页上绘图:建议用 Jscharts 工具(从网上查吧,各位),将单词统计表作图, 成为单词统计曲线图或直方图;
  6. 在网页上显示gif动图、视频、音频;
  7. 将汉字字频表格查询出后显示在前端页面。

1. 系统的工作流程以及原理

1.1 Servelt介绍

首先简单介绍一下Servelt,它是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。这个关系我们可以再下边的图中展示。
在这里插入图片描述
再来说一下Servelt的作用以及任务吧

  1. 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
  2. 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
  3. 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
  4. 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
  5. 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。

另外,相比于CGL,servelt还有其以下几点优势:

  1. 性能明显更好。
  2. Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
  3. Servlet 是独立于平台的,因为它们是用 Java 编写的。
  4. 服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
  5. Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。

1.2 jsp介绍

  1. JSP(全称Java Server Pages)是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求,而动态生成 HTML、XML 或其他格式文档的Web网页的技术标准。
  2. JSP 技术是以 Java 语言作为脚本语言的,JSP 网页为整个服务器端的 Java 库单元提供了一个接口来服务于HTTP的应用程序。JSP文件后缀名为 *.jsp 。
  3. JSP开发的WEB应用可以跨平台使用,既可以运行在 Linux 上也能运行在 Windows 上。

正因为Jsp是以java语言作为脚本语言的,所以,在整个系统的前端部分,由jsp页面来担任。

1.3 Tomcat介绍

\qquad 开源小型web服务器 ,完全免费,主要用于中小型web项目,只支持Servlet和JSP 等少量javaee规范(就是JavaWeb编程接口)。也正因为tomcat对于java和servelt很好的嵌合,所以我们的此次系统选用了Tomcat服务器。

2.功能实现

2.1 建立四六级单词的MYSQL表格

写了一个python程序,来执行将四级单词的txt表格存入mysql数据库

# @Time : 2019/6/21 15:29 
# @Author : kingback
# @File : CET4-MySQL.py 
# @Software: PyCharm
import re
import pymysql

# 打开数据库连接
db = pymysql.connect(host="127.0.0.1",user="root",  password="123456",db="words",charset = 'utf8')

# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
filename = "C:/Users/kingback/Desktop/四六级但系/四级.txt"
for line in open(filename, encoding="utf-8"):
    hh = re.split(r"\t|\n", line)
    english = hh[0]
    sent = hh[1]
    chinese = hh[2]
    level="4"
    #2、插入操作
    sql="insert into cet(english,chinese,sent,level) values('%s', '%s', '%s','%s')"
    data=(english,chinese,sent,level)
    cursor.execute(sql%data)   # execute也可以执行创建和修改库与表语句
    print("当前插入单词: ",english)
    db.commit()
# 关闭数据库连接
db.close()

为了区别四级单词和六级单词的区别,我又单独写了一个针对存取六级单词的Python文件,其内容如下:

# @Time : 2019/6/21 15:30 
# @Author : kingback
# @File : CET6-MySQL.py 
# @Software: PyCharm
import re
import pymysql

# 打开数据库连接
db = pymysql.connect(host="127.0.0.1",user="root",  password="123456",db="words",charset = 'utf8')
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
filename = "C:/Users/kingback/Desktop/四六级但系/六级.txt"
for line in open(filename, encoding="utf-8"):
    hh = re.split(r"\t|\n", line)
    english = hh[0]
    sent = hh[1]
    chinese = hh[2]
    level="6"
    #2、插入操作
    sql="insert into cet(english,chinese,sent,level) values('%s', '%s', '%s','%s')"
    data=(english,chinese,sent,level)
    cursor.execute(sql%data)   # execute也可以执行创建和修改库与表语句
    print("当前插入单词: ",english)
    # db.commit()
# 关闭数据库连接
db.close()

接下来我展示一下四级单词存取的运行过程,
在这里插入图片描述
因为六级的运行和四级的运行相差不多,于是我就仅展示了四级的。

2.2 功能实现

2.2.1 整个项目组成

整个项目是由

  1. index.jsp (登陆主界面)、Chinese.jsp 、pic.jsp (使用jscharts画图界面)、data.jsp四个jsp页面
  2. ChangeServelt (实际未使用)、DemoServelt (未用到,测试时使用)、TranslateServelt (实现主体功能)三个servelt
  3. 一个DBoper类(数据库操作类)、Chinese_Frequent类(用来存储词频)以及一个Word类(用来存储单词)
  4. 一个Image文件夹(用来存放整个项目中用到的图片)
  5. 一个js文件夹(用来存放js文件)
  6. 一个video文件夹(用来存放动图、视频、音频) 组成。
    整个的目录结构如下所示:
    在这里插入图片描述

2.2.2 介绍一下index.jsp文件内容

这是程序运行后首先展示的界面,也是我们用户进行操作的主界面。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@page import="java.lang.*,java.util.Enumeration"%>
<%@ page import="java.util.*" %>

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <meta charset="UTF-8">
    <title>kingback首页</title>
    <link href="https://shared.ydstatic.com/images/favicon.ico" type="image/x-icon" rel="shortcut icon">
</head>
<body>
<div style="text-align: center;">
<!-- gif -->
<img src="video/pkq.gif" width="320" height="240" alt="">
<!-- audio -->
<audio src="video/xs.mp3" controls="controls"></audio>
<!-- video -->
<video width="320" height="240" controls>
    <source src="video/tf.mp4" type="video/mp4">
    <source src="video/tf.ogg" type="video/ogg">
    <source src="video/tf.webm" type="video/webm">
    <object data="video/tf.mp4" width="320" height="240">
        <embed src="video/tf.swf" width="320" height="240">
    </object>
</video>

</div>>

<div id="margin1"></div>
<div id="logo">
    <div class="logo"></div>
</div>
<div id="margin2"></div>
<form action="search" method="post">
    <div class="border">
        <select name="type" id="selectType">
            <option value="四级">四级</option>
            <option value="六级" selected id="type">六级</option>	//预选设置
            <option value="汉译英" >汉译英</option>
            <option value="英译汉" >英译汉</option>
            <option value="统计">统计</option>
            <option value="字频">字频</option>
        </select>
        <input type="text" name="inputWord" placeholder="请输入单词" id="translateContent" />
        <span id="hnwBtn" class="hand-write"></span>
    </div>
    <input type="submit" value="查 询" id="btn">
    <input type="reset" value="重 置" id="btn1">
</form>
</body>
</html>

\qquad 很多人或许会想,前台用户输入的数据,后台是怎么获得的呢,因为jsp很好的嵌合了java以及servelt所以,在刚才的主界面中我们将需要传递给后台的数据放在这个 form 内,当用户点击查询按钮的时候,该动作就称之为 search ,并且将其中包括的内容传递给后台的 servelt

<form action="search" method="post">
......
</form>

2.2.4 介绍TranslateServelt.java

\qquad 接下来我就来讲一下,前台提交过来的action search是怎么和后台配对的。请注意看该java文件的开头的这句话

@WebServlet("/search")

\qquad 我们会发现前台提交的search动作通过这句话找到了与它配对的servelt,也就是说前台用户输入的数据已经成功传到后台来处理。 然后再在这个java文件中执行查询数据库的操作。

import javax.jws.WebService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: kingback
 * Author:king@王延凯
 * Date: 2019/6/17
 * Time: 14:14
 * Description: No Description
 */

@WebServlet("/search")
public class TranslateServlet extends HttpServlet {
    //idea快速重写父类方法,使用快捷键ctrl+O选择需要重写的方法即可
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        super.doPost(request, response);
        //设置编码格式
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset = utf-8");
        //获取选择的类别
        String type=request.getParameter("type");
        //获取用户输入的单词或汉字
        String inputWord=request.getParameter("inputWord");
        //验证输出
        // System.out.println(inputWord);
        // System.out.println("当前选项为:"+type);
        // System.out.println(type.equals("六级"));
        //根据不同的type选择不同的sql语句
        //汉译英,支持模糊搜索
        String sql="select * from cet where chinese like "+"'%"+inputWord+"%'";
        //英译汉
        String sql1="select * from cet where english="+"'"+inputWord+"'";
        //四级
        String CET_4="select * from cet where level="+"'4'";
        //六级
        String CET_6="select * from cet where level="+"'6'";
        //统计
        String count="";
        //字频
        String sql_frequent="select * from chinese_word where pin like "+"'"+inputWord+"%'";

        //初始化连接变量,用来存储数据
        String server="localhost";
        String dbname="words";
        String dbuser="root";
        String dbpwd="123456";
        //创建一个Word链表来承接数据库查询的数据
        List<Word> wordList1=new ArrayList();
        //创建一个Chinese_Frequent链表来承接数据查询的数据
        List<Chinese_Frequent> wordList2=new ArrayList();
        //实例化一个数据库连接类
        DBoper dBoper=new DBoper();
        //链接数据库
        dBoper.getConn(server,dbname,dbuser,dbpwd);
        //初始化数据库结果参数
        ResultSet rs = null;
        //执行sql查询
        if(type.equals("四级")){
            // System.out.println("当前执行到四级!");
            //执行sql语句
            rs=dBoper.executeQuery(CET_4,null);
            //调用DataDeal方法,开始对数据进行操作
            DataDeal(rs,wordList1,request,response,dBoper);
        }
        else if(type.equals("六级")){
            // System.out.println("当前执行到六级!");
            //执行sql语句
            rs=dBoper.executeQuery(CET_6,null);
            //开始对数据进行操作
            DataDeal(rs,wordList1,request,response,dBoper);
        }
        else if(type.equals("英译汉")){
            //执行sql语句
            rs=dBoper.executeQuery(sql1,null);
            //开始对数据进行操作
            DataDeal(rs,wordList1,request,response,dBoper);
        }
        //汉译英处理函数
        else if(type.equals("汉译英")) {
            //执行sql语句
            rs=dBoper.executeQuery(sql,null);
            //开始对数据进行操作
            DataDeal(rs,wordList1,request,response,dBoper);
        }
        //统计处理函数
        else if(type.equals("统计")) {
            //开始对数据进行操作

            Account(request,response,dBoper);
        }
        else if (type.equals("字频")){
            rs=dBoper.executeQuery(sql_frequent,null);
            System.out.println(sql_frequent);
            Frequent(wordList2,dBoper,request,response,rs);
        }
    }

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

    public static void DataDeal(ResultSet resultSet,List<Word> wordList1,HttpServletRequest request, HttpServletResponse response,DBoper dBoper){
        try {
            //将数据存入wordList1里边
            while (resultSet.next()){
                //获取数据库中查询到的数据
                String type2=resultSet.getString("english");
                String word2=resultSet.getString("chinese");
                String sent2=resultSet.getString("sent");
                String level2=resultSet.getString("level");
                Word word=new Word(type2,word2,sent2,level2);
                //添加至wordList1列表
                wordList1.add(word);
            }
            //调用数据库连接类的方法,关闭数据库连接
            dBoper.closeAll();

            //利用request将WordList传送到前端页面
            if(wordList1.size()==0){
                //如果没有读取到数据,返回报错
                response.sendRedirect("success.jsp?error=yes");
            }else {
                //使用request封装数据
                request.setAttribute("wordList", wordList1);
                System.out.println(wordList1);
                //传送至前台jsp网页
                request.getRequestDispatcher("data.jsp").forward(request, response);
            }
            //异常处理
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }

    public static void Account(HttpServletRequest request, HttpServletResponse response,DBoper dBoper) {
        //用来存储单词个数
        int[] nums=new int[26];
        String character="a.b.c.d.e.f.g.h.i.g.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z";
        //拆分字符串
        String characters[] = character.split(" |\\.");
        ResultSet rs = null;
        for (int i = 0; i < 26; i++) {
            try {
                String sql="select * from cet where english like "+"'%"+characters[i]+"%'";
//                System.out.println(sql);
                rs=dBoper.executeQuery(sql,null);
                //将数据存入wordList1里边
                while (rs.next()){
                    nums[i]++;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        //调用数据库连接类的方法,关闭数据库连接
        dBoper.closeAll();


        //已经统计到数据
        for (int i = 0; i < 26; i++) {
            characters[i]=characters[i]+","+nums[i];
//            System.out.println(nums[i]);
        }

        try {
            //使用request封装数据
            request.setAttribute("nums", nums);
            request.setAttribute("characters", characters);

            //System.out.println(nums);
            //传送至前台jsp网页
            request.getRequestDispatcher("pic.jsp").forward(request, response);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void Frequent(List<Chinese_Frequent> wordList2,DBoper dBoper,HttpServletRequest request, HttpServletResponse response,ResultSet rs){
        try {
            while (rs.next()) {
                //获取数据库中查询到的数据
                String chinese = rs.getString("words");
                String counts = rs.getString("counts");
                String pin = rs.getString("pin");
                Chinese_Frequent CF = new Chinese_Frequent(chinese, counts, pin);
                wordList2.add(CF);
            }
            //调用数据库连接类的方法,关闭数据库连接
            dBoper.closeAll();

                //利用request将WordList传送到前端页面
            if(wordList2.size()==0){
                //如果没有读取到数据,返回报错
                response.sendRedirect("success.jsp?error=yes");
            }else {
                //使用request封装数据
                request.setAttribute("wordList2", wordList2);
                System.out.println(wordList2);
                //传送至前台jsp网页
                request.getRequestDispatcher("chinese.jsp").forward(request, response);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }
}

2.2.5 后台数据返回前台

\qquad 执行完前边的步骤,我们或许会发现,虽然我们将数据传到了后台,并且进行了查询数据库等一系列操作,但是我们又如何将后台的数据传输到前台呢,这里我们需要注意一点就是,因为在这里可能会查询到很多结果,所以一条一条数据的往前台传显得不是那么显示,例如我们查询单词,每一个单词所涵盖的信息我们可以称之为一个Word 类实例化出来的对象,如果我们将这些一个一个的Word对象封装成一个集合WordList,传递给前台,那样岂不更容易一些呢。于是我们根据需要就构建了一个Word类,其代码如下:

/**
 * Created with IntelliJ IDEA.
 * User: kingback
 * Author:king@王延凯
 * Date: 2019/6/15
 * Time: 14:14
 * Description: No Description
 */
public class Word {
    public String getEnglish() {
        return english;
    }

    public void setEnglish(String english) {
        this.english = english;
    }

    public String getChinese() {
        return chinese;
    }

    public void setChinese(String chinese) {
        this.chinese = chinese;
    }

    public String getSent() {
        return sent;
    }

    public void setSent(String sent) {
        this.sent = sent;
    }

    public String getLevel() {
        return level;
    }

    public void setLevel(String level) {
        this.level = level;
    }

    //快捷键 Alt+Insert
    //get set方法

    private String english;
    private String chinese;
    private String sent;
    private String level;

    public Word(String english,String chinese,String sent,String level){
    super();
    this.english=english;
    this.sent=sent;
    this.chinese=chinese;
    this.level=level;
    }
    public Word(){
        super();
    }

}

\qquad 接下来我们再来讨论将后台数据反传给前台的方法和策略,前边我们已经说到了封装为WordList,而前台又是怎么得到的呢,我们可以看到在前边讲到的 TranteServelt 里边的最后有这么几句代码:

  //使用request封装数据
        request.setAttribute("wordList2", wordList2);
        System.out.println(wordList2);
        //传送至前台jsp网页
         request.getRequestDispatcher("chinese.jsp").forward(request, response);

\qquad 到了这里我们似乎一切都明白了,如果当程序执行到这部分代码的时候,他就会将它之前封装好的wordList数据传递到chinese.jsp页面。

2.2.6 前台接收后台的数据并处理,显示在前端页面。

\qquad 在前边我们已经讲到了,传递到前台的WordList在对应的jsp界面里边是这样被识别并一个个拆解为Word的。下面我们就以chinese.jsp为例:

<%--
  Created by IntelliJ IDEA.
  User: kingback
  Date: 2019/8/4
  Time: 22:20
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ page isELIgnored="false" %>

<html>
<head>
    <title>词频查询</title>
    <meta charset="UTF-8">
    <link href="https://shared.ydstatic.com/images/favicon.ico" type="image/x-icon" rel="shortcut icon">
</head>
<body>
<div id="margin1"></div>
<div id="logo">
    <div class="logo"></div>
</div>
<div id="margin2"></div>
<form action="search" method="post">
    <div class="border">
        <select name="type" id="selectType">
            <option value="四级">四级</option>
            <option value="六级" selected id="type">六级</option>	//预选设置
            <option value="汉译英" >汉译英</option>
            <option value="英译汉" >英译汉</option>
            <option value="统计" >统计</option>
            <option value="字频">字频</option>
        </select>
        <input type="text" name="inputWord" placeholder="请输入单词或汉字" id="translateContent" />
        <span id="hnwBtn" class="hand-write"></span>
    </div>
    <input type="submit" value="查 询" id="btn">
    <input type="reset" value="重 置" id="btn1">
</form>
<table class="hovertable">
    <tr>
        <th>汉字</th>
        <th>个数</th>
        <th>拼音</th>
    </tr>
    <c:forEach items="${wordList2}" var="CH">
        <form action="test1" method="post">
            <tr οnmοuseοver="this.style.backgroundColor='#ffff66';" οnmοuseοut="this.style.backgroundColor='#d4e3e5';">
                <td name="china"><c:out value="${CH.chinese}"/></td>
                <td><c:out value="${CH.counts}"/></td>
                <td><c:out value="${CH.pin}"/></td>
                <%--<td>--%>
                    <%--<input type="submit" value="修改" id="btn2" name="test">--%>
                <%--</td>--%>
            </tr>
        </form>
    </c:forEach>
</table>
</body>
</html>

\qquad 如果你观察仔细的话,或许会在以上代码的后半部分发现这句话:<c:forEach items="${wordList2}" var=“CH”>,我们很容易就会想到我们是通过这句话来接收后台传过来的数据的,并将Wordlist拆解为一个个Word显示在页面。

2.2.7 其它文件

\qquad 到目前为止,主体流程我已经走完了,只是含有几个文件没有展示出来,一个是数据库操作类DBoper(这个类在我之前发布的博客中是有的,都是一样的内容)、一个就是Chinese_Frequent.java ,其实该文件和Word的作用差不多,都是为了承接在数据库中查询到的结果,然后封装成List类型的传递给前台。
以下我展示的代码内容为 Chinese_Frequent.java 的。

/**
 * Created with IntelliJ IDEA.
 * User: kingback
 * Author:king@王延凯
 * Date: 2019/8/4
 * Time: 22:53
 * Description: No Description
 */
public class Chinese_Frequent {
    public String getChinese() {
        return Chinese;
    }

    public void setChinese(String chinese) {
        Chinese = chinese;
    }

    public String getCounts() {
        return Counts;
    }

    public void setCounts(String counts) {
        Counts = counts;
    }

    public String getPin() {
        return Pin;
    }

    public void setPin(String pin) {
        Pin = pin;
    }

    private String Chinese;
    private String Counts;
    private String Pin;

    public Chinese_Frequent(String Chinese,String Counts,String Pin){
        super();
        this.Chinese=Chinese;
        this.Counts=Counts;
        this.Pin=Pin;
    }

}

\qquad 至于还有几个jsp页面的代码没有展示出来,我这么告诉你吧,其实这几个jsp页面的代码基本上都是也一样的。但如果你非得要全部的代码的话,可以私聊我,当我看到,我定会免费赠送所有资料。

3.运行结果

在这里插入图片描述

  • 4
    点赞
  • 0
    评论
  • 10
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

王延凯的博客

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值