Spring MVC - Display a PDF file into web browser - spring-mvc

I am trying to display a PDF file in a web browser with spring MVC.
public void displayActiviteFiles (Activite activite, HttpServletResponse response) throws IOException {
File file = new File(activite.getLienUploadUn());
FileInputStream inputStream = new FileInputStream(file);
IOUtils.copy(inputStream, response.getOutputStream());
response.setHeader("Content-Disposition", "attachment; filename="+file.getName());
response.setContentType("application/pdf");
response.flushBuffer();
}
But I am getting weird characters instead of the pdf content.
Where am I wrong?

To answer my question and help some others in my case, this works :
File file = new File(activite.getLienUploadUn());
FileInputStream inputStream = new FileInputStream(file);
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1)
{
baos.write(buffer, 0, bytesRead);
}
response.setHeader("Content-Disposition","inline; filename=\""+file.getName()+"\"");
response.setContentType("application/pdf");
ServletOutputStream outputStream = response.getOutputStream();
baos.writeTo(outputStream);
outputStream.flush();

You can display including this code.
#GetMapping(value = "/pdf")
public void showPdf(HttpServletResponse response) throws IOException {
response.setContentType("application/pdf");
InputStream inputStream = new FileInputStream(new File("/sample.pdf"));
int nRead;
while ((nRead = inputStream.read()) != -1) {
response.getWriter().write(nRead);
}
}

If it matters to anyone, then this is the 100% working solution in spring boot 1.5.11. Haven't run on manual Spring MVC projects. Maybe with some minor tweaks, can make it work.
#GetMapping(value = "/downloadFile")
public StreamingResponseBody getSteamingFile(HttpServletResponse response) throws URISyntaxException {
File file = new File(getClass().getClassLoader().getResource("templates/more/si.pdf").toURI());
//viewing in web browser
response.setContentType("application/pdf");
//for downloading the file directly if viewing is not possible
response.setHeader("Content-Disposition", "inline; filename=" + file.getName());
file = null;
//put the directory architecture according to your target directory
// generated during compilation in maven spring boot
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("templates/more/si.pdf");
return outputStream -> {
int nRead;
byte[] data = new byte[1024];
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
outputStream.write(data, 0, nRead);
}
inputStream.close();
};
}

Related

is there any better way to import database from .realm file to device?

I have a pre-initialized realm. I am going to copy into where it should be on device using snip of code below.
//import from assets
public static RealmConfiguration importDatabase(Context context, String realm_file_name){
RealmConfiguration defaultRealm = new RealmConfiguration.Builder(context).build();
String dir = defaultRealm.getPath();
AssetManager assetManager = context.getAssets();
try {
InputStream is;
is = assetManager.open(realm_file_name);
File dest = new File(dir);
if (dest.exists())
dest.delete();
copy(is,dest);
}catch (IOException e){
Log.e(LOG_TAG,"import database error");
}
return defaultRealm;
}
public static void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
public static void copy(InputStream in, File dst) throws IOException {
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
So it will overwrite old realm file them write new realm file in same place.
Is it right ways to import database.
If not, how can I make it better ?

Can't download file. Browser opens it instead.

I have tried a lot of contentTypes and headers I have seen here but still can't figure out what I am doing wrong. I have the following Spring Controller:
#RequestMapping(value = "/anexo/{id}", method = RequestMethod.GET)
#ResponseBody
public ResponseEntity<String> getAnexoById(#PathVariable int id, HttpServletResponse response) {
Anexo a = anexoDAO.getAnexo(id);
if (a == null)
return new ResponseEntity<String>(HttpStatusMessage.NOT_FOUND, HttpStatus.NOT_FOUND);
else {
try {
File dir = new File("temp");
if (!dir.exists())
dir.mkdirs();
String filePath = dir.getAbsolutePath() + File.separator + a.getName();
File serverFile = new File(filePath);
FileInputStream fistream = new FileInputStream(serverFile);
org.apache.commons.io.IOUtils.copy(fistream, response.getOutputStream());
response.setHeader("Content-Disposition", "attachment; filename=" + a.getName());
response.setContentType("application/octet-stream");
response.setHeader("Content-Length", String.valueOf(serverFile.length()));
response.setHeader("Content-Transfer-Encoding", "binary");
response.flushBuffer();
System.out.println(response.toString());
return new ResponseEntity<String>(HttpStatus.OK);
} catch (IOException ex) {
return new ResponseEntity<String>("Exception on getting file", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
I also have tried with and without #ResponseBody.
The user will be able to upload any type of file to the server and then he will be able to download through this controller. The problem is that instead of the download window, the browser open the file in the page. How can I make it download?
Thanks in advance
This work for me:
#ResponseBody
void getOne(#PathVariable("id") long id, HttpServletResponse response) throws IOException {
MyFile file = fileRepository.findOne(id);
if(file == null) throw new ResourceNotFoundException();
response.setContentType(file.getContentType());
response.setHeader("Content-Disposition", "attachment; filename=\""+ file.getName() +"\"");
response.setContentLength(file.getData().length);
FileCopyUtils.copy(file.getData(), response.getOutputStream());
}
Where MyFile is a class like this:
class MyFile {
private Long id;
private String contentType;
private String name;
private bit[] data;
...
}

Pdf Download but not Opening decoding error

This is my jsp we are calling an java method
<%
PDFFileUploader.generatePDcFile(); //Calls the PDF method;
%>
This is my PDFFileUploader code
public class PDFFileUploader {
static final String UPLOAD_URL = "http://localhost:7080/pdf/GetPDFFile";
static final int BUFFER_SIZE = 4096;
public static void generatePDcFile() throws IOException
{
System.out.println("Inside generatePDC File");
// takes file path from first program's argument
String filePath = "H:/report1.pdf";
File uploadFile = new File("H:/report1.pdf");
System.out.println("File to upload: " + filePath);
// creates a HTTP connection
URL url = new URL(UPLOAD_URL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
// sets file name as a HTTP header
httpConn.setRequestProperty("fileName", uploadFile.getName());
// opens output stream of the HTTP connection for writing data
OutputStream outputStream = httpConn.getOutputStream();
// Opens input stream of the file for reading data
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
System.out.println("Start writing data...");
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
System.out.println("Data was written.");
outputStream.close();
inputStream.close();
//Read pdc file
//FileOutputStream test = new FileOutputStream("test");
// always check HTTP response code from server
InputStream test = null;
File pdcFile = new File("H:/report123.pdf");
FileOutputStream outputStreamTest = new FileOutputStream(pdcFile);
//byte[] bufferTest = new byte[BUFFER_SIZE];
//int bytesReadTest = -1;
//final OutputStream ostream = new FileOutputStream("/tmp/data.pdc");
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// reads server's response
/* BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));*/
test = httpConn.getInputStream();
String message= httpConn.getResponseMessage();
System.out.println("Message is///"+message);
System.out.println("Header :: "+httpConn.getHeaderField(0));
final byte[] bufferTest = new byte[1024*14];
while (true) {
int len = test.read(bufferTest);
if (len <= 0) {
break;
}
outputStreamTest.write(bufferTest, 0, len);
}
outputStreamTest.close();
test.close();
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
System.out.println("Get File Name"+fileName);
/* Map<String, List<String>> map = httpConn.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() +
" ,Value : " + entry.getValue());
}*/
// String response = reader.readLine();
//System.out.println("Server's response: " + response);
} else {
System.out.println("Server returned non-OK code: " + responseCode);
}
}
from here a servlet is called through the URL provided above the code for doPost method for the getPDFFile Servlet is
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
// Gets file name for HTTP header
String fileName = request.getHeader("fileName");
File saveFile = new File(SAVE_DIR + fileName);
// prints out all header values
System.out.println("===== Begin headers =====");
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
String headerName = names.nextElement();
System.out.println(headerName + " = " + request.getHeader(headerName));
}
System.out.println("===== End headers =====\n");
// opens input stream of the request for reading data
InputStream inputStream = request.getInputStream();
// opens an output stream for writing file
/*FileOutputStream outputStream = new FileOutputStream(saveFile);*/
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
System.out.println("Receiving data...");
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
System.out.println("Data received.");
outputStream.close();
inputStream.close();
System.out.println("File written to: " + saveFile.getAbsolutePath());
int processStatus = 0;
//temp file (used for conversion)
/* boolean success = (new File
(saveFile.getAbsolutePath())).delete();
System.out.println("File deleted :: "+success);
//delete pdc file too
boolean successtemp = (new File
(recentlyConvertedFile.getAbsolutePath())).delete();
System.out.println("File deleted :: "+successtemp);*/
response.setContentType("application/octet-stream" );
response.setHeader("Content-Disposition","inline;filename=\"" + saveFile.getName() + "\"");
response.setContentLength((int) saveFile.length());
OutputStream os = response.getOutputStream();
FileInputStream fis = new FileInputStream(saveFile);
//op.write(response.toString().getBytes(Charset.forName("utf-8")));
//op.flush();
try {
int byteRead = 0;
while ((byteRead = fis.read()) != -1) {
os.write(buffer, 0, byteRead);
}
os.flush();
} catch (Exception excp) {
excp.printStackTrace();
} finally {
os.close();
fis.close();
}
// sends response to client
//response.getWriter().print("UPLOAD DONE");
}
The file is getting downloaded but not opening the generated pdf have the same size of the original and I have taken a text file and printed the content to another file it seems to read only first line of the text file taken as input
Your final loop returning a file from the servlet to the client looks like this:
while ((byteRead = fis.read()) != -1) {
os.write(buffer, 0, byteRead);
}
You seem to have forgotten to use buffer in the fis.read() which should look like this:
while ((byteRead = fis.read(buffer)) != -1) {
os.write(buffer, 0, byteRead);
}
Thus, you send back as many copies of the buffer contents as fis returns numbers != -1.
BTW: Your servlet puts the data it receives into the ByteArrayOutputStream outputStream and drops that, but it claims to have written them into the file it eventually attempts to return to the caller.

Upload file from applet to servlet using apache fileupload

To accomplish:
Upload a file from my local to server using an applet and servlet using apache fileupload jar.
Tried:
I have used a simple jsp, with a browse button and posted the action to my servlet (where I used apache fileupload). I was successful in uploading the file to the server.
Issue:
I am trying to upload a file, from my local machine, using an applet. I do not want to manually select files, instead upload files that are present in a specific folder. For now I have hardcoded the folder. I am able to look at the folder and get the list of files I want to upload.
Also, I have successfully established a connection from my applet to servlet.
Issue arises at the upload.parseRequest(request) in the servlet. I'm thinking its because the applet cannot post to servlet's request object.
Also, I have set the request type to multipart/form-data in my applet.
Right now, I am trying to pass the absolute path of the file to servlet and upload.
I have seen other posts where byte stream data is passed from applet to servlet, but the servlet uses the traditional File.write.
For me, it is mandatory to achieve this using apache fileupload.
Please suggest on how to pass a file/file path from applet to servlet, where the upload is handled by apache fileupload.
Below are my FileUploadHandler (where the HTTP requests are handled) and FileUpload(which is my applet)
Below is my FileUpload Handler:
#WebServlet(name = "FileUploadHandler", urlPatterns = { "/upload" })
#MultipartConfig
public class FileUploadHandler extends HttpServlet {
String uploadFolder ="";
#Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost-servlet URL is: "
+ request.getRequestURL());
try {
uploadFolder = fileToUpload(request);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
uploadFolder = getServletContext().getRealPath("")+ File.separator;
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// process only if its multipart content
if (ServletFileUpload.isMultipartContent(request)) {
System.out.println("Yes, it is a multipart request...");
try {
List<FileItem> multiparts = upload.parseRequest(request);
System.out.println("Upload.parseRequest success !");
for (FileItem item : multiparts) {
if (!item.isFormField()) {
String name = new File(item.getName()).getName();
item.write(new File(uploadFolder + File.separator
+ name));
}
}
System.out.println("File uploaded to server !");
// File uploaded successfully
request.setAttribute("message", "File Uploaded Successfully");
} catch (Exception ex) {
request.setAttribute("message", "File Upload Failed due to "
+ ex);
}
} if(!ServletFileUpload.isMultipartContent(request)){
throw new ServletException("Content type is not multipart/form-data");
}
doGet(request, response);
//request.getRequestDispatcher("/result.jsp").forward(request, response);
OutputStream outputStream = response.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject("Success !");
objectOutputStream.flush();
objectOutputStream.close();
}
private String fileToUpload(HttpServletRequest request) throws IOException,
ClassNotFoundException {
ServletInputStream servletIn = request.getInputStream();
ObjectInputStream in = new ObjectInputStream(servletIn);
String uploadFile = (String) in.readObject();
System.out.println("Value in uploadFolder is: " + uploadFile);
return uploadFile;
}
Below is the fileupload applet:
public class FileUpload extends Applet {
private JButton capture;
private JTextField textField;
private final String pathDirectory = "C:\\";
private final String captureConfirmMessage = "Are you sure you want to continue?";
private final String confirmDialogTitle = "Confirm upload";
final File folder = new File(pathDirectory);
public void init() {
upload= new JButton("Upload");
textField = new JTextField();
capture.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int selection = JOptionPane.showConfirmDialog(upload,
uploadConfirmMessage, confirmDialogTitle,
JOptionPane.YES_NO_OPTION);
if (selection == JOptionPane.OK_OPTION) {
listFilesForFolder(folder);
} else if (selection == JOptionPane.CANCEL_OPTION) {
JOptionPane.showMessageDialog(upload,
"You have aborted upload", "Upload Cancelled", 2);
}
}
});
add(upload);
add(textField);
}
public void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
try {
onSendData(fileEntry.getAbsolutePath());
System.out.println(fileEntry.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private URLConnection getServletConnection() throws MalformedURLException,
IOException {
// Open the servlet connection
URL urlServlet = new URL("http://localhost:8081/UploadFile/upload");
HttpURLConnection servletConnection = (HttpURLConnection) urlServlet
.openConnection();
// Config
servletConnection.setDoInput(true);
servletConnection.setDoOutput(true);
servletConnection.setUseCaches(false);
servletConnection.setDefaultUseCaches(false);
servletConnection.setRequestProperty("Content-Type", "multipart/form-data;");
servletConnection.connect();
return servletConnection;
}
private void onSendData(String fileEntry) {
try {
// Send data to the servlet
HttpURLConnection servletConnection = (HttpURLConnection) getServletConnection();
OutputStream outstream = servletConnection.getOutputStream();
ObjectOutputStream objectOutputStream= new ObjectOutputStream(
outstream);
objectOutputStream.writeObject(fileEntry);
// Receive result from servlet
InputStream inputStream = servletconnection.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(
inputStream);
String result = (String) objectInputStream.readObject();
objectInputStream.close();
inputStream.close();
out.flush();
out.close();
// Display result on the applet
textField.setText(result);
} catch (java.net.MalformedURLException mue) {
mue.printStackTrace();
textField.setText("Invalid serlvetUrl, error: " + mue.getMessage());
} catch (java.io.IOException ioe) {
ioe.printStackTrace();
textField.setText("Couldn't open a URLConnection, error: "
+ ioe.getMessage());
} catch (Exception e) {
e.printStackTrace();
textField.setText("Exception caught, error: " + e.getMessage());
}
}
public void paint(Graphics g) {
g.drawString("Click the button above to capture", 5, 50);
}
I could finally succeed posting the request to the servlet from the applet.
It was a simple logic that I was missing. I did not add the header and trailer while posting to the servlet, which was the key, in the servlet to identify the incoming request as a multipart data.
FileInputStream fileInputStream = new FileInputStream(new File(
fileEntry));
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream
.writeBytes("Content-Disposition: form-data; name=\"upload\";"
+ " filename=\"" + fileEntry + "\"" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dataOutputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
System.out.println(fileEntry + " uploaded.");
}
// send multipart form data necesssary after file data
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens
+ lineEnd);
I added the header and trailer and also used this to create the URL connection.
private URLConnection getServletConnection() throws MalformedURLException,
IOException {
// Open the servlet connection
URL urlServlet = new URL("http://localhost:8083/UploadFile/upload");
HttpURLConnection servletConnection = (HttpURLConnection) urlServlet
.openConnection();
// Config
servletConnection.setDoInput(true);
servletConnection.setDoOutput(true);
servletConnection.setUseCaches(false);
servletConnection.setDefaultUseCaches(false);
servletConnection.setRequestMethod("POST");
servletConnection.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + this.boundary);
servletConnection.setRequestProperty("Connection", "Keep-Alive");
servletConnection.connect();
return servletConnection;
}
Then, in the servlet, I was just reading the data using upload.ParseRequest(request).
Thank you for the help.

Writing mp3 file to response output stream

I am new to Servlets and following Headfirst. It has an example to download jar file with mime type "application/jar". I changed it to "audio/mpeg3" to download an mp3 file. I get the player on the browser but it doesn't play. Here is the code:
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
resp.setContentType("audio/mpeg3");
ServletContext ctx=this.getServletContext();
InputStream is=ctx.getResourceAsStream("/RaOne.mp3");
int read=0;
byte[] bytes=new byte[1024];
OutputStream os=resp.getOutputStream();
while((read=is.read(bytes))!=-1)
{
os.write(bytes, 0, read);
}
os.flush();
os.close();
}
Can someone please help to figure out the problem?
you can try out something like this
ServletOutputStream stream = null;
BufferedInputStream buf = null;
try {
stream = response.getOutputStream();
File mp3 = new File("/myCollectionOfSongs" + "/" + fileName);
//set response headers
response.setContentType("audio/mpeg");
response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
response.setContentLength((int) mp3.length());
FileInputStream input = new FileInputStream(mp3);
buf = new BufferedInputStream(input);
int readBytes = 0;
//read from the file; write to the ServletOutputStream
while ((readBytes = buf.read()) != -1)
stream.write(readBytes);
} catch (IOException ioe) {
throw new ServletException(ioe.getMessage());
} finally {
if (stream != null)
stream.close();
if (buf != null)
buf.close();
}

Resources