SpringBoot整合RestTemplate用法讲解(完整详细)

news2024/11/15 19:32:48

前言:本篇主要介绍了RestTemplate中的GET,POST,PUT,DELETE、文件上传和文件下载6大常用的功能,每一个方法和每一行代码都进行了详细的讲解,代码都是亲自测试过的,整篇博客写完以后自己也是受益匪浅,于是在这做个技术分享!

目录

一、RestTemplate简介

二、基础配置

1、先导入pom.xml依赖

2、创建RestTemplateConfig配置类

3、User实体类

三、对象和方法讲解

1、getForEntity()方法

2、postForObject() 方法

3、exchange()方法

4、execute()方法

5、HttpEntity对象

6、RequestCallback对象

四、发送Get请求

1、参数拼接 

2、占位符传参

3、请求头携带Token

4、请求头携带Cookie

五、发送Post请求   

1、带@RequestBody

2、不带@RequestBody  

3、请求头携带Token

六、发送Put请求

1、无返回值

2、带返回值 

3、请求头携带Token

七、发送DELETE请求 

1、无返回值

2、有返回值

3、请求头携带Token 

八、文件上传 

九、文件下载 

十、总结


一、RestTemplate简介

RestTemplateSpring框架用来访问RESTFUL服务的客户端模板类,主要功能有:

1、发起HTTP请求,包括GETPOSTPUTDELETE等方法。

2、自动将响应结果映射为对象,不用手动解析JSONXML。

3、设置请求头、消息转码、Cookie等功能。

4、对不同的输入/输出类型提供对应的方法,如字符串、对象、多部分等。

5、支持远程调用,不受同源策略限制。

二、基础配置

1、先导入pom.xml依赖

    <dependencies>

        <!-- RestTemplate需要的依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Lombok依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- 单元测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

2、创建RestTemplateConfig配置类

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

3、User实体类

package com.example.resttemplate.domain;

public class User {

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    private int id;
    private String username;

    private String password;

    private int sex;

    private String address;

    private String phone;

    private String remark;

}

三、对象和方法讲解

1、getForEntity()方法

方法简介:

执行HTTP GET请求,并将返回结果自动封装为指定的Java对象。

方法签名:

<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)

参数含义:

url:请求的URL。

responseType:响应结果的类型。指定要封装成哪个Java对象,它可以是POJO或者任何Java类型。

uriVariables:URL中的变量,如果URL中有{id}这样的变量,这里就传入具体的值。

2、postForObject() 方法

方法简介:

执行HTTP POST请求,并自动将响应结果封装为指定的Java对象。

方法签名:

public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables) 

参数含义:

url:请求的URL。

request:POST请求的实体,可以是任何Java对象。

responseType:响应结果的类型,指定要封装成哪个Java对象。

uriVariables:URL中的变量替换值。

3、exchange()方法

方法简介:

执行HTTP请求,并返回ResponseEntity对象。

方法签名:

public <T> ResponseEntity<T> exchange(URI url, 
                                      HttpMethod method, 
                                      HttpEntity<?> requestEntity,
                                      Class<T> responseType,
                                      Object... uriVariables)

参数含义: 

url:请求的URL。

method:请求的HTTP方法,如GET、POST等。

requestEntity:请求的实体,包含请求头和请求体。

responseType:响应结果的类型。

uriVariables:URL中的变量替换值。

4、execute()方法

方法简介:

执行HTTP请求,允许高度定制HTTP请求。

参数含义: 

url:请求的URL,可以是String或URL对象。

method:HTTP方法,如GET、POST、PUT等。

requestCallback:处理Request的Callback对象,用于定义Request,如设置请求头、查询字符串参数等等。

responseExtractor:处理Response的Callback对象,用于提取Response内容。

5、HttpEntity对象

对象简介:

Spring框架定义的数据结构,它表示一个完整的HTTP请求或响应。

它主要有两个作用:

