当前位置 博文首页 > 努力充实,远方可期:谷粒商城笔记-分布式高级(3/4)
笔记-基础篇-1(P1-P28):https://blog.csdn.net/hancoder/article/details/106922139
笔记-基础篇-2(P28-P100):https://blog.csdn.net/hancoder/article/details/107612619
笔记-高级篇(P340):https://blog.csdn.net/hancoder/article/details/107612746
笔记-vue:https://blog.csdn.net/hancoder/article/details/107007605
笔记-elastic search、上架、检索:https://blog.csdn.net/hancoder/article/details/113922398
笔记-认证服务:https://blog.csdn.net/hancoder/article/details/114242184
笔记-分布式锁与缓存:https://blog.csdn.net/hancoder/article/details/114004280
笔记-集群篇:https://blog.csdn.net/hancoder/article/details/107612802
springcloud笔记:https://blog.csdn.net/hancoder/article/details/109063671
笔记版本说明:2020年提供过笔记文档,但只有P1-P50的内容,2021年整理了P340的内容。请点击标题下面分栏查看系列笔记
声明:
sql:https://github.com/FermHan/gulimall/sql文件
本项目其他笔记见专栏:https://blog.csdn.net/hancoder/category_10822407.html
请直接ctrl+F搜索内容
学到高级篇已经击败90%的人了,加油
ES笔记:https://blog.csdn.net/hancoder/article/details/113922398
商品发布只是可以上架了,上架后才可被检索
远程调用源码
// ReflectiveFeign
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (!"equals".equals(method.getName())) {
if ("hashCode".equals(method.getName())) {
return this.hashCode();
} else {
return "toString".equals(method.getName()) ? this.toString() : ((MethodHandler)this.dispatch.get(method)).invoke(args);
}
} else {
try {
Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
return this.equals(otherHandler);
} catch (IllegalArgumentException var5) {
return false;
}
}
}
// SynchronousMethodHandler.JAVA;
public Object invoke(Object[] argv) throws Throwable {
// 传过来的数据,构造 RequestTemplate,里面body有数据
RequestTemplate template = this.buildTemplateFromArgs.create(argv);
Options options = this.findOptions(argv);
// 重试器,要注意重复调用、接口幂等性。可以写重试器自己的实现
Retryer retryer = this.retryer.clone();
while(true) {
try {
// 执行后得到响应,解码得到bean
return this.executeAndDecode(template, options);
} catch (RetryableException var9) {
RetryableException e = var9;
try {
retryer.continueOrPropagate(e);
} catch (RetryableException var8) {
Throwable cause = var8.getCause();
if (this.propagationPolicy == ExceptionPropagationPolicy.UNWRAP && cause != null) {
throw cause;
}
throw var8;
}
}
}
}
body里是数据,feign将bean转为了 json
Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
// 构造出请求
Request request = this.targetRequest(template);
if (this.logLevel != Level.NONE) {
// 打印日志
this.logger.logRequest(this.metadata.configKey(), this.logLevel, request);
}
long start = System.nanoTime();
Response response;
try {
// 执行。client是LoadBalancerFeignClient。跳转到远程
response = this.client.execute(request, options);
response = response.toBuilder().request(request).requestTemplate(template).build();
} catch (IOException var16) {
if (this.logLevel != Level.NONE) {
this.logger.logIOException(this.metadata.configKey(), this.logLevel, var16, this.elapsedTime(start));
}
throw FeignException.errorExecuting(request, var16);
}
。。。
因为是个hashmap,所以setData不成功
public class R<T> extends HashMap<String,Object>{
// 把setData重写成PUT
public R setData(Object data){
put("data", data);
return this;
}
public <T> T getData(TypeReference<T> typeReference){
// get("data") 默认是map类型 所以再由map转成string再转json
Object data = get("data");//得到list,list每个值是map类型
// list<Map>转json
String s = JSON.toJSONString(data);
// json转list<T>
return JSON.parseObject(s, typeReference);
}
}
在其他处是new TypeReference<List<T>>
data的值对应的是List,而list的每个值是map
P136
不使用前后端分离开发了,管理后台用vue
页面在课件位置: 【高级篇-资料源码.zip\代码\html】
静态资源处理
nginx发给网关集群,网关再路由到微服务
静态资源放到nginx中,后面的很多服务都需要放到nginx中
html\首页资源\index放到gulimall-product下的static文件夹
把index.html放到templates中
pom依赖
导入thymeleaf依赖、热部署依赖devtools使页面实时生效
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
关闭thymeleaf缓存,方便开发实时看到更新
thymeleaf:
cache: false
suffix: .html
prefix: classpath:/templates/
web开发放到web包下,原来的controller是前后分离对接手机等访问的,所以可以改成app,对接app应用
刚导入index.html时,里面的分类菜单都是写死的,我们要访问数据库拿到放到model中,然后在页面foreach填入
thymeleaf笔记:https://blog.csdn.net/hancoder/article/details/113945941
@GetMapping({"/", "index.html"})
public String getIndex(Model model) {
//获取所有的一级分类
List<CategoryEntity> catagories = categoryService.getLevel1Catagories();
model.addAttribute("catagories", catagories);
return "index";
}
页面遍历菜单数据
<li th:each="catagory:${catagories}" >
<a href="#" class="header_main_left_a" ctg-data="3" th:attr="ctg-data=${catagory.catId}"><b th:text="${catagory.name}"></b></a>
</li>
@ResponseBody
@RequestMapping("index/catalog.json")
public Map<String, List<Catelog2Vo>> getCatlogJson() {
Map<String, List<Catelog2Vo>> map = categoryService.getCatelogJson();
return map;
}
@Override
public Map<String, List<Catelog2Vo>> getCatelogJson() {
List<CategoryEntity> entityList = baseMapper.selectList(null);
// 查询所有一级分类
List<CategoryEntity> level1 = getCategoryEntities(entityList, 0L);
Map<String, List<Catelog2Vo>> parent_cid = level1.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
// 拿到每一个一级分类 然后查询他们的二级分类
List<CategoryEntity> entities = getCategoryEntities(entityList, v.getCatId())