We are doing the same, basically sending PDF as JSON to Android/iOS and Web-Client (so Java and Swift).
The JSON Object:
public class Attachment implements Serializable {
private String name;
private String content;
private Type contentType; // enum: PDF, RTF, CSV, ...
// Getters and Setters
}
And then from byte[] content it is set the following way:
public Attachment createAttachment(byte[] content, String name, Type contentType) {
Attachment attachment = new Attachment();
attachment.setContentType(contentType);
attachment.setName(name);
attachment.setContent(new String(Base64.getMimeEncoder().encode(content), StandardCharsets.UTF_8));
}
Client Side Java we create our own file type object first before mapping to java.io.File:
public OurFile getAsFile(String content, String name, Type contentType) {
OurFile file = new OurFile();
file.setContentType(contentType);
file.setName(name);
file.setContent(Base64.getMimeDecoder().decode(content.getBytes(StandardCharsets.UTF_8)));
return file;
}
And finally:
public class OurFile {
//...
public File getFile() {
if (content == null) {
return null;
}
try {
File tempDir = Files.createTempDir();
File tmpFile = new File(tempDir, name + contentType.getFileEnding());
tempDir.deleteOnExit();
FileUtils.copyInputStreamToFile(new ByteArrayInputStream(content), tmpFile);
return tmpFile;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Answer from seBaka28 on Stack OverflowWe are doing the same, basically sending PDF as JSON to Android/iOS and Web-Client (so Java and Swift).
The JSON Object:
public class Attachment implements Serializable {
private String name;
private String content;
private Type contentType; // enum: PDF, RTF, CSV, ...
// Getters and Setters
}
And then from byte[] content it is set the following way:
public Attachment createAttachment(byte[] content, String name, Type contentType) {
Attachment attachment = new Attachment();
attachment.setContentType(contentType);
attachment.setName(name);
attachment.setContent(new String(Base64.getMimeEncoder().encode(content), StandardCharsets.UTF_8));
}
Client Side Java we create our own file type object first before mapping to java.io.File:
public OurFile getAsFile(String content, String name, Type contentType) {
OurFile file = new OurFile();
file.setContentType(contentType);
file.setName(name);
file.setContent(Base64.getMimeDecoder().decode(content.getBytes(StandardCharsets.UTF_8)));
return file;
}
And finally:
public class OurFile {
//...
public File getFile() {
if (content == null) {
return null;
}
try {
File tempDir = Files.createTempDir();
File tmpFile = new File(tempDir, name + contentType.getFileEnding());
tempDir.deleteOnExit();
FileUtils.copyInputStreamToFile(new ByteArrayInputStream(content), tmpFile);
return tmpFile;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Yes so the problem was with the client.
while decoding we should use
byte[] decodedBytes = Base64.decodeBase64(fileJson.getString("fileContent"));
rather than
byte[] decodedBytes = Base64.decodeBase64(fileJson.get("fileContent").toString());
Since encoded data.toString() yields some think else
Also replaced encodeBase64URLSafeString with encodeBase64String Well quite a simple solution :)
Java/Spring - Send Post Request to retrieve a PDF-File from anoter Rest Endpoint - Stack Overflow
How to send a pdf file in Post method of rest API
Sample code to send pdf file via rest api | OneSpan Community Platform
java - Display pdf in browser using a rest service - Stack Overflow
change
response.header("Content-Disposition", "attachment; filename=restfile.pdf");
to
response.header("Content-Disposition", "filename=restfile.pdf");
Using InputStream first we can load the file into inputstream, then pass to IOUtils.copy and use this response.header("Content-Disposition", "attachment; filename=restfile.pdf") for download, use this for preview response.setHeader("Content-disposition", " filename=" + output)
InputStream inputStream = new FileInputStream(new File(path)); // load the file
IOUtils.copy(inputStream, response.getOutputStream());
response.setContentType("application/pdf");
response.setHeader("Content-disposition", " filename=" + output);
response.flushBuffer();
Return type of the method is `ResponseEntity
I was able to achieve a similar output by converting the file to string/byte[] data and sending it via REST.
My implementation was in Java and the steps used is outline below
- Convert the file on disk to byte[] array (apache common-io can convert the file to byte[] in easy step. Try the IOUtils class)
- Encoded the byte[] as String (apache common-codec was used for the encoding)
- Wrapped the string data in a model class
- Converted the model class to json format (GSON was used for the conversion)
- Sent the json data over to the server
- The server application reversed the process, and the file was available on the server
A rest service isn't the right way for what you want. The input for this kind of services are HTTP request attributes or some kind of pushed data. Maybe it's possible to implement a file upload but it's not typical. For restful services is also common to tell your service how to handle the requested resource via the used request method (GET, POST, PUT, DELETE) The response of rest services is normally some kind of structured text output - for instance json.
All in all rest services seems to me not the way to implement your desired scenario. What about a normal cgi or servlet solution?
PDF data should be transferable as a response of a rest-ful request just fine.
Set the correct content type and transfer the binary content of the PDF.
Nothing special about it.
- What are you doing right now? Are you using an library?
- Describe your "unexepected results".
- Describe your "expression error"
Basically, you need to provide a lot more details.
Your responses from the Java platform are most definitely going to be byte arrays in order to provide the PDF. From the server side you need to make sure that MIME types for PDF are registered and that it's providing and accepting the correct headers for PDF.
If you're serving PDF, Java needs to figure out where that is and hosted under the url that you defined your RESTful resource.
If it's dynamic, your PDF library (I've used iText in the past) needs to be able to output the PDF binary and serve it via your defined RESTful resource.
I came across another solution that helped me a lot! different solution here is my final code and solution for my own question.
HttpHeaders headers = createHeaders(username, password);
headers.setContentType(MediaType.APPLICATION_PDF);
headers.set("X-Async-Scope", timelineEntryId);
InputStream inputStream = new FileSystemResource(new File(file.getPath())).getInputStream();
byte[] binaryData = IOUtils.toByteArray(inputStream);
HttpEntity<byte[]> requestEntity = new HttpEntity<>(binaryData, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(baseUrl, HttpMethod.PUT, requestEntity, String.class);
Maybe, you need set header content type?
headers.set("Content-Type", "application/pdf")
If it doesn't help, you should also set header Content-Disposition:
headers.set("Content-Disposition", "attachment; filename="+fileName)
Your request headers should also include MediaType.APPLICATION_OCTET_STREAM
This response object will return a byte array- which will be your pdf.
So, the complete example would be something like this-
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_PDF, MediaType.APPLICATION_OCTET_STREAM));
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<byte[]> result =
restTemplate.exchange(uri, HttpMethod.GET, entity, byte[].class);
byte[] content = result.getBody();
Files.write(Paths.get("/home/123.pdf"), content, StandardOpenOption.CREATE );
Hope this helps.
You can Use PDFbox(or itext) API, which is a great way of parsing and creating PDF. It will allow you to place your text etc,
That said
public static void writeToFIle(InputStream uploadedInputStream, String uploadedFileLocation) {
try {
OutputStream out = new FileOutputStream(new File(uploadedFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
should be enough to create a PDF, if its blank check if the value arn't null
I personnaly use jersey to link client and server so i cant really tell you if your method to get the pdf works
Try this
HttpResponse response = HttpContext.Current.Response;
response.ClearContent();
response.Clear();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(strPath));
response.TransmitFile(strPath); //File
response.Flush();
response.End();
Response.ContentType = ContentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(strPath));
Response.WriteFile(strPath);
Response.End();
Here is a spring boot example. you can refer this example https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started-first-application.html and attach the below class in the project
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.*;
import java.io.File;
import java.nio.file.Files;
@Controller
public class DemoController {
@RequestMapping(value="/getpdf", method=RequestMethod.GET)
public ResponseEntity<byte[]> getPDF() {
File file = new File("sample.pdf"); // change to relative path
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
String filename = "output.pdf";
headers.setContentDispositionFormData(filename, filename);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ResponseEntity<byte[]> response = null;
try {
response = new org.springframework.http.ResponseEntity<>(Files.readAllBytes(file.toPath()), headers, org.springframework.http.HttpStatus.OK);
} catch (java.io.IOException e) {
e.printStackTrace();
}
return response;
}
}
package com.javatpoint;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.darwinsys.spdf.PDF;
import com.darwinsys.spdf.Page;
import com.darwinsys.spdf.Text;
import com.darwinsys.spdf.MoveTo;
public class ServletPDF extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
PrintWriter out = response.getWriter();
response.setContentType("application/pdf");
response.setHeader("Content-disposition","inline; filename='javatpoint.pdf'");
PDF p = new PDF(out);
Page p1 = new Page(p);
p1.add(new MoveTo(p, 200, 700));
p1.add(new Text(p, "www.javatpoint.com"));
p1.add(new Text(p, "by Sonoo Jaiswal"));
p.add(p1);
p.setAuthor("Ian F. Darwin");
p.writePDF();
}
}
You have to use ServletOutputStream and its write() method to write bytes to the response .
You need to convert file to byte array and pass it on to service on server do the reverse to get file back.
Here is very good article on doing this using JAXWS
You can use Java EE 6 technology, it fits your purposes good. Just create a web-service, which will return byte array within a responce on GET.
See this manual.