关于课程管理系统的开发

127 阅读11分钟

根据以前学习的知识制作一个关于教育管理的后台系统,业务人员可以在 这个后台管理系统中,对课程信息、讲师信息、 学员信息等数据进行维护。首先我们需要明确几点:需要做的内容,前后端技术选型接口文档,前后端开发方式

一.概述

1.1 课程管理后台系统需要做的内容

  1. 课程信息页面展示
  2. 课程营销信息配置
  3. 配置课时( 即课程内容管理)

1.2 前后端技术选型

前端:

image.png

后端:

image.png

dao层主要就是封装一些数据库的增删改查操作,但仅仅是封装了操作,具体的实现并不在dao层里,所以我们可以看到日常的dao层都是以接口形式实现,里面写的方法也都是交给业务层也就是service层去调用。

Service层主要负责业务模块的逻辑。一般service层我们会先写一个interface,这个接口以service为后缀表示这是一个service接口,在这个类里定义好我们需要的方法,然后写实现类去实现这个接口里的方法.

1.3 前后端开发方式

此项目中 采用前后端分离开发方式(前后端分离的核心思想就是前端HTML页面通过AJAX调用后端的API接口,并通过JSON数据进行交互。) 前后端开发方式优势:

  1. 模式下,如果发现bug可以快速定位是谁的问题.
  2. 后端分离可以减少后端服务器的并发/负载压力。除了接口以外的其他所有HTTP请求全部转移到 前端Nginx上,接口的请求则转发调用Tomcat.
  3. 前后端分离的模式下,即使后端服务器暂时超时或宕机了,前端页面也会正常访问,只不过数据刷 不出来而已。
  4. 前后端分离会更加合理的分配团队的工作量,减轻后端团队的工作量,提高了性能和可扩展性。

1.4 接口文档

在项目中使用的是前后端分离开发方式,需要由前后端工程师共同定义接口,编写接口文档, 之后大家都根据这个接口文档进行开发,到项目结束前都要一直进行接口文档的维护。 为什么要写接口文档?

  1. 项目开发过程中前后端工程师有一个统一的文件进行沟通交流,并行开发
  2. 项目维护中或者项目人员更迭,方便后期人员查看、维护

二.开发前准备

开发工程前我们需要搞清楚此工程需要的依赖(我们项目中需要使用的第三方Jar包),如果按照之前学习的方式我们一个一个的导入Jar包的话,不仅麻烦还需要我们解决随时可能发生的jar包冲突问题,所以在这里我们使用Maven 项目管理工具

2.1 Maven介绍

Maven是一个跨平台的项目管理工具。作为Apache组织的一个颇为成功的开源项目,其主要服务于 基于Java平台的项目创建,依赖管理和项目信息管理。maven是Apache的顶级项目,解释为“专家,内 行”,它是一个项目管理的工具,maven自身是纯java开发的,可以使用maven对java项目进行构建、 依赖管理。

2.2 Maven的作用

(1).依赖管理

Maven可以很方便的对项目所需要的Jar进行管理,,包括快速引入Jar包,以及对使用的 Jar包进行统一的版本控制

(2).一键构建项目

之前我们创建项目,需要确定项目的目录结构,比如 src 存放Java源码, resources 存放配置文件,还要配置环境比如JDK的版本等等,如果有多个项目那么就需要每次自己搞一套配置,十分麻烦。

Maven为我们提供了一个标准化的Java项目结构,我们可以通过Maven快速创建一个标准的 Java项目

三.后台系统搭建

项目目录

image.png

3.1 模块内容分析

配置好Maven之后我们进入我们的项目开发中,首先我们分析一下需要完成的课程模块:

(1)课程管理 实现以下功能:

  • 展示课程列表
  • 根据课程名和状态进行查询
  • 新建课程
  • 课程上架与下架

(2)营销信息(设置课程的详细信息) 实现以下功能:

  • 回显课程信息
  • 修改课程信息,包含了图片上传

(3)配置课时(配置课时指的是对课程下所属的章节与课时进行配置(一个课程对应多个章节,一个章节有多个课时))

  • 以树形结构的下拉框形式,
  • 展示课程对应的章节与课时信息
  • 添加章节功能
  • 修改章节功能
  • 修改章节状态功能

3.2 Mysql数据库表分析

这是表关系的分析图,包括了每个表的名字,每个表行的名字。 image.png

3.3 通用Servlet

