本次记录的是 前端上传一个文件后,经过服务器使用restTemplate Post到其他地址上去的过程。
Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.example.entity.ResponseEntity;
import com.example.service.BaseDataService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
/**
* 获取数据接口
*
* @author chenxue(chenxue4076 @ 163.com)
* @version v1.0 - 2022/7/28 17:02
* @since v1.0
*/
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Tag(name = "获取政府数据接口", description = "获取政府数据接口, 开发者(chenxue)")
@RequestMapping("/base")
public class BaseDataController {
private final BaseDataService baseDataService;
/**
* 3.4. 上传音频文件
*
* @param file 音频文件
* @return 结果
*/
@Operation(summary = "3.4. 上传音频文件")
@PostMapping(value = "/save-audio", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity uploadAudio(@RequestParam("file") MultipartFile file) {
return baseDataService.saveAudio(file);
}
}
Service
package com.example.service;
import java.util.Collections;
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import com.example.enums.SuccessEnum;
import com.example.request.BaseDataRequestVO;
import com.example.conf.IotPlatformProperties;
import com.example.entity.ResponseEntity;
import com.example.request.AreaListRequestVO;
import com.example.util.TokenUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* 城市接口获取服务
*
* @author chenxue(chenxue4076 @ 163.com)
* @version v1.0 - 2022/7/28 17:15
* @since v1.0
*/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class BaseDataService {
private final BaseService baseService;
private final IotPlatformProperties properties;
private final TokenUtil tokenUtil;
/**
* 3.4. 上传音频文件
*
* @param file map3文件
* @return 文件url
*/
public ResponseEntity saveAudio(MultipartFile file) {
if (file.isEmpty()) {
return ResponseEntity.builder().code(SuccessEnum.FAILED.ordinal())
.msg("请上传文件!")
.build();
}
HttpHeaders headers = new HttpHeaders();
baseService.addHeaderToken(headers, tokenUtil.getTokenInfo());
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
var request = new LinkedMultiValueMap<String, Object>();
try {
//这里一定要重写这两个方法,不然会存在问题
var byteFile = new ByteArrayResource(file.getBytes()) {
@Override
public long contentLength() {
return file.getSize();
}
@Override
public String getFilename() {
return file.getOriginalFilename();
}
};
request.put("file", Collections.singletonList(byteFile));
} catch (Exception e) {
log.error("upload file {} error {}", file.getOriginalFilename(), e.getMessage());
return ResponseEntity.builder().code(SuccessEnum.FAILED.ordinal())
.msg(e.getMessage())
.build();
}
var entity = new HttpEntity<>(request, headers);
return baseService.postForObject(properties.getUriSaveAudio(), entity, ResponseEntity.class);
}
}
基础Service
package com.example.service;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSON;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
/**
* 默认说明
*
* @author chenxue(chenxue4076 @ 163.com)
* @version v1.0 - 2022/7/28 17:19
* @since v1.0
*/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class BaseService {
private final RestTemplate restTemplate;
/**
* 添加 token header
*
* @param headers headers
* @param token token
*/
public void addHeaderToken(HttpHeaders headers, String token) {
if (StringUtils.hasText(token)) {
headers.setBearerAuth(token);
}
}
/**
* 提交URL请求,并获取结果
*
* @param uri 请求地址
* @param request 请求参数 含 header 和 body
* @param clazz 返回格式定义
* @param <T> 定义格式
* @return 指定类型对象
*/
public <T> T postForObject(String uri, Object request, Class<T> clazz) {
try {
log.info(uri);
log.info(request.toString());
// 因返回格式是 text/html 无法直接解析,这里转下
var result = restTemplate.postForObject(uri, request, String.class);
return JSON.parseObject(result, clazz);
} catch (Exception e) {
// e.printStackTrace();
log.error("post {}, {} error {}", uri, request.toString(), e.getMessage());
}
return null;
}
}
最重要的是要 使用 ByteArrayResource 的时候要重写里面的 contentLength() , getFilename() 方法。
(416)