RestTemplate请求访问简单使用

简介: RestTemplate请求访问简单使用

RestTemplate 发送 GET 请求

RestAPI - 通过@RequestParam接收参数的GET接口

@RequestMapping(value = "accounts/filter", method = RequestMethod.GET)
public Account filter(@RequestParam String name, @RequestParam Integer age) {
    return new Account(new Random().nextLong(), name, age, "********");
}

RestTemplate Demo

/**
 * 使用 RestTemplate 发送 GET 请求
 * RestTemplate 发送 GET 请求时,如果需要传入参数,需要以示例方法 url 的方式传入
 * RestTemplate有两组方法发送 Get 请求
 * <code>
 * restTemplate.getForObject(String url, Class responseType, Map uriVariables)<br/>
 * restTemplate.getForEntity(String url, Class responseType, Map uriVariables)<br/>
 * </code>
 * restTemplate.getForObject是对restTemplate.getForEntity的简化,<br/>
 * 通过restTemplate.getForEntity,我们可以获取HttpStatus的相关信息并加以使用.<br/>
 * 如果我们不关心 HttpStatus,那么使用 restTemplate.getForObject() 即可.
 */
@Test
public void getMethodTest() {
    // http://ip:port/project-name/accounts/filter
    String url = "http://192.168.1.121:9001/rest-server/accounts/filter?name={name}&age={age}";
    RestTemplate restTemplate = new RestTemplate();
    Map<String, Object> params = new HashMap<>();
    params.put("age", "26");
    params.put("name", "lee");
    Account account = restTemplate.getForObject(url, Account.class, params);
    System.out.println(account);
    // 上面 2 行等价于下面 5 行
    /*ResponseEntity<Account> responseEntity = restTemplate.getForEntity(url, Account.class, params);
    if (responseEntity.getStatusCode().is2xxSuccessful()) {
        Account account1 = responseEntity.getBody();
        System.out.println(account1);
    }*/
}

RestAPI - 通过@PathVariable提取url变量的GET接口

@RequestMapping(value = "accounts/{id}", method = RequestMethod.GET)
public Account get(@PathVariable("id") Long id, @RequestParam String name) {
    return new Account(id, name, 18, "!@#$%^&*");
}

RestTemplate Demo

@Test
public void getMethodTest2() {
    String url = "http://192.168.1.121:9001/rest-server/accounts/{id}?name={name}";
    RestTemplate restTemplate = new RestTemplate();
    Map<String, Object> params = new HashMap<>();
    params.put("id", "100001");
    params.put("name", "libai");
    Account account = restTemplate.getForObject(url, Account.class, params);
    Assert.assertEquals(account.toString(), "Account{id=100001, age=18, name='libai', pwd='!@#$%^&*'}");
}12345678910

使用 RestTemplate 发送 POST 请求

RestAPI - 使用@RequestBody接收请求参数的POST接口

@RequestMapping(value = "accounts", method = RequestMethod.POST)
public Account create(@RequestBody Account account) {
    return account;
}

RestTemplate Demo

/**
 * 使用 RestTemplate 发送 POST 请求<br/>
 * 请求接口:{@link RestServer#create(Account)}<br/>
 * <br/>
 * 根据接口{@link RestServer#create(Account)}的要求,我们需要使用Payload提交方式来提交数据<br/>
 * Payload提交方式区别于Form提交方式<br/>
 * Form提交方式提交的数据,服务端可以通过{@link HttpServletRequest#getParameter(String)}方法获取,<br/>
 * 体现在SpringMVC框架中,即数据参数通过 {@link org.springframework.web.bind.annotation.RequestParam} 注解绑定获取<br/>
 * Payload提交方式提交的数据,服务端可以通过{@link HttpServletRequest#getInputStream()}方法获取,<br/>
 * 体现在SpringMVC框架中,即数据参数通过 {@link org.springframework.web.bind.annotation.RequestBody} 注解绑定获取<br/>
 * <br/>
 * RestTemplate 默认使用 Payload 方式提交数据,数据的格式是 json。<br/>
 * 即本示例中 <code>params</code> 会被格式化成 json 格式数据,并放在request body中发送给服务端
 */
