接口调用神器RestTemplate(三)

简介: 接口调用神器RestTemplate

4、POST 请求

4.1、post 请求常见的 3 种类型

http 请求头中的 Content-Type 用来指定请求的类型,常见的有 3 种

Content-Type 说明
application/x-www-form-urlencoded 页面中普通的 form 表单提交时就是这种类型,表单中的元素会按照名称和值拼接好,然后之间用&连接,格式如:p1=v1&p2=v2&p3=v3然后通过 urlencoded 编码之后丢在 body 中发送
multipart/form-data 页面中表单上传文件的时候,用到的就是这种格式
application/json 将发送的数据转换为 json 格式,丢在 http 请求的 body 中发送,后端接口通常用@RequestBody 配合对象来接收。

下面看则种方式的案例。

4.2、普通表单请求

普通表单默认为 application/x-www-form-urlencoded 类型的请求。

接口代码

@PostMapping("/test/form1")
@ResponseBody
public BookDto form1(BookDto bookDto) {
    return bookDto;
}

使用 RestTemplate 调用接口

@Test
public void test10() {
    RestTemplate restTemplate = new RestTemplate();
    String url = "http://localhost:8080/chat16/test/form1";
    //①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
    MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
    //调用add方法填充表单数据(表单名称:值)
    body.add("id","1");
    body.add("name","SpringMVC系列");
    //②:发送请求(url,请求体,返回值需要转换的类型)
    BookDto result = restTemplate.postForObject(url, body, BookDto.class);
    System.out.println(result);
}

如果想携带头信息,代码如下

@Test
public void test11() {
    RestTemplate restTemplate = new RestTemplate();
    String url = "http://localhost:8080/chat16/test/form1";
    //①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
    MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
    //调用add方法放入表单元素(表单名称:值)
    body.add("id","1");
    body.add("name","SpringMVC系列");
    //②:请求头
    HttpHeaders headers = new HttpHeaders();
    //调用set方法放入请求头
    headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
    //③:请求实体:包含了请求体和请求头
    HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(body, headers);
    //④:发送请求(url,请求实体,返回值需要转换的类型)
    BookDto result = restTemplate.postForObject(url, httpEntity, BookDto.class);
    System.out.println(result);
}

4.3、上传本地文件

上传文件 Content-Type 为 multipart/form-data 类型。

接口如下,上传上传单个文件,返回值为一个 Map 类型,是泛型类型

@PostMapping(value = "/test/form2")
@ResponseBody
public Map<String, String> form2(@RequestParam("file1") MultipartFile file1) {
    Map<String, String> fileMetadata = new LinkedHashMap<>();
    fileMetadata.put("文件名", file1.getOriginalFilename());
    fileMetadata.put("文件类型", file1.getContentType());
    fileMetadata.put("文件大小(byte)", String.valueOf(file1.getSize()));
    return fileMetadata;
}

使用 RestTemplate 调用接口,主要下面代码上传的文件需要包装为org.springframework.core.io.Resource,常用的有 3 中[FileSystemResource、InputStreamResource、ByteArrayResource],这里案例中我们用到的是 FileSystemResource 来上传本地文件,另外 2 种(InputStreamResource、ByteArrayResource)用法就比较特殊了,见下个案例。

@Test
public void test12() {
    RestTemplate restTemplate = new RestTemplate();
    String url = "http://localhost:8080/chat16/test/form2";
    //①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
    MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
    //调用add方法放入表单元素(表单名称:值)
    //②:文件对应的类型,需要是org.springframework.core.io.Resource类型的,常见的有[FileSystemResource、InputStreamResource、ByteArrayResource]
    body.add("file1", new FileSystemResource(".\\src\\main\\java\\com\\javacode2018\\springmvc\\chat16\\dto\\UserDto.java"));
    //③:头
    HttpHeaders headers = new HttpHeaders();
    headers.add("header1", "v1");
    headers.add("header2", "v2");
    //④:请求实体
    RequestEntity<MultiValueMap<String, Object>> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
    //⑤:发送请求(请求实体,返回值需要转换的类型)
    ResponseEntity<Map<String, String>> responseEntity = restTemplate.exchange(
        requestEntity,
        new ParameterizedTypeReference<Map<String, String>>() {
        });
    Map<String, String> result = responseEntity.getBody();
    System.out.println(result);
}

4.4、通过流或字节数组的方式上传文件

有时候,上传的文件是通过流的方式或者字节数组的方式,那么就需要用到 InputStreamResource、ByteArrayResource 这俩了。 **注意:**使用这俩的时候,需要重写 2 个方法,否则会上传失败

  • getFilename:文件名称
  • contentLength:长度