1、表示HTTP请求:当表示HTTP请求时,HttpEntity有两个主要组成部分:请求头和请求体。

2、表示HTTP响应当表示HTTP响应时,有三个部分:状态码、响应头和响应体。

通过HttpEntity我们可以方便的构建和处理HTTP请求和响应。

主要参数:

headers:HttpHeaders类型,包括所有头信息。

body:请求或响应体,可以是任何对象。

statusCode:HttpStatus类型,只有在表示响应时才有效。

6、RequestCallback对象

RequestCallback是Spring RestTemplate中用来定制HTTP请求的一个接口,可以设置请求头、请求体、查询字符串参数。Callback接口只有一个方法:

void doWithRequest(ClientHttpRequest request) throws IOException

在该方法中可以调用ClientHttpRequest对象的方法来定制Request。

如设置请求头:

new RequestCallback() {
    public void doWithRequest(ClientHttpRequest request) {
        request.getHeaders().set("myHeader", "myValue");
    }
}

设置请求体:

new RequestCallback() {      
    public void doWithRequest(ClientHttpRequest request) {
       request.getBody() 
             .write(("some data".getBytes());
    }
}

设置查询参数:

new RequestCallback() {
    public void doWithRequest(ClientHttpRequest request) {
        MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
        map.add("param1", "value1");
        request.setURI(request.getURI(), map);
    }
}

四、发送Get请求

请求层是这样写的

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/getUserByUsername")
    public User getUserById(@RequestParam("username") String username,
                              @RequestParam("address") String address){
        ....//业务代码   
        return user;
    }
}

这样写也可以:

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/getUserByUsername")
    public User getUserById(User user){
        ....//业务代码   
        return user;
    }
}

1、参数拼接 

直接把参数拼接在url上面:

    @Resource
    private RestTemplate restTemplate;

    public void sendGet(){
        String url = "http://localhost:8080/user/getUserByUsername?username=张三&&address=上海";
        ResponseEntity<String> result = restTemplate.getForEntity(url, String.class);
        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());
        System.out.println(result.getHeaders());
    }

执行结果如下:

2、占位符传参

直接在方法中指定参数:

    @Resource
    private RestTemplate restTemplate;
    
    public void sendGet(){
        String url = "http://localhost:8080/user/getUserByUsername?username={name}&address={address}";
        ResponseEntity<String> result = restTemplate.getForEntity(url, String.class,"李四","广东");
        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());
        System.out.println(result.getHeaders());
    }

执行结果如下:

通过Map集合传递参数,此种方式必须使用占位符,并且map中的key值,要与请求路径中的占位符一致 : 

    @Resource
    private RestTemplate restTemplate;

    public void sendGet(){
        String url = "http://localhost:8080/user/getUserByUsername?username={username}&address={address}";
        Map<String, Object> map = new HashMap<>();
        map.put("username", "李四");
        map.put("address", "广东");
        ResponseEntity<String> result = restTemplate.getForEntity(url,String.class,map);
        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());
        System.out.println(result.getHeaders());
    }

执行结果如下:

3、请求头携带Token

定义头信息:

HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());

创建一个HttpEntity对象,用于封装HTTP请求的头信息:

HttpEntity<Object> entity = new HttpEntity<>(headers);

使用exchange方法发送Get请求:

ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.GET,entity, String.class);

完整代码:

    @Resource
    private RestTemplate restTemplate;

    public void sendGet(){
        HttpHeaders headers = new HttpHeaders();
        headers.add("token", UUID.randomUUID().toString());
        String url = "http://localhost:8080/user/getUserByUsername?username=李四&&address=广东";
        HttpEntity<Object> entity = new HttpEntity<>(headers);
        ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.GET,entity, String.class);
        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());
        System.out.println(result.getHeaders());
    }

执行结果如图: 

4、请求头携带Cookie

创建一个Cookie:

Cookie cookie = new Cookie("cookie", UUID.randomUUID().toString());

