Reputation: 1017
So I am having trouble with REST (which I am a beginner at). I would like to PUT a multipart form to a certain URL. I had accomplished this with Jersey from an example I found on the web, unfortunately in my project I am supposed to use the spring framework web client. Below is my working Jersey Code.
// setup properties
String publishUrl = "http://localhost:8080/url/to/rest/api";
File schemaFile = new File("myfile.xml");
String catalogName = "myFileName";
FileInputStream inputStream = new FileInputStream(schemaFile);
String jndiName = "myJNDI";
boolean overwrite = true;
boolean enableXmla = true;
//set up multi part form.
FormDataMultiPart part = new FormDataMultiPart()
.field("uploadAnalysis", inputStream, MediaType.MULTIPART_FORM_DATA_TYPE)
.field("catalogName", catalogName, MediaType.MULTIPART_FORM_DATA_TYPE)
.field("Datasource", jndiName, MediaType.MULTIPART_FORM_DATA_TYPE)
.field("overwrite", overwrite ? "true" : "false", MediaType.MULTIPART_FORM_DATA_TYPE)
.field("xmlaEnabledFlag", enableXmla ? "true" : "false", MediaType.MULTIPART_FORM_DATA_TYPE)
.field("parameters", "Datasource=" + jndiName, MediaType.MULTIPART_FORM_DATA_TYPE);
// If the import service needs the file name do the following.
part.getField("uploadAnalysis").setContentDisposition(FormDataContentDisposition.name("uploadAnalysis").fileName(schemaFile.getName()).build());
//set up client and create web resource
Client client = Client.create();
client.addFilter(new HTTPBasicAuthFilter("Admin", "password"));
WebResource resource = client.resource(publishUrl);
ClientResponse response = resource.type(MediaType.MULTIPART_FORM_DATA_TYPE).put(ClientResponse.class, part);
System.out.println(response.getStatus());
This works fine. So now I have tried to transcribe this over to work with the spring web client. The following is my current code
//setup properties
String publishUrl = "http://localhost:8080/url/to/rest/api";
File schemaFile = new File("myFile.xml");
String catalogName = "myFileName";
String jndiName = "myJNDI";
boolean overwrite = true;
boolean enableXmla = true;
//setup form
MultiValueMap<String, Object> form = new LinkedMultiValueMap<String, Object>();
form.add("uploadAnalysis", new FileSystemResource(schemaFile));
form.add("catalogName", catalogName);
form.add("Datasource", jndiName);
form.add("overwrite", overwrite ? "true" : "false");
form.add("xmlaEnabledFlag", enableXmla ? "true" : "false");
form.add("parameters", "Datasource=" + jndiName);
//Set up credentials
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("Admin", "password"));
//set up http client
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
//create client request factory using httpcient
HttpComponentsClientHttpRequestFactory fact = new HttpComponentsClientHttpRequestFactory(httpclient);
//create rest template
RestTemplate rt = new RestTemplate(fact);
//create http headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
//use put method.
rt.put(publishUrl, headers, form);
This code does not work, I always get the following error:
WARN 26-04 14:57:11,988 - PUT request for "http://localhost:8080/url/to/rest/api" resulted in 415 (Unsupported Media Type); invoking error handler
I am a bit confused by this because in Jersey I set the MediaType to "MULTIPART_FORM_DATA_TYPE" and in Spring I set it to "MULTIPART_FORM_DATA" so I am not sure why this would give me a unsupported media type. Any ideas would be helpful.
Edit
So I changed my code to not use the .put() method as I was using it wrong, the changes look like this.
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<MultiValueMap<String, Object>>(form, headers);
ResponseEntity<String> response = rt.exchange(publishUrl, HttpMethod.PUT, entity, String.class);
However, after making these changes I am getting a no response error
org.springframework.web.client.ResourceAccessException: I/O error on PUT request for "http://localhost:8080/url/to/rest/api":localhost:8080 failed to respond; nested exception is org.apache.http.NoHttpResponseException: localhost:8080 failed to respond
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:543)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:489)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:431)
The odd thing is the that the file is uploaded to the server, however I dont get any response from the server. Is there some type of header I have to set to get a response or something? When using Jersey I would get a response every time, so I am wondering if there was something pre-configured in jersey that I am unaware of.
Upvotes: 0
Views: 3856
Reputation: 280178
You're using RestTemplate#put(...)
incorrectly. The 3rd argument is meant to be a Map
of URI variables. Instead use one of the RestTemplate#exchange(..)
methods where you can pass an HttpEntity
with the appropriate headers.
Upvotes: 1