@Test
public void test13() {
    RestTemplate restTemplate = new RestTemplate();
    String url = "http://localhost:8080/chat16/test/form2";
    //①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
    MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
    /**
     * ②:通过流的方式上传文件,流的方式需要用到InputStreamResource类,需要重写2个方法
     * getFilename:文件名称
     * contentLength:长度
     */
    InputStream inputStream = RestTemplateTest.class.getResourceAsStream("/1.txt");
    InputStreamResource inputStreamResource = new InputStreamResource(inputStream) {
        @Override
        public String getFilename() {
            return "1.txt";
        }
        @Override
        public long contentLength() throws IOException {
            return inputStream.available();
        }
    };
    body.add("file1", inputStreamResource);
    //③:头
    HttpHeaders headers = new HttpHeaders();
    headers.add("header1", "v1");
    headers.add("header2", "v2");
    //④:请求实体
    RequestEntity<MultiValueMap<String, Object>> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
    //⑤:发送请求(请求实体,返回值需要转换的类型)
    ResponseEntity<Map<String, String>> responseEntity = restTemplate.exchange(
            requestEntity,
            new ParameterizedTypeReference<Map<String, String>>() {
            });
    Map<String, String> result = responseEntity.getBody();
    System.out.println(result);
}

4.5、复杂表单:多个普通元素+多文件上传

接口

/**
 * 复杂的表单:包含了普通元素、多文件
 *
 * @param userDto
 * @return
 */
@PostMapping("/test/form3")
@ResponseBody
public Map<String, String> form3(UserDto userDto) {
    Map<String, String> result = new LinkedHashMap<>();
    result.put("name", userDto.getName());
    result.put("headImg", userDto.getHeadImg().getOriginalFilename());
    result.put("idImgList", Arrays.toString(userDto.getIdImgList().stream().
                                            map(MultipartFile::getOriginalFilename).toArray()));
    return result;
}

UserDto:包含了多个元素(姓名、头像、多张证件照),这种可以模拟复杂的表单

public class UserDto {
    //姓名
    private String name;
    //头像
    private MultipartFile headImg;
    //多张证件照
    private List<MultipartFile> idImgList;
    //get set 省略了...
}

用 RestTemplate 调用这个接口,代码如下

@Test
public void test14() {
    RestTemplate restTemplate = new RestTemplate();
    String url = "http://localhost:8080/chat16/test/form3";
    //①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
    MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
    body.add("name", "路人");
    body.add("headImg", new FileSystemResource(".\\src\\main\\resources\\1.jpg"));
    //来2张证件照,元素名称一样
    body.add("idImgList", new FileSystemResource(".\\src\\main\\resources\\2.jpg"));
    body.add("idImgList", new FileSystemResource(".\\src\\main\\resources\\3.jpg"));
    //③:头
    HttpHeaders headers = new HttpHeaders();
    headers.add("header1", "v1");
    headers.add("header2", "v2");
    //④:请求实体
    RequestEntity<MultiValueMap<String, Object>> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
    //⑤:发送请求(请求实体,返回值需要转换的类型)
    ResponseEntity<Map<String, String>> responseEntity = restTemplate.exchange(
            requestEntity,
            new ParameterizedTypeReference<Map<String, String>>() {
            });
    Map<String, String> result = responseEntity.getBody();
    System.out.println(result);
}

输出

{name=路人, headImg=1.jpg, idImgList=[2.jpg, 3.jpg]}


相关文章
|
6月前
|
Java Spring
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
126 0
|
Java
SpringBoot 整合JWT实现基于自定义注解的-登录请求验证拦截(保姆级教学,附:源码)2
SpringBoot 整合JWT实现基于自定义注解的-登录请求验证拦截
218 0
|
JSON Java Maven
接口调用神器RestTemplate(四)
接口调用神器RestTemplate
144 1
|
缓存
RestTemplate请求访问简单使用
RestTemplate请求访问简单使用
95 1
|
6月前
|
小程序 前端开发 JavaScript
java后台restTemplate生成二小程序维码,前端渲染
java后台restTemplate生成二小程序维码,前端渲染
147 0
|
6月前
|
小程序
uniapp 微信小程序请求拦截器 接口封装
uniapp 微信小程序请求拦截器 接口封装
|
Java 测试技术 Apache
接口调用神器RestTemplate(一)
接口调用神器RestTemplate
106 0
|
JSON Java 数据格式
SpringBoot使用RestTemplate访问第三方接口
SpringBoot使用RestTemplate访问第三方接口
SpringBoot使用RestTemplate访问第三方接口
|
JSON Java fastjson
restTemplate 调用第三方接口获取json数据
restTemplate 调用第三方接口获取json数据