放入请求头当中 :

HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.COOKIE, cookie.toString());

完整代码:

    @Resource
    private RestTemplate restTemplate;

    public void sendGet(){
        Cookie cookie = new Cookie("cookie", UUID.randomUUID().toString());
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.COOKIE, cookie.toString());
        String url = "http://localhost:8080/user/getUserByUsername?username=李四&&address=广东";
        HttpEntity<Object> entity = new HttpEntity<>(headers);
        ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.GET,entity, String.class);
        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());
        System.out.println(result.getHeaders());
    }

执行结果如图:

五、发送Post请求   

请求层用到了@RequestBody注解接收参数,具体是这么写的:

@RestController
@RequestMapping("/user")
public class UserController {

    @PostMapping("/insert")
    public String insertUser(@RequestBody User user){
        ...//逻辑代码
        return message;
    }
    
}

下面进行发送Post请求测试。 

1、带@RequestBody

如果请求层是带有@RequestBody注解的,可以通过Json格式进行传参:

    @Resource
    private RestTemplate restTemplate;

    public void sendPost(){
        User user = new User();
        user.setId(2);
        user.setUsername("赵七");
        user.setSex(1);
        user.setPassword("123456");
        user.setAddress("江苏");
        user.setPhone("123123123");
        user.setRemark("无");
        String url = "http://localhost:8080/user/insert";
        String result = restTemplate.postForObject(url, user, String.class);
        System.out.println(result);
    }

运行结果如下:

我们也可以通过Map集合进行传参,效果是一样的:

    @Resource
    private RestTemplate restTemplate;
    
    public void sendPost(){
        Map<String, Object> map = new HashMap<>();
        map.put("id", 5);
        map.put("username","赵七");
        map.put("sex",1);
        map.put("password","123456");
        map.put("address","江苏");
        map.put("phone","123123123");
        map.put("remark","无");
        String url = "http://localhost:8080/user/insert";
        String result = restTemplate.postForObject(url, map, String.class);
        System.out.println(result);
    }

执行结果如下:

2、不带@RequestBody  

如果请求层不带这个注解,用上面的两种方法来传递参数是获取不到!

MultiValueMap常用于封装HTTP请求头或查询参数,它可以同一个key下面放多个value,我们也可以通过MultiValueMap集合来进行传递参数:

    @Resource
    private RestTemplate restTemplate;    

    public void sendPost(){
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        map.add("id", 5);
        map.add("username","赵七");
        map.add("sex",1);
        map.add("password","123456");
        map.add("address","江苏");
        map.add("phone","123123123");
        map.add("remark","无");
        String url = "http://localhost:8080/user/insert";
        String result = restTemplate.postForObject(url, map, String.class);
        System.out.println(result);
    }

运行结果如下:

3、请求头携带Token

定义头信息:

HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());

使用HttpEntity把请求对象user和header进行组装:

HttpEntity<User> userHttpEntity = new HttpEntity<>(user, headers);

完整代码如下:

    @Resource
    private RestTemplate restTemplate;    

    public void sendPost(){
        HttpHeaders headers = new HttpHeaders();
        headers.add("token", UUID.randomUUID().toString());
        User user = new User();
        user.setId(2);
        user.setUsername("赵七");
        user.setSex(1);
        user.setPassword("123456");
        user.setAddress("江苏");
        user.setPhone("123123123");
        user.setRemark("无");
        String url = "http://localhost:8080/user/insert";
        // 使用 HttpEntity 把请求对象user 和 header 进行组装
        HttpEntity<User> userHttpEntity = new HttpEntity<>(user, headers);
        String result = restTemplate.postForObject(url, userHttpEntity, String.class);
        System.out.println(result);
    }

运行结果如下:

六、发送Put请求

请求层是这么写的:

@RestController
@RequestMapping("/user")
public class UserController {

    @PutMapping
    public String update(@RequestBody User user){
        ...//业务代码
        return message;
    }
}

