java之学习记录 5 - 1 - 模拟拉勾项目介绍与后台系统搭建

项目架构(此文章只供个人学习的记录)

1 项目介绍

  • 拉勾教育后台管理系统,是提供给拉勾教育的相关业务人员使用的一个后台管理系统, 业务人员可以在这个后台管理系统中,对课程信息、讲师信息、 学员信息等数据进行维护.
  • 为了巩固自身对 web阶段的技术的理解,提高自身综合运用技术的能力, 接下来会带领同学们去完成拉勾教育后台管理系统中的课程管理模块.

2 模块介绍

 
打开产品需求文档 , 我们一起去看一下课程管理模块中都包含哪些内容 :
  • 1. 课程信息页面展示
  • 2. 课程营销信息配置
  • 3. 配置课时( 即课程内容管理)

3 前后端分离开发

3.1 前后端分离架构介绍
  • 前后端分离已成为互联网项目开发的业界标准使用方式,将前端和后端的开发进行解耦。并且前后端分离会为以后的大型分布式架构、微服务架构、多端化服务(各种客户端,比如浏览器、车载终端、安卓、IOS等)打下坚实的基础。
  • 前后端分离的核心思想就是前端HTML页面通过AJAX调用后端的API接口,并通过JSON数据进行交互。

3.2 接口文档

3.2.1 什么是接口文档?
  • 在我们的项目中使用的是前后端分离开发方式,需要由前后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发,到项目结束前都要一直进行接口文档的维护。
3.2.2 为什么要写接口文档?
  • 1. 项目开发过程中前后端工程师有一个统一的文件进行沟通交流,并行开发
  • 2. 项目维护中或者项目人员更迭,方便后期人员查看、维护
3.2.3 接口规范是什么?
 
一个接口的描述至少包括下面几项 :
  • 名称: findCourseList
  • 描述: 根据条件查询课程信息
  • URL: http://localhost:8080/lagou_edu_home/course/
  • 请求方式: GET
  • 请求参数:methodName:"findCourseList";
  • 响应结果
{ "status": "0", "msg": "success" }

3.3 前后端分离架构的优势

3.3.1 前后端耦合的开发方式
  • 这种方式中 Java程序员又当爹又当妈,又搞前端,又搞后端。 正所谓术业有专攻,一个人如果什么都会,那么他肯定也什么都不精.

3.3.2 前后端耦合的缺陷 ( JSP 为例 )
  • 1. UI出好设计图之后,前端开发工程师只负责将设计图切成HTML,需要由Java开发工程师来将HTML套成JSP页面,修改问题的时候需要双方协同开发,效率低下。
  • 2. JSP页面必须要在支持JavaWEB服务器上运行(如TomcatJetty等),无法使用Nginx等(官方宣称单实例HTTP并发高达5W),性能提升不上来。
  • 3. 第一次请求JSP,必须要在WEB服务器中编译成Servlet,第一次运行会较慢。 之后的每次请求JSP都是访问Servlet再用输出流输出的HTML页面,效率没有直接使用HTML
3.3.3 前后端分离的开发方式 前端技术
3.3.4 前后端分离的优势
  • 1. 前后端分离的模式下,如果发现Bug,可以快速定位是谁的问题,不会出现互相踢皮球的现象
  • 2. 前后端分离可以减少后端服务器的并发/负载压力。除了接口以外的其他所有HTTP请求全部转移到前端Nginx上,接口的请求则转发调用Tomcat.
  • 3. 前后端分离的模式下,即使后端服务器暂时超时或宕机了,前端页面也会正常访问,只不过数据刷不出来而已。
  • 4. 前后端分离会更加合理的分配团队的工作量,减轻后端团队的工作量,提高了性能和可扩展性。

4 技术选型

4.1 前端技术选型
前端技术
说明
Vue.js
是一套用于构建用户界面的渐进式 JavaScript 框架
Element UI
element-ui 是饿了么前端出品的基于 Vue.js 的 后台组件库,方便程序员进行页面快速布局和构建
node.js
简单的说 Node.js 就是运行在服务端的 JavaScript 运行环境 .
axios
ajax 的封装 , 简单来说就是 ajax 技术实现了局部数据的刷新, axios 实现了对ajax的封装,
4.2 后端技术选型 后端技术
后端技术
说明
Web
a) Servlet :前端控制器
b) Filter :过滤器
c) BeanUtils :数据封装
Service
a) 业务处理
dao
a) Mysql :数据库
b) Druid :数据库连接池
c) DBUtils: 操作数据库

