Zendesk file upload through Spring boot REST - spring-boot

I'm trying to upload an image to the zendesk through its API, Once the file is uploaded I can get the token but files seems empty,
Reference : https://support.zendesk.com/hc/en-us/community/posts/4588002835994-Uploaded-image-is-empty-or-corrupted?page=1#community_comment_4588190155802
This is how my code looks like,
fis = new FileInputStream(file);
fis.read(contents);
byte[] encoded = Base64.encodeBase64(contents);
fis.close();
body.add("file", encoded);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
UploadResponseObject result = restTemplate.postForObject(
remoteUri + "/api/v2/uploads.json?filename=" + multipartFile.getOriginalFilename(),
new HttpEntity<>(body, headers),
UploadResponseObject.class);
I have tried with several different headers,
headers.set("Content-Disposition","form-data; name=\"attachment\"; filename=\"laptop_183544.jpg\"");
headers.add("Content-Type","image/jpeg");
headers.add("Content-Type","multipart/form-data");
headers.add("Content-Type","application/binary");
But nothing seems to be working, File is uploaded but always an 1 KB empty file.
Can someone please help me on this?
Thanks.

I just tried this and have an answer to this question, I just got it too complicated early. so here is the simple solution.
//make the headers as you wish
HttpHeaders headers = new HttpHeaders();
//I have not added createHeaders method here.
HttpHeaders headers = createHeaders(username+":"+password, headers);
for (MultipartFile multipartFile : attachments) {
try {
String url = remoteUri+"/api/v2/uploads.json?filename="+multipartFile.getName();
headers.add("Content-Type","application/binary");
HttpEntity httpEntity = new HttpEntity(multipartFile.getBytes(),headers);
ResponseEntity<YourResponseObject> response = restTemplate.exchange(url, HttpMethod.POST,httpEntity, YourResponseObject.class);
} catch (IOException e) {
LOG.error("Input output error while uploading the image");
} catch (Exception e) {
LOG.error("Error while uploading the image");
}
}

Related

Writing Wrapper for FileUpload in Spring boot : File not Present

Use Case
I need to write a wrapper for a FileUpload API, which takes Files from UI, and upload those to remote API. What I have chalked out so far:
Made a Controller which takes File and Content body as Request part, then I try to upload them to remote API, code snippets follow:
Controller Endpoint
ResponseEntity uploadFiles(#RequestPart("files") MultipartFile[] files, #RequestPart("someData") Metadata fileMetadata)
File Upload Code
byte[][] fileArray = Arrays.stream(files).map(multipartFile -> {
try {
return multipartFile.getBytes();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}).toArray(byte[][]::new);
//add file
LinkedMultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
configuration.getDocumentCategory());
params.add(DocStorageConstants.FILE, fileArray);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
ResponseEntity<FileUploadResponse> responseEntity = restTemplate.postForEntity(configuration.getUploadEndpoint(), requestEntity, FileUploadResponse.class);
The remote API returns response as if Files never reached this API, what I need to do to avoid this? I might try writing file to a temporary file and then upload that file to remote endpoint, not sure if that is a clean approach. Thanks in advance for any suggestions!
[Update]: The cURL that I am trying to form is below:
curl --location --request POST 'http://<host>:<port>/file-endpoint' \
--header 'X-Api-Client:<api-key>' \
--header 'x-service-id: <service-id>' \
--form 'file=#"/aggregate.csv"' \
--form 'uploadRequest="{\"bn\":\"NFA\",\"dc\":\"generalDocs\",
\"tags\":[\"test\", \"test2\"]
}"'
Following snippet worked
Arrays.stream(files).forEach(multipartFile -> params.add(DocStorageConstants.FILE, multipartFile.getResource()));

How to make jira attachments download work using jira rest api

