Java Servlet Downloading File - java

So I have two files, the servlet:
package com.servlets;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import com.java.DataDownloader;
/**
* Servlet implementation class downloaderServ
*/
public class DownloaderServ extends HttpServlet {
private static final long serialVersionUID = 1L;
DataDownloader dl;
/**
* #see HttpServlet#HttpServlet()
*/
public DownloaderServ() {
super();
dl = new DataDownloader();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
dl.download();
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
The application which does the processing:
package com.java;
import java.io.*;
import java.net.*;
import org.apache.commons.io.*;
public class DataDownloader {
private static boolean get(String address, String fileName) {
try {
URL url = new URL(address);
File f = new File(fileName);
FileUtils.copyURLToFile(url, f);
}
catch(MalformedURLException e) {
System.out.println(e);
return false;
}
catch(IOException e) {
System.out.println(e);
return false;
}
return true;
}
public boolean download() {
String[][] urls = new String[3][2];
urls[0][0] = "http://data.london.gov.uk/datafiles/crime-community-safety/mps-recordedcrime-borough.csv";
urls[0][1] = "crimes.csv";
urls[1][0] = "http://data.london.gov.uk/datafiles/housing/average-house-prices-borough.xls";
urls[1][1] = "prices.xls";
urls[2][0] = "http://data.london.gov.uk/datastorefiles/datafiles/demographics/gla_2012rnd_SHLAA_based_borough_projections.xls";
urls[2][1] = "population.xls";
for (int i = 0; i < 3; i++) {
if (get(urls[i][0], urls[i][1]) == false) {
System.out.println(false);
return false;
}
}
return true;
}
}
I can run it with no problems but there does not seem to be any files downloaded. I have also printed out the return values (true or false) and it does print true. Is downloading a file not as simple as this?

Code looks fine, so if prints true and you don't see any exceptions as well while running the program, then your problem is you are not able to locate the files copied from url.
Since no directories are specified in destination File, it must be dumping your file in the folder at which you are invoking java program. If it's an IDE (Eclipse) etc with which program is being run, refresh and check the associated project folder.

Kevin, as you clearly didn't get any exception, here's what I suggest: please right click your Eclipse project root folder and click: Refresh. Your files will be there directly at that path.
Also, I'm removing the servlet tag from your question as the issue has totally nothing to do with servlets. It's just that you're using them inside a servlet, but this same code would work in isolation, even outside of Java EE in fact.
I added fileutils instead.

I changed the it so an absolute path is taken e.g.
File f = new File("C:\\data\\" + fileName);
This works. Does having it in a servlet change it so an absolute path is needed and render relative paths unusable? I tested the downloading part outside of a servlet and it works with relative paths or it just downloads into project folder if nothing is specified.

Related

How can I set setContentType("text/html") or setContentType("text/plain") dynamically

I need to modify the code that read a text file, in a dynamically to read text or html files.
Now the code use only
response.setContentType("text/plain");
because the file is saved in text format. But I would like to save in html format to manage all tag and have a better view, but If I modify in
response.setContentType("text/html");
all file saved as text have a wrong viewer
My code is:
package uk.co.mycode.fax.controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import uk.co.mycode.fax.dao.mycodeFaxDAO;
import uk.co.mycode.fax.domain.Image;
import uk.co.morpheus.logging.Logger;
public class FaxImageRequest
extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { performTask(request, response); }
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { performTask(request, response); }
public void performTask(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String url = request.getParameter("U");
if (url == null || url.length() < 1) {
url = request.getParameter("URL");
}
Logger.log(4, getClass().getName(), "<**** Entered FaxImageRequest (" + url + ") ****>");
try {
Cookie[] cookies = request.getCookies();
String userId = "";
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals("IMPS3IAuserid")) {
userId = cookies[i].getValue();
break;
}
}
}
if (userId.length() < 1) {
userId = "NOT LOGGED ON";
}
mycodeFaxDAO dao = mycodeFaxDAO.getInstance();
Image image = dao.getImage(url);
Logger.log(4, getClass().getName(), "Image: " + image);
if (image != null) {
ServletOutputStream out = response.getOutputStream();
if (image.type.toLowerCase().startsWith("f")) {
response.setContentType("image/tiff");
} else {
//----------------------------------------------------------------------------
response.setContentType("text/plain");
//----------------------------------------------------------------------------
}
for (int i = 0; i < image.bytes.length; ) { out.write(image.bytes, i, (image.bytes.length - i > 4096) ? 4096 : (image.bytes.length - i)); i += 4096; }
dao.updateImageArchive(userId, request.getParameter("U"));
} else {
response.setContentType("text/html");
PrintWriter pw = response.getWriter();
pw.println("<HTML>");
pw.println("<BODY>");
pw.println("<B>No image found</B>");
pw.println("</BODY>");
pw.println("</HTML>");
pw.close();
}
} catch (Throwable th) {
Logger.log(1, getClass().getName(), "Error during image read or update:" + th.getMessage());
th.printStackTrace();
}
Logger.log(4, getClass().getName(), "<**** Finished FaxImageRequest ****>");
}
}
I tried to write this:
if (response.getContentType() == null) {
response.setContentType("text/html");
} else {
response.setContentType("text/plain");
}
but it is always null.
Thanks for the support.
The correct answer, if I may bring up your "hosting platform" - is that such settings are usually changed in the hosting platform. I have hosted three different web domains with GCS (Google Cloud Server) because it is (mostly) free.
In Google Cloud, when you save a file, generally it will recognize what type of file you have save (Content-Type) based on the file's extension - '.txt' or '.html'. The Content-Type setting can be changed in Google's bucket file explorer GUI using a mouse. It may also be changed manually at the command line using the GSUTIL command line program.
You may make calls to GSUTIL from Java by using Java's shell execution libraries (the Java Standard library routines for calling UNIX Shell commands). This is what I do...
... But you may even download Google's Java Jar files to access GCS and make Java based calls to GCS for doing things like changing the content type of a storage bucket file....
If you were using.MSFT Azure, or GoDaddy or something else this would be different.

