how2j.cn


39分59秒
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器

步骤 1 : IDEA 版本问题   
步骤 2 : 先运行,看到效果,再学习   
步骤 3 : 模仿和排错   
步骤 4 : 关于 SpringBoot 版本   
步骤 5 : 新建项目   
步骤 6 : 选中maven webapp格式   
步骤 7 : 项目参数   
步骤 8 : 依赖   
步骤 9 : 项目路径   
步骤 10 : Maven仓库   
步骤 11 : maven项目启动缓慢   
步骤 12 : 删除 TmallSpringbootApplication.java   
步骤 13 : pom.xml   
步骤 14 : Category.java   
步骤 15 : CategoryDAO.java   
步骤 16 : CategoryService.java   
步骤 17 : AdminPageController.java   
步骤 18 : CategoryController.java   
步骤 19 : Application.java   
步骤 20 : CORSConfiguration.java   
步骤 21 : GloabalExceptionHandler.java   
步骤 22 : TestTmall 测试数据   
步骤 23 : application.properties   
步骤 24 : 静态资源   
步骤 25 : listCategory.html   
步骤 26 : vue-cli   
步骤 27 : 测试地址   
步骤 28 : 可运行项目   
步骤 29 : 思路图   
步骤 30 : Redis,ElasticSearch 和 Shiro   
步骤 31 : 热部署问题   

步骤 1 :

IDEA 版本问题

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
注: IDEA 必须使用 IDEA 2017, 2018版本有BUG,无法部署本项目
如果一定要用idea 2018, 需要做如下修改:
File->Settings->Build,Execution,Deployment->Build Tools->Maven->Importing 取消 "Store generated project files externally"
这样才能用
步骤 2 :

先运行,看到效果,再学习

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
接下来就开始一步一步来,由浅入深地开发功能了。

因为项目用到了Springboot技术,Springboot 技术本身较为复杂,涉及到了多个框架、多个类、多个配置文件。 不仅如此,模仿天猫业务也较为复杂,所以在进行项目开发之前,一定要先按照 可运行的项目的指导,先下载右上角的可运行项目,配置运行起来, 先自己跑起来,确认项目本身没有问题,建立对学习内容的信心,然后再跟着步骤,一步步做出来。

十分不推荐一来就跟着步骤做下去,本知识点一共有20多个步骤,只要任何一个步骤,跟着做的时候写错了,都有可能导致项目无法成功启动,影响学习情绪和学习效果。 所以一定要先按照 可运行的项目的指导,先下载右上角的可运行项目,配置运行起来,成功跑起来,然后再照着教程,一个一个地做下去,这样出了问题心里才有底,通过代码比较等手段,定位到问题所在,成功消化掉这个知识点。
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。

推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。
这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来
这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
步骤 4 :

关于 SpringBoot 版本

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
本项目教程用的是 1.5.9.RELEASE, 现在已经有更新的 Springboot 2.x 版本了。
他们之间的用法大同小异,但是仍然有一些区别。

希望同学们先在 1.5.9.RELEASE 的基础上学习、掌握、熟练之后,如果还有兴趣,再自行切换到 2.x 版本上。
这里要强调的是,如果现在就切换成 2.x 版本了,并且运行站长当前 springboot 教材里的代码,会出现难以预料的错误,最后是给自己学习制造了障碍。
所以站长扯着嗓子破音连喊3句: 不要随意修改版本号!不要随意修改版本号!不要随意修改版本号!
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
点击Create New Project新建项目
新建项目
步骤 6 :

选中maven webapp格式

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
1. 左边选中Spring Initializr
2. Next
选中maven webapp格式
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
GroupId: com.how2java.tmall
Artifact: tmall_springboot
项目参数
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
1. 左边选中 Web
2. 右边选中 Web
依赖
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
项目路径选择

e:\project\tmall_springboot

然后点Finish
项目路径
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
天猫springboot项目会用到一系列的jar包,在右上角的.m2.rar 只有64m,里面包含了这个项目用到的jar包。 解压出来后,放在maven的仓库目录里。

通常来讲,maven 仓库的默认目录是:${user.home}/.m2/repository。
对应我的机器就是

C:\Users\X7TI\.m2\repository

把这些jar包复制进去,否则导入项目的时候,就要自己从网站上下载,会很花费时间的
步骤 11 :