I am trying to download attachments from Jira. I use /rest/api/2/attachment/{id} to get json response of the attachment. It has field "content" that is the attachment url. I use this url and construct HttpGet and execute to get response that always gives me html content asking for login. I am sending Basic Authorization in the httpGet header. Apparently this works for downloading .png files but not any other file types. I am using java spring rest to connect to Jira horizon.
Closeable httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(jira attachmenturl);
httpGet.setHeader("Authorization", "Basic <base64Credentials>);
CloseableHttpResponse response = httpclient.execute(httpGet)
The response for .txt, .jpeg, Microsoft documents is different from response that I get for .png files.
This works:
#GetMapping(value = "/getAttachment")
public String getAttachment(#RequestParam("id") String attachmentID) throws Exception {
Client client = Client.create();
WebResource webResource = client.resource(jiraBaseURLRest + "attachment/" +
attachmentID);
ClientResponse response = webResource.header("Authorization", "Basic " +
base64Creds).type("application/json")
.accept("application/json").get(ClientResponse.class);
String result = response.getEntity(String.class);
JSONObject jsonObj = new JSONObject(result);
System.out.println("JSON Object = "+jsonObj);
URL url = new URL(jsonObj.getString("content"));
Closeable httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url.toURI());
httpGet.setHeader("Authorization", "Basic " + base64Creds);
CloseableHttpResponse response1 = ((CloseableHttpClient) httpclient).execute(httpGet);
if(response1.getStatusLine().getStatusCode() == 200)
{
HttpEntity entity = response1.getEntity();
if (entity.isStreaming())
{
System.out.println("Streaming...");
byte data[] = EntityUtils.toByteArray(entity);
FileOutputStream fout = new FileOutputStream(new File("D://pdf1.pdf"));
fout.write(data);
fout.close();
System.out.println("Done!!");
}
}
return "Success";
}

Invalid mimetype exception in Spring boot rest call

I am new to both Spring boot and rest calls.
I am trying to consume a rest service and I do not have any information about that rest API except URL. When I hit that URL from a browser I am getting a response as {key:value}. So, I assumed that it is a JSON response.
I am consuming it in spring boot as follows
restTemplate.getForObject(url, String.class) .
This is giving Invalid mime type "content-type: text/plain; charset=ISO-8859-1": Invalid token character ':' in token "content-type: text"
I assume that this error is because response content type is set to text/plain but it is returning JSON format.
EDIT:
Tried this way but did not work.
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters",headers);
ResponseEntity<String> result = restTemplate.exchange(url,HttpMethod.GET,
entity, String.class);
How to handle and solve it?
You might want to read about the request headers your REST API needs. Content-Type header specifies the media type of the request you're sending to the server. Because you're just getting data from the server you should set the Accept header to the kind of response you want i.e., Accept: application/json.
Unfortunately, you can't set headers using getForObject(). You could try this:
URL url = new URL("Enter the URL of the REST endpoint");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Accept", "application/json");
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuffer content = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
}

Having trouble recreating a cURL command in a Spring RestTemplate Using Headers

Here's the curl command I'm trying to recreate :
curl https://bannana-pajamas.com/services/data/v20.0/query/?q=BananaQuery -H 'Authorization: Bearer Banana_Token'
This curl command works just fine in my terminal and returns a json file.
Here's my attempt at recreating it in a Spring Rest Template:
//Create a rest template
RestTemplate rest = new RestTemplate();
System.out.println("This here is the token "+Banana_Token);
//Create the headers
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization","Bearer "+Banana_Token);
HttpEntity<String> entity = new HttpEntity<>(headers);
//Create the url
String url = "https://bannana-pajamas.com/services/data/v20.0/query/?q=BananaQuery";
String response;
try{
response = rest.exchange(url, HttpMethod.GET, entity, String.class).toString();
}catch(Exception error){
System.out.println("This still ain't working bro. Imma make this null till you get stuff right");
response = null;
}
return response;
When I run this, I get the following error:
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
I've tried several of the similar answers on this site, but I keep getting that error. I probably missing something very minor.
Anybody have any ideas?
Thanks!

Oracle MAF-MCS API call