1.5 项目开发环境

  • 开发工具
    • 后端: IDEA 2019
    • 前端: VS code
    • 数据库: SQLYog
  • 开发环境
    • JDK 11
    • Maven 3.6.3
    • MySQL 5.7

Maven 项目管理工具

1 Maven介绍

1.1 什么是 Maven
  • Maven是一个跨平台的项目管理工具。作为Apache组织的一个颇为成功的开源项目,其主要服务于基于Java平台的项目创建,依赖管理和项目信息管理。mavenApache的顶级项目,解释为专家,内,它是一个项目管理的工具,maven自身是纯java开发的,可以使用mavenjava项目进行构建、依赖管理。
1.2 Maven 的作用
  • 依赖管理
    • 依赖指的就是是 我们项目中需要使用的第三方Jar, 一个大一点的工程往往需要几十上百个Jar,按照我们之前的方式,每使用一种Jar,就需要导入到工程中,还要解决各种Jar冲突的问题.
    • Maven可以对Jar包进行统一的管理,包括快速引入Jar,以及对使用的 Jar包进行统一的版本控
  • 一键构建项目
    • 之前我们创建项目,需要确定项目的目录结构,比如 src 存放Java源码, resources 存放配置文,还要配置环境比如JDK的版本等等,如果有多个项目 那么就需要每次自己搞一套配置,十分麻
    • Maven为我们提供了一个标准化的Java项目结构,我们可以通过Maven快速创建一个标准的Java项目.

2 Maven 的使用

2.1 Maven 软件的下载
 
使用 Maven 管理工具,我们首先要到官网去下载它的安装软件。
 
2.2 Maven 软件的安装
 
Maven 下载后,将 Maven 解压到一个没有中文没有空格的路径下,比如 :H:\software\maven 下面。
解压后目录结构如下:
 
  • 1. bin:存放了 maven 的命令
  • 2. boot:存放了一些 maven 本身的引导程序,如类加载器等
  • 3. conf:存放了 maven 的一些配置文件,如 setting.xml 文件
  • 4. lib:存放了 maven 本身运行所需的一些 jar
2.3 Maven 环境变量配置
  • 1) 配置 MAVEN_HOME ,变量值就是你的 maven 安装的路径(bin 目录之前一级目录)

  • 2) MAVEN_HOME 添加到Path系统变量

2.4 Maven 软件版本测试
  • 通过 mvn -v命令检查 maven 是否安装成功,看到 maven 的版本为 3.6.3 java 版本为 jdk-11 即为安装成功。 打开命令行,输入 mvn –v命令,如下图:

Maven 仓库

  • Maven中的仓库是用来存放maven构建的项目和各种依赖的(Jar)
1 Maven 的仓库分类
  • 本地仓库: 位于自己计算机中的仓库, 用来存储从远程仓库或中央仓库下载的插件和 jar 包,
  • 远程仓库: 需要联网才可以使用的仓库,阿里提供了一个免费的maven 远程仓库。
  • 中央仓库: maven 软件中内置一个远程仓库地址 http://repo1.maven.org/maven2 ,它是中央仓库,服务于整个互联网,它是由 Maven 团队自己维护,里面存储了非常全的 jar 包,它包 含了世界上大部分流行的开源项目构件

2 Maven 本地仓库的配置
  • 1) maven仓库默认是在 C .m2 目录下,我们不要将仓库放在C,所以这里要重新配置一下.
  • 2) 为了方便使用,我提供了一个本地仓库,将 “repository.rar”解压至自己的电脑上,我解压在 H:\software\repository 目录下(注意最好放在没有中文及空格的目录下)。

  • 2) maven安装目录中,进入 conf文件夹, 可以看到一个 settings.xml 文件中, 我们在这个文件中, 进行本地仓库的配置

  • 3) 打开 settings.xml文件,进行如下配置如下:

3.3 配置阿里云远程仓库
  • Maven默认的远程仓库是在国外, 所以下载jar包时速度会非常慢, 这里推荐大家使用阿里云仓库
  • 1) 打开 settings.xml,找到 标签 , 下面的内容复制到 中 即可
<mirror> 
    <id>alimaven</id> 
    <name>aliyun maven</name> 
    <url>http://maven.aliyun.com/nexus/content/groups/public/ </url>        
    <mirrorOf>central</mirrorOf>
</mirror>

4 创建Maven项目

