根据以前学习的知识制作一个关于教育管理的后台系统,业务人员可以在 这个后台管理系统中,对课程信息、讲师信息、 学员信息等数据进行维护。首先我们需要明确几点:需要做的内容,前后端技术选型,接口文档,前后端开发方式。
一.概述
1.1 课程管理后台系统需要做的内容
- 课程信息页面展示
- 课程营销信息配置
- 配置课时( 即课程内容管理)
1.2 前后端技术选型
前端:
后端:
dao层主要就是封装一些数据库的增删改查操作,但仅仅是封装了操作,具体的实现并不在dao层里,所以我们可以看到日常的dao层都是以接口形式实现,里面写的方法也都是交给业务层也就是service层去调用。
Service层主要负责业务模块的逻辑。一般service层我们会先写一个interface,这个接口以service为后缀表示这是一个service接口,在这个类里定义好我们需要的方法,然后写实现类去实现这个接口里的方法.
1.3 前后端开发方式
此项目中 采用前后端分离开发方式(前后端分离的核心思想就是前端HTML页面通过AJAX调用后端的API接口,并通过JSON数据进行交互。) 前后端开发方式优势:
- 模式下,如果发现bug可以快速定位是谁的问题.
- 后端分离可以减少后端服务器的并发/负载压力。除了接口以外的其他所有HTTP请求全部转移到 前端Nginx上,接口的请求则转发调用Tomcat.
- 前后端分离的模式下,即使后端服务器暂时超时或宕机了,前端页面也会正常访问,只不过数据刷 不出来而已。
- 前后端分离会更加合理的分配团队的工作量,减轻后端团队的工作量,提高了性能和可扩展性。
1.4 接口文档
在项目中使用的是前后端分离开发方式,需要由前后端工程师共同定义接口,编写接口文档, 之后大家都根据这个接口文档进行开发,到项目结束前都要一直进行接口文档的维护。 为什么要写接口文档?
- 项目开发过程中前后端工程师有一个统一的文件进行沟通交流,并行开发
- 项目维护中或者项目人员更迭,方便后期人员查看、维护
二.开发前准备
开发工程前我们需要搞清楚此工程需要的依赖(我们项目中需要使用的第三方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项目
三.后台系统搭建
项目目录
3.1 模块内容分析
配置好Maven之后我们进入我们的项目开发中,首先我们分析一下需要完成的课程模块:
(1)课程管理 实现以下功能:
- 展示课程列表
- 根据课程名和状态进行查询
- 新建课程
- 课程上架与下架
(2)营销信息(设置课程的详细信息) 实现以下功能:
- 回显课程信息
- 修改课程信息,包含了图片上传
(3)配置课时(配置课时指的是对课程下所属的章节与课时进行配置(一个课程对应多个章节,一个章节有多个课时))
- 以树形结构的下拉框形式,
- 展示课程对应的章节与课时信息
- 添加章节功能
- 修改章节功能
- 修改章节状态功能
3.2 Mysql数据库表分析
这是表关系的分析图,包括了每个表的名字,每个表行的名字。
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)。
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
}
语法注意:
-
外面由{}括起来
-
数据以"键:值"对的形式出现(其中键多以字符串形式出现,值可取字符串,数值,甚至其他json 对象)
-
每两个"键:值"对以逗号分隔(最后一个"键:值"对省略逗号
-
参数值如果是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);
}