maven项目启动缓慢

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
此时用的maven配置是idea自带的maven,默认仓库地址也是国外的,所以在启动maven项目的时候会比较卡。 解决办法请点击:idea 启动maven项目缓慢的解决办法
步骤 12 :

删除 TmallSpringbootApplication.java

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
首先删除 TmallSpringbootApplication.java 这个自动创建的类,并且把其包也删除掉。
删除掉后,就是如图所示的光秃秃的样子~
删除 TmallSpringbootApplication.java
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
复制如下内容到已经存在的pom里,如图所示,这个过程会导致idea去下载pom里声明的相关jar包,会花一定的时间,视网络和计算机性能而定。
此时会弹出如图所示的提醒,为了避免每次修改 pom.xml 都出现这个对话框,点击 "Enable Auto-Import"
为了确保导入成功,右键点击pom.xml->Maven->Reimport
pom.xml
<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.how2java.tmall</groupId> <artifactId>tmall_springboot</artifactId> <version>0.0.1-SNAPSHOT</version> <name>tmall_springboot</name> <description>tmall_springboot</description> <packaging>war</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent> <dependencies> <!-- springboot web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- springboot tomcat 支持 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <!-- 热部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- jpa--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- springboot test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- thymeleaf --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- elastic search --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <!-- 用了 elasticsearch 就要加这么一个,不然要com.sun.jna.Native 错误 --> <dependency> <groupId>com.sun.jna</groupId> <artifactId>jna</artifactId> <version>3.0.9</version> </dependency> <!-- thymeleaf legacyhtml5 模式支持 --> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version> </dependency> <!-- 测试支持 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- tomcat的支持.--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>8.5.23</version> </dependency> <!-- mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version> 4.12</version> </dependency> <!-- commons-lang --> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <!-- shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.3.2</version> </dependency> <!-- hsqldb --> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> </dependency> </dependencies> <properties> <java.version>1.8</java.version> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
首先新建包,菜单 -> File -> Package -> 然后输入

com.how2java.tmall.pojo

然后创建类 Category,接下来.讲解这个类。

@Entity

表示这是一个实体类

@Table(name = "category")

表示对应的表名是 category

@JsonIgnoreProperties({ "handler","hibernateLazyInitializer" })