4.1 IDEA 中配置 Maven
  • 1) 打开IDEA 创建一个新的project

  • 2) 起名为web_work(我这里的名字)

  • 3) 首先打开IDEA 选择File --> Settings --> 搜素maven,就会看到如下界面

  • 4) 修改默认配置配置

4.2 创建 Maven 工程
 
IDEA 中配置好 maven , 接下来使用 maven 去快速的去构建一个 JavaWeb 项目
  • 1) project创建好以后, 选择创建module

  • 2) 选中创建一个 maven 工程

  • 3) 点击 Next填写项目信息

进行一下修改
  • 4) 创建好的工程,长这个样子

Maven 目录说明 :
src/main/java —— 存放项目的.java 文件 
src/main/resources —— 存放项目资源文件,如数据库的配置文件 
src/test/java —— 存放所有单元测试.java 文件,如 JUnit 测试类 
target —— 项目输出位置,编译后的class 文件会输出到此目录 
pom.xml ——maven 项目核心配置文件

4.3 Maven工程改造

当前创建的maven项目是一个 普通的Java项目,不是web项目,要进行一下改造

  • 1) main目录下创建一个webapp文件夹

  • 2) 选择 project Structure ---> facets---> 点击+号 添加web ---> 选择当前工程hello_maven
  • 3) 修改路径信息

修改前:

  • 4)修改为 我们的 webapp目录
修改后
  • 5) 点击ok 后,项目就变为了web项目, webapp目录下再创建一个 index.jsp,OK

4.4 pom 核心配置文件
 
一个 maven 工程都有一个 pom.xml 文件,通过 pom.xml 文件定义项目的信息、项目依赖、引入插 件等等。
  • 1) 创建一个Servlet, 缺少jar包报错, 要解决问题,就是要将 servlet-api-xxx.jar 包放进来,作为 maven工程应当添加 servlet的坐标,从而导入它的 jar

  • 2) 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>hello_maven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 引入依赖包的坐标  -->
    <dependencies>
        <dependency>
            <!--组织或者公司的名称-->
            <groupId>javax.servlet</groupId>
            <!--实际项目的名称-->
            <artifactId>servlet-api</artifactId>
            <!--项目的版本-->
            <version>3.1.0</version>
            <!--指定依赖范围 -->
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>
  • 3) 一个Maven工程就是由 groupId artifactId version 作为唯一标识, 我们在引用其他第三方库的时候,也是通过这3个变量确定。
    • 坐标的概念
      • 在maven中坐标就是为了定位一个唯一确定的jar包。
      • maven世界拥有大量构建,我们需要找一个用来唯一标识一个构建的统一规范,拥有了统一规范,就可以把查找工作交给机器
    • Maven坐标主要组成(GAV) - 确定一个jar在互联网位置
标签
含义
groupId
定义当前 Maven 组织名称 , 通常是公司名
artifactId
定义实际项目名称
version
定义当前项目的当前版本
packaging
打包类型
jar :执行 package 会打成 jar
war :执行 package 会打成 war
dependency
使用 <dependency> 声明一个依赖后, Maven 就会自动下载这个依赖包
  • 4) maven 的依赖管理, 是对项目所依赖的 jar 包进行统一管理。
标签
含义
dependencies
表示依赖关系
dependency
使用 <dependency> 声明一个依赖后, Maven 就会自动下载这个依赖包
<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>
  • 5) 坐标的来源方式
添加依赖需要指定依赖 jar 包的坐标,但是很多情况我们是不知道 jar 包的的坐标,可以通过如下方式查询:从网站中搜索即可

  • 5.2) 点击进入后,可以看到各个版本的信息,选择3.1.0

4.5 添加插件
  • 1) 添加编译插件, 设置 jdk 编译版本
本教程使用 jdk11 ,需要设置编译版本为 11 ,这里需要使用 maven 的插件来设置
pom 中加入如下配置 :
 <!-- 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>

    <!-- 在build中 我们需要指定一下项目的JDK编译版本,maven默认使用1.5版本进行编译 注意 build 与 dependencies是平级关系,标签不要写错位置 -->
    <build>
        <!--    maven编译插件    -->
        <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>
4.6 运行 Maven 项目
  • 1) 完善项目代码
ServletDemo01
@WebServlet("/demo01")
public class ServletDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("hello maven!!!");
    }

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

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>这是我的第一个maven工程</h1>
</body>
</html>
  • 2) 配置tomcat ,部署项目

  • 3) 运行项目, 默认访问 index.jsp

  • 4) 访问Servlet