完成模块分析和表关系分析后,创建项目,导入pom.xml。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lagou</groupId>
    <artifactId>lagou_edu_home</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <!-- properties 是全局设置,可以设置整个maven项目的编译器 JDK版本 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>


        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>

        <!--    Beanutils    -->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.3</version>
        </dependency>

        <!--   DBUtils    -->
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.6</version>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>


        <!-- 数据库相关 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>

        <!--fastjson工具包 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>com.colobu</groupId>
            <artifactId>fastjson-jaxrs-json-provider</artifactId>
            <version>0.3.1</version>
        </dependency>

        <!--  文件上传 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.1</version>
        </dependency>

        <!--   Lombok  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <!--  maven编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>

        </plugins>
    </build>


</project>
```

Servlet是用来写功能的,那一个功能就有一个servlet,那100个功能就有100个servlet。数量多不仅不好管理,而且会影响服务器效率。所以我们这时候让一个模块下只有一个servlet。

首先在我们的index.jsp下写出网页功能大概:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <a href="${pageContext.request.contextPath}/test?methodName=addCourse">新建课程</a>
    <a href="${pageContext.request.contextPath}/test?methodName=findByName">根据课程名查询</a>
    <a href="${pageContext.request.contextPath}/test?methodName=findByStatus">根据课程状态查询</a>



</body>
</html>

TestServlet

/**
 *  模拟课程模块 ,模块中有很多功能
**/
 @WebServlet("/test")
 public class TestServlet extends HttpServlet {
 /**
     *  doGet()方法作为调度器 控制器,根据请求的功能不同,调用对应的方法
     *
     * */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
        //1.获取参数
        //获取要调用的方法名
        String methodName = req.getParameter("methodName");
        //2.业务处理
        //判断 执行对应的方法
        if("addCourse".equals(methodName)){
            addCourse(req,resp);
        }else if("findByStatus".equals(methodName)){
            findByName(req,resp);
        }else if("findByStatus".equals(methodName)){
            findByStatus(req,resp);
        }else{
            System.out.println("访问的功能不存在!");
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
        doGet(req,resp);
    }
    /**
     *  2.模块对应的功能部分
     * */
    public void addCourse(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("新建课程");
    }
    public void findByStatus(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根据状态查询");
    }
    public void findByName(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根据课程名称查询");
    }
 }

以上的Servlet代码有一些问题,我们现在有三个方法,if语句里判断了三次,很合理,但是如果我们一个页面有一百个方法呢,写一百条if语句?所以这时候就需要我们的反射方法了

3.4 提高代码的可维护性(反射)

反射的知识回顾:

  • 第一步:先获取请求携带的方法参数值
  • 第二步:获取指定类的字节码对象
  • 第三步:根据请求携带的方法参数值,再通过字节码对象获取指定的方法 
  • 第四步:最后执行指定的方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    //1.获取参数 要访问的方法名
    //String methodName = req.getParameter("methodName");
    String methodName = null;

    //1.获取POST请求的 Content-Type类型
    String contentType = req.getHeader("Content-Type");

    //2.判断传递的数据是不是JSON格式
    if("application/json;charset=utf-8".equals(contentType)){
        //是JOSN格式 调用getPostJSON
        String postJSON = getPostJSON(req);

        //将JSON格式的字符串转化为map
        Map<String,Object> map = JSON.parseObject(postJSON, Map.class);

        //从map集合中获取 methodName
        methodName =(String) map.get("methodName");

        //将获取到的数据,保存到request域对象中
        req.setAttribute("map",map);

    }else{
        methodName = req.getParameter("methodName");
    }

    //2.判断 执行对应的方法
    if(methodName != null){
        //通过反射优化代码 提升代码的可维护性

        try {
            //1.获取字节码文件对象
            Class c = this.getClass();

            //2.根据传入的方法名,获取对应的方法对象  findByName
            Method method = c.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

            //3.调用method对象的 invoke方法,执行对应的功能
            method.invoke(this,req,resp);

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("请求的功能不存在!!");
        }
    }

}

四.JSON

4.1 JSON简述

JSON(JavaScript Object Notation) JavaScript对象表示法(JSON源于JS)。

image.png JSON的特点:

  • JSON 是一种轻量级的数据交换格式。
  • JSON采用完全独立于语言的文本格式,就是说不同的编程语言JSON数据是一致的。
  • JSON易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。

4.2 XML与JSON的区别

JSON: (JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。

XML : 可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言。

相同点:它们都可以作为一种数据交换格式。

二者区别:

XML是重量级的,JSON是轻量级的,XML在传输过程中比较占带宽,JSON占带宽少,易于压 缩。

XML和json都用在项目交互下,XML多用于做配置文件,JSON用于数据交互

JSON独立于编程语言存在,任何编程语言都可以去解析json

4.3 JSON语法


 "id": 110,
 "name": "李会长",
 "age": 2

 }

语法注意:

  1. 外面由{}括起来

  2. 数据以"键:值"对的形式出现(其中键多以字符串形式出现,值可取字符串,数值,甚至其他json 对象)

  3. 每两个"键:值"对以逗号分隔(最后一个"键:值"对省略逗号

  4. 参数值如果是string类型,就必须加引号,如果是数字类型,引号可加可不加 遵守上面4点,便可以形成一个json对象

代码示例:

 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>Title</title>
<script typet="text/javascript" 
src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
 <script>
 //自定义JSON数据格式 (Java中的对象)
 var person = {"name":"tom","sex":"女", "age":12};
 console.log(person);
 //数组格式
var persons = {"person":[{"name":"tom","sex":"女", "age":12},
 {"name":"jack","sex":"男", "age":22}]};
 console.log(persons);
 </script>
 </head>
 <body>
 //集合
var list = [{"name":"老五","sex":"女", "age":12},{"name":"会
长","sex":"男", "age":12}];
 console.log(list);
 </body>
 </html>

4.4 JSON转换

目前, 前后端的ajax通讯几乎用的都是json格式的了,所以在开发的过程中,我们经常会涉及到JSON数据 的转换

(1).FastJson介绍

Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换 为 Java 对象。

(2).FastJson特点如下:

能够支持将java bean序列化成JSON字符串,也能够将JSON字符串反序列化成Java bean。

顾名思义,FastJson操作JSON的速度是非常快的。

无其他包的依赖, 使用比较方便

(3).FastJson的使用

首先在Maven的配置文件里导入FastJson的依赖

 <groupId>com.alibaba</groupId>
 <artifactId>fastjson</artifactId>
 <version>1.2.3</version>
 </dependency>
 <dependency>
 <groupId>com.colobu</groupId>
 <artifactId>fastjson-jaxrs-json-provider</artifactId>
 <version>0.3.1</version>
 </dependency>
 

然后将Java 对象转换为 JSON 格式:

 //Java对象转JSON
 @Test
 public void javaBeanToJSON(){
 //创建Person对象
Person p = new Person("码云",15, DateUtils.getDateFormart());
 //使用JSON对象的 toString方法将对象转换为JOSN数据
String s = JSON.toJSONString(p);
 System.out.println(s); //{"age":15,"birthday":"2020-07-03 
19:54:33","username":"码云"}
 }
 //List集合转Json
 @Test
public void ListToJSON(){
 //创建Person对象
Person p1 = new Person("码云",15, DateUtils.getDateFormart());
 Person p2 = new Person("虎子",13, DateUtils.getDateFormart());
 Person p3 = new Person("小斌",18, DateUtils.getDateFormart());
 List<Person> list = new ArrayList<>();
 Collections.addAll(list,p1,p2,p3);
 //使用JSON对象的 toString方法将对象转换为JOSN数据
String s = JSON.toJSONString(list);
 System.out.println(s);
 //[{"age":15,"birthday":"2020-07-03 19:59:05","username":"码云"},
 {"age":13,"birthday":"2020-07-03 19:59:05","username":"虎子"},
 {"age":18,"birthday":"2020-07-03 19:59:05","username":"小斌"}]
 }
 }

(4).Fastjson中的 @JSONField 注解

通过 @JSONField 我们可以自定义字段的名称进行输出,并控制字段的排序,还可以进行序列化 标记。

 public class Person {
 //自定义输出的名称, 并且进行输出排序
@JSONField(name="USERNAME",ordinal = 1)
 private String username;
 @JSONField(name="AGE",ordinal = 2)
 private int age;
 //排除不需要序列化的字段
@JSONField(serialize = false)
 private String birthday;
 public Person() {
 }
 }
 public Person(String username, int age, String birthday) {
 this.username = username;
 this.age = age;
 this.birthday = birthday;
 }
 }

(5).JSON 字符串转换为 Java 对象

可以使用 JSON.parseObject() 将 JSON 字符串转换为 Java 对象。

注意反序列化时为对象时,必须要有默认无参的构造函数,否则会报异常

可以使用 JSON.parseArray() 将 JSON 字符串转换为 集合对象

    @Test
    public void JSONToJavaBean(){
        String json = "{\"age\":15,\"birthday\":\"2020-07-03 
19:54:33\",\"username\":\"码云\"}";
        Person person = JSON.parseObject(json, Person.class);
        System.out.println(person);
        //创建Person对象
        String json2 ="[{\"age\":15,\"birthday\":\"2020-07-03 
19:59:05\",\"username\":\"码云\"},{\"age\":13,\"birthday\":\"2020-07-03 
19:59:05\",\"username\":\"虎子\"},{\"age\":18,\"birthday\":\"2020-07-03 
19:59:05\",\"username\":\"小斌\"}]";
        List<Person> list  = JSON.parseArray(json2,Person.class);
        System.out.println(list);
    }