How can I ignore the error of HTTP Status 404 in Tomcat v7.0? [duplicate]

This question already has answers here:
Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"
(19 answers)
Closed 5 years ago.
I am trying to learn servlets using Eclipse Juno. I am trying to run a servlet Hello2.java using Tomcat v7.0. This error of HTTP Status 404 keeps coming up. If there is any error in my code, then How can I debug it. And if there is something by which I can ignore this error please do tell me as soon as possible.
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
#WebServlet("/Hello2")
public class Hello2 implements Servlet {
private static final long serialVersionUID = 1L;
ServletConfig config = null;
public Hello2() {
super();
}
#Override
public void init(ServletConfig config) throws ServletException {
this.config=config;
System.out.println("Servlet is initialized!");
System.out.println(serialVersionUID);
}
#Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("<html><title>");
out.println("Hello again!");
out.println("</title><body>");
out.println("Hello Hello!!!!!!");
out.println("</body></html>");
//out.close();
}
#Override
public void destroy() {
System.out.println("Servlet is destroyed.");
}
#Override
public ServletConfig getServletConfig() {
return config;
}
#Override
public String getServletInfo() {
return "Copyright 2017-2018";
}
}
Your URL is incorrect. That's why you get 404 (client error).
Try the URL http://localhhost:8080/SDM1/Hello2
Those links were correct earlier but then I viewed some posts of other people questioning about the same error error and some solutions were given in which they were trying to add a folder names 'classes' in 'WEB-INF' folder and then adding that folder to the build path.
Even if I correct the requesting URL it still gives me this error message.
You should call the index file on running/debugging the Project.
try this URL http://localhost:8080/ or
http://localhost:8080/SDM1/WEB-INF/classes/Hello2.html

Jetty servlet override extension reading file

I'm trying to make a servlet on Jetty that overrides a file extension but that still needs to read the file being accessed.
I've been trying with resources but I could achieve nothing yet. I've tryed this code so far and, as you'll see, the resources are there but I somehow can't access them:
package valarionch.lab0.webapp.todo;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#SuppressWarnings("serial")
#WebServlet(urlPatterns = { "*.ToDo" })
public class ToDoHandler extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
String s = req.getParameter("s");
boolean small = (s != null && s.equals("1"));
PrintWriter out = resp.getWriter();
if (!small) {
out.println("<html><head><title>ToDo list</title></head>"
+ "<body>");
}
for (String res : getServletContext().getResourcePaths("/")) {
System.out.println("Resource: " + res);
System.out.println("ResourceURL: " + getServletContext().getResource(res));
System.out.println("ResourceStream: " + getServletContext().getResourceAsStream(res));
}
InputStream input = getServletContext().getResourceAsStream(req.getRequestURI());
System.out.println(input);
ToDoFormatter.parse(input, out, req.getParameter("q"));
if (!small) {
out.println("</body></html>");
}
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
this code prints this:
Resource: /META-INF/
ResourceURL: null
ResourceStream: null
Resource: /WEB-INF/
ResourceURL: null
ResourceStream: null
Resource: /index.html
ResourceURL: null
ResourceStream: null
Resource: /ToDoList.ToDo
ResourceURL: null
ResourceStream: null
null
I tryed with the next code too but also didn't worked:
getClass().getClassLoader().getResource(".").toString()+"../.."+req.getRequestURI()
so getClass().getClassLoader().getResource(".").toString() goes to WEB-INF/classess and +"../.."+req.getRequestURI() picks the actual file.
Am I missing something about how resources work? Is there another way to read the file?
You can use getServletContext().getRealPath() for such task. Let's imagine that you have the file myText.txt in the webapps folder:
#SuppressWarnings("serial")
#WebServlet(urlPatterns = { "*.ToDo" })
public class UseGetRealPath extends HttpServlet {
public void doGet( HttpServletRequest req, HttpServletResponse res )
throws ServletException, IOException {
String todoFile = getServletContext().getRealPath("/myText.txt");
FileReader fr = new FileReader( todoFile );
for( int c = fr.read(); c != -1; c = fr.read() ) {
System.out.print( (char) c );
}
fr.close();
res.getWriter().println( "check the console!" );
}
}
The code will open the file and dump its content in the console.

