loading a pdf in-browser from a file in the server file system? - spring

How can I get a pdf located in a file in a server's directory structure to load in a browser for users of a Spring MVC application?
I have googled this and found postings about how to generate PDFs, but their answers do not work in this situation. For example, this other posting is not relevant because res.setContentType("application/pdf"); in my code below does not solve the problem. Also, this other posting describes how to do it from a database but does not show full working controller code. Other postings had similar problems that caused them not to work in this case.
I need to simply serve up a file (not from a database) and have it been viewable by a user in their browser. The best I have come up with is the code below, which asks the user to download the PDF or to view it in a separate application outside the browser. What specific changes can I make to the specific code below so that the user automatically sees the PDF content inside their browser when they click on the link instead of being prompted to download it?
#RequestMapping(value = "/test-pdf")
public void generatePdf(HttpServletRequest req,HttpServletResponse res){
res.setContentType("application/pdf");
res.setHeader("Content-Disposition", "attachment;filename=report.pdf");
ServletOutputStream outStream=null;
try {
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(new File("/path/to", "nameOfThe.pdf")));
/*ServletOutputStream*/ outStream = res.getOutputStream();
//to make it easier to change to 8 or 16 KBs
int FILE_CHUNK_SIZE = 1024 * 4;
byte[] chunk = new byte[FILE_CHUNK_SIZE];
int bytesRead = 0;
while ((bytesRead = bis.read(chunk)) != -1) {outStream.write(chunk, 0, bytesRead);}
bis.close();
outStream.flush();
outStream.close();
}
catch (Exception e) {e.printStackTrace();}
}

Change
res.setHeader("Content-Disposition", "attachment;filename=report.pdf");
To
res.setHeader("Content-Disposition", "inline;filename=report.pdf");
You should also set the Content Length
FileCopyUtils is handy:
#Controller
public class FileController {
#RequestMapping("/report")
void getFile(HttpServletResponse response) throws IOException {
String fileName = "report.pdf";
String path = "/path/to/" + fileName;
File file = new File(path);
FileInputStream inputStream = new FileInputStream(file);
response.setContentType("application/pdf");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "inline;filename=\"" + fileName + "\"");
FileCopyUtils.copy(inputStream, response.getOutputStream());
}
}

Related

Spring MVC - Copy image into WEB-INF/assets folder

I am trying to copy image into assets folder inside WEB-INF folder. Following code successfully copy images outside the project but can't copy inside WEB-INF folder.
public static void copyFile(String source, String destination) throws IOException {
try {
File sourceFile = new File(source);
File destinationFile = new File(destination);
FileInputStream fileInputStream = new FileInputStream(sourceFile);
FileOutputStream fileOutputStream = new FileOutputStream(destinationFile);
int bufferSize;
byte[] bufffer = new byte[512];
while ((bufferSize = fileInputStream.read(bufffer)) > 0) {
fileOutputStream.write(bufffer, 0, bufferSize);
}
fileInputStream.close();
fileOutputStream.close();
} catch (IOException e) {
throw new IOException(e.getMessage());
}
}
I get a image path from Http request.
CopyFile.copyFile(imageUrl, "http://localhost:8080/M.S.-Handloom-Fabrics/static/"+imageName+".png");
I have mapped the resources in dispatcher-servlet.xml
<mvc:resources mapping="/static/**" location="/WEB-INF/assets/"/>
Here is the error
Info: http:\localhost:8080\M.S.-Handloom-Fabrics\static\TueJun1216_27_54NPT20180.png (The filename, directory name, or volume label syntax is incorrect)
http://localhost:8080/M.S.-Handloom-Fabrics/static/"+imageName+".png"
is a URL, not a file-path, and is therefore meaningless as a parameter to the File constructor.
IF you configured your app server to explode your webapp on deploy then you could use ServletContext.getRealPath but as this SO post details nicely you most likely do not want to do this as your saved files will be lost upon re-deploy.
Saving them outside of the web app is the way to go.

HtmlUnit - HTMLParser (page with characters)