1、无返回值

直接调用put方式是不带返回值的:

    @Resource
    private RestTemplate restTemplate;    

    public void update(){
        String url = "http://localhost:8080/user";
        User user = new User();
        user.setId(2);
        user.setUsername("赵七");
        user.setSex(1);
        user.setPassword("123456");
        restTemplate.put(url, user);
    }

2、执行结果如下:

2、带返回值 

我们使用exchange方法就可以了,具体代码如下:

    @Resource
    private RestTemplate restTemplate; 
   
    public void update(){
        String url = "http://localhost:8080/user";
        User user = new User();
        user.setId(2);
        user.setUsername("赵七");
        user.setSex(1);
        user.setPassword("123456");
        HttpEntity<User> body = new HttpEntity<>(user);
        ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.PUT,body,String.class);
        System.out.println(result);
    }

执行结果如图:

3、请求头携带Token

定义头信息:

HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());

使用HttpEntity把请求对象user和header进行组装,然后调用exchange方法即可:

HttpEntity<User> body = new HttpEntity<>(user,headers);

七、发送DELETE请求 

请求层是这样写的:

@RestController
@RequestMapping("/user")
public class UserController {

    @DeleteMapping("{id}")
    public String delete(@PathVariable String id){
        ...//业务代码
        return message;
    }
}

1、无返回值

直接调用delete方式是不带返回值的:

    @Resource
    private RestTemplate restTemplate;

    public void update(){
        String url = "http://localhost:8080/user/{id}";
        restTemplate.delete(url,1);
    }

执行结果如图:

2、有返回值

使用exchange方法执行即可,具体代码如下:

    @Resource
    private RestTemplate restTemplate;

    public void update(){
        String url = "http://localhost:8080/user/1";
        ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.DELETE,null,String.class);
        System.out.println(result);
    }

执行结果如下:

3、请求头携带Token 

定义头信息

HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());

使用HttpEntity把请求对象user和header进行组装,然后调用exchange方法即可:

HttpEntity<User> body = new HttpEntity<>(headers);
ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.DELETE,body,String.class);

八、文件上传 

请求层代码:

@RestController
@RequestMapping("/user")
public class UserController {

    @PostMapping("/upload")
    public String upload(MultipartFile file){
        return file.getOriginalFilename();
    }

}

设置请求头:

HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());

创建一个FileSystemResource,将文件封装为resource:

File file = new File("F:/test.jar");
FileSystemResource resource = new FileSystemResource(file);

创建一个MultiValueMap,将文件添加进去,键名是"file":

MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
multiValueMap.add("file", resource);

使用MultiValueMap和headers创建HttpEntity,表示这是个POST请求,且请求体是文件,发送POST请求到url,请求体是前面创建的HttpEntity:

HttpEntity< MultiValueMap<String, Object>> request = new HttpEntity<>(multiValueMap, headers);
ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, request, String.class);

完整代码:

    @Resource
    private RestTemplate restTemplate;

    public void sendFile(){
        String url = "http://localhost:8080/user/upload";
        HttpHeaders headers = new HttpHeaders();
        headers.add("token", UUID.randomUUID().toString());
        File file = new File("F:/test.jar");
        FileSystemResource resource = new FileSystemResource(file);

        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        multiValueMap.add("file", resource);

        HttpEntity< MultiValueMap<String, Object>> request = new HttpEntity<>(multiValueMap, headers);
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
        System.out.println(exchange);
    }

7、执行结果如图:

九、文件下载 

请求层具体是这么写的:

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/download")
    public void download(HttpServletResponse response) throws IOException {
        File file = new File("D:\\test.jar");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=test.jar");

        InputStream in = new FileInputStream(file);
        IOUtils.copy(in, response.getOutputStream());
    }
}

定义请求头,申明可以接收所有类型的响应内容:

RequestCallback requestCallback = request -> request.getHeaders()
        .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));

