本文最后更新于:2023年3月23日 上午
SpringBoot范围:(1简答、2-8选择、9-12编程)
1、是什么,特性,优势
(1)是什么
Spring Boot是Spring社区较新的一个项目。该项目的目的是帮助开发者更容易的创建基于Spring的应用程序和服务,让更多人能更快的对Spring进行入门体验,让Java开发也能够实现Ruby on Rails那样的生产效率。为Spring生态系统提供了一种简约的、约定优于配置风格的框架。
(2)特性
- 简约风格:简化Maven操作、简化配置、简化注解
- 约定优于配置:基于企业项目架构中的常识性规范,为使用者做出自动化配置。此举规范整体项目结构的同时,极大提高生产效率。
- 工具库:为企业级项目而生,提供了更加丰富的工具库。
(3)优势
- 为基于Spring的开发提供更快的入门体验
- 开箱即用,没有代码生成,也无需XML配置。同时也可以修改默认值来满足特定的需求。
- 提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等。
- Spring Boot并不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式。
2、项目创建方式
(1)Maven手动创建
3、依赖组件:spring-boot-starter-*
了解有哪些依赖组件可用:https://docs.spring.io/spring-boot/docs/2.5.2/reference/html/using.html
4、注解以及作用
(1)@RestController
是@Controller和@ResponseBody的合集,表示这是个控制器 bean。
(2)@SpringBootApplication
这个注解是 Spring Boot 项目的基石,创建 SpringBoot 项目之后会默认在主类加上。
@SpringBootApplication 是 @Configuration 、@EnableAutoConfiguration、@ComponentScan注解的集合。
(3)@EnableAutoConfiguration
启用 SpringBoot 的自动配置机制。
(4)@SpringBootConfiguration
是一个类级别的注释,它指示此类提供了应用程序配置。
(5)@ConfigurationProperties
通过设置prefix属性找到配置文件中的对应的key 取到value值,从而赋值给对应的属性。
1 2 3 4
| school.name=厦门大学 school.website=www.xmu.com school.address=厦门
|
1 2 3 4 5 6 7 8 9 10 11
| @Component @ConfigurationProperties(prefix = "school") public class SchoolInfo { private String name; private String website; private String address; }
|
5、项目启动方式
(1)通过main方法启动
在IDE中直接直接执行main方法,然后访问http://localhost:8080即可
(2)打Jar包启动
用maven打包为可执行jar包,然后执行java -jar xxx.jar
(3)通过Maven命令启动
mvn spring-boot:run
6、支持的配置优先级
这些方式优先级如下:
- 命令行参数
- 来自java:comp/env的JNDI属性
- Java系统属性(System.getProperties())
- 操作系统环境变量
- RandomValuePropertySource配置的random.*属性值
- jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
- jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
- jar包外部的application.properties或application.yml(不带spring.profile)配置文件
- jar包内部的application.properties或application.yml(不带spring.profile)配置文件
- @Configuration注解类上的@PropertySource
- 通过SpringApplication.setDefaultProperties指定的默认属性
7、yaml配置文件的格式与好处
(1)格式
1 2 3 4
| k: k1: v1 k11: v11 k2: v2
|
(2)好处
8、Restful风格(资源等价于服务、标准化增删改查)
REST ( REpresentational State Transfer ),State Transfer 为 “状态传输” 或 “状态转移 “,Representational 中文有人翻译为”表征”、”具象”,合起来就是 “表征状态传输” 或 “具象状态传输” 或 “表述性状态转移”。
REST是一种架构风格,REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。其核心是面向资源,REST专门针对网络应用设计和开发方式,以降低开发的复杂性,提高系统的可伸缩性。
特点:
(1)资源等价于服务(一般不含资源的后缀名)。
仅有网站的路径,采用网站的多级路径携带参数信息 例如:
传统风格:
a/b/1.html
a/b/add.action?param1=123¶m2=456
rest风格:
a/b/123/456/add.action
(如果过滤器配成/*,就可以支持add/123/456)
(2)POST, DELETE, PUT, GET 分别对应 CRUD。
这也是REST的核心,即状态转化:使用这种机制可以达到相同的路径,根据不同的请求方式,产生不同的效果。如:同样是“11/zhangsan/user”请求,用GET就可以是按条件查询,用PUT就可以是按条件修改等等。
(3)无状态原则
这个状态指的是客户端与服务端交互时用于存储客户信息的作用域数据,一般用session存。但REST强调无状态,原因是,当下主流的项目都是前后端分离,前端和后端可能完全不在同一个服务里,那么作用域就毫无作用了。此时REST可以通过路径参数携带所有必要用户信息来发起请求,这样就不管谁对后端服务发起请求,后端服务都能够做出响应。从而突破了单一服务的限制,从此支持多服务与分布式场景,另外还提高了可用度
9、基于Restful风格的Controller
@Controller—>@RestController
@RequestMapping–>@GetMapping、@PostMapping、@PutMapping、@DeleteMapping
延承自SpringMVC的特性,支持路径参数:@PathVariable,JSON参数@RequestBody
- @Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。
- @RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器 bean
- @RequestParam是位列Controller层,作用是为获取前端参数,解决的是前后端参数不一致的问题。
- @PathVariable用于获取路径参数
- @RequestParam用于获取查询参数。
- @RequestBody将请求的 body 中的 json 字符串转换为 java 对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| @RestController public class GoodsController { @Autowired private GoodsService goodsService; @PostMapping("goods") public JsonResult addGoods(@Valid Goods goods,BindingResult br) { if(br.hasErrors()) { throw new MyException(ErrorEnums.CHECK_ERROR, br.getFieldError().getDefaultMessage()); }else { goodsService.addGoods(goods); return new JsonResult("添加成功"); } } @PutMapping("goods") public JsonResult editGoods(Goods goods) { goodsService.editGoods(goods); return new JsonResult("修改成功"); } @DeleteMapping("goods/{gid}") public JsonResult removeGoods(@PathVariable int gid) { goodsService.removeGoods(gid); return new JsonResult("删除成功"); } @GetMapping("goods/less/{price}/{type}") public JsonResult<Goods> findGoods(@PathVariable double price,@PathVariable String type){ GoodsExample ge = new GoodsExample(); ge.createCriteria().andTypeEqualTo(type).andPriceLessThan(price); return new JsonResult<Goods>(goodsService.findByCondition(ge)); } @GetMapping("goods/page/{pageNum}/{pageSize}") public JsonResult<Goods> findAllGoods(@PathVariable int pageNum,@PathVariable int pageSize){ PageHelper.startPage(pageNum, pageSize); return new JsonResult<Goods>(goodsService.findAll()); }
@GetMapping("goods") public JsonResult<Goods> findAllGoods(int pageNum,int pageSize,String sort,String order,String gname,String type){ PageHelper.startPage(pageNum, pageSize, sort+" "+order); GoodsExample ge = new GoodsExample(); ge.createCriteria().andGnameLike("%"+gname+"%").andTypeLike("%"+type+"%"); PageInfo<Goods> pagedata = new PageInfo<Goods>(goodsService.findByCondition(ge)); return new JsonResult<Goods>(pagedata); }
}
|
10、基于AOP统一日志类HttpAspect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package com.xxx.advice; @Aspect @Component public class HttpAspect {
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class); @Pointcut("execution(public * com.etc.controller.*.*(..))") public void log() {} @Before("log()") public void logbefore(JoinPoint point) { ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); logger.info("url={}",request.getRequestURI()); logger.info("method={}",request.getMethod()); logger.info("IP:PORT={}",request.getRemoteAddr()); logger.info("Class_Method={}",point.getSignature().getDeclaringTypeName()+"."+point.getSignature().getName()); Object[] args = point.getArgs(); String argsStr = ""; for(Object arg : args) { argsStr+=arg.toString(); } logger.info("args={}",argsStr); } @AfterReturning(pointcut = "log()", returning = "ret") public void logAfterRet(Object ret) { logger.info("response={}",ret.toString()); } }
|
11、统一异常处理类ExceptionHandle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.xxx.exception.handle; @ControllerAdvice public class ExceptionHandle { private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class); @ExceptionHandler(value=Exception.class) @ResponseBody public JsonResult handle(Exception e) { logger.error("【系统异常】:",e); return new JsonResult(-1,"【系统异常】:"+e.getMessage()); }
@ExceptionHandler(value=MyException.class) @ResponseBody public JsonResult myHandle(MyException e) { logger.error("【操作异常】:",e); return new JsonResult(e.getCode(),"【操作异常】:"+e.getMessage()); } }
|
12、统一的前后端数据类JsonResult
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| package com.xxx.entity; public class JsonResult<T> {
public static final int SUCCESS=0; private int state; private String message = ""; private T data; private List<T> datas; private PageInfo<T> pagedatas; private long total; private List<T> rows; public JsonResult(String message) { this.state = SUCCESS; this.message = message; } public JsonResult(int state,String message) { this.state = state; this.message = message; } public JsonResult(T data) { this.state = SUCCESS; this.data = data; } public JsonResult(String message,T data) { this.state = SUCCESS; this.message = message; this.data = data; } public JsonResult(int state,String message,T data) { this.state = state; this.message = message; this.data = data; }
public JsonResult(List<T> datas) { this.state = SUCCESS; this.datas = datas; } public JsonResult(String message,List<T> datas) { this.state = SUCCESS; this.message = message; this.datas = datas; } public JsonResult(int state,String message,List<T> datas) { this.state = state; this.message = message; this.datas = datas; } public JsonResult(PageInfo<T> pagedatas) { this.state = SUCCESS; this.pagedatas = pagedatas; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } public List<T> getDatas() { return datas; } public void setDatas(List<T> datas) { this.datas = datas; } public int getState() { return state; } public void setState(int state) { this.state = state; } public PageInfo<T> getPagedatas() { return pagedatas; } public void setPagedatas(PageInfo<T> pagedatas) { this.pagedatas = pagedatas; } public long getTotal() { return pagedatas!=null?pagedatas.getTotal():0; } public List<T> getRows() { return pagedatas!=null?pagedatas.getList():null; } }
|
Thymeleaf范围:(选择)
1、是什么,特点
(1)是什么
Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。它与 JSP,Velocity,FreeMaker 等模板引擎类似,也可以轻易地与 Spring MVC 等 Web 框架集成。
Thymeleaf 是新一代 Java 模板引擎,支持 HTML 原型,以直接被浏览器打开,此时浏览器会忽略未定义的 Thymeleaf 标签属性,展示 thymeleaf 模板的静态页面效果。当在应用程序中会动态地替换掉页面设置的标签属性。
(2)特点
与其它模板引擎相比,Thymeleaf 最大的特点是,即使不启动 Web 应用,也可以直接在浏览器中打开并正确显示模板页面 。
- 动静结合:Thymeleaf 既可以直接使用浏览器打开,查看页面的静态效果,也可以通过 Web 应用程序进行访问,查看动态页面效果。
- 开箱即用:Thymeleaf 提供了 Spring 标准方言以及一个与 SpringMVC 完美集成的可选模块,可以快速地实现表单绑定、属性编辑器、国际化等功能。
- 多方言支持:它提供了 Thymeleaf 标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL 表达式;必要时,开发人员也可以扩展和创建自定义的方言。
- 与 SpringBoot 完美整合:SpringBoot 为 Thymeleaf 提供了的默认配置,并且还为 Thymeleaf 设置了视图解析器,因此 Thymeleaf 可以与 Spring Boot 完美整合。
2、基本语法:th:text、th:with、th:object、th:if、th:each
(1)th:text
<div th:text="${name}">name</div>
它用于显示控制器传入的name值
如果name不存在,要显示默认值,则使用一下代码
<span th:text="${name}?:'默认值'"></span>
(2)th:with
局部变量,th:with能定义局部变量:
1 2 3 4 5
| <div th:with="firstPer=${persons[0]}"> <p> The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>. </p> </div>
|
(3)th:object
它用于接收后台传过来的对象,如以下代码:
<th:obejct="${user}">
(4)th:if
下方代码演示了if判断,表示:如果从控制器传来的role值等于”admin”,则显示”欢迎您,管理员“;如果role值等于”vip“,则显示”欢迎您,vip会员“
1 2 3 4 5 6 7
| <div th:if="${role} eq admin"> <span>欢迎您,管理员</span> </div> <div th:if="${role} eq vip"> <span>欢迎您,vip会员</span> </div>
|
(5)th:each
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <table> <thead> <tr> <th>序号</th> <th>用户名</th> <th>密码</th> <th>用户昵称</th> </tr> <tr th:each="user:${userlist}"> <td th:text="${user.id}"></td> <td th:text="${user.username}"></td> <td th:text="${user.password}"></td> <td th:text="${user.petname}"></td> </tr> </thead> </table>
|
${…}:变量表达式
*{…}:选择表达式
#{…}:消息表达式(i18n)
@{…}:链接表达式(URL)
~{…}:片段表达式
Redis(1简答、2-3选择、4编程)
1、是什么,特点,优势
(1)是什么
- redis是一个开源的、使用C语言编写的、可基于内存也可持久化的Key-Value数据库,最常用的NoSQL数据库没有之一。
- NoSQL: not only sql 不仅仅是sql 高性能开发
- c语言开发:支持多语言 java、php、python、c#、object-c、js…..
(2)特点
- 内存数据库,速度快,也支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持集群与数据备份,即master-slave模式的数据备份。
- 支持事务
(3)优势
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制形式的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。(事务:要么同时成功,要么同时回滚)
- 丰富的特性 – Redis还支持 publish/subscribe(发布/订阅)以实现读写分离, 通知, key 过期等等特性。
2、数据类型;String、List、Hash
(1)String
string是redis最基本的类型。一个key对应一个value。
单键 —— 单值
在以上实例中我们使用了 Redis 的 SET 和 GET 命令。键为 name,对应的值为redis.net.cn。注意:一个键最大能存储512MB。
(2)List
Redis列表是简单的字符串列表,按照插入顺序排序。你可以从头部(左边)或者尾部(右边)添加一个元素导列表。
单键——多值
常用案例:聊天系统、社交网络中获取用户最新发表的帖子、简单的消息队列、新闻的分页列表、博客的评论系统。
(3)Hash
hash 是一个键值(key=>value)对集合。
KV模式不变,但是V是一个键值对(适合用来存java中的对象数据)
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。可以避免序列化的开销和并发修改控制的问题。
以上实例中 hash 数据类型存储了包含用户脚本信息的用户对象。 实例中我们使用了 Redis HMSET, HGETALL 命令,user:1 为键值。
3、常用命令:set、get、incr、lpush、lpop、hset、hmset
set key value设置指定 key 的值[如果有键,则自动覆盖]
get key 获取指定 key 的值
del key 删除指定key
getset key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
incr key : 将键的整数值增一【只有数字才能进行加减】
decr key: 将键的整数值减少-1
INCRBY key increment 将 key 所储存的值加上给定的增量值(increment) 。
LPUSH key value1 [value2] 将一个或多个值插入到列表头部
RPUSH key value1 [value2] 在列表中添加一个或多个值
LPOP key 移出并获取列表的第一个元素
RPOP key 移除并获取列表最后一个元素
hset key field value (field相当于类的属性)将哈希表 key 中的字段 field 的值设为 value
hget key field 获取存储在哈希表中指定字段的值
hmset key field1 value1 [field2 value2 ]同时将多个 field-value (域-值)对设置到哈希表 key 中。
hmget key field1[field2] 获取所有给定哈希字段的值
4、基于jedis驱动的java redis API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| 1.在pom.xml中配置依赖: redis.clients jedis 2.创建一个redis连接:
Jedis jedis=new Jedis("127.0.0.1", 6379);
3.写入一个字符串String;
jedis.set("key1", "string-value1");
String value1 = jedis.get("key1");
jedis.expire("key1", 60);
System.out.println(value1);
System.out.println(jedis.get("key1"));
4.写入一个hash:
HashMap hashMap = new HashMap();
hashMap.put("name", "zhang-");
hashMap.put("age", "36");
jedis.hmset("user", hashMap);
jedis.expire("user", 20);
List hmget = jedis.hmget("user", "name", "age");
System.out.println(hmget);
Boolean isExist = jedis.hexists("user", "name");
System.out.println(isExist);
jedis.hdel("user", "name");
Map map = jedis.hgetAll("user");
System.out.println(map);
5.写入一个list(列表)
jedis.lpush("user1", "name1", "name2");
jedis.rpush("user1", "name1", "name2");
jedis.lindex("key", 1);
long length = jedis.llen("user2");
System.out.println(length);
6.无序set操作:
jedis.sadd("set1", "value1");
jedis.sadd("set1", "value2");
jedis.sadd("set1", "value3");
Set set1 = jedis.smembers("set1");
jedis.srem("set1", "value2");
boolean sismember = jedis.sismember("set1", "value2");
7.有序set操作:
jedis.zadd("set2", 1, "value1");
jedis.zadd("set2", 10, "value10");
jedis.zadd("set2", 11, "value11");
jedis.zadd("set2", 9, "value9");
jedis.zadd("set2", 5, "value5");
Long set21 = jedis.zcard("set2");
System.out.println(set21);
Set set2 = jedis.zrange("set2", 0, 10);
System.out.println(set2);
|
SpringCloud(1-3简答、4-5选择、6编程)
1、微服务架构演进,课上前后讲了两遍,印象不深的去看视频(简答题重点考区)
2、是什么,特点,优势
(1)是什么
Spring cloud是一个开发工具集,含多个子项目
- 利用spring Boot的开发便利
- 主要是基于对netfilix开源组件进行封装
Spring cloud 简化了分布式开发
(2)特点
Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来,从而简化了开发者的代码量
(3)优势
- 集大成者
• Spring Cloud 包含了微服务架构的方方面面
- 约定优于配置
• 基于注解,没有配置文件
- 轻量级组件
• Spring Cloud 整合的组件大多比较轻量级,且都是各自领域的佼佼者
- 开发简便
• Spring Cloud 对各个组件进行了大量的封装,从而简化了开发
- 开发灵活
• Spring Cloud 的组件都是解耦的,开发人员可以灵活按需选择组件
3、知识沉淀——微服务学习过程中必须了解的5个问题
问题1:分布式系统中为什么需要注册中心?
问题2:服务多的时候,如何找到最适合我的服务?
问题3:客户端和服务端所用语言不同怎么办?
问题4:原有项目如何拆分成微服务项目?
问题5:哪些项目不适合演进成微服务架构?
问题1:分布式系统中为什么需要注册中心?
问题2:服务多的时候,如何找到最适合我的服务?
问题3:客户端和服务端所用语言不同怎么办?
问题4:原有项目如何拆分成微服务项目?
问题5:哪些项目不适合演进成微服务架构?
4、注册中心Eureka 配置、注解、运行效果、高可用!!
application.yml
1 2 3 4
| eureka: client: registerWithEureka: false fetchRegistry: false
|
application-e1.yml
1 2 3 4 5 6 7 8 9
| server: port: 8761 eureka: instance: hostname: eureka-1 client: service-url: defaultZone: http://eureka-2:8762/eureka/
|
application-e2.yml
1 2 3 4 5 6 7 8 9
| server: port: 8762 eureka: instance: hostname: eureka-2 client: service-url: defaultZone: http://eureka-1:8761/eureka/
|
5、服务消费者RestTemplate和Feign 配置、注解、运行效果
(1)RestTemplate
AppClient
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package com.xxx.controller; @RestController public class ClientController { @Autowired private RestTemplate restTemplate;
@RequestMapping("getmsg") public String getMsg(String name) { String response = restTemplate.getForObject("http://APPSERVICE/hello?name="+name, String.class); return response; } @PostMapping("goods") public String addGood(@Valid Goods goods) throws Exception{
String response = restTemplate.postForObject("http://APPSERVICE/goods",goods, String.class); return response; } @PutMapping("goods") public void editGoods(Goods goods) {
restTemplate.put("http://APPSERVICE/goods",goods); } @DeleteMapping("goods/{gid}") public void removeGoods(@PathVariable int gid) { restTemplate.delete("http://APPSERVICE/goods/"+gid, String.class); } @GetMapping("goods/{gid}") public Goods findGood(@PathVariable int gid) { Goods response = restTemplate.getForObject("http://APPSERVICE/goods/"+gid, Goods.class); return response; }
}
|
AppService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| @RestController public class GoodsController { @Value("${server.port}") private int port; @Autowired private GoodsService goodsService; @PostMapping("goods") public String addGoods(@RequestBody Goods goods,BindingResult br) { if(br.hasErrors()) { return br.getFieldError().getDefaultMessage(); }else { System.out.println(goods.getGname()); System.out.println(goods.getGname()); System.out.println(goods.getGname()); System.out.println(goods.getGid()); goodsService.addGoods(goods); return "添加成功"; } } @PutMapping("goods") public String editGoods(@RequestBody Goods goods) { goodsService.editGoods(goods); return "修改成功"; } @DeleteMapping("goods/{gid}") public String removeGoods(@PathVariable int gid) { goodsService.removeGoods(gid); return "删除成功"; } @GetMapping("goods/less/{price}/{type}") public List<Goods> findGoods(@PathVariable double price,@PathVariable String type){ GoodsExample ge = new GoodsExample(); ge.createCriteria().andTypeEqualTo(type).andPriceLessThan(price); return goodsService.findByCondition(ge); } @GetMapping("goods/{gid}") public Goods findGood(@PathVariable int gid){ return goodsService.findByGid(gid); }
}
|
AppClientApplication
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.xxx;
@EnableEurekaClient @SpringBootApplication public class AppClientApplication {
public static void main(String[] args) { SpringApplication.run(AppClientApplication.class, args); }
@Bean @LoadBalanced public RestTemplate getRestTemplate() { RestTemplate restTemplate = new RestTemplate(); return restTemplate; } }
|
(2)Feign
1 2 3 4 5 6 7 8 9 10 11 12
| package com.xxx; @EnableEurekaClient @EnableFeignClients @SpringBootApplication public class FeignClientApplication {
public static void main(String[] args) { SpringApplication.run(FeignClientApplication.class, args); }
}
|
1 2 3 4 5 6 7 8
| package com.xxx.client; @FeignClient("APPSERVICE") public interface HelloClient {
@RequestMapping("hello") public String sayHello(@RequestParam("name") String name); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.xxx.controller; @RestController public class ClientController { @Autowired private HelloClient helloClient; @RequestMapping("msg") public String getMsg(String name) { String response = helloClient.sayHello(name); return response; } @RequestMapping("/hi") public String sayHi() { return "hi"; } }
|
6、SpringCloud编程题只靠配置文件写法,不考Java代码
(1)AppClient
application.yml
1 2 3 4 5 6 7 8 9 10 11
| server: port: 8888 spring: application: name: appclient eureka: client: service-url: defaultZone: http://eureka-1:8761/eureka/
|
(2)AppService
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| eureka: client: service-url: defaultZone: http://eureka-1:8761/eureka/
spring: application: name: appservice datasource: url: jdbc:mysql://localhost:3306/shop?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:com/etc/mapper/xml/GoodsMapper.xml
|
application-as1.yml
application-as2.yml
application-as3.yml
(3)EurekaServer-ha
application.yml
1 2 3 4
| eureka: client: registerWithEureka: false fetchRegistry: false
|
application-e1.yml
1 2 3 4 5 6 7 8 9
| server: port: 8761 eureka: instance: hostname: eureka-1 client: service-url: defaultZone: http://eureka-2:8762/eureka/
|
application-e2.yml
1 2 3 4 5 6 7 8 9
| server: port: 8762 eureka: instance: hostname: eureka-2 client: service-url: defaultZone: http://eureka-1:8761/eureka/
|
题型:
单选:10-15题 (每题2分)
多选:5-8题(每题3分)
判断:0-10题(每题1分)
简答:6-8题(每题6分)
编程:1-2题(每题10分)