I have a resource (a static html page), that I wanna use to test. But, when I get the static page, it comes with some characters encoding. I try with the class StringEscapeUtils but it doesn't work.
My function:
private HtmlPage getStaticPage() throws IOException, ClassNotFoundException {
final Reader reader = new InputStreamReader(this.getClass().getResourceAsStream("/" + "testPage" + ".html"), "UTF-8");
final StringWebResponse response = new StringWebResponse(StringEscapeUtils.unescapeHtml4(IOUtils.toString(reader)), StandardCharsets.UTF_8, new URL(URL_PAGE));
return HTMLParser.parseHtml(response, WebClientFactory.getInstance().getCurrentWindow());
}
import org.apache.commons.lang3.StringEscapeUtils;
final Reader reader = new InputStreamReader(this.getClass().getResourceAsStream("/" + "testPage" + ".html"), "UTF-8");
For the reader use the encoding of the file (from your comment i guess this is windows-1252 in your case).
Then read the file into an string (e.g. use commons.io).
Then you can process it like this
final StringWebResponse tmpResponse = new StringWebResponse(anHtmlCode,
new URL("http://www.wetator.org/test.html"));
final WebClient tmpWebClient = new WebClient(aBrowserVersion);
try {
final HtmlPage tmpPage = HTMLParser.parseHtml(tmpResponse, tmpWebClient.getCurrentWindow());
return tmpPage;
} finally {
tmpWebClient.close();
}
If you still have problem please make a simple sample out of your page that shows your problem and upload it here together with your code.

Spring MVC Resources not refreshing

I'm working on an image manager system for my Spring MVC project, with the basic functions of displaying the gallery of all images stored in the local image folder, deleting images and uploading new images.
I would like that, once a new image is uploaded, the page reloads the images gallery, including the image just added. What it happens in fact is that the new image is correctly saved on the HD, but it doesn't automatically show up in the resources/img folder in the Java project; therefore, once the page is reloaded, the new image is not there. Only when I manually refresh the project, the new image appears in the resources/img folder.
The odd thing is, I don't have the same problem with the delete method: once an image is deleted, it disappears from the HD AND the resources/img folder, and the page reloads the gallery without showing the image just deleted.
Any idea where the problem could be?
Here is my controller
#Controller
public class imagesManagerController {
// READ ALL FILES FROM IMG FOLDER
#RequestMapping(value = "/imagesManager", method = RequestMethod.GET)
public ModelAndView readImages
(#RequestParam(value = "error", required = false) String error) {
// create model and link it to jsp imagesManager
ModelAndView model = new ModelAndView("imagesManager");
// return content from images folder and add it to model
File imgsPath = new File("C:/Users/Alessandro/workspace/SpringMVCBlog/WebContent/resources/img");
String[] imgsNames = imgsPath.list();
model.addObject("imgsNames", imgsNames);
//if upload fails, display error message
if (error != null) {
model.addObject("error",
"Please select a file to upload");
}
return model;
}
//UPLOAD FILE TO HD
#RequestMapping(value = "/imagesManager/upload", method = RequestMethod.POST)
public String handleFileUpload (#RequestParam("file") MultipartFile file) {
//get img name
String imgName = file.getOriginalFilename();
System.out.println(imgName);
//create file path
String folder = "C:/Users/Alessandro/workspace/SpringMVCBlog/WebContent/resources/img/";
File path = new File (folder+imgName);
System.out.println(path);
if (!file.isEmpty()) {
try {
//get bytes array from file
byte[] bytes = file.getBytes();
//create output stream
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(path));
//write img content on path
stream.write(bytes);
//close stream
stream.close();
//if upload is successful, reload page
return "redirect:/imagesManager";
} catch (Exception e) {
return "You failed to upload " + imgName + " => " + e.getMessage();
}
} else {
return "redirect:/imagesManager?error";
}
}
// DELETE FILE FROM HD
#RequestMapping(value = "/imagesManager/delete", method = RequestMethod.POST)
public String deleteFile(#RequestParam (value="imgName") String imgName) {
//create file path to be deleted
String folder = "C:/Users/Alessandro/workspace/SpringMVCBlog/WebContent/resources/img/";
File path = new File (folder+imgName);
// delete file
if (path.delete()) {
//if delete is successful, reload page
return "redirect:/imagesManager";
} else {
return "Delete operation failed";
}
}
}
The problem is in the path:
WebContent/resources/img
It is refreshing probably due to IDE server auto-deployment. Test with %TEMP% path and check.
1) You should not save uploaded files to the application server file system.
2) You should not save uploaded files to the application folder as it is part of the deployment. It will only be deployed once and that folder is only for the application files.
Instead, use the cloud or a dedicated file system.