因为是做前后端分离,而前后端数据交互用的是 json 格式。 那么 Category 对象就会被转换为 json 数据。 而本项目使用 jpa 来做实体类的持久化,jpa 默认会使用 hibernate, 在 jpa 工作过程中,就会创造代理类来继承 Category ,并添加 handler 和 hibernateLazyInitializer 这两个无须 json 化的属性,所以这里需要用 JsonIgnoreProperties 把这两个属性忽略掉。
Category.java
package com.how2java.tmall.pojo; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Entity @Table(name = "category") @JsonIgnoreProperties({ "handler","hibernateLazyInitializer" }) public class Category { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") int id; String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
步骤 15 :

CategoryDAO.java

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
Category.java 步骤里已经讲解过了如何创建包,这里就不讲解如何创建包,而是直接给出类了。
CategoryDAO 类继承了 JpaRepository,就提供了CRUD和分页 的各种常见功能。 这就是采用 JPA 方便的地方~
package com.how2java.tmall.dao; import org.springframework.data.jpa.repository.JpaRepository; import com.how2java.tmall.pojo.Category; public interface CategoryDAO extends JpaRepository<Category,Integer>{ }
package com.how2java.tmall.dao;
 
import org.springframework.data.jpa.repository.JpaRepository;

import com.how2java.tmall.pojo.Category;

public interface CategoryDAO extends JpaRepository<Category,Integer>{

}
步骤 16 :

CategoryService.java

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买

@Service

标记这个类是 Service类

@Autowired CategoryDAO categoryDAO;

自动装配 上个步骤的 CategoryDAO 对象

public List<Category> list() {
Sort sort = new Sort(Sort.Direction.DESC, "id");
return categoryDAO.findAll(sort);
}

首先创建一个 Sort 对象,表示通过 id 倒排序, 然后通过 categoryDAO进行查询。

注: 这里抛弃了 CategoryService 接口 加上 CategoryService 实现类的这种累赘的写法,而是直接使用 CategoryService 作为实现类来做。
package com.how2java.tmall.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import com.how2java.tmall.dao.CategoryDAO; import com.how2java.tmall.pojo.Category; @Service public class CategoryService { @Autowired CategoryDAO categoryDAO; public List<Category> list() { Sort sort = new Sort(Sort.Direction.DESC, "id"); return categoryDAO.findAll(sort); } }
package com.how2java.tmall.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.how2java.tmall.dao.CategoryDAO;
import com.how2java.tmall.pojo.Category;

@Service
public class CategoryService {
	@Autowired CategoryDAO categoryDAO;

	public List<Category> list() {
    	Sort sort = new Sort(Sort.Direction.DESC, "id");
		return categoryDAO.findAll(sort);
	}
}
步骤 17 :

AdminPageController.java

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
后台管理页面跳转专用控制器。
因为是做前后端分离,所以数据是通过 RESTFUL接口来取的,而在业务上,除了 RESTFUL 服务要提供,还要提供页面跳转服务,所以所有的后台页面跳转都放在 AdminPageController 这个控制器里。 而RSTFUL 专门放在 Category 对应的控制器 CategoryController.java 里面。 这样代码更清晰,不会搅起搅起的~

@Controller

表示这是一个控制器。

@GetMapping(value="/admin")
public String admin(){
return "redirect:admin_category_list";
}

访问地址 admin,就会客户端跳转到 admin_category_list去。

@GetMapping(value="/admin_category_list")
public String listCategory(){
return "admin/listCategory";
}

访问地址 admin_category_list 就会访问 admin/listCategory.html 文件。
package com.how2java.tmall.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class AdminPageController { @GetMapping(value="/admin") public String admin(){ return "redirect:admin_category_list"; } @GetMapping(value="/admin_category_list") public String listCategory(){ return "admin/listCategory"; } }
package com.how2java.tmall.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class AdminPageController {
	@GetMapping(value="/admin")
    public String admin(){
		return "redirect:admin_category_list";
    }
	@GetMapping(value="/admin_category_list")
	public String listCategory(){
		return "admin/listCategory";
	}
}
步骤 18 :

CategoryController.java

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
这个就是专门用来提供 RESTFUL 服务器控制器了

@RestController

表示这是一个控制器,并且对每个方法的返回值都会直接转换为 json 数据格式。

@Autowired CategoryService categoryService;

自动装配 CategoryService

@GetMapping("/categories")
public List<Category> list() throws Exception {
return categoryService.list();
}

对于categories 访问,会获取所有的 Category对象集合,并返回这个集合。 因为是声明为 @RestController, 所以这个集合,又会被自动转换为 JSON数组抛给浏览器。
package com.how2java.tmall.web; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.service.CategoryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class CategoryController { @Autowired CategoryService categoryService; @GetMapping("/categories") public List<Category> list() throws Exception { return categoryService.list(); } }
package com.how2java.tmall.web;

import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
 
@RestController
public class CategoryController {
	@Autowired CategoryService categoryService;
    
	@GetMapping("/categories")
    public List<Category> list() throws Exception {
    	return categoryService.list();
    }
}

步骤 19 :

Application.java

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
启动类,代替自动生成的 TmallSpringbootApplication.java
package com.how2java.tmall; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
package com.how2java.tmall;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; 
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
    	SpringApplication.run(Application.class, args);    	
    }
}
步骤 20 :