使用流的方式读取响应内容,而不是将响应内容全部加载到内存中 :

restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
    Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
    return null;
});

完整代码:

    @Resource
    private RestTemplate restTemplate;

    public void download() throws MalformedURLException {
        String url = "http://localhost:8080/user/download";

        String targetPath = "test.jar";

        RequestCallback requestCallback = request -> request.getHeaders()
                .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));

        restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
            Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
            return null;
        });
    }

执行结果如下:

十、总结

以上就是对于日常使用RestTemplate常用功能的一些汇总,如有异议和遗漏欢迎评论区补充。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/728087.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

缓存穿透、缓存击穿、缓存雪崩详解以及解决方案

缓存穿透、缓存击穿、缓存雪崩详解以及解决方案 一。缓存穿透 查询一个不存在的数据&#xff0c;mysql查询不到数据也不会直接写入缓存&#xff0c;就会导致每次请求都查数据库 方案一&#xff1a; 方案二&#xff1a; 二。缓存击穿 给某一个key设置了过期时间&#xff0…

Mongdb之Robo3T

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;MyBatis详解 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你的加入: 林在闪闪发光的…

2023年PTA行业研究报告

第一章 行业概况 精对苯二甲酸&#xff08;Pure Terephthalic Acid&#xff0c;简称PTA&#xff09;是一种主要用于制造聚酯纤维和塑料的关键化学品。PTA是一种白色结晶固体&#xff0c;可通过对苯二酮在催化剂的作用下进行氧化得到。它是聚对苯二甲酸乙二醇酯&#xff08;PET…

机器视觉三维重建

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D开发工具链。 1、Meshroom ⭐4,474 Meshroom是一款基于AliceVision摄影测量计算机视觉框架的免费开源三维重建软件。 https://github.com/alicevision/meshroom 2、Openmvg ⭐2,829 Openmvg库根据三维计算机视觉和结构的运动。…

Web3 通过truffle 脚本进行智能合约测试

上文 Web3 处理智能合约部署到本地区块链&#xff0c;并在本地进行测试中 我们讲解了部署智能合约 然后在终端测试的方法 但上文那种终端测试 其实并不保险 而且也比较不专业 对于这个 有一个mocha测试 这是基于node部署环境的一种环境测试 但是这个需要一定的基础 大家可以专门…

国产BI工具和国外BI工具,差距大不大,用哪种比较好?

自“十四五”以来&#xff0c;我国诸多政策开始推动信创产业的深入&#xff0c;实现关键数字技术自主研发和自主可控。我国信创产业竞争力不断突破&#xff0c;国产化进程稳步推进。2022年开始政策重点提及“数字经济”、“数字政府”和国家信息化。在此背景下&#xff0c;BI产…

el-date-picker 的初始化数据格式理解、报错 “TypeError: date.getFullYear is not a function“

个人理解 如果后端传给前端的时间数据是字符串类型的&#xff0c;那么当触发 el-date-picker 组件时&#xff0c;就会报出很多错误&#xff0c;例如 这是由于初始化赋值格式的问题&#xff0c;需要对初始化值&#xff0c;进行一个 new Date(your_time_data) 前端演示模板&…

虚拟机快速克隆的步骤

目录 1、关于让应用的快捷方式出现在开始栏的方法2、使用VMware快速克隆2-12-22-32-42-5 克隆虚拟机命名 1、关于让应用的快捷方式出现在开始栏的方法 把应用的快捷方式&#xff0c;放到这个目录中 C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs2、…

uniapp app分享pdf等文件等到微信以及其他应用

uniapp自带的api uni.share只能分享图文等&#xff0c;但不能分享pdf这种之类的 想实现分享文件这种就要调用系统的分享功能 分享插件地址 这个插件完美解决&#xff0c;安卓分享到微信也不需要配置appid 封装用法 /*** 任意文件分享,需勾选云插件并云打包* 安卓调用系统分享无…

DFS解决N-皇后问题

