I am trying to load images from server to my JSP
My files are:
image.jsp
<img src='servlet1' height='300px'/>
DisplayImage.java
public class DisplayImage extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{
response.setContentType("image/jpeg");
ServletOutputStream out;
out = response.getOutputStream();
FileInputStream fin = new FileInputStream("path/to/my/img.jpg");
BufferedInputStream bin = new BufferedInputStream(fin);
BufferedOutputStream bout = new BufferedOutputStream(out);
int ch =0;
while((ch=bin.read())!=-1){
bout.write(ch);
}
bin.close();
fin.close();
bout.close();
out.close();
}
}
Application I'm supposed to build is a Vehicle Directory where I can upload images, and these images are stored in a folder /home/upload/ outside CATALINA
(NB: I didn't use a folder inside project directory coz I am deploying the project via *.war file, which removes every files inside when a new version needs to be deployed.)
I want to display the details and image based on search parameters.
( Edit: I have the file name stored in database when I upload them, so can get the list of image names from DB for a particular vehicle, Since it is stored in folder /home/upload/ , full path will be like /home/upload/fileName.jpg which I need to pass to servlet to load)
Problem I face is that:
image src attribute is specified as servlet1 and the servlet by default serves the image from path defined in DisplayImage.java file
Is there any way that I can pass /another/file/Path.jpg or fileName.jpg to the servlet so that I can display other image files too,
Yeah, In JSP, you can pass your search parameters in request.
Like
<input id="imageSerach" name="imageSerach"/>
<div id="ImageContent"/>
and make ajax call to servlet with imageSearch param.
$.ajax({
url: servleturl,
data: {
imageSerach : $('#imageSerach').val()
},
success: function(responseData){
$('#ImageContent').html('<img src="data:image/png;base64,' + responseData + '" />');
}
});
Servlet :-
public class DisplayImage extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{
String fileName = req.getParameter("imageSerach");
response.setContentType("image/jpeg");
ServletOutputStream out;
File f = new File("path/of/file/"+fileName);
if (f.exists())
out = response.getOutputStream();
FileInputStream fin = new FileInputStream("path/of/file/"+fileName);
BufferedInputStream bin = new BufferedInputStream(fin);
BufferedOutputStream bout = new BufferedOutputStream(out);
int ch =0;
while((ch=bin.read())!=-1){
bout.write(ch);
}
bin.close();
fin.close();
bout.close();
out.close();
else
// no file exit
}
}
Related
I am working on a Java application and what I want to do is to give to the users the functionality to upload an image and view it at their profile. I know similar questions have been answered many many times but this is my first time doing this and I am really struggling to make it work.
So this is my testing code:
upload.jsp
...
<body>
<form method="post" action="FileUploader" encType="multipart/form-data">
<input type="file" name="file" value="select images..."/>
<input type="submit" value="start upload"/>
</form>
</body>
...
FileUploader.java
As you can see here, I store all my images in Tomcat's webapps/ROOT/files folder.
#WebServlet("/FileUploader")
public class FileUploader extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
if(!ServletFileUpload.isMultipartContent(request)){
out.println("Nothing to upload");
return;
}
FileItemFactory itemfactory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(itemfactory);
try{
List<FileItem> items = upload.parseRequest(new ServletRequestContext(request));
for(FileItem item:items){
String contentType = item.getContentType();
if(!contentType.equals("image/png")){
out.println("only png format image files supported");
continue;
}
File uploadDir = new File("/home/agg/apache-tomcat/webapps/ROOT/files");
File file = File.createTempFile("img",".png",uploadDir);
item.write(file);
out.println("Filename: " + file.getName());
out.println("File Saved Successfully");
response.sendRedirect("message.jsp");
}
}
catch(FileUploadException e){
out.println("upload fail");
}
catch(Exception ex){
out.println("can't save");
}
}
}
message.jsp
Here, I am trying to load one of the images saved through another servlet.
...
<body>
<img src="file/img1.png">
</body>
FileServlet.java
Servlet that retrieves the image.
#WebServlet("/file/*")
public class FileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
private String filePath;
public void init() throws ServletException {
this.filePath = "/files";
}
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("================In do get==================");
// Get requested file by path info.
String requestedFile = request.getPathInfo();
System.out.println("Requested File: " + requestedFile);
// Check if file is actually supplied to the request URI.
if (requestedFile == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
// Decode the file name (might contain spaces and on) and prepare file object.
File file = new File(filePath, URLDecoder.decode(requestedFile, "UTF-8"));
System.out.println("Filename: " + file.getName());
System.out.println(file.getAbsolutePath());
// Check if file actually exists in filesystem.
if (!file.exists()) {
System.out.println("DOES NOT EXIST");
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
// more code here but it does not matter
}
}
The problem is that the image does not load. The path printed at the console seems to be correct. What am I missing here?
For me your problem is here
<img src="file/img1.png">
It doesn't seem to be the correct path for the next reasons:
The root directory is /.../webapps/ROOT/files so it should start with files not file.
The name of the file should be img + a random long + .png here you set the random long to 1 which doesn't seem to be correct
As it is in the ROOT webapp, you should rather put an absolute path instead of a relative path, in other words the path should start with a slash
Inside server.xml of my tomcat folder, i have a virtual folder under <Host> tag:
<Context docBase="C:\app_files\" path="/app_files"/>
So i can access files from inside this folder through the url: http://localhost:8080/app_files/some_file.jpg
But this only works if the image or file was already there BEFORE the server was started. If i go to a URL pointing to an image created after the server was started, it gives the 404 error. After restarting the server, the image loads correctly.
How to sove this problem?
If you use Tomcat application manager you can undeploy/deploy your single application without restarting the whole server (and without impact on other webapps) or, more brutally, you can replace the desired war from the webapps dir (again undeploy/deploy will ensue). If you have to guarantee uptime for your application even in this case you have to go with parallel deployment (here a guide for tomcat 8)
try to add the attribute autoDeploy="true" to your context configuration, this will tell catalina to monitor your docbase location for changes
I actually managed to do what i wanted without using the Context on the server.xml.
It's based on the BalusC's solution to serve static files through servlets
Here's how:
First, i created an environment variable in my system (can be done in every os, just google for "how to create environment variable on windows, linux, etc"), called MANAGEMENT_FILES, the variable value in my case was c:/management_files/
Then, on the method that creates the image that should be shown to the user, i save the image on this folder (which is the value of the environment variable from the previous step):
public String imageUrl;
public void createAndShowImage() {
try {
String imageName = "/nice_images_folder/cool_image.jpg";
File imageFile = new File(System.getenv("MANAGEMENT_FILES") + imageName);
//Here goes your logic to create the file
createImage(imageFile);
//Here i use a fixed URL, you can do it as you see fit
this.imageUrl = "http://localhost:8080/MyCoolApp/" + CoolFileServlet.BASE_URL + imageName + "?delete=true";
} catch (Exception e) {
e.printStackTrace();
}
}
And this is the servlet you have to create, this servlet returns the image or any other file that you put inside the folder:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLDecoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet(name="CoolFileServlet", urlPatterns={CoolFileServlet.BASE_URL + "*"})
public class CoolFileServlet extends HttpServlet {
public static final String BASE_URL = "/shiny_happy_files/";
private static final int DEFAULT_BUFFER_SIZE = 10240;
private String filePath;
public void init() throws ServletException {
this.filePath = System.getenv("MANAGEMENT_FILES");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String requestedFile = request.getPathInfo();
if (requestedFile == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
File file = new File(filePath, URLDecoder.decode(requestedFile, "UTF-8"));
if (!file.exists()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
String contentType = getServletContext().getMimeType(file.getName());
if (contentType == null) {
contentType = "application/octet-stream";
}
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
close(output);
close(input);
try {
if ("true".equals(request.getParameter("delete"))) {
if (!file.delete()) {
throw new RuntimeException("File could not be deleted");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Notice that you can pass the parameter delete=true in the url when it is accessed, to delete it right after it is recovered (in cases when it will not be needed anymore).
In my case i needed to show the image on the page after the user performed some action, so all i had to do was show the image url:
<h:graphicImage url="#{myManagedBean.imageUrl}"/>
That's it, you can serve any type of file with this servlet, and it will return the file you want, instantly, and the file will remain active between server restart/redeploy (if it was not deleted through delete=true.
If you care for a different approach, you can also do this by mapping a function in a controller that returns a IOUtils object while specifying the media type, then calling the function's URL in your img's src.
#ResponseBody
#RequestMapping(value="/load_photo", params = {"myPhoto"}, method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
public byte[] loadPhoto(#RequestParam(value = "myPhoto") String myPhoto) throws IOException {
File file = new File(servletContext.getRealPath("")+Constants.PATH_TO_FILE+myPhoto);
FileInputStream fis = new FileInputStream(file);
return IOUtils.toByteArray(fis);
}
Then you call your img in your JSP:
<img class="photo" src="/app/controller/load_photo?myPhoto=${myPhoto}">
With this, you can serve dynamically generated images.
I am having an image stored at a location say : C:\Users\admin\Desktop\SharedCrpto1\web\RetrievedFiles\FILE310#ST-testemp\abc.png .Now when i try to show it in my jsp page the image is not getting visible even when the path to image is correct.
This image is to be displayed after my server process the browsed image provided by the client.
I tried :
<img src="<%=path%>" alt="No image" />
The image in the particular folder is being created by my servlet like this :
File filesstore = new File("C:\\Users\\admin\\Desktop\\SharedCrpto1\\web\\RetrievedFiles\\FILE310#ST-testemp\\");
if(!filesstore.exists())
{
System.out.println("MAKING DIRECTORY..");
filesstore.mkdirs();
}
To copy one file to this location I did :
FileInputStream fis = new FileInputStream("C:\\test.png");
int xx=fis.available();
byte[] b = new byte[xx];
fis.read(b);
FileOutputStream fos=new FileOutputStream("C:\\Users\\admin\\Desktop\\SharedCrpto1\\web\\RetrievedFiles\\FILE310#ST-testemp\\abc.png");
fos.write(b);
Am i doing something wrong?Please help
From your question what I understood is that You want to read a image file from your local file system & display in a jsp page using
STEP 1
For this you need a servlet or jsp which will read the file and convert to byte[] and again write the byte[] to ServletOutputStream .
STEP 2:
Create a JSP page which have a img tag & it's src should point to servlet url instead of real file path.As img tag's src attribute can take file path or byte stream.In this we are giving it byte stream because file path will not work.
When you call your jsp page it will try to render the img tag and at that time it will call your servlet & get the byte stream of image data .So it will render your image
Image Servlet
#WebServlet("/ImageServlet")
public class ImageServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//place your file path
File imageFile =new File("/home/ashok/Pictures/Siberischer.jpg");
ServletOutputStream outputStream = response.getOutputStream();
byte[] imageBytes = FileUtils.readFileToByteArray(imageFile);
outputStream.write(imageBytes);
outputStream.close();
}
}
JSP PAGE(to display image) In your jsp just write this tag
JspPage is the application name & ImageServlet is the servlet url pattern
<img alt="NO IMAGE" src="/JspImage/ImageServlet">
FileUtils is present Apache Commons IO Library download the jar to your project
Current situation: I'm trying to create a JSF app (portlet) which should contains links to excel files (xls, xlt) stored on public network drive G: mapped for all users in our company. The main goal is to unify access to these files and save work to users in search of the reports somewhere on G drive. I hope it's clear..?
I'm using following servlet to open a file. Problem is, that it's not just opened, but downloaded by browser and after that, opened:
#WebServlet(name="fileHandler", urlPatterns={"/fileHandler/*"})
public class FileServlet extends HttpServlet
{
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
private String filePath;
public void init() throws ServletException {
this.filePath = "c:\\Export";
System.out.println("fileServlet initialized: " + this.filePath);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
{
String requestedFile = request.getPathInfo();
File file = new File(filePath, URLDecoder.decode(requestedFile, "UTF-8"));
String contentType = getServletContext().getMimeType(file.getName());
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
close(output);
close(input);
}
}
private static void close(Closeable resource) {
if (resource != null) resource.close();
}
}
How to just start appropriate application (e.g. Excel, Word, etc.) clicking on link (with absolute file path) and open the file in its original location?
UPDATE: I'm trying to use <a> tag:
File // various "/" "\" "\\" combinations
File
But it doesn't work:
type Status report
message /G:/file.xls
description The requested resource is not available.
File URLs are considered as a security risk by most browsers, because they cause files to be opened on a client's machine by a web page, without the end user being aware of it. If you really want to do that, you'll have to configure the browser to allow it.
See the wikipedia article for solutions.
I am uploading file using spring MVC and jquery. Inside my class method I have written
#RequestMapping(value="attachFile", method=RequestMethod.POST)
public #ResponseBody List<FileAttachment> upload(
#RequestParam("file") MultipartFile file,
HttpServletRequest request,
HttpSession session) {
String fileName = null;
InputStream inputStream = null;
OutputStream outputStream = null;
//Save the file to a temporary location
ServletContext context = session.getServletContext();
String realContextPath = context.getRealPath("/");
fileName = realContextPath +"/images/"+file.getOriginalFilename();
//File dest = new File(fileName);
try {
//file.transferTo(dest);
inputStream = file.getInputStream();
outputStream = new FileOutputStream(fileName);
inputStream.close();
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Its uploading the file correctly I am using
ServletContext context = session.getServletContext();
String realContextPath = context.getRealPath("/");
to get the path. My first question is , Is this the correct way to get the path and it stores the file somewhere at
workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/myproject/images
and when I am trying to display this image on my jsp page using the following code
<img src="<%=request.getRealPath("/") + "images/images.jpg" %>" alt="Upload Image" />
It does not display the image, Its generating the following html
<img src="/home/name/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/myproject/images/images.jpg" alt="Upload Image">
Am I doing the things right? In my project I have to upload large number of files everyday.
Please let me know if you need anything else to understand my question
It will be better if you upload your files in some directory by absolute path(e.g. C:\images\) instead of relative (your approach). Usually, web apps runs on linux mathines on production and it is good practice to make save path configurable.
Create some application property which will holds save path for files(in xml or property file).