CORSConfiguration.java

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
配置类,用于允许所有的请求都跨域。
因为是二次请求,第一次是获取 html 页面, 第二次通过 html 页面上的 js 代码异步获取数据,一旦部署到服务器就容易面临跨域请求问题,所以允许所有访问都跨域,就不会出现通过 ajax 获取数据获取不到的问题了。
package com.how2java.tmall.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class CORSConfiguration extends WebMvcConfigurerAdapter{ @Override public void addCorsMappings(CorsRegistry registry) { //所有请求都允许跨域 registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .allowedHeaders("*"); } }
package com.how2java.tmall.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class CORSConfiguration extends WebMvcConfigurerAdapter{
	@Override
	public void addCorsMappings(CorsRegistry registry) {
		//所有请求都允许跨域
		registry.addMapping("/**")
				.allowedOrigins("*")
				.allowedMethods("*")
				.allowedHeaders("*");
	}
}
步骤 21 :

GloabalExceptionHandler.java

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
异常处理,主要是在处理删除父类信息的时候,因为外键约束的存在,而导致违反约束。
package com.how2java.tmall.exception; import javax.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestController; @RestController @ControllerAdvice public class GloabalExceptionHandler { @ExceptionHandler(value = Exception.class) public String defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { e.printStackTrace(); Class constraintViolationException = Class.forName("org.hibernate.exception.ConstraintViolationException"); if(null!=e.getCause() && constraintViolationException==e.getCause().getClass()) { return "违反了约束,多半是外键约束"; } return e.getMessage(); } }
步骤 22 :

TestTmall 测试数据

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
刚开始用的时候,数据库里是没有数据的。 这里使用 简单的 jdbc 代码插入10条数据。
注: 既然是Springboot 教程,为什么不用 jpa 创建测试数据,而要用JDBC创建? 因为增加功能要到下个知识点才讲啊。。。
TestTmall 测试数据
package com.how2java.tmall.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class TestTmall { public static void main(String args[]){ //准备分类测试数据: try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } try ( Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/tmall_springboot?useUnicode=true&characterEncoding=utf8", "root", "admin"); Statement s = c.createStatement(); ) { for (int i = 1; i <=10 ; i++) { String sqlFormat = "insert into category values (null, '测试分类%d')"; String sql = String.format(sqlFormat, i); s.execute(sql); } System.out.println("已经成功创建10条分类测试数据"); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
步骤 23 :

application.properties

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
springboot 配置文件,有些项目会用 application.yml ,站长习惯用 .properties ,觉得更易读。
下面是配置文件的内容:

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tmall_springboot?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto = none

分别是数据库访问地址,账号密码,驱动以及表结构自动生成策略(none)。


spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false

使用 thymeleaf 作为视图,这个是springboot 官方推荐视图,它的好处是可以是纯 html 。
其中LEGACYHTML5表示经典html5模式,即允许非严格的html出现,元素少点什么也可以编译通过, 这个比较符合大家的编写习惯,太过严格的html,写起来累。
cache=false 表示不要缓存,以免在开发过程中因为停留在缓存而给开发人员带来困扰。


server.context-path=/tmall_springboot

上下文地址为 tmall_springboot, 所以访问的时候,都要加上这个,比如:

http://127.0.0.1:8080/tmall_springboot/admin



spring.http.multipart.maxFileSize=100Mb
spring.http.multipart.maxRequestSize=100Mb

设置上传文件大小,默认只有1 m


spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

jpa对实体类的默认字段会把驼峰命名的属性,转换为字段名的时候自动加上下划线。 这个配置的作用就是去掉下划线
比如属性名称是 createDate, jpa 默认转换为字段名 create_Date。 有了这个配置之后,就会转换为同名字段 createDate


spring.jpa.show-sql=true

显示 hibernate 执行的sql语句。 这个在上线之后,应该是关掉的,因为大量的 控制台输出会严重影响系统性能。 但是呢,因为本项目会和 redis 和 es 整合,打印 sql 语句的目的是为了观察 缓存是否起效果。
application.properties
#database spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tmall_springboot?characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=admin spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.hibernate.ddl-auto = none #thymeleaf spring.thymeleaf.mode=LEGACYHTML5 spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.content-type=text/html spring.thymeleaf.cache=false #context server.context-path=/tmall_springboot #设置上传文件大小,默认只有1 m spring.http.multipart.maxFileSize=100Mb spring.http.multipart.maxRequestSize=100Mb spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl #显示 hibernate运行的 sql 语句 spring.jpa.show-sql=true
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
接下来是各种静态资源,诸如jquery, bootstrap, css, 图片,公用 html 等,内容稍杂,就不挨个列出来了。
这些静态资源打包在webapp.rar 里,被包含的文件打包在 include.rar里,放在右上角供下载,下载后解压即可,解压之后应该看到多出来如图所示的几个目录。

1. css,img,js目录是样式,图片脚本等文件
2. include/admin目录下是4个HTML 包含关系中讲解到的被包含文件

注: 如果目录不存在,比如 webapp目录, templates 目录不存在,请自行创建。
注: 静态资源为什么不放在 static 目录下? 一般说来,在约定里,springboot 的静态资源会在 static 目录下,但是我们是放在 webapp 目录下,为什么会这样呢? 因为我们还要做上传图片的功能,如果是放在 static 下,上传后的图片就无法被访问,还是放在 webapp 下,上传后,能够立即被访问。
静态资源
步骤 25 :

listCategory.html

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
接着在 templates 下面新建 admin目录,然后新建 listCategory.html 文件。
listCategory.html 看着复杂,其实没那么复杂,它其实就了两件事: 获取数据 和 展示数据
1. 获取数据

$(function(){
}

这个是jquery的代码,表示当整个html加载好了之后执行

var data4Vue = {
uri:'categories',
beans: []
};

vue用到的数据, uri表示访问哪个地址去获取数据,这里的值是 categories,和 CategoryController.java 相呼应


var vue = new Vue({
el: '#workingArea',
data: data4Vue,

创建Vue对象,el 表示和本页面的 <div id="workingArea" > 元素绑定,data 表示vue 使用上面的data4Vue对象。

mounted:function(){
this.list();
},

加载Vue对象成功之后会调用,成功的时候去调用 list() 函数。


methods: {
list:function(){
var url = this.uri;
axios.get(url).then(function(response) {
vue.beans = response.data;
});
}
}

list 函数使用 data4Vue里的 uri作为地址,然后调用 axios.js 这个 ajax库,进行异步调用。 调用成功之后,把服务端返回的数据,保存在 vue.beans 上。

2. 展示数据

<tr v-for="bean in beans ">

使用 v-for进行遍历, 这个 beans 就表示data4Vue里面的beans属性。

<td>{{bean.id}}</td>

bean就是遍历出来的每个id, 这里就是输出每个分类的id.

<a :href="'admin_property_list?cid=' + bean.id "><span class="glyphicon glyphicon-th-list"></span></a>

在超链里的href里拼接分类id.

如果不熟悉 Vue的用法,请学习 Vue.js 系列教材
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head th:include="include/admin/adminHeader::html('分类管理')" ></head> <body> <div th:replace="include/admin/adminNavigator::html" ></div> <script> $(function(){ var data4Vue = { uri:'categories', beans: [] }; //ViewModel var vue = new Vue({ el: '#workingArea', data: data4Vue, mounted:function(){ //mounted 表示这个 Vue 对象加载成功了 this.list(); }, methods: { list:function(){ var url = this.uri; axios.get(url).then(function(response) { vue.beans = response.data; }); } } }); }); </script> <div id="workingArea" > <h1 class="label label-info" >分类管理</h1> <br> <br> <div class="listDataTableDiv"> <table class="table table-striped table-bordered table-hover table-condensed"> <thead> <tr class="success"> <th>ID</th> <th>图片</th> <th>分类名称</th> <th>属性管理</th> <th>产品管理</th> <th>编辑</th> <th>删除</th> </tr> </thead> <tbody> <tr v-for="bean in beans "> <td>{{bean.id}}</td> <td> <img height="40px" :src="'img/category/'+bean.id+'.jpg'"> </td> <td> {{bean.name}} </td> <td> <a :href="'admin_property_list?cid=' + bean.id "><span class="glyphicon glyphicon-th-list"></span></a> </td> <td> <a :href="'admin_product_list?cid=' + bean.id "><span class="glyphicon glyphicon-shopping-cart"></span></a> </td> <td> <a :href="'admin_category_edit?id=' + bean.id "><span class="glyphicon glyphicon-edit"></span></a> </td> <td> <a href="#nowhere" @click="deleteBean(bean.id)"><span class=" glyphicon glyphicon-trash"></span></a> </td> </tr> </tbody> </table> </div> </div> <div th:replace="include/admin/adminFooter::html" ></div> </body> </html>
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
本站提供了 node.js webpack 和vue-cli的教程。
vue-cli
webpack
node.js
但是为什么项目里不使用 vue-cli 呢?
因为几个原因
1. vue-cli 更适合做单页面开发,本项目是复杂的多页面。 为了使得 vue-cli 支持多页面,需要做很复杂的风险高的配置工作。
2. 版本原因。 webpack 有一个深受广大开发人员诟病的地方,就是其不同版本之间的兼容性有非常大的问题,很多不同版本之间完全不考虑兼容性,新版本直接就不能使用了。 比如本项目,假设我采用 vue-cli+webpack 进行开发,也许项目做出来一个月之内还是可以使用的。 但是这些工具一旦发生了更新,很有可能因为兼容性问题,大家就完全无法跟着教程做出一样的效果来了。 当一个教程,无法导致确定的学习效果,大家也就没有办法从这个教程上学到东西了,因为根本跑不通~~~

所以为了规避学习过程中的风险,本项目放弃了 vue-cli + webpack 的风格。(虽然当初花了很多时间做 vue-cli 和 webpack 等等教程。。。现在想想,真是有点天真呀,哈哈)。

虽然没有用 vue-cli 来做,也就是说,项目没有创建 .vue 这样的文件,但是项目中对 vue 的使用依然是其核心使用方式,一旦掌握了项目中的这些处理技巧和经验, 切换到 vue-cli 上做,也是很容易的,所以不要担心因为 没有用 vue-cli 而感觉损失了很大~
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
访问如下测试地址:

http://localhost:8080/tmall_springboot/admin
测试地址
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
在右上角有本知识点对应的可运行项目下载 ,实在自己搞不出来,就下载解压出来比较一下。
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
1. 首先浏览器上访问路径 /admin
2. 这个路径被 AdminPageController 的admin方法匹配,然后客户端跳转到 admin_category_list
3. admin_category_list 被 AdminPageController 的 listCategory 方法匹配,服务端跳转到 admin/listCategory.html
4. listCategory.html 这个html页面通过http协议传输到浏览器端
5. 浏览器根据html 上的js代码,异步调用 categories 这个地址。 CategoryController 获取捕捉到这个请求,到数据库里查出所有的分类数据,并转换为 json数组返回给浏览器。
6. 浏览器根据这个json数组,通过 vue 的v-for 方式把其遍历到 多个 tr 元素上,用户就看到了表格里的多条数据了。
思路图
步骤 30 :

Redis,ElasticSearch 和 Shiro

edit
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
关于 Redis, ES (ElasticSearch) 和 Shiro 的支持,会放在后面专门来做。
这样做的好处是什么呢? 先做不支持 Redis, ES 和 Shiro 的功能,然后再在这个基础上进行改造,这样就可以很清楚的明白二者的区别。 比起以来就什么都上,脉络更清晰,更容易掌握,理解和消化。
完整的 Springboot 模仿天猫项目,使用 Springboot 、Vue.js、shiro、redis、elasticsearch 等一整套技术栈, 从无到有涵盖全部129个知识点,565个开发步骤, 充实 Springboot 项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
在idea里,修改了html和java,需要重启springboot 才能看到效果。
为了解决这个问题专门提供了解决方案:
在 idea2017 里 springboot thymeleaf 修改 html 之后不能立即看到效果的解决办法

eclipse 没有这个问题。。。


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2021-05-11 站长,求助!<div id="workingArea"></div>中的内容不显示
Quan79

如题 但如果把el: '#workingArea'注释掉,页面可以正常显示,但没有数据;如果不注释,则整个workingArea中的内容都不会显示,但浏览器能收到数据,用f12查看从数据库查询成功。 可能是什么原因呢? 我用的是eclipse,vue的版本是2.6.12




1 个答案

how2j
答案时间:2021-05-13
任何版本改动,都可能造成不可预知的兼容性问题,所以请用站长提供的 vue 版本。



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2021-05-09 下面的代码为跳转为什么不直接写一个方法呢有些想不明白
zixue




@GetMapping(value="/admin") public String admin(){ return "redirect:admin_category_list"; } @GetMapping(value="/admin_category_list") public String listCategory(){ return "admin/listCategory"; } 这两段代码写成一个直返回 return "admin/listCategory";不好吗,这样设计有别的功能吗
package com.how2java.tmall.web;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
 
@Controller
public class AdminPageController {
    @GetMapping(value="/admin")
    public String admin(){
        return "redirect:admin_category_list";
    }
    @GetMapping(value="/admin_category_list")
    public String listCategory(){
        return "admin/listCategory";
    }
}

							


1 个答案

how2j
答案时间:2021-05-13
本来只有:/admin_category_list 但是怕你们敲起来麻烦,所以又配置了一个 /admin 方便敲打



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2021-05-08 application.properties
2021-04-09 请问这样跑起来就算是全部的项目做完了吗?
2021-03-21 麻烦站长帮忙看看,分类名称里面是乱码,什么原因呢?


提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 137 条以前的提问,请 点击查看

提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 实践项目-天猫整站Springboot-查询 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 496725845
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图