Spring Boot Upload file via PUT - spring-boot

I have a curl query:
curl -v -X PUT --upload-file "test.txt" http://remote_api_service/api/files
I have a Spring Boot application and my goal is to write a query that reflects the curl I posted above. How can I do that with RestTemplate or WebClient?

You need to create HttpEntity with header and body. Set the content-type header value to MediaType.MULTIPART_FORM_DATA.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource("test.txt"));
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
String serverUrl = "http://remote_api_service/api/files";
RestTemplate restTemplate = new RestTemplate();
restTemplate.put(serverUrl, requestEntity);

Related

How to add file as Form data in Http request in spring boot

I'm writing test cases to a controller in spring boot which takes MultipartFile as RequestParam. In the test case method I'm using TestRestTemplate.exchange() to send the request to the controller. I'm not sure how to make the Headers correctly so that I can send the request.
The Postman curl looks like this:
curl --location --request POST 'localhost:9091/response/upload'
--form 'file=#"/home/adityak/Downloads/ClientLog_NEW.txt"'
For file uploading to any service or endpoint
private String testExchange(File file) {
//add file
LinkedMultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("file", new FileSystemResource(file));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity =
new HttpEntity<>(params, headers);
ResponseEntity<String> responseEntity = restTemplate.exchange(
"/upload-file",
HttpMethod.POST,
requestEntity,
String.class);
HttpStatus statusCode = responseEntity.getStatusCode();
if (statusCode == HttpStatus.ACCEPTED) {
result = responseEntity.getBody();
}
return result;
}

Sending multipart requests using Spring Boot with specific header for every part

Postman request
As mentioned in image I would like to send content-type as application/json for a particular part of a multipart request in springboot application.
use MultipartBodyBuilder to build your request.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add("add custome header", "header value");
MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("json_part", "").header("Content-Type", "application/json");
MultiValueMap<String, HttpEntity<?>> body = builder.build();
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity(body,
headers);
RestTemplate restTemplate = new RestTemplateBuilder().build();
ResponseEntity<String> postResponse = restTemplate
.postForEntity("yoururl", requestEntity, String.class);

How to not escape form body characters in Spring RestTemplate when making a POST request?

I have following code where I am making a POST form request. The request body contains username and password. Password contains # characters, which is replaced by RestTemplate with %40 and I am getting "unauthorized" error as the password is wrong now.
Following is the debug info from bufferOutput(request body)
merchant_id=firstname+de-lastname%40gmail.com&password=%40Password
Here is the code snippet that is making the call.
MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
String url = "SOME_URL";
formData.add("username", "xay#gmail.com");
formData.add("password", "#name321");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String,String>> requestEntity = new HttpEntity<MultiValueMap<String,String>>(formData,headers);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters()
.add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
restTemplate.exchange(url, HttpMethod.POST, requestEntity, Authentication.class,"321");
The question is how to tell restTemplate not to escape body data ?
Note that the request has to be a post form request and I can not use UriComponentsBuilder to fix the problem.
I think you need to add a FormHttpMessageConverter to your RestTemplate rather than a StringHttpMessageConverter.

curl ok, RestTemplate fails

This works:
curl --verbose -H "Content-Type: application/json" --data "{\"parm1\":\"1\", \"parm2\":\"1\"}" http://server:8080/service/meth
and returns:
{"success":true,"errorMessage":null}
This fails:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("parm1", "1");
map.add("parm2", "1");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
String response = (String) restTemplate.postForObject("http://server:8080/service/meth",
request,
String.class);
with 500 Internal Server Error
I'm using springframework-boot 1.3.3.RELEASE and java 1.8 and am at a loss as to what's wrong. The server side log shows no errors other than 500
Has anyone been faced with a Spring RestTemplate call that mysteriously failed? How did you approach diagnosing the problem?

Spring RestTemplate redirect 302

I'm trying to use spring rest template to do a post request to login in.
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
LinkedMultiValueMap<String, Object> mvm = new LinkedMultiValueMap<String, Object>();
mvm.add("LoginForm_Login", "login");
mvm.add("LoginForm_Password", "password");
ResponseEntity<String> result = restTemplate.exchange(uriDWLogin, HttpMethod.POST, requestEntity, String.class);
My ResponseEntity status is 302, i want to follow this request to get the body response , because i didn't get the body for this request.
18:59:59.170 MAIN [http-nio-8080-exec-83] DEBUG c.d.s.c.DemandwareCtlr - loginToSandbox - StatusResponse - 302
18:59:59.170 MAIN [http-nio-8080-exec-83] DEBUG c.d.s.c.DemandwareCtlr - loginToSandbox - BodyResponse -
What can I do to solve this problem ?!
The redirection is followed automatically if the request is a GET request (see this answer). To make it happen on POST requests, one option might be to use a different request factory, like HttpComponentsClientHttpRequestFactory, and set it to use an HttpClient with the required settings to follow the redirect (see LaxRedirectStrategy):
final RestTemplate restTemplate = new RestTemplate();
final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
final HttpClient httpClient = HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy())
.build();
factory.setHttpClient(httpClient);
restTemplate.setRequestFactory(factory);
I haven't tested, but this should work.

Resources