http://localhost:8080/hello_maven/demo01
4.7 Maven 的常用命令
  • 1) 一个maven项目生命周期
使用 maven 完成项目的构建,项目构建包括:清理、编译、测试、部署等过程, maven 将这些过程规范为一个生命周期,如下所示是生命周期的各各阶段:
maven 通过执行一些简单命令即可实现上边生命周期的各个过程
命令
说明
mvn compile
完成编译操作 , 执行完毕后,会生成 target 目录,该目录中存放了编译后的字节码文件。
mvn clean
执行完毕后,会将 target 目录删除 .
mvn test
执行完毕后,会在 target 目录中生成三个文件夹:
surefire surefire-reports (测试报告)、 test-classes (测试的字节码文件)
mvn package
完成打包操作 , 执行完毕后,会在 target 目录中生成一个文件,该文件可能是 jar、 war
mvn install
执行 mvn install 命令,完成将打好的 jar 包安装到本地仓库的操作 ,
执行完毕后,会在本地仓库中出现安装后的 jar 包,方便其他工程引用
  • 2) idea中安装好maven, 在界面左侧有一个maven视图, 里面有对应的命令插件,可以执行上面表格中的命令

  • 3) 工具栏介绍

  • 1.根据pom.xml文件重新导入所有Maven项目和依赖,刷新
  • 2.创建源码(重新编译)并更新目录
  • 3.下载源码或文档
  • 4.添加Maven项目
  • 5.执行生命周期中的阶段,选中lifecycle选项中生命周期中的一个阶段(phase),才能点击执行。
  • 6.运行Maven生命周期或插件
  • 7.切换离线模式,就是关闭和远程仓库的链接,从本地仓库中获取,也不能将jar包提交到远程仓库
  • 8.是否跳过测试,点击选中就可以跳过测试,在点击选择取消跳过测试
  • 9.展示当前选中的maven项目jar包的依赖,并且可以直接在图形化依赖图上进行排除依赖操作
  • 10.收起下面展开的视图
  • 11.跳转到mavenSetting页面
4.8 依赖范围介绍
  • 1) A 依赖 B,需要在 A pom.xml 文件中添加 B 的坐标,添加坐标时需要指定依赖范围,依赖范围包括:
依赖范围
说明
compile
编译范围,指 A 在编译时依赖 B ,此范围为默认依赖范围。编译范围的依赖会用在编译、测试、运行,由于运行时需要所以编译范围的依赖会被打包。
provided
provided 依赖只有在当 JDK 或者一个容器已提供该依赖之后才使用, provided 依赖在编译和测试时需要,在运行时不需要,比如:servlet api tomcat 容器提供。
runtime
runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如: jdbc的驱动包。由于运行时需要所以 runtime 范围的依赖会被打包。
test
test 范围依赖 在编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用, 比如:junit 。由于运行时不需要所以 test 范围依赖不会被打包。
system
system 范围依赖与 provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径,需要指定 systemPath 磁盘路径, system 依赖不推荐使用。
  • 2) 项目中添加的坐标 ,并指定依赖范围
    <dependencies>
        <dependency> 
            <!-- 项目名称 -->
            <groupId>javax.servlet</groupId> 
            <!-- 模块名称 -->
            <artifactId>servlet-api</artifactId> 
            <!-- 版本信息 -->
            <version>3.1.0</version> 
            <!-- 依赖范围, 指定依赖范围是编译与测试时有效,运行时无效,运行时使用tomcat中的依赖,避 免冲突 -->
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1.2</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version> 
            <!-- 在测试时有效 -->
            <scope>test</scope>
        </dependency>
    </dependencies>

后台系统搭建

1 课程管理模块功能分析

  • 在本次的项目中,主要完成拉钩教育后台管理系统的 课程管理模块, 课程管理模块包含了添加课程,配置课程相关信息, 以及管理课程章节等功能,我们来一起看一下产品的原型图
1.1 课程管理
  • 实现以下功能:
    • 展示课程列表
    • 根据课程名和状态进行查询
    • 新建课程
    • 课程上架与下架

1.2 营销信息
  • 营销信息,其实就是设置课程的详细信息
    • 回显课程信息
    • 修改课程信息,包含了图片上传

3.1.3 配置课时
  • 配置课时指的是对课程下所属的章节与课时进行配置(一个课程对应多个章节,一个章节有多个课时)
    • 以树形结构的下拉框形式, 展示课程对应的章节与课时信息
    • 添加章节功能
    • 修改章节功能
    • 修改章节状态功能