iText working Google App engine

I'm trying create pdf in java with google app engine but it doesn't work yet:
#SuppressWarnings("serial")
public class GuestbookServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("application/pdf");
try {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("HelloWorld.pdf"));
document.open();
document.add(new Paragraph("Hello World"));
document.close();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
This is the error:
HTTP ERROR 500
Problem accessing /guestbook. Reason:
com/itextpdf/text/DocumentException
Caused by:
java.lang.NoClassDefFoundError: com/itextpdf/text/DocumentException
I have read the incompatibility with java.awt and java.nio with google appengine. But I don't know how to do it. Is there any special version of itext to google app engine? Or do you know any clue that can help me?
Yes, there's a GAE version of iText. See http://lowagie.com/iPadSchools to watch a demo. The GAE port is distributed by iText Software. There's no link to get it online.
package mx.gob.campeche.sit.web.reportes;
import java.io.IOException;
import java.io.OutputStream;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import mx.gob.campeche.sit.doc.recibo_oficial.ReciboOficial;
#WebServlet("/reciboOficial")
public class ReporteReciboOficialServlet extends HttpServlet {
#Inject
ReciboOficial reciboOficial;
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpServletRequestWrapper srw = new HttpServletRequestWrapper(request);
String folio = "";
if (request.getParameterMap().containsKey("folio")) {
folio = request.getParameter("folio");
System.out.println("contenido" + folio);
}else
if (request.getParameterMap().containsKey("numero")) {
folio = request.getParameter("numero");
System.out.println("contenido" + folio);
}else{
throw new ServletException("No ingreso parametro");
}
byte[] pdfData = reciboOficial.crearReciboOFicialCajas(folio, srw.getRealPath(""));
response.setContentType("application/pdf");
response.reset();
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "inline; filename=\"" +"samplePDF2.pdf" +"\"");
OutputStream output = response.getOutputStream();
output.write(pdfData);
output.close();
}
this is small example, this help

How do I invoke a command when loading the URL in JSP MVC?

I'm using the design pattern found here. It has a FrontController, Command -> Service, and Dao.
If I load this URL in my browser (viewprofile is the name of the jsp):
http://localhost:8080/MyApplication/FrontController/viewprofile
I don't know how to automatically invoke ViewProfileCommand to then display the details of a user.
Currently the way I have it is like this, in order to invoke ViewProfileCommand I have to concatenate it onto the URL like: http://localhost:8080/MyApplication/FrontController/viewprofile?action=ViewProfile.
How do I map a jsp to a command without having to concatenate it onto the URL? Thanks
FrontController:
package com.secret.bookstore.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.secret.bookstore.command.Command;
import com.secret.bookstore.command.CommandFactory;
import com.secret.bookstore.exceptions.CommandCreationException;
import com.sun.net.httpserver.Filter.Chain;
/*
* Front Controller (Mediator Pattern)
*/
#WebServlet(urlPatterns={"/FrontController"})
public class FrontController extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public FrontController(){
super();
}
protected void service(HttpServletRequest request, HttpServletResponse response){
String action = request.getParameter("action");
CommandFactory commandFactory = CommandFactory.getInstance();
Command command = null;
String view = null;
view = request.getPathInfo().substring(1);
if(action != null){
try {
command = commandFactory.createCommand(action);
view = command.execute(request, response);
} catch(CommandCreationException e) {
e.printStackTrace();
}
}
forwardToPage(request, response, view);
}
/**
* Forward to server to the supplied page
*/
private void forwardToPage(HttpServletRequest request, HttpServletResponse response, String view){
//Get the request dispatcher object and forward the request to the appropriate JSP page...
if(view.equals(request.getPathInfo().substring(1))){
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/" + view + ".jsp");
try {
dispatcher.forward(request, response);
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
response.sendRedirect(view);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
You have designed your front controller to determine actions based on request parameters instead of request path info. So you really have to supply a request parameter in order to invoke an action.
The front controller example in the linked answer determines the action based on request method and request path info which is also a more sensible way. You'd need to do the same in order to achieve your functional requirement of being able to preprocess GET requests.
Basically:
command = commandFactory.createCommand(request.getMethod(), request.getPathInfo());
or just as in the given example:
command = commandFactory.createCommand(request);

Categories