? 拉钩教育后台管理系统,是提供给拉钩教育的相关业务人员使用的一个后台管理系统, 业务人员可以在这个后台管理系统中,对课程信息、讲师信息、 学员信息等数据进行维护.
? 为了巩固同学们对 web阶段的技术的理解,提高同学们综合运用技术的能力, 接下来会带领同学们去完成拉钩教育后台管理系统中的课程管理模块.
打开产品需求文档,我们一起去看一下课程管理模块中都包含哪些内容:
? 前后端分离已成为互联网项目开发的业界标准使用方式,将前端和后端的开发进行解耦。并且前后端分离会为以后的大型分布式架构、微服务架构、多端化服务(各种客户端,比如浏览器、车载终端、安卓、IOS等)打下坚实的基础。
前后端分离的核心思想就是前端HTML页面通过AJAX调用后端的API接口,并通过JSON数据进行交互。
? 在我们的项目中使用的是前后端分离开发方式,需要由前后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发,到项目结束前都要一直进行接口文档的维护。
一个接口的描述至少包括下面几项:
名称: findCourseList
描述: 根据条件查询课程信息
请求方式: GET
请求参数
methodName:"findCourseList";
响应结果
{
"status": "0",
"msg": "success"
}
? 这种方式中 Java程序员又当爹又当妈,又搞前端,又搞后端。 正所谓术业有专攻,一个人如果什么都会,那么他肯定也什么都不精.
? Maven是一个跨平台的项目管理工具。作为Apache组织的一个颇为成功的开源项目,其主要服务于基于Java平台的项目创建,依赖管理和项目信息管理。maven是Apache的顶级项目,解释为“专家,内行”,它是一个项目管理的工具,maven自身是纯java开发的,可以使用maven对java项目进行构建、依赖管理。
src
存放Java源码, resources
存放配置文件,还要配置环境比如JDK的版本等等,如果有多个项目 那么就需要每次自己搞一套配置,十分麻烦使用 Maven 管理工具,我们首先要到官网去下载它的安装软件。
http://maven.apache.org/download.cgi
目前最新版是 apache-maven-3.6.3 版本
Maven 下载后,将 Maven 解压到一个没有中文没有空格的路径下,比如:H:\software\maven 下面。 解压后目录结构如下:
2.将MAVEN_HOME 添加到Path系统变量
通过 mvn -v命令检查 maven 是否安装成功,看到 maven 的版本为 3.6.3 及 java 版本为 jdk-11 即为安装 成功。 打开命令行,输入 mvn –v命令,如下图:
maven仓库默认是在 C盘 .m2 目录下,我们不要将仓库放在C盘,所以这里同学们要重新配置一下.
为了方便同学们的使用,老师为大家提供了一个本地仓库,将 “repository.rar”解压至自己的 电脑上,我解压在 H:\software\repository 目录下(注意最好放在没有中文及空格的目录下)。
3.在maven安装目录中,进入 conf文件夹, 可以看到一个
settings.xml 文件中, 我们在这个文件中, 进行本地仓库的配置
4.打开 settings.xml文件,进行如下配置如下:
Maven默认的远程仓库是在国外, 所以下载jar包时速度会非常慢, 这里推荐大家使用我大天朝的阿里云仓库
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>
http://maven.aliyun.com/nexus/content/groups/public/
</url>
<mirrorOf>central</mirrorOf>
</mirror>
2.起名为web_work
3.首先打开IDEA 选择File --> Settings --> 搜素maven,就会看到如下界面
4.修改默认配置配置
在IDEA中配置好maven后, 接下来我们使用maven去快速的去构建一个 JavaWeb项目
2.选中创建一个 maven 工程
3.点击 Next填写项目信息
进行一下修改
4.创建好的工程,长这个样子
Maven目录说明:
src/main/java —— 存放项目的.java 文件
src/main/resources —— 存放项目资源文件,如数据库的配置文件
src/test/java —— 存放所有单元测试.java 文件,如 JUnit 测试类
target —— 项目输出位置,编译后的class 文件会输出到此目录
pom.xml ——maven 项目核心配置文件
当前创建的maven项目是一个 普通的Java项目,不是web项目,我们要进行一下改造
3.修改路径信息
修改前
4.修改为 我们的 webapp目录
修改后
5.点击ok 后,项目就变为了web项目, 在webapp目录下再创建一个 index.jsp,就OK了
一个 maven 工程都有一个 pom.xml 文件,通过 pom.xml 文件定义项目的信息、项目依赖、引入插件等等。
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>
</dependency>
</dependencies>
</project>
groupId
,artifactId
和 version
作为唯一标识, 我们在引用其他第三方库的时候,也是通过这3个变量确定。坐标的概念
Maven坐标主要组成(GAV) - 确定一个jar在互联网位置
4.maven 的依赖管理, 是对项目所依赖的 jar 包进行统一管理。
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
添加依赖需要指定依赖 jar 包的坐标,但是很多情况我们是不知道 jar 包的的坐标,可以通过如下方 式查询:
从网站中搜索即可
5.1) 输入网址,进入网址 , 进行查询
https://mvnrepository.com/
5.2) 点击进入后,可以看到各个版本的信息,选择3.1.0
本教程使用 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>
<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>
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>
3.运行项目, 默认访问 index.jsp
http://localhost:8080/hello_maven/demo01
? 使用 maven 完成项目的构建,项目构建包括:清理、编译、测试、部署等过程,maven 将这些 过程规范为一个生命周期,如下所示是生命周期的各各阶段:
maven 通过执行一些简单命令即可实现上边生命周期的各个过程
3.工具栏介绍
1.根据pom.xml文件重新导入所有Maven项目和依赖,刷新
2.创建源码(重新编译)并更新目录
3.下载源码或文档
4.添加Maven项目
5.执行生命周期中的阶段,选中lifecycle选项中生命周期中的一个阶段(phase),才能点击执行。
6.运行Maven生命周期或插件
7.切换离线模式,就是关闭和远程仓库的链接,从本地仓库中获取,也不能将jar包提交到远程仓库
8.是否跳过测试,点击选中就可以跳过测试,在点击选择取消跳过测试
9.展示当前选中的maven项目jar包的依赖,并且可以直接在图形化依赖图上进行排除依赖操作
10.收起下面展开的视图
11.跳转到maven的Setting页面
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>
? 在本次的项目中,主要完成拉钩教育后台管理系统的 课程管理模块, 课程管理模块包含了添加课程,配置课程相关信息, 以及管理课程章节等功能,我们来一起看一下产品的原型图
在资料中找到 lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入数据库及表
使用Maven快速构建工程, 项目名为: lagou_edu_home
2.填写项目相关信息,创建maven项目
详见 2.4.3 Maven工程改造
<?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>
1) Lombok介绍
在项目中使用Lombok可以减少很多重复代码的书写。比如说getter/setter/toString等方法的编写。
2) IDEA中安装 lombok插件
打开IDEA的Setting –> 选择Plugins选项 –> 搜索lombok –> 点击安装 –> 安装完成重启IDEA
3) 添加依赖
在项目中添加Lombok依赖jar,在pom文件中添加如下部分
<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) 导入表对应的实体类
? 每个模块下都有很多的功能, 比如课程模块 的 新建课程, 上架课程,下架课程,根据课程名查询等等功能 , 每一个功能都是一个Servlet.
我们使用一个Servlet对应一个模块的方式进行开发
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%-- 一个模块对应一个Servlet --%>
<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("根据课程名称查询");
}
}
我们可以使用反射去对代码进行优化, 提升代码的可维护性/可扩展性.
反射的知识回顾:
? 第一步:先获取请求携带的方法参数值
? 第二步:获取指定类的字节码对象
? 第三步:根据请求携带的方法参数值,再通过字节码对象获取指定的方法
? 第四步:最后执行指定的方法
/**
* 模拟课程模块 ,模块中有很多功能
* */
@WebServlet("/test")
public class TestServlet extends HttpServlet {
/**
* doGet()方法作为调度器 控制器,根据请求的功能不同,调用对应的方法
*
* */
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//1.获取参数
//获取要调用的方法名
String methodName = req.getParameter("methodName");
//2.业务处理
if(methodName != null){
//通过反射优化代码,提升代码的可维护性
//1.获取字节码对象 this = TestServlet对象
Class c = this.getClass();
//2.根据传入的方法名, 获取对应方法对象,执行方法即可
Method method = c.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//3.调用Method对象的 invoke()方法,执行对应的功能
method.invoke(this,req,resp);
}
} catch (Exception e) {
System.out.println("请求的功能不存在! !");
e.printStackTrace();
}
}
@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都需要写一份相同的反射代码
解决方案:
? 将反射相关的代码抽取到一个类中 BaseServlet, 让BaseServlet去继承HTTPServlet
public class BaseServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//1.获取参数
//获取要调用的方法名
String methodName = req.getParameter("methodName");
//2.业务处理
if(methodName != null){
//通过反射优化代码,提升代码的可维护性
//1.获取字节码对象 this = TestServlet对象
Class c = this.getClass();
//2.根据传入的方法名, 获取对应方法对象,执行方法即可
Method method = c.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//3.调用Method对象的 invoke()方法,执行对应的功能
method.invoke(this,req,resp);
}
} catch (Exception e) {
System.out.println("请求的功能不存在! !");
e.printStackTrace();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
@WebServlet("/test")
public class TestServlet extends BaseServlet {
/**
* 在模块对应的Servlet中只保留 业务相关代码
* 当有请求访问到 TestServlet时, 发现没有doGet和doPost方法,就回去父类中找,从而执行BaseServlet中的
* doGet方法
* */
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("根据课程名称查询");
}
}
JSON(JavaScript Object Notation) JavaScript对象表示法(JSON源于JS)。
JSON的特点:
XML : 可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言。
JSON: (JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。
相同点:
二者区别:
XML是重量级的,JSON是轻量级的,XML在传输过程中比较占带宽,JSON占带宽少,易于压缩。
XML和json都用在项目交互下,XML多用于做配置文件,JSON用于数据交互
JSON独立于编程语言存在,任何编程语言都可以去解析json
我们先来看一下JSON数据:
{
"id": 110,
"name": "李会长",
"age": 24
}
语法注意:
遵守上面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>
目前, 前后端的ajax通讯几乎用的都是json格式的了,所以在开发的过程中,我们经常会涉及到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>
public class Person {
private String username;
private int age;
private String birthday;
get/set
}
public class TestFastJSON {
//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":"小斌"}]
}
}
@Data
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;
}
}
//JSON转Java对象
@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);
}
原文:https://www.cnblogs.com/china-soldier/p/15221019.html