# OpenFeign
**Repository Path**: tangcco/open-feign
## Basic Information
- **Project Name**: OpenFeign
- **Description**: SpringClould组件OpenFeign
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2021-01-30
- **Last Updated**: 2022-06-23
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
```
http 的背景原理
a. 两台服务器建立 http 连接的过程是很复杂的一个过程,涉及到多个数据包的交换,并且也很耗时间。
b. Http 连接需要的 3 次握手 4 次分手开销很大,这一开销对于大量的比较小的 http 消息来说更大。
2优化解决方案
a. 如果我们直接采用 http 连接池,节约了大量的 3 次握手 4 次分手;这样能大大提升吞吐率。
b. feign 的 http 客户端支持 3 种框架;HttpURLConnection、httpclient、okhttp;默认是HttpURLConnection。
c. 传统的 HttpURLConnection 是 JDK 自带的,并不支持连接池,如果要实现连接池的机制,还需要自己来管理连接对象。
对于网络请求这种底层相对复杂的操作,如果有可用的其他方案,也没有必要自己去管理连接对象。
d. HttpClient 相比传统 JDK 自带的 HttpURLConnection,它封装了访问 http 的请求头,参数,内容体,响应等等;
它不仅使客户端发送 HTTP 请求变得容易,而且也方便了开发人员测试接口(基于 Http 协议的),即提高了开发的效率,也方便提高代码的健壮性;
另外高并发大量的请求网络的时候,还是用“连接池”提升吞吐量。
```
```shell
maven打包时可以通过两种方式传入参数:
a)、通过 -D命令传入属性值profileActive,如:clean install -Dmaven.test.skip=true -DprofileActive=dev
b)、通过-P命令指定profile环境,如:clean package -P prod
```
### 启动注册中心
```shell
./consul agent -dev -client=0.0.0.0 -ui
```
### service-provider
#### 1. pom.xml
```xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.4.2
cn.kgc.tangcco
idiom-provider
0.0.1-SNAPSHOT
war
idiom-provider
consul project for Spring Boot
15
2020.0.0
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-commons
org.springframework.cloud
spring-cloud-starter-consul-discovery
org.springframework.boot
spring-boot-devtools
runtime
true
mysql
mysql-connector-java
runtime
com.alibaba
druid-spring-boot-starter
1.2.4
org.springframework.boot
spring-boot-configuration-processor
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-tomcat
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
${project.artifactId}
../package
org.projectlombok
lombok
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
```
#### 2. 配置文件
```yaml
server:
port: 8080
compression:
enabled: true # 是否开启压缩
servlet:
encoding:
force: true
charset: UTF-8
spring:
application:
name: idiom-provider #应用名称 集群环境下相同
servlet:
multipart:
max-file-size: 50MB # 文件上传大小限制为500kb
max-request-size: 200MB # 请求大小限制为500kb
datasource:
url: jdbc:mysql://47.94.130.233:3306/knowledge?useUnicode=true&characterEncoding=UTF8&useSSL=true&serverTimeZone=Aisa/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 200
# 配置获取连接等待超时的时间
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
max-pool-prepared-statement-per-connection-size: 20
filters: stat,wall,slf4j
use-global-data-source-stat: true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
stat-view-servlet:
login-username: admin
login-password: 123456
reset-enable: false
url-pattern: /druid/*
allow: 0.0.0.0
#deny:
enabled: true
web-stat-filter:
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
jpa:
database: MySQL
database-platform: org.hibernate.dialect.MySQL8Dialect
show-sql: true
hibernate:
ddl-auto: none
cloud:
consul:
host: 192.168.1.110 # 注册中心地址
port: 8500 # 注册中心端口
discovery:
register: true # 是否注册
instance-id: ${spring.application.name}-00 # 注册实例 id 必须唯一
service-name: ${spring.application.name} # 服务名称
port: ${server.port} # 服务端口
prefer-ip-address: true # 是否使用 ip 注册
ip-address: ${spring.cloud.client.ip-address} # 服务请求 ip
heartbeat:
enabled: true # 是否打开心跳监测
# 度量指标监控与健康检查
management:
endpoints:
web:
exposure:
include: shutdown # 开启 shutdown 端点访问
endpoint:
shutdown:
enabled: true # 开启 shutdown 请求方式必须是post
health:
show-details: ALWAYS
logging:
level:
com.netflix: warn
```
#### 3. pojo类
```java
package cn.kgc.tangcco.pojo;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
import java.io.Serializable;
/**
* @author 李昊哲
* @Description
* @create 2020/12/29 14:22
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@DynamicInsert
@DynamicUpdate
@Table(name = "idiom")
@Entity
public class Idiom implements Serializable {
private static final long serialVersionUID = 7553935244407585482L;
/**
* 主键ID
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
/**
* 成语
*/
@Column(name = "name")
private String name;
/**
* 拼音
*/
@Column(name = "spell")
private String spell;
/**
* 解释
*/
@Column(name = "content")
private String content;
/**
* 典故
*/
@Column(name = "derivation")
private String derivation;
/**
* 举例句子
*/
@Column(name = "samples")
private String samples;
}
```
```java
package cn.kgc.tangcco.pojo;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* @author 李昊哲
* @Description
* @create 2021/1/30 10:54
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Paginator {
private Integer page;
private Integer size;
}
```
#### 4. 持久层接口
```java
package cn.kgc.tangcco.repository;
import cn.kgc.tangcco.pojo.Idiom;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
* @author 李昊哲
* @Description
* @create 2020/12/29 14:48
*/
@Repository
public interface IdiomRepository extends JpaRepository, JpaSpecificationExecutor {}
```
#### 5. service接口
```java
package cn.kgc.tangcco.service;
import cn.kgc.tangcco.pojo.Idiom;
import org.springframework.data.domain.Page;
import java.util.List;
/**
* @author 李昊哲
* @Description
* @create 2020/12/29 14:51
*/
public interface IdiomService {
/**
* 分页查询
*
* @param page 查询页码
* @param size 每页记录数
* @return
*/
public Page findAll(Integer page, Integer size);
/**
* 根据主键查找
*
* @param id
* @return
*/
public Idiom findById(Integer id);
public Idiom save(Idiom idiom);
public Long deleteById(Integer id);
public long count();
}
```
#### 6. service实现类
```java
package cn.kgc.tangcco.service.impl;
import cn.kgc.tangcco.pojo.Idiom;
import cn.kgc.tangcco.repository.IdiomRepository;
import cn.kgc.tangcco.service.IdiomService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
/**
* @author 李昊哲
* @Description
* @create 2021/1/27 11:51
*/
@Service
public class IdiomServiceImpl implements IdiomService {
private final IdiomRepository idiomRepository;
public IdiomServiceImpl(IdiomRepository idiomRepository) {
this.idiomRepository = idiomRepository;
}
@Override
public Page findAll(Integer page, Integer size) {
return idiomRepository.findAll(PageRequest.of(page - 1, size));
}
@Override
public Idiom findById(Integer id) {
Optional optional = idiomRepository.findById(id);
if (optional.isEmpty()) {
return null;
}
return optional.get();
}
@Transactional
@Override
public Idiom save(Idiom idiom) {
return idiomRepository.saveAndFlush(idiom);
}
@Transactional
@Override
public Long deleteById(Integer id) {
long count = idiomRepository.count();
idiomRepository.deleteById(id);
return count - idiomRepository.count();
}
@Override
public long count() {
return idiomRepository.count();
}
}
```
#### 7. controller
```java
package cn.kgc.tangcco.controller;
import cn.kgc.tangcco.pojo.Idiom;
import cn.kgc.tangcco.pojo.Paginator;
import cn.kgc.tangcco.service.IdiomService;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author 李昊哲
* @Description
* @create 2021/1/27 11:59
*/
@RestController
@RequestMapping(value = "/idiom")
public class IdiomController {
private final IdiomService idiomService;
public IdiomController(IdiomService idiomService) {
this.idiomService = idiomService;
}
@GetMapping(value = "/count")
public long count() {
return idiomService.count();
}
@GetMapping(value = "/findById/{id}")
public Idiom findById(@PathVariable("id") Integer id) {
return idiomService.findById(id);
}
@GetMapping(value = "/findAllWithGetForm")
public Page findAllWithGetForm(Integer page, Integer size) {
return idiomService.findAll(page, size);
}
@PostMapping(value = "/findAllWithPostForm")
public Page findAllWithPostForm(Integer page, Integer size) {
return idiomService.findAll(page, size);
}
@PostMapping(value = "/findAllWithPostJson")
public Page findAllWithPostJson(@RequestBody Paginator paginator) {
return idiomService.findAll(paginator.getPage(), paginator.getSize());
}
@PutMapping(value = "/save")
public Idiom save(@RequestBody Idiom idiom) {
return idiomService.save(idiom);
}
@DeleteMapping(value = "/deleteById/{id}")
public Long deleteById(@PathVariable("id") Integer id) {
return idiomService.deleteById(id);
}
}
```
### idiom-consumer
#### 1. pom.xml
```xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.4.2
cn.kgc.tangcco
idiom-consumer
0.0.1-SNAPSHOT
war
idiom-consumer
consul project for Spring Boot
15
2020.0.0
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-consul-discovery
org.springframework.cloud
spring-cloud-starter-openfeign
io.github.openfeign
feign-httpclient
11.0
io.github.openfeign
feign-okhttp
11.0
org.springframework.boot
spring-boot-devtools
runtime
true
org.springframework.boot
spring-boot-configuration-processor
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-tomcat
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
${project.artifactId}
../package
org.projectlombok
lombok
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
```
#### 2. 配置文件
```yaml
spring:
profiles:
active: httpclient
```
```yaml
server:
port: 80
compression:
enabled: true # 是否开启压缩
servlet:
encoding:
force: true
charset: UTF-8
spring:
application:
name: idiom-consumer #应用名称 集群环境下相同
servlet:
multipart:
max-file-size: 50MB # 文件上传大小限制为500kb
max-request-size: 200MB # 请求大小限制为500kb
cloud:
consul:
host: 192.168.1.110 # 注册中心地址
port: 8500 # 注册中心端口
discovery:
register: false # 是否注册
instance-id: ${spring.application.name}-01 # 注册实例 id 必须唯一
service-name: ${spring.application.name} # 服务名称
port: ${server.port} # 服务端口
prefer-ip-address: true # 是否使用 ip 注册
ip-address: ${spring.cloud.client.ip-address} # 服务请求 ip
heartbeat:
enabled: true # 是否打开心跳监测
feign:
httpclient:
enabled: true
logging:
level:
com.netflix: warn
```
```yaml
server:
port: 80
compression:
enabled: true # 是否开启压缩
servlet:
encoding:
force: true
charset: UTF-8
spring:
application:
name: idiom-consumer #应用名称 集群环境下相同
servlet:
multipart:
max-file-size: 50MB # 文件上传大小限制为500kb
max-request-size: 200MB # 请求大小限制为500kb
cloud:
consul:
host: 192.168.1.110 # 注册中心地址
port: 8500 # 注册中心端口
discovery:
register: false # 是否注册
instance-id: ${spring.application.name}-01 # 注册实例 id 必须唯一
service-name: ${spring.application.name} # 服务名称
port: ${server.port} # 服务端口
prefer-ip-address: true # 是否使用 ip 注册
ip-address: ${spring.cloud.client.ip-address} # 服务请求 ip
heartbeat:
enabled: true # 是否打开心跳监测
feign:
okhttp:
enabled: true
logging:
level:
com.netflix: warn
```
#### 3. pojo类
```java
package cn.kgc.tangcco.pojo;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @author 李昊哲
* @Description
* @create 2020/12/29 14:22
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Idiom implements Serializable {
private static final long serialVersionUID = 7553935244407585482L;
/**
* 主键ID
*/
private Integer id;
/**
* 成语
*/
private String name;
/**
* 拼音
*/
private String spell;
/**
* 解释
*/
private String content;
/**
* 典故
*/
private String derivation;
/**
* 举例句子
*/
private String samples;
}
```
```java
package cn.kgc.tangcco.pojo;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* @author 李昊哲
* @Description
* @create 2021/1/30 10:54
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Paginator {
private Integer page;
private Integer size;
}
```
#### 4. service接口
```java
package cn.kgc.tangcco.service;
import cn.kgc.tangcco.pojo.Idiom;
import cn.kgc.tangcco.pojo.Paginator;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author 李昊哲
* @Description
* @create 2020/12/29 14:51
*/
@FeignClient("idiom-provider")
public interface IdiomService {
@GetMapping(value = "/idiom/count")
public long count();
@GetMapping(value = "/idiom/findById/{id}")
public Idiom findById(@PathVariable("id") Integer id);
/**
* 分页查询
*
* @param page 查询页码
* @param size 每页记录数
* @return
*/
@GetMapping(value = "/idiom/findAllWithGetForm")
public String findAllWithGetForm(@RequestParam Integer page, @RequestParam Integer size);
/**
* 分页查询
*
* @param page 查询页码
* @param size 每页记录数
* @return
*/
@PostMapping(value = "/idiom/findAllWithPostForm")
public String findAllWithPostForm(@RequestParam Integer page, @RequestParam Integer size);
/**
* 分页查询
*
* @return
*/
@PostMapping(value = "/idiom/findAllWithPostJson")
public String findAllWithPostJson(@RequestBody Paginator paginator);
@PutMapping(value = "/idiom/save")
public Idiom save(@RequestBody Idiom idiom);
@DeleteMapping(value = "/idiom/deleteById/{id}")
public Long deleteById(@PathVariable("id") Integer id);
}
```
#### 5. controller
```java
package cn.kgc.tangcco.controller;
import cn.kgc.tangcco.pojo.Idiom;
import cn.kgc.tangcco.pojo.Paginator;
import cn.kgc.tangcco.service.IdiomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author 李昊哲
* @Description
* @create 2021/1/27 11:59
*/
@RestController
@RequestMapping(value = "/idiom")
public class IdiomController {
@Autowired
private IdiomService idiomService;
@GetMapping(value = "/count")
public long count() {
return idiomService.count();
}
@GetMapping(value = "/findById/{id}")
public Idiom findById(@PathVariable("id") Integer id) {
return idiomService.findById(id);
}
@GetMapping(value = "/findAllWithGetForm")
public String findAllWithGetForm(
@RequestParam(name = "page", defaultValue = "1", required = true) Integer page,
@RequestParam(name = "size", defaultValue = "2", required = true) Integer size) {
return idiomService.findAllWithGetForm(page, size);
}
@PostMapping(value = "/findAllWithPostForm")
public String findAllWithPostForm(
@RequestParam(name = "page", defaultValue = "1", required = true) Integer page,
@RequestParam(name = "size", defaultValue = "2", required = true) Integer size) {
return idiomService.findAllWithPostForm(page, size);
}
@PostMapping(value = "/findAllWithPostJson")
public String findAllWithPostJson(@RequestBody Paginator paginator) {
return idiomService.findAllWithPostJson(paginator);
}
@PutMapping(value = "/save")
public Idiom save(Idiom idiom) {
return idiomService.save(idiom);
}
@DeleteMapping(value = "/deleteById/{id}")
public Long deleteById(@PathVariable("id") Integer id) {
return idiomService.deleteById(id);
}
}
```
#### 6. 启动类
```java
package cn.kgc.tangcco;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestOperations;
@EnableFeignClients
@SpringBootApplication
public class IdiomConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(IdiomConsumerApplication.class, args);
}
}
```
#### 7. 测试
##### 7.1 GET方式无参数的请求
测试地址:http://localhost/idiom/count
请求方式:GET
请求参数:无
返回结果:31851
##### 7.2 GET方式地址栏传参
测试地址:http://localhost/idiom/findById/
请求方式:GET
请求参数:3
返回结果:
```json
{
"id": 3,
"name": "备而不用",
"spell": "bèi ér bù yòng",
"content": "准备好了,以备急用,眼下暂存不用。",
"derivation": "清·吴趼人《糊涂世界》:“虽说备而不用,到得那时候,听凭兵丁造一句谣言,开上几排枪,那人可就死了不少。”",
"samples": "凡是零星物件,本地买不出,一定要用,或是~的,也都齐全。(清·颐琐《黄绣球》第十七回)"
}
```
##### 7.3 GET方式传参
测试地址:http://localhost/idiom/findAllWithGetForm
请求方式:GET
请求参数:
| key | value |
| ---- | ----- |
| page | 2 |
| size | 2 |
返回结果:
```json
{
"content": [
{
"id": 3,
"name": "备而不用",
"spell": "bèi ér bù yòng",
"content": "准备好了,以备急用,眼下暂存不用。",
"derivation": "清·吴趼人《糊涂世界》:“虽说备而不用,到得那时候,听凭兵丁造一句谣言,开上几排枪,那人可就死了不少。”",
"samples": "凡是零星物件,本地买不出,一定要用,或是~的,也都齐全。(清·颐琐《黄绣球》第十七回)"
},
{
"id": 4,
"name": "贝阙珠宫",
"spell": "bèi què zhū gōng",
"content": "用珍珠宝贝做的宫殿。形容房屋华丽。",
"derivation": "战国·楚·屈原《九歌·河伯》:“鱼鳞屋兮龙堂,紫贝阙兮朱宫。”",
"samples": "你看那香焚宝鼎,紫雾漾漾,玉楼金殿,~,便如天宫之景也。(明·无名氏《庆长生》第四折)"
}
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"offset": 2,
"pageSize": 2,
"pageNumber": 1,
"paged": true,
"unpaged": false
},
"last": false,
"totalPages": 15926,
"totalElements": 31851,
"size": 2,
"number": 1,
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"first": false,
"numberOfElements": 2,
"empty": false
}
```
##### 7.4 POST方式表单传参
测试地址:http://localhost/idiom/findAllWithPostForm
请求方式:POST
请求参数:
| key | value |
| ---- | ----- |
| page | 2 |
| size | 2 |
返回结果:
```json
{
"content": [
{
"id": 3,
"name": "备而不用",
"spell": "bèi ér bù yòng",
"content": "准备好了,以备急用,眼下暂存不用。",
"derivation": "清·吴趼人《糊涂世界》:“虽说备而不用,到得那时候,听凭兵丁造一句谣言,开上几排枪,那人可就死了不少。”",
"samples": "凡是零星物件,本地买不出,一定要用,或是~的,也都齐全。(清·颐琐《黄绣球》第十七回)"
},
{
"id": 4,
"name": "贝阙珠宫",
"spell": "bèi què zhū gōng",
"content": "用珍珠宝贝做的宫殿。形容房屋华丽。",
"derivation": "战国·楚·屈原《九歌·河伯》:“鱼鳞屋兮龙堂,紫贝阙兮朱宫。”",
"samples": "你看那香焚宝鼎,紫雾漾漾,玉楼金殿,~,便如天宫之景也。(明·无名氏《庆长生》第四折)"
}
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"offset": 2,
"pageSize": 2,
"pageNumber": 1,
"paged": true,
"unpaged": false
},
"last": false,
"totalPages": 15926,
"totalElements": 31851,
"size": 2,
"number": 1,
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"first": false,
"numberOfElements": 2,
"empty": false
}
```
##### 7.5 POST方式传递json
测试地址:http://localhost/idiom/findAllWithPostJson
请求方式:POST
请求参数:
```json
{
"page":"4",
"size":"2"
}
```
返回结果:
```json
{
"content": [
{
"id": 7,
"name": "毕恭毕敬",
"spell": "bì gōng bì jìng",
"content": "形容态度十分恭敬。",
"derivation": "《诗经·小雅·小弁》:“维桑与梓,必恭敬止,靡瞻匪父,靡依匪母。”",
"samples": "他~地将书递给了老师,请求解答两个疑难问题。"
},
{
"id": 8,
"name": "婢作夫人",
"spell": "bì zuò fū rén",
"content": "婢:侍女;夫人:主妇。旧时指在文艺方面虽刻意模仿别人,但才力和作品的规模总赶不上。",
"derivation": "唐·张彦远《法书要录》引南朝梁袁昂《古今书评》:“羊欣书如大家婢为夫人。虽处其位,而举止羞涩,终不似真。”",
"samples": "不过偶尔学着写,正是~,那里及得到大哥什一。(清·吴趼人《二十年目睹之怪现状》第四十一回)"
}
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"offset": 6,
"pageNumber": 3,
"pageSize": 2,
"paged": true,
"unpaged": false
},
"last": false,
"totalPages": 15926,
"totalElements": 31851,
"size": 2,
"number": 3,
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"first": false,
"numberOfElements": 2,
"empty": false
}
```
##### 7.6 PUT新增数据
测试地址:http://localhost/idiom/save
请求方式:PUT
请求参数:
| key | value |
| ---------- | ------------------------------------------------------------ |
| name | 桃李不言下自成蹊 |
| spell | táo lǐ bù yán xià zì chéng xī |
| content | 原意是桃树和李树不主动招引人,但人们都来看它们开出的鲜花,采摘它们结出的果实,在树下走成了一条小路。 |
| derivation | 西汉·司马迁《史记·李将军列传论》:“太史公曰:传曰:‘其身正,不令而行;其身不正,虽令不从。’其李将军之谓也。余睹李将军,悛悛如鄙人,口不能道辞。及死之日,天下知与不知,皆为尽哀。彼其忠实心诚信于士大夫也。谚曰:‘桃李不言,下自成蹊。’此言虽小,可以谕大也。” |
| samples | 俗话说:“桃李不言,下自成蹊”,你不必过于急躁 。 |
返回结果:
```json
{
"id": 31852,
"name": "桃李不言下自成蹊",
"spell": "táo lǐ bù yán xià zì chéng xī",
"content": "原意是桃树和李树不主动招引人,但人们都来看它们开出的鲜花,采摘它们结出的果实,在树下走成了一条小路。",
"derivation": " 西汉·司马迁《史记·李将军列传论》:“太史公曰:传曰:‘其身正,不令而行;其身不正,虽令不从。’其李将军之谓也。余睹李将军,悛悛如鄙人,口不能道辞。及死之日,天下知与不知,皆为尽哀。彼其忠实心诚信于士大夫也。谚曰:‘桃李不言,下自成蹊。’此言虽小,可以谕大也。”",
"samples": "俗话说:“桃李不言,下自成蹊”,你不必过于急躁 。"
}
```
##### 7.7 PUT修改数据
测试地址:http://localhost/idiom/save
请求方式:PUT
请求参数:
| key | value |
| ---------- | ------------------------------------------------------------ |
| id | 31852 |
| name | 桃李不言下自成蹊 |
| spell | táo lǐ bù yán xià zì chéng xī |
| content | 比喻为人品德高尚、诚实、正直,用不着自我宣传,就自然受到人们的[尊重](https://baike.baidu.com/item/尊重/788873)和敬仰。 |
| derivation | 西汉·司马迁《史记·李将军列传论》:“太史公曰:传曰:‘其身正,不令而行;其身不正,虽令不从。’其李将军之谓也。余睹李将军,悛悛如鄙人,口不能道辞。及死之日,天下知与不知,皆为尽哀。彼其忠实心诚信于士大夫也。谚曰:‘桃李不言,下自成蹊。’此言虽小,可以谕大也。” |
| samples | 俗话说:“桃李不言,下自成蹊”,你不必过于急躁 。 |
返回结果:
```json
{
"id": 31852,
"name": "桃李不言下自成蹊",
"spell": "táo lǐ bù yán xià zì chéng xī",
"content": "比喻为人品德高尚、诚实、正直,用不着自我宣传,就自然受到人们的尊重和敬仰。",
"derivation": " 西汉·司马迁《史记·李将军列传论》:“太史公曰:传曰:‘其身正,不令而行;其身不正,虽令不从。’其李将军之谓也。余睹李将军,悛悛如鄙人,口不能道辞。及死之日,天下知与不知,皆为尽哀。彼其忠实心诚信于士大夫也。谚曰:‘桃李不言,下自成蹊。’此言虽小,可以谕大也。”",
"samples": "俗话说:“桃李不言,下自成蹊”,你不必过于急躁 。"
}
```
##### 7.8 DELETE地址栏传参
测试地址:http://localhost/idiom/deleteById/
请求方式:DELETE
请求参数:31852
返回结果:1