Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top