The following servlet creates a directory named Shared and then copies the video into this directory.Next it presents the link,to download this video. But when I click the link,nothing happens. Why is this ?
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
String path = request.getServletContext().getRealPath("/") + "Shared/" + "sweet-love-story-that-might-make-your-day[www.savevid.com].3gp";
path = path.replace("\\","/");
try {
File f = new File(request.getServletContext().getRealPath("/") + "Shared/");
if(!f.exists()) {
f.mkdir();
// now copy the animation to this directory
} else {
System.out.println("directory already made");
}
writer.println("<html> <head> <title> </title> </head>");
writer.println("<body>");
writer.println("Click to download");
writer.println("</body>");
writer.println("</html>");
}catch(Exception exc) {
exc.printStackTrace();
}
}
Ironically when I write a html that is in the same directory as the video (in Shared) I am able to download/see the video. Why doesn't the link work when I access it via localhost ?
(I am using Tomcat)
**Note: The statement request.getServletContext().getRealPath("/") prints W:\UnderTest\NetbeansCurrent\App-1\build\web**
The following are the snapshots of html accessed from localhost and locally respectively.
and
Related
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
}
}
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 working in a old project.The project is in Spring MVC .In the project I have to generate a pdf file from a jsp page and store in a location and download that file. For that I am using wkhtmltopdf tool to convert the one specific jsp page into pdf format. Using wkhtmltopdf sometime works fine, it generate the pdf in specific location, but sometime it require more time. Also when I am trying to download the file from specific location , sometime it download a 0KB size file or sometime the downloaded file can't be open (with some size) but sometime download perfectly. If I check the file at define location, it exist and open normally.
Here is my code in controller class.
#RequestMapping(value="/dwn.htm",method=RequestMethod.GET)
public void dwAppFm(HttpSession session,HttpServletRequest request,HttpServletResponse response,#RequestParam String id) throws IOException,InterruptedException
{
final int BUFFER_SIZES=4096;
ServletContext context=request.getServletContext();
String savePath="/tmp/";//PDF file Generate Path
String fileName="PDFFileName"; //Pdf file name
FileInputStream inputStream=null;
BufferedInputStream bufferedInputStream=null;
OutputStream outputStream=null;
printApp(id,fileName);
Thread.sleep(1000);
printApp(id,fileName);
File download=new File(savePath+fileName+".pdf");
while(!download.canRead())
{
Thread.sleep(1000);
printApp(id,fileName);
download=new File(savePath+fileName+".pdf");
}
if(download.canRead()){//if the file can read
try{
Thread.sleep(1000);
inputStream=new FileInputStream(download);
bufferedInputStream=new BufferedInputStream(inputStream);
String mimeType = context.getMimeType(savePath+fileName+".pdf");
if (mimeType == null) {
mimeType = "application/octet-stream";
}
System.out.println("MIME type: " + mimeType);
response.setContentType(mimeType);
response.setContentLength((int)download.length());
String headerKey="Content-Disposition";
String headerValue=String.format("attachment;filename=\"%s\"", download.getName());
response.setHeader(headerKey, headerValue);
outputStream=response.getOutputStream();
byte[] buffer=new byte[BUFFER_SIZES];
int bytesRead=-1;
while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}catch(Exception e)
{
e.printStackTrace();
}
finally
{
try{
if(inputStream!=null)inputStream.close();
if(bufferedInputStream!=null)bufferedInputStream.close();
if(outputStream!=null)outputStream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
public void printApp(String id,String fileName)
{
try{
String urlPath="http://localhost:8080/proj";
urlPath+="/genApp.htm?id="+id;//generate url to execute wkhtmltopdf
String wxpath="/home/exm/wkhtmltopdf";//the path where wkhtmltopdf located
String save="/tmp/"+fileName+".pdf";//File save Pathname
Process process=null;
process=Runtime.getRuntime().exec(wxpath+" "+urlPath+" "+save);
}catch(Exception e)
{}
}
#RequestMapping(value="/genApp.htm",method=RequestMethod.GET)
public String getApplicationPDF(HttpServletRequest request,HttpSession session,#RequestParam String id)
{
UDets uDets=uService.getAllById(Long.parseLong(id));//Methods to get details
request.setAttribute("uDets",uDets );
return "makeApp";//Name of the jsp page
}
In my code I have use Thread.sleep(1000) and printApp(id,fileName) method three times , since sometime wkhtmltopdf fail to generate pdf in certain time and then probability of downloading 0KB file is more. I haven't share the jsp page since the jsp page contain simple jsp page code of lots of line (the size of the generated pdf file is two page).
So the problem is what should I change in my code so that the pdf file generated and download without a failure also in heavy load in server.
If there is any best procedure or idea please share.
I don't like to use itext, since the jsp page contain complex design. Any advise is also appreciable and also thanks in advance.
I would say that your code is flawed not just a little but big time. You are checking if a file can be read, if not you start again a proces writing to the same file (at least twice). At some time you will endup with multiple processes trying to write to the same file, resulting in strange behavior.
I would refactor the printApp method to return the Process it created. Then call waitFor on that process. If it returns 0 and doesn't get interrupted it completed successfully and you should be able to download the file.
#RequestMapping(value="/dwn.htm",method=RequestMethod.GET)
public void dwAppFm(HttpSession session,HttpServletRequest request,HttpServletResponse response,#RequestParam String id) throws IOException,InterruptedException
{
String savePath="/tmp/";//PDF file Generate Path
String fileName="PDFFileName.pdf"; //Pdf file name
File download = new File(savePath, fileName);
try {
Process process = printApp(id, download.getPath());
int status = process.waitFor();
if (status == 0) {
response.setContentType("application/pdf");
response.setContentLength((int)download.length());
String headerKey="Content-Disposition";
String headerValue=String.format("attachment;filename=\"%s\"", download.getName());
StreamUtils.copy(new FileInputStream(download), response.getOutputStream())
} else {
// do something if it fails.
}
} catch (IOException ioe) {
// Do something to handle exception
} catch (InterruptedException ie) {
// Do something to handle exception
}
}
}
public Process printApp(String id, String pdf) throws IOException {
String urlPath="http://localhost:8080/proj";
urlPath+="/genApp.htm?id="+id;//generate url to execute wkhtmltopdf
String wxpath="/home/exm/wkhtmltopdf";//the path where wkhtmltopdf located
String command = wxpath+" "+urlPath+" "+pdf;
return Runtime.getRuntime().exec(command);
}
Something like the code above should to the trick.
This question is continuation to my previous question Accessing External Files Into Our Web Application, actually I am uploading file using struts tag <html:file property="file" />
But now I wanted to show the uploaded images from that location but I am getting src location as http://localhost:9443/D:/resources/images/img1.jpg which is not a valid path for that image.
How to access that image which is outside my server directory.
This is how I am sending Ajax response with Absolute path of images
public ActionForward getAjaxUploadedFiles(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
{
String imagePath = "D:/resources/images/";
ArrayList<String> path = new ArrayList<String>();
File imageFile = new File(imagePath);
File imageFiles[] = imageFile.listFiles();
for (int i = 0; i < imageFiles.length; i++) {
path.add(imageFiles[i].getAbsolutePath());
}
PrintWriter out = response.getWriter();
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
response.setStatus(HttpServletResponse.SC_OK);
StringBuffer strXMl = new StringBuffer();
strXMl.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
strXMl.append("<start>");
for (String imagePth : path) {
strXMl.append("<imagePath>");
strXMl.append(imagePth);
strXMl.append("</imagePath>");
}
strXMl.append("</start>");
if(strXMl != null){
String Xml = strXMl.toString();
out.write(Xml);
System.err.println("XMl Reponse is: " + Xml);
}
else {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
out.flush();
return mapping.findForward(null);
}
This is how I am rendering images at JSP
$(response).find("imagePath").each(function() {
row = tblReportList.insertRow(0);
row.className="TableBordergray";
row.style.width="100%";
var imagePath = $(this).text();
cell = row.insertCell(0);
cell.innerHTML="<img src='" + imagePath + "' alt='" + imagePath + "' height='42' width='42'>";
});
but at img tag I am getting image path as http://localhost:9443/D:/resources/images/img1.jpg
Hi Below is the answer to my question, I have created ImageServlet for displaying image, steps to perform:
1. you need to add mapping in web.xml file:
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/ImageServlet/*</url-pattern>
2. create ImageServlet:
public class ImageServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
//Setting image path
ImageLocationService locationService = new ImageLocationService();
try {
String imageCategory = request.getParameter("imageCategory");
if (imageCategory != null) {
this.imagePath = locationService.getImageLocation(imageCategory);
}else{
this.imagePath = ConfigConstants.imageLocation;
}
} catch (Exception e) {
e.printStackTrace();
}
// Get requested image by path info.
String requestedImage = request.getPathInfo();
// Check if file name is actually supplied to the request URI.
if (requestedImage == null) {
// Do your thing if the image is not supplied to the request URI.
// Throw an exception, or send 404, or show default/warning image, or just ignore it.
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
// Decode the file name (might contain spaces and on) and prepare file object.
File image = new File(imagePath, URLDecoder.decode(requestedImage, "UTF-8"));
// Check if file actually exists in filesystem.
if (!image.exists()) {
// Do your thing if the file appears to be non-existing.
// Throw an exception, or send 404, or show default/warning image, or just ignore it.
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
// Get content type by filename.
String contentType = getServletContext().getMimeType(image.getName());
// Check if file is actually an image (avoid download of other files by hackers!).
// For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
if (contentType == null || !contentType.startsWith("image")) {
// Do your thing if the file appears not being a real image.
// Throw an exception, or send 404, or show default/warning image, or just ignore it.
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
// Init servlet response.
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(image.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\"");
// Prepare streams.
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
// Open streams.
input = new BufferedInputStream(new FileInputStream(image), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
// Gently close streams.
close(output);
close(input);
}
}
private static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
// Do your thing with the exception. Print it, log it or mail it.
e.printStackTrace();
}
}
}
}
3. At jsp side you need to add the mapping in step 1 in your img tag i.e. input type='image':
<input type="image" alt='No image found' src='../ImageServlet/append image name that you want to display' />
You can even create Action class and use execute method for doing the same.
You can't render images in such way. Web server treated your image path as relative and add qualifying url location on the server. You should create an action to serve images, for example
<action path="/image" ... scope="request" validate="false"/>
Then render HTML like
cell.innerHTML="<img src='" + '/image?path=' + imagePath + "' alt='" + imagePath + "' height='42' width='42'>";
Now, create the action that write the binary image data to the response output stream. Take a parameter path in the action that let you find a file for binary output. After the flushing output return null so struts should not forward the action further. You could also add headers to turn off a Cache-Control to make sure the images are retrieved from the server.