I have created a custom POST api for getting login information in MCS. when i check in SOAPUI it works perfectly fine. the parameters passed are
1. header
Oracle-Mobile-Backend-Id: ********************
2. Authentocation
Username:****************
password: **************
and basic login info username and password as "User1" and "user1" respectively.
Step2:
when i call the API from MAF i am getting an error 400
the post method used is
public static Response callPost(String restURI, String jsonRequest) {
String responseJson = "";
Response response = new Response();
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
//restServiceAdapter.setConnectionName("MiddlewareAPI");
// restServiceAdapter.setConnectionName("");
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_POST);
restServiceAdapter.addRequestProperty("Content-Type", "application/json");
restServiceAdapter.addRequestProperty("Accept", "application/json; charset=UTF-8");
restServiceAdapter.addRequestProperty("Oracle-Mobile-Backend-Id", "**********");
restServiceAdapter.addRequestProperty("Domain", "mcsdem0001");
restServiceAdapter.addRequestProperty("Username", "******");
restServiceAdapter.addRequestProperty("Password", "*****");
//restServiceAdapter.addRequestProperty("Authorization", "Basic "+new String(encodedBytes));
System.out.println("**** Authorization String ****=>"+new String(encodedBytes));
System.out.println("**** RestURI ******=>"+restURI);
System.out.println("**** jsonRequest ******=>"+jsonRequest);
restServiceAdapter.setRequestURI(restURI);
restServiceAdapter.setRetryLimit(0);
try {
responseJson = restServiceAdapter.send(jsonRequest);
int responseCode = restServiceAdapter.getResponseStatus();
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
response.setHeader(restServiceAdapter.getResponseHeaders());
} catch (Exception e) {
int responseCode = restServiceAdapter.getResponseStatus();
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
}
System.out.println("Response:" + responseJson);
return response;
}
Could anyone please tell me is there any error in the post method??
This can be due to the version conflict. Try to use HttpUrlConnection instead of RestServiceAdapter and let me know if it works.
actually this bit
restServiceAdapter.addRequestProperty("Username", "******");
restServiceAdapter.addRequestProperty("Password", "*****");
doesn't work because you attempt to pass username and password as a HTTP header. Instead it should be passed as you were trying here
restServiceAdapter.addRequestProperty("Authorization", "Basic "+new String(encodedBytes));
However, these should not be encoded bytes but a base64 encoded string in the form
Basis (without the < abd >)
Note that user identity domains only need to be provided in multi-tenant environments. In MCS, the user domain is defined through the mobile backend you connect to.
Frank
Use the MAF MCS Utility library to make it allot easier.
The developer guide can be found here: http://download.oracle.com/otn_hosted_doc/maf/mafmcsutility-api-doc-082015.pdf
Example code:
MBEConfiguration mbeConfiguration =
new MBEConfiguration(
<mbe rest connection>,<mobileBackendId>,
<anonymous key string>,<application key string>,
MBEConfiguration.AuthenticationType.BASIC_AUTH);
mbeConfiguration.setEnableAnalytics(true);
mbeConfiguration.setLoggingEnabled(false)
mbeConfiguration.setMobileDeviceId(
DeviceManagerFactory.getDeviceManager().getName());
MBE mobileBackend = MBEManager.getManager().
createOrRenewMobileBackend(<mobile backend Id>, mbeConfiguration);
CustomAPI customApiProxy = mbe.getServiceProxyCustomApi();
MCSRequest request = new MCSRequest(mobileBackend.getMbeConfiguration());
request.setConnectionName(<Rest connection name>);
request.setRequestURI("/moile/custom/mockup/employees");
request.setHttpMethod(MCSRequest.HttpMethod.POST);
request.setPayload("{\"id\":\"1\"\"name\":\"nimphius\",\"firstName\":\"frank\"}");
request.setRetryLimit(0);
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type","application/json");
request.setHttpHeaders(headers);
MCSResponse response = customApiProxy .sendForStringResponse(request);
String jsonResponse = (String) response.getMessage();

Resources