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不缓存文件)
- 背景
-
有两个服务,A服务有一个文件上传的接口,B服务通过restTemplate调用A服务的接口上传一个文件。
-
B服务已经拿到文件内容。那么是否能够在不需要生成临时文件的情况下上传文件到A服务呢?
- 实现过程
- 定义内容
String fileStr = "文件内容";
- 字符串转换成byte[]
byte[] xmlBytes = fileStr.getBytes();
- 自定义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);
}
}
- 构造上传文件对象
MultipartFile mf = new BASE64DecodedMultipartFile(xmlBytes, fileName);
- 通过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