2 课程管理模块表设计

2.1 创建数据库及表 ( 表关系介绍)

3 环境搭建

3.1 创建项目
 
使用 Maven 快速构建工程 , 项目名为 : lagou_edu_home
 
  • 1) 选择maven ,直接next

  • 2) 填写项目相关信息,创建maven项目

  • 3) 当前maven项目还不是 一个web项目,进行一下改造
    • 详见 Maven下4.3 Maven工程改造
3.2 项目目录
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.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>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>
        <!--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>
3.4 导入工具类及配置文件
  • 1) 导入连接池工具类以及数据库配置文件

3.5 导入实体类
  • 1) Lombok介绍
    • 在项目中使用Lombok可以减少很多重复代码的书写。比如说getter/setter/toString等方法的编写。
  • 2) IDEA中安装 lombok插件
    • 打开IDEASetting –> 选择Plugins选项 –> 搜索lombok –> 点击安装 –> 安装完成重启IDEA

  • 3) 添加依赖
    • 在项目中添加Lombok依赖jar,在pom文件中添加如下部分(3.3 导入pom.xml已经包含
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.0</version>
    <scope>provided</scope>
</dependency>
  • 4) Lombok常用注解
    • @Getter/@Setter: 作用类上,生成所有成员变量的getter/setter方法
    • @ToString : 作用于类,覆盖默认的toString()方法 ,可以通过of属性限定显示某些字段,通过exclude属性排除某些字段
    • @AllArgsConstructor:生成全参构造器
    • @NoArgsConstructor:生成无参构造器
    • @Data: 该注解使用在上,该注解会提供 getter setter equals hashCode toString 方法。
  • 5) 导入表对应的实体类(四张表对应四个类,表中字段对应类中的自定义名称)

4 通用Servlet

4.1 需求分析
  • 课程模块下有两个子模块:
    • 课程模块
      • 营销信息
      • 配置课时(课程内容管理)
每个模块下都有很多的功能 , 比如课程模块 的 新建课程 , 上架课程 , 下架课程 , 根据课程名查询等等功 , 每一个功能都是一个 Servlet.
  • 问题: 一个功能就是一个Servlet, 那么一个项目下有海量的Servlet, 这种方式好吗 ?
    • Servlet太多了,不好管理, 而且Servlet越多 服务器运行就越慢,资源消耗就越多.
4.2 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("根据课程名称查询"); 
    } 
}

4.3 提高代码的可维护行

  • 我们可以使用反射去对代码进行优化, 提升代码的可维护性/可扩展性.

  • 反射的知识回顾:
    • 第一步:先获取请求携带的方法参数值
    • 第二步:获取指定类的字节码对象
    • 第三步:根据请求携带的方法参数值,再通过字节码对象获取指定的方法
    • 第四步:最后执行指定的方法

将反射相关的代码抽取到一个类中 BaseServlet, BaseServlet去继承HTTPServlet

BaseServlet

package com.lagou.base;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

public class BaseServlet extends HttpServlet {
    /**
     * doGet方法作为一个调度器 根据请求功能的不同,调用对应的方法
     *  规定必须传递一个参数
     *  methodName=功能名
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取参数 要访问的方法名
        String methodName = req.getParameter("methodName");
        // 判断执行对应的方法
        if (methodName != null){
            // 通过反射优化代码 提升代码的可维护性 this = TestServlet
            try {
                Class aClass = this.getClass();
                // 根据传入的方法名,获取对应的方法对象
                // 获取字节码文件对象s
                Method method = aClass.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
                // 调用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);
    }
}
修改 TestServlet, 继承 BaseServlet
package com.lagou.web.servlet;

import com.lagou.base.BaseServlet;

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.lang.reflect.Method;

/**
 * 当前的Servlet对应的是课程管理模块
 */
@WebServlet("/test")
public class TestServlet extends BaseServlet {

    // 添加课程
    public void addCourse(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("新建课程");
    }

    // 根据课程名查询课程
    public void findByName(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根据课程名进行查询");
    }

    // 根据课程状态查询课程
    public void findByStatus(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根据课程状态查询");
    }
}

JSON

1 JSON简述

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

2 XMLJSON的区别

