前言
文章内容输出来源:拉勾教育JAVA就业训练营
1. 项目架构
1.1 项目介绍
拉钩教育后台管理系统,是提供给拉钩教育的相关业务人员使用的一个后台管理系统, 业务人员可以在这个后台管理系统中,对课程信息、讲师信息、 学员信息等数据进行维护.
1.2 模块介绍
打开产品需求文档,我们一起去看一下课程管理模块中都包含哪些内容:
- 课程信息页面展示
- 课程营销信息配置
- 配置课时( 即课程内容管理)
1.3 前后端分离开发
1.3.1 前后端分离架构介绍
- 前后端分离已成为互联网项目开发的业界标准使用方式,将前端和后端的开发进行解耦。并且前后端分离会为以后的大型分布式架构、微服务架构、多端化服务(各种客户端,比如浏览器、车载终端、安卓、IOS等)打下坚实的基础。
1.3.2 接口文档
1.3.2.1 什么是接口文档?
- 在我们的项目中使用的是前后端分离开发方式,需要由前后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发,到项目结束前都要一直进行接口文档的维护。
1.3.2.2 为什么要写接口文档?
- 项目开发过程中前后端工程师有一个统一的文件进行沟通交流,并行开发
- 项目维护中或者项目人员更迭,方便后期人员查看、维护
1.3.2.3 接口规范是什么?
一个接口的描述至少包括下面几项:
- 名称: findCourseList
- 描述: 根据条件查询课程信息
- URL: http://localhost:8080/lagou_edu_home/course/
- 请求方式: GET
- 请求参数
methodName:"findCourseList";
- 响应结果
{
"status": "0",
"msg": "success"
}
1.3.3 前后端分离架构的优势
1.3.3.1 前后端耦合的开发方式
1.3.3.2 前后端耦合的缺陷 (以JSP为例)
- UI出好设计图之后,前端开发工程师只负责将设计图切成HTML,需要由Java开发工程师来将
HTML套成JSP页面,修改问题的时候需要双方协同开发,效率低下。 - JSP页面必须要在支持Java的WEB服务器上运行(如Tomcat、Jetty等),无法使用Nginx等(官方
宣称单实例HTTP并发高达5W),性能提升不上来。 - 第一次请求JSP,必须要在WEB服务器中编译成Servlet,第一次运行会较慢。 之后的每次请求JSP
都是访问Servlet再用输出流输出的HTML页面,效率没有直接使用HTML高
1.3.3.3 前后端分离的开发方式
1.3.3.4 前后端分离的优势
- 前后端分离的模式下,如果发现Bug,可以快速定位是谁的问题,不会出现互相踢皮球的现象
- 前后端分离可以减少后端服务器的并发/负载压力。除了接口以外的其他所有HTTP请求全部转移到
前端Nginx上,接口的请求则转发调用Tomcat. - 前后端分离的模式下,即使后端服务器暂时超时或宕机了,前端页面也会正常访问,只不过数据刷
不出来而已。 - 前后端分离会更加合理的分配团队的工作量,减轻后端团队的工作量,提高了性能和可扩展性
1.4 技术选型
1.4.1 前端技术选型
前端技术 | 说明 |
---|---|
Vue.js | 是一套用于构建用户界面的渐进式JavaScript框架 |
Element UI库 | element-ui 是饿了么前端出品的基于 Vue.js的 后台组件库,方便程序员进行页面快速布局和构建 |
node.js | 简单的说 Node.js 就是运行在服务端的 JavaScript 运行环境 . |
axios | 对ajax的封装, 简单来说就是ajax技术实现了局部数据的刷新,axios实现了对ajax的封装, |
1.4.2 后端技术选型
前端技术 | 说明 |
---|---|
Web层 | a) Servlet:前端控制器b) Filter:过滤器c) BeanUtils:数据封装 |
Service层 | a) 业务处理 |
dao层 | a) Mysql:数据库b) Druid:数据库连接池c) DBUtils: 操作数据库 |
2. Maven 项目管理工具
2.1 Maven的作用
- 依赖管理
- 依赖指的就是是 我们项目中需要使用的第三方Jar包, 一个大一点的工程往往需要几十上百个Jar包,按照我们之前的方式,每使用一种Jar,就需要导入到工程中,还要解决各种Jar冲突的问题.
- Maven可以对Jar包进行统一的管理,包括快速引入Jar包,以及对使用的 Jar包进行统一的版本控制
- 一键构建项目
- 之前我们创建项目,需要确定项目的目录结构,比如 src 存放Java源码, resources 存放配置文件,还要配置环境比如JDK的版本等等,如果有多个项目 那么就需要每次自己搞一套配置,十分麻烦
- Maven为我们提供了一个标准化的Java项目结构,我们可以通过Maven快速创建一个标准的Java项目.
3. 后台系统搭建
3.1 课程管理模块功能分析
- 在本次的项目中,主要完成拉钩教育后台管理系统的 课程管理模块, 课程管理模块包含了添加课程,配置课程相关信息, 以及管理课程章节等功能,我们来一起看一下产品的原型图
3.1.1 课程管理
实现以下功能:
- 展示课程列表
- 根据课程名和状态进行查询
- 新建课程
- 课程上架与下架
3.1.2 营销信息
营销信息,其实就是设置课程的详细信息
- 回显课程信息
- 修改课程信息,包含了图片上传
3.1.3 配置课时
配置课时指的是对课程下所属的章节与课时进行配置(一个课程对应多个章节,一个章节有多个课时)
- 以树形结构的下拉框形式, 展示课程对应的章节与课时信息
- 添加章节功能
- 修改章节功能
- 修改章节状态功能
3.2 课程管理模块表设计
创建四张表
3.3 环境搭建
3.3.1 创建项目
使用Maven快速构建工程, 项目名为: linle_home
3.3.2 项目目录
3.3.3 导入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.linle</groupId>
<artifactId>linle_home</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.1.0</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>
<!-- 对象转为json 工具包 -->
<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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 重点 -->
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<!-- 在build中 我们需要指定一下项目的JDK编译版本,maven默认使用1.5版本进行编译
注意 build 与 dependencies是平级关系,标签不要写错位置 -->
<build>
<plugins>
<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>
3.3.4 导入工具类及配置文件
3.3.5 导入实体类
- Lombok介绍
在项目中使用Lombok可以减少很多重复代码的书写。比如说getter/setter/toString等方法的编写。 - IDEA中安装 lombok插件
- 添加依赖
在项目中添加Lombok依赖jar,在pom文件中添加如下部分
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<scope>provided</scope>
</dependency>
- Lombok常用注解
- @Getter/@Setter: 作用类上,生成所有成员变量的getter/setter方法
- @ToString : 作用于类,覆盖默认的toString()方法 ,可以通过of属性限定显示某些字段,通过exclude属性排除某些字段
- @AllArgsConstructor:生成全参构造器
- @NoArgsConstructor:生成无参构造器
- @Data: 该注解使用在类上,该注解会提供 getter 、 setter 、 equals 、 hashCode 、toString 方法。
- 导入表对应的实体类
3.4 通用Servlet
3.4.1 需求分析
课程模块下有两个子模块:
- 课程模块
- 营销信息
- 配置课时(课程内容管理)
- 每个模块下都有很多的功能, 比如课程模块 的 新建课程, 上架课程,下架课程,根据课程名查询等等功能 , 每一个功能都是一个Servlet.
3.4.2 Servlet对应模块
我们使用一个Servlet对应一个模块的方式进行开发
3.4.3 抽取通用的BaseServlet
- 将反射相关的代码抽取到一个类中 BaseServlet, 让BaseServlet去继承HTTPServlet
public class BaseServlet extends HttpServlet {
@Override
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)){
//是JSON格式 调用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("请求的功能不存在!!");
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
/**
* POST请求格式为: application/json;charset=utf-8
* 使用该方法进行读取
* */
public String getPostJSON(HttpServletRequest request){
try {
//1.从request中 获取缓冲输入流对象
BufferedReader reader = request.getReader();
//2.创建StringBuffer 保存读取出的数据
StringBuffer sb = new StringBuffer();
//3.循环读取
String line = null;
while((line = reader.readLine()) != null){
//将每次读取的数据 追加到StringBuffer
sb.append(line);
}
//4.返回结果
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
4. JSON
4.1 JSON简述
- JSON(JavaScript Object Notation) JavaScript对象表示法(JSON源于JS)。
- JSON的特点:
- JSON 是一种轻量级的数据交换格式。
- SON采用完全独立于语言的文本格式,就是说不同的编程语言JSON数据是一致的。
- JSON易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。
4.2 XML与JSON的区别
- XML : 可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言。
- JSON: (JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。
相同点:
- 它们都可以作为一种数据交换格式。
二者区别:
- XML是重量级的,JSON是轻量级的,XML在传输过程中比较占带宽,JSON占带宽少,易于压缩。
- XML和json都用在项目交互下,XML多用于做配置文件, JSON用于数据交互
- JSON独立于编程语言存在,任何编程语言都可以去解析json
4.3 JSON语法格式
{
"id": 110,
"name": "李会长",
"age": 24
}
语法注意:
- 外面由{}括起来
- 数据以"键:值"对的形式出现(其中键多以字符串形式出现,值可取字符串,数值,甚至其他json
对象) - 每两个"键:值"对以逗号分隔(最后一个"键:值"对省略逗号
- 参数值如果是string类型,就必须加引号,如果是数字类型,引号可加可不加
4.4 JSON数据的转换
4.4.1 FastJson介绍
Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。
FastJson特点如下:
- 能够支持将java bean序列化成JSON字符串,也能够将JSON字符串反序列化成Java bean。
- 顾名思义,FastJson操作JSON的速度是非常快的。
- 无其他包的依赖, 使用比较方便。
4.4.2 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>
4.4.3 将 Java 对象转换为 JSON 格式
- 可以使用 JSON.toJSONString() 将 Java 对象转换换为 JSON 对象:
- Fastjson中的 @JSONField 注解
通过 @JSONField 我们可以自定义字段的名称进行输出,并控制字段的排序,还可以进行序列化标记。- 指定name属性, 字段的名称
- 使用 ordinal属性, 指定字段的顺序
- 使用 serialize属性, 指定字段不序列化
4.4.4 JSON 字符串转换为 Java 对象
-
JSON.parseObject()
- 可以使用 JSON.parseObject() 将 JSON 字符串转换为 Java 对象。
- 注意反序列化时为对象时,必须要有默认无参的构造函数,否则会报异常
-
JSON.parseArray()
- 可以使用 JSON.parseArray() 将 JSON 字符串转换为 集合对象。