Я хочу превратить этого клиента-почтальона с запросом заголовка multipart / form-data в клиент шаблона Spring.
Сейчас у меня естьбазовый контроллер отдыха, который работает хорошо.
@RestController
@RequestMapping("/api")
public class MainConroller {
private static final Logger log = LoggerFactory.getLogger(MainConroller.class);
@Autowired
private MainService mainService;
public MainConroller(MainService mainService) {
this.mainService = mainService;
}
@PostMapping("/mails/send")
public void send(
@RequestParam("usertoken") String usertoken,
@RequestParam("sendTo") String sendTo,
@RequestParam("subject") String subject,
@RequestParam("content") String content,
@RequestParam(required = false, name = "files") List<MultipartFile> multipartFiles) {
log.debug("{}, {}, {}, {}", usertoken, sendTo, subject, content);
mainService.processMessage(usertoken, sendTo, subject, content, multipartFiles);
}
}
Мне нужно, однако, создать клиент отдыха, поэтому я использовал шаблон отдыха, сейчас он выглядит так:
ArrayList<HttpMessageConverter<?>> converters = new ArrayList<>(
Arrays.asList(new MappingJackson2HttpMessageConverter(), new ResourceHttpMessageConverter(), new FormHttpMessageConverter()));
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(converters);
}
File file = new File("*********");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> fileValueMap = new LinkedMultiValueMap<>();
fileValueMap.add(file.getName(), file);
fileValueMap.add(file.getName(), file);
fileValueMap.add(file.getName(), file);
HttpEntity<MultiValueMap<String, Object>> filesPart = new HttpEntity<>(fileValueMap, httpHeaders);
// String key values part
MultiValueMap<String, String> stringPart = new LinkedMultiValueMap<>();
stringPart.add("usertoken", "test");
stringPart.add("sendTo", "test");
stringPart.add("subject", "test");
stringPart.add("content", "test");
HttpEntity<MultiValueMap<String, String>> objectPart = new HttpEntity<>(stringPart, httpHeaders);
MultiValueMap<String, Object> multiPartRequest = new LinkedMultiValueMap<>();
multiPartRequest.add("ObjectPart", objectPart);
multiPartRequest.add("FilesPart", filesPart);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(multiPartRequest, httpHeaders);
String serverUrl = "****";
restTemplate().postForEntity(serverUrl, requestEntity, String.class);
Проблема в том, что когда я пытаюсь отправить запрос, он выдает
Exception in thread "main" org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [multipart/form-data]
Обновление
Решение на стороне клиента очень простое, вы можете просто отправитьСтроковые значения в значениях объекта, которые будут автоматически преобразованы в строки через универсальные шаблоны.
Кроме того, файлы нельзя отправлять только в виде файлов, но вместо этого необходимо создать FileSystemResource, вот полный кодсторона клиента:
@Service
public class RestTemplatePost {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public void prepareMessage() throws Exception {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
form.add("usertoken", "test");
form.add("sendTo", "test");
form.add("subject", "test");
form.add("content", "test");
form.add("files", getTestFile());
form.add("files", getTestFile());
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(form, httpHeaders);
String serverUrl = "******";
restTemplate().postForEntity(serverUrl, requestEntity, String.class);
}
public static Resource getTestFile() throws IOException {
Path testFile = Paths.get("C****");
System.out.println("Creating and Uploading Test File: " + testFile);
Files.write(testFile, "Hello World !!, This is a test file.".getBytes());
return new FileSystemResource(testFile.toFile());
}
}