题目&#xff1a; n−皇后问题是指将 n个皇后放在 nn的国际象棋棋盘上&#xff0c;使得皇后不能相互攻击到&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。 现在给定整数 n&#xff0c;请你输出所有的满足条件的棋子摆法。 输入格式 共一行&#xff0c;包…

《IntelliJ IDEA 2023最新版快捷键大全GIF动图演示》——提升你的开发效率

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

用css来实现上下左右箭头

i {/* 用border值来控制箭头粗细 */border: 3px solid black;/* 上、右、下、左 四个边框的宽度 */border-width: 0px 1px 1px 0px;display: inline-block;/* padding值控制箭头大小 */padding: 5px; } ____________________________________.right {transform: rotate(-45deg…

浮动——案例

案例1——做出如下图的框架 提示&#xff1a;用ul li来完成 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sc…

KnowStreaming系列教程第一篇——安装和使用

KnowStreaming介绍 Know Streaming是一套云原生的Kafka管控平台&#xff0c;脱胎于众多互联网内部多年的Kafka运营实践经验&#xff0c;专注于Kafka运维管控、监控告警、资源治理、多活容灾等核心场景。在用户体验、监控、运维管控上进行了平台化、可视化、智能化的建设&#…

一份保姆级的Stable Diffusion部署教程,开启你的炼丹之路 | 京东云技术团队

市面上有很多可以被用于AI绘画的应用&#xff0c;例如DALL-E、Midjourney、NovelAI等&#xff0c;他们的大部分都依托云端服务器运行&#xff0c;一部分还需要支付会员费用来购买更多出图的额度。在2022年8月&#xff0c;一款叫做Stable Diffusion的应用&#xff0c;通过算法迭…

利用css实现渐变色(通俗易懂)

利用css实现渐变色 0、前言1、线性渐变2、径向渐变2.1 径向渐变2.1.1 圆形2.1.2 椭圆形 2.2 重复性径向渐变 3、边框颜色渐变3.1 边框渐变3.1.1 线性渐变3.1.2 径向渐变 3.2 单侧边框渐变3.2.1 底部边框线性渐变3.2.2 右侧边框线性渐变 4、扩展&#xff08;CSS线性渐变颜色网站…

vscode离线安装插件提示版本不兼容,安装失败的处理方法

因为公司是内网&#xff0c;无法在线下载插件&#xff0c;只能通过离线下载的方式安装插件&#xff0c;但是提示版本不兼容&#xff0c;安装失败&#xff0c;后面解决了&#xff0c;记录一下处理方法。 1. 首先查看vscode版本号 2. 将.vsix文件压缩 然后打开压缩文件&#x…

Lesson3-2:OpenCV图像处理---形态学操作

形态学操作 学习目标 理解图像的邻域&#xff0c;连通性 了解不同的形态学操作&#xff1a;腐蚀&#xff0c;膨胀&#xff0c;开闭运算&#xff0c;礼帽和黑帽等&#xff0c;及其不同操作之间的关系 1 连通性 在图像中&#xff0c;最小的单位是像素&#xff0c;每个像素周围…

springboot dubbo seata nacos集成 分布式事务seata实现

文章目录 Seata介绍dubbo介绍目标版本说明和代码地址pom.xml验证模块microservice-boot-commonmicroservice-boot- plat 验证结果注意事项 Seata介绍 官网&#xff1a;http://seata.io/zh-cn/docs/overview/what-is-seata.html Seata 是一款开源的分布式事务解决方案&#xff…

从零开始 Spring Boot 63:Hibernate 继承映射

从零开始 Spring Boot 63&#xff1a;Hibernate 继承映射 图源&#xff1a;简书 (jianshu.com) 关系型数据库设计中是不存在继承概念的&#xff0c;但实体类可以用继承来组织代码结构&#xff0c;所以需要用一种方式将实体类的继承结构映射到表结构。 本文将介绍几种在 JPA&a…