  • XML : 可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言。
  • JSON: (JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。
  • 相同点:
    • 它们都可以作为一种数据交换格式。
  • 二者区别:
    • XML是重量级的,JSON是轻量级的,XML在传输过程中比较占带宽,JSON占带宽少,易于压缩。
    • XMLjson都用在项目交互下,XML多用于做配置文件,JSON用于数据交互
    • JSON独立于编程语言存在,任何编程语言都可以去解析json
  • 3 JSON语法格式
我们先来看一下 JSON 数据:
{ "id": 110, "name": "李会长", "age": 24 }
语法注意:
  • 1. 外面由{}括起来
  • 2. 数据以"键:值"对的形式出现(其中键多以字符串形式出现,值可取字符串,数值,甚至其他json对象)
  • 3. 每两个"键:值"对以逗号分隔(最后一个"键:值"对省略逗号
  • 4. 参数值如果是string类型,就必须加引号,如果是数字类型,引号可加可不加
遵守上面 4 点,便可以形成一个 json 对象。
代码示例 :
<!DOCTYPE html>
<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)

        // 集合
        var list = [{"name":"劳务","sex":"女","age":12},{"name":"会长","sex":"女","age":12}];
        console.log(list)
    </script>
</head>
<body>

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

4.1 FastJson 介绍
  • Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换 Java 对象。
  • FastJson特点如下:
    • 能够支持将java bean序列化成JSON字符串,也能够将JSON字符串反序列化成Java bean
    • 顾名思义,FastJson操作JSON的速度是非常快的。
    • 无其他包的依赖, 使用比较方便。
4.2 FastJson 的使用
  • Maven项目中使用FastJson库,需要提前在Maven的配置文件中添加此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.2 Java 对象转换为 JSON 格式
  • 1) 定义一个名为 Person JavaBean
public class Person { 
    private String username; 
    private int age; 
    private String birthday; 

    //get/set 
}
  • 2) 可以使用 JSON.toJSONString() Java 对象转换换为 JSON 对象:
public class TestFastjson {
    // Java对象转换为json
    @Test
    public void javaBeanToJSON(){
        // 创建Person对象
        Person p = new Person("小马",25, DateUtils.getDateFormart());
        // 使用json对象将person对象转换为json数据
        String jsonString = JSON.toJSONString(p);
        System.out.println(jsonString);
    }

    // java中的集合转JSON
    @Test
    public void ListToJSON(){
        // 创建Person对象
        Person p = new Person("小马",25, DateUtils.getDateFormart());
        Person p1 = new Person("小马",25, DateUtils.getDateFormart());
        Person p2 = new Person("小马",25, DateUtils.getDateFormart());
        // 创建ArrayList集合
        List<Person> list = new ArrayList<>();
        // 将对象封装到集合
        Collections.addAll(list,p,p1,p2);
        // 使用json对象的toJSONString()方法
        String jsonString = JSON.toJSONString(list);
        System.out.println(jsonString);
    }

}
3) Fastjson 中的 @JSONField 注解
  • 通过 @JSONField 我们可以自定义字段的名称进行输出,并控制字段的排序,还可以进行序列化标记。
    • 指定name属性, 字段的名称
    • 使用 ordinal属性, 指定字段的顺序
    • 使用 serialize属性, 指定字段不序列化
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    // 可以通过 name 去指定输出的名称
    // 可以使用ordinal属性,指定字段的顺序
    // 使用serialize属性,指定字段是否序列化
    @JSONField(name = "USERNAME",ordinal = 1)
    private String username;
    @JSONField(name = "AGE",ordinal = 2)
    private int age;
    @JSONField(serialize = false)
    private String birthday;
}
4.3 JSON 字符串转换为 Java 对象
  • JSON.parseObject()
    • 可以使用 JSON.parseObject() JSON 字符串转换为 Java 对象。
    • 注意反序列化时为对象时,必须要有默认无参的构造函数,否则会报异常
  • JSON.parseArray()
    • 可以使用 JSON.parseArray() JSON 字符串转换为 集合对象。
public class TestFastjson {

    // JSON转对象
    @Test
    public void JSONToJavaBean(){
        String json = "{\"USERNAME\":\"小马\",\"AGE\":25}";
        // 使用JSON对象的parseObject()
        Person person = JSON.parseObject(json, Person.class);
        System.out.println(person);
    }

    // JSON转List集合
    @Test
    public void JSONToList(){
        String json = "[{\"USERNAME\":\"小马\",\"AGE\":25},{\"USERNAME\":\"小马\",\"AGE\":25},{\"USERNAME\":\"小马\",\"AGE\":25}]";
        // 使用parseArray()方法将json转换为集合
        List<Person> list = JSON.parseArray(json, Person.class);
        System.out.println(list);
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值