@Test
public void postMethodTest() {
    String url = "http://192.168.1.121:9001/rest-server/accounts";
    RestTemplate restTemplate = new RestTemplate();
    Map<String, Object> params = new HashMap<>();
    params.put("id", "100001");
    params.put("name", "李白");
    params.put("age", "100001");
    params.put("pwd", "&*()#$%^");
    Account account = restTemplate.postForObject(url, params, Account.class);
    System.out.println(account);
}

RestAPI - 使用@RequestParam接收请求参数的POST接口

@RequestMapping(value = "accounts/create", method = RequestMethod.POST)
public Account create(@RequestParam Long id,
                        @RequestParam String name,
                      @RequestParam Integer age,
                      @RequestParam String pwd) {
    return new Account(id, name, age, pwd);
}

RestTemplate Demo

/**
 * 使用 RestTemplate 发送 POST 请求<br/>
 * 请求接口:{@link RestServer#create(Long, String, Integer, String)}<br/>
 * <br/>
 * 根据接口 {@link RestServer#create(Long, String, Integer, String)}的要求,我们需要使用Form提交方式来提交数据<br/>
 * RestTemplate 默认使用 Payload 方式提交数据,想要使用Form方式提交,需要通过 HttpHeaders 设置<br/>
 * 另外,多个参数需要使用{@link LinkedMultiValueMap}来封装
 */
@Test
public void postMethodTest2() {
    String url = "http://192.168.1.121:9001/rest-server/accounts/create";
    RestTemplate restTemplate = new RestTemplate();
    // 此处不能换成 HashMap
    MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
    params.add("id", "100001");
    params.add("name", "杜甫");
    params.add("age", "100001");
    params.add("pwd", "&*()#$%^");
    // 通过 HttpHeaders 设置Form方式提交
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(params, headers);
    Account account = restTemplate.postForObject(url, httpEntity, Account.class);
    System.out.println(account);
}

使用 RestTemplate 发送带有 HttpHeader 信息的请求

RestAPI - 使用@RequestHeader获取请求头信息的POST接口

@RequestMapping(value = "accounts/authorization", method = RequestMethod.POST)
public Account create(@RequestHeader("authorization") String authorization,
                      @RequestHeader("token") String token,
                      @RequestBody Account account) {
    if (authorization.equals("12345678") && token.equals("bce235emn97jjf00")) {
        return account;
    }
    return new Account();
}

RestTemplate Demo

@Test
public void httpHeaderTest() {
    String url = "http://192.168.1.121:9001/rest-server/accounts/authorization";
    HttpHeaders headers = new HttpHeaders();
    headers.add("authorization", "12345678");
    headers.add("token", "bce235emn97jjf00");
    Map<String, Object> params = new HashMap<>();
    params.put("id", "100001");
    params.put("name", "李白");
    params.put("age", "100001");
    params.put("pwd", "&*()#$%^");
    HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(params, headers);
    RestTemplate restTemplate = new RestTemplate();
    Account account = restTemplate.postForObject(url, httpEntity, Account.class);
    System.out.println(account.toString());
}

使用 RestTemplate 进行文件上传

使用@RequestPart接收文件上传请求的POST接口

@RequestMapping(value = "accounts/logo", method = RequestMethod.POST)
public boolean changeLogo(@RequestPart("logo") MultipartFile file, 
    @RequestParam(value = "nickname", required = false) String nickname) throws IOException {
    String fileName = file.getOriginalFilename();
    File f = new File(fileName);
    file.transferTo(f);
    System.out.println(f.getAbsolutePath());
    return true;
}

RestTemplate Demo

@Test
public void uploadImgTest() {
    String url = "http://192.168.1.121:9001/rest-server/accounts/logo";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
    params.add("logo", new FileSystemResource("C:\\Users\\lixiangke\\Pictures\\Saved Pictures\\jdsadh.jpg"));
    params.add("nickname", "nick");
    HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(params, headers);
    RestTemplate restTemplate = new RestTemplate();
    String str = restTemplate.postForObject(url, httpEntity, String.class);
    System.out.println(str);

Account.java

package com.springboot.web.rest_template;
/**
 * @author odllu
 */
public class Account {
    private Long id;
    private int age;
    private String name;
    private String pwd;
    public Account() {
    }
    public Account(Long id, String name, int age, String pwd) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.pwd = pwd;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

RESTful文件上传与下载

文件上传

    @Test
    public void whenUploadSuccess() {
        try {
            String file = mockMvc.perform(MockMvcRequestBuilders.fileUpload("/file")
                    .file(new MockMultipartFile("file", "test.txt",
                            "multipart/form-data", "hello upload".getBytes("UTF-8"))))
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andReturn().getResponse().getContentAsString();
            log.info("file:{}",file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @PostMapping
    public FileInfo upload(MultipartFile file) {
        log.info(file.getName());
        log.info(file.getOriginalFilename());
        log.info(String.valueOf(file.getSize()));
        File localFile = new File(folder, new Date().getTime() + ".txt");
        try {
            file.transferTo(localFile);
            return new FileInfo(localFile.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

文件下载

    @GetMapping("/{id}")
    public void download(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
        try (InputStream ips = new FileInputStream(new File(folder, id + ".txt"));
             OutputStream ops = response.getOutputStream();) {
            response.setContentType("application/x-download");
            response.setHeader("Content-Disposition", "attachment;filename=test.txt");
            IOUtils.copy(ips, ops);
            ops.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

个人代码:

  /**
     * 文件下载/预览
     *
     * @param
     * @return
     * @throws ApiException
     */
    @GetMapping(value = "/downloadEmailFile/{fileId}")
    @ApiOperation(value = "文件下载/预览", notes = "文件下载/预览")
    public void downloadEmailFile(@PathVariable String fileId, HttpServletResponse response) throws ApiException {
        byte[] body =fileInfoService.downFileByte(fileId);
        FileInfoVO fileInfoById = fileInfoService.getFileInfoById(fileId);
        InputStream inputStream=new ByteArrayInputStream(body);
        try (
                OutputStream ops = response.getOutputStream();)
        {
            response.setContentType("application/x-download");
            response.setHeader("Content-Disposition", "attachment;filename="+fileInfoById.getFileSysName());
            IOUtils.copy(inputStream, ops);
            ops.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

RestTemplate无法@Autowired注入解决

package com.oldlu.lcls;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@EnableSwagger2
@MapperScan("com.oldlu.lcls.DAO")
public class LclsApplication {
    //防止RestTemplate无法自动装配
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(LclsApplication.class, args);
    }
}

RestTemplate请求上传文件(MultipartFile不缓存文件)

  • 背景
  1. 有两个服务,A服务有一个文件上传的接口,B服务通过restTemplate调用A服务的接口上传一个文件。
  1. B服务已经拿到文件内容。那么是否能够在不需要生成临时文件的情况下上传文件到A服务呢?
  • 实现过程
  1. 定义内容
String fileStr = "文件内容";
  1. 字符串转换成byte[]
byte[] xmlBytes = fileStr.getBytes();
  1. 自定义MultipartFile实现类
     public class BASE64DecodedMultipartFile implements MultipartFile {
         // 上传文件字节流
         private final byte[] imgContent;
         // 上传文件的文件名
         private final String originalFilename;
         public BASE64DecodedMultipartFile(byte[] imgContent, String originalFilename) {
             this.imgContent = imgContent;
             this.originalFilename = originalFilename;
         }
         @Override
         public String getName() {
             // TODO - implementation depends on your requirements
             return null;
         }
         @Override
         public String getOriginalFilename() {
             // TODO - implementation depends on your requirements
             return this.originalFilename;
         }
         @Override
         public String getContentType() {
             // TODO - implementation depends on your requirements
             return null;
         }
         @Override
         public boolean isEmpty() {
             return imgContent == null || imgContent.length == 0;
         }
         @Override
         public long getSize() {
             return imgContent.length;
         }
         @Override
         public byte[] getBytes() throws IOException {
             return imgContent;
         }
         @Override
         public InputStream getInputStream() throws IOException {
             return new ByteArrayInputStream(imgContent);
         }
         @Override
         public void transferTo(File dest) throws IOException, IllegalStateException {
             new FileOutputStream(dest).write(imgContent);
         }
     }
  1. 构造上传文件对象
MultipartFile mf = new BASE64DecodedMultipartFile(xmlBytes, fileName);
  1. 通过restTemplate调用远程接口
     HttpHeaders headers = new HttpHeaders();
     headers.setContentType(MediaType.MULTIPART_FORM_DATA);
     MultiValueMap<String, Object> requestparams = new LinkedMultiValueMap<>();
     requestparams.add("file", mf.getResource());
     requestparams.add("filename", mf.getOriginalFilename());
     HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(requestparams, headers);
     RestTemplate restTemplate = new RestTemplate();
     Object resultVo = restTemplate.postForObject(url, requestEntity, Object.class);

其中的文件可以传递一下资源

如果需要缓存文件直接将MultipartFile转换为本地File

File和MultipartFile互相转化工具类

目录
相关文章
|
Java Spring
spring boot 配置log4j 日志
spring boot 配置log4j 日志
485 0
|
Java
Java 清空 List 的多种方法?
Java 清空 List 的多种方法?
2798 0
|
5月前
|
消息中间件 数据可视化 Kafka
docker arm架构部署kafka要点
本内容介绍了基于 Docker 的容器化解决方案,包含以下部分: 1. **Docker 容器管理**:通过 Portainer 可视化管理工具实现对主节点和代理节点的统一管理。 2. **Kafka 可视化工具**:部署 Kafka-UI 以图形化方式监控和管理 Kafka 集群,支持动态配置功能, 3. **Kafka 安装与配置**:基于 Bitnami Kafka 镜像,提供完整的 Kafka 集群配置示例,涵盖 KRaft 模式、性能调优参数及数据持久化设置,适用于高可用生产环境。 以上方案适合 ARM64 架构,为用户提供了一站式的容器化管理和消息队列解决方案。
410 10
|
7月前
|
Java Spring
JDK动态代理和CGLIB动态代理的区别
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理: ● JDK动态代理只提供接口的代理,不支持类的代理Proxy.newProxyInstance(类加载器, 代理对象实现的所有接口, 代理执行器) ● CGLIB是通过继承的方式做的动态代理 , 如果某个类被标记为final,那么它是无法使用 CGLIB做动态代理的。Enhancer.create(父类的字节码对象, 代理执行器)
|
安全 Java 开发者
Spring Security自定义认证异常和授权异常
Spring Security自定义认证异常和授权异常
1265 4
|
人工智能 计算机视觉
AI计算机视觉笔记十五:编写检测的yolov5测试代码
该文为原创文章,如需转载,请注明出处。本文作者在成功运行 `detect.py` 后,因代码难以理解而编写了一个简易测试程序,用于加载YOLOv5模型并检测图像中的对象,特别是“人”类目标。代码实现了从摄像头或图片读取帧、进行颜色转换,并利用YOLOv5进行推理,最后将检测框和置信度绘制在输出图像上,并保存为 `result.jpg`。如果缺少某些模块,可使用 `pip install` 安装。如涉及版权问题或需获取完整代码,请联系作者。
|
前端开发 Java 测试技术
Spring、SpringMVC、SpringBoot、SpringCloud 框架常用注解说明
Spring、SpringMVC、SpringBoot、SpringCloud 框架常用注解说明
683 1
|
JSON JavaScript 前端开发
JS对象和字符串的相互转换
JS对象和字符串的相互转换
358 4
|
存储 NoSQL 中间件
单点登录简述
单点登录简述
304 1