Uploading more than one image

Dear All,
Working on Spring MVC. I want to upload more than one images from the client. How to achieve it. I know how to handle the multipart form data for single image. But now I am expecting some data with some images from the client.
Any help or url that will help me.
Thanks,
Op
Image is also a file. Whether you would be storing it in database / in file system but it is still a file.
In spring MVC, you could do as shown in the below link:
http://viralpatel.net/blogs/spring-mvc-multiple-file-upload-example/
Here are the code i tried and it is working fine at my end.
//Handle multiple images
#RequestMapping(method = RequestMethod.POST, value="upload", consumes=MediaType.MULTIPART_FORM_DATA_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody JSONResponse uploadImages(HttpServletRequest req)
throws Exception {
try{
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) req;
Set set = multipartRequest.getFileMap().entrySet();
Iterator i = set.iterator();
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
String fileName = (String)me.getKey()+"_"+System.currentTimeMillis();
MultipartFile multipartFile = (MultipartFile)me.getValue();
System.out.println("Original fileName - " + multipartFile.getOriginalFilename());
System.out.println("fileName - " + fileName);
saveImage(fileName, multipartFile);
}
}
catch(Exception e){
e.printStackTrace();
}
return new JSONResponse();
}

How do you save images to a Blackberry device via HttpConnection?

My script fetches xml via httpConnection and saves to persistent store. No problems there.
Then I loop through the saved data to compose a list of image url's to fetch via queue.
Each of these requests calls the httpConnection thread as so
...
public synchronized void run()
{
HttpConnection connection = (HttpConnection)Connector.open("http://www.somedomain.com/image1.jpg");
connection.setRequestMethod("GET");
String contentType = connection.getHeaderField("Content-type");
InputStream responseData = connection.openInputStream();
connection.close();
outputFinal(responseData, contentType);
}
public synchronized void outputFinal(InputStream result, String contentType) throws SAXException, ParserConfigurationException, IOException
{
if(contentType.startsWith("text/"))
{
// bunch of xml save code that works fine
}
else if(contentType.equals("image/png") || contentType.equals("image/jpeg") || contentType.equals("image/gif"))
{
// how to save images here?
}
else
{
//default
}
}
What I can't find any good documentation on is how one would take the response data and save it to an image stored on the device.
Maybe I just overlooked something very obvious. Any help is very appreciated.
Thanks
I tried following this advise and found the same thing I always find when looking up BB specific issues: nothing.
The problem is that every example or post assumes you know everything about the platform.
Here's a simple question: What line of code writes the read output stream to the blackberry device? What path? How do I retrieve it later?
I have this code, which I do not know if it does anything because I don't know where it is supposedly writing to or if that's even what it is doing at all:
** filename is determined on a loop based on the url called.
FileOutputStream fos = null;
try
{
fos = new FileOutputStream( File.FILESYSTEM_PATRIOT, filename );
byte [] buffer = new byte [262144];
int byteRead;
while ((byteRead = result.read (buffer ))!=- 1)
{
fos.write (buffer, 0, byteRead);
}
fos.flush();
fos.close();
}
catch(IOException ieo)
{
}
finally
{
if(fos != null)
{
fos.close();
}
}
The idea is that I have some 600 images pulled from a server. I need to loop the xml and save each image to the device so that when an entity is called, I can pull the associated image - entity_id.png - from the internal storage.
The documentation from RIM does not specify this, nor does it make it easy to begin figuring it out.
This issue does not seem to be addressed on this forum, or others I have searched.
Thanks
You'll need to use the Java FileOutputStream to do the writing. You'll also want to close the connection after reading the data from the InputStream (move outputFinal above your call to close). You can find all kinds of examples regarding FileOutputStream easily.
See here for more. Note that in order to use the FileOutputStream your application must be signed.

Resources