Errore 500 in servlet che cerca file in Eclipse

di il
8 risposte

Errore 500 in servlet che cerca file in Eclipse

Salve a tutti, sono novizio e sto impazzendo su un problema di path. Ho la seguente servlet, scritta su Eclipse Mars, connessa a tomcat 8, quando la eseguo in questo modo funziona perfettamente, al momento che intendo cambiare il path del file:
da File f = new File("c:\\a.jpg"); in un path che contenga la cartella "Images", creata dentro il progetto (Web Dynamic) allo stesso livello della src, mi da errore di non trovato:
HTTP Status 500 - Can't read input file!
, ho provato in tutte le maniere
tipo: File f = new File("/Images/a.jpg"); e molte altre simili....
ma non ne vengo fuori, come dovrei scrivere il path relativo al file per farlo vedere? ... ho sbaglio altre cose?
Grazie
package test;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
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("/Immagine2")
public class Immagine2 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
response.setContentType("image/jpeg");
File f = new File("c:\\a.jpg");
BufferedImage bi = ImageIO.read(f);
OutputStream out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
out.close();
}
}

8 Risposte

  • Re: Errore 500 in servlet che cerca file in Eclipse

    sergioprogramma ha scritto:


    al momento che intendo cambiare il path del file:
    da File f = new File("c:\\a.jpg"); in un path che contenga la cartella "Images", creata dentro il progetto (Web Dynamic) allo stesso livello della src, mi da errore di non trovato:
    HTTP Status 500 - Can't read input file!
    , ho provato in tutte le maniere
    tipo: File f = new File("/Images/a.jpg"); e molte altre simili....
    Uno slash iniziale denota la "root" del file-system e si presume non sia quello che vuoi ... né che sia particolarmente appropriato.

    Se la immagine è fissa e "fa parte" della applicazione, puoi:
    - trattarla come "risorsa" secondo i termini di getResource / getResourceAsStream di java.lang.Class (ti è più utile il secondo metodo in questo caso)
    oppure
    - ServletContext ha getRealPath(), vedi documentazione. ServletContext ha anche la coppia getResource/getResourceAsStream ma con un concetto diverso da quello di Class.

    sergioprogramma ha scritto:


    sbaglio altre cose?
    		File f = new File("c:\\a.jpg");
    		BufferedImage bi = ImageIO.read(f);
    		OutputStream out = response.getOutputStream();
    		ImageIO.write(bi, "jpg", out);
    		out.close();
    Quale è il senso/utilità di decodificare una immagine jpeg per poi ricodificarla in jpeg (potenzialmente perdendo qualità a seconda di cosa fa ImageIO) ?
    Hai un file .... fai lo streaming di quello direttamente.
    Tra l'altro dovresti mandare anche il Content-Length che se fai lo streaming diretto del contenuto del file, è semplice perché è la lunghezza del file (che puoi sapere banalmente dal java.io.File). Mentre se fai la ricodifica .... non sai a priori la lunghezza.
  • Re: Errore 500 in servlet che cerca file in Eclipse

    In verità io ho copiato l'esempio:
    http://www.avajava.com/tutorials/lessons/how-do-i-return-an-image-from-a-servlet-using-imageio.html?page=1
    e credevo di cavarmela con poco per farla funzionare, invece non c'è stato verso....
    ho risolto creando una cartella sotto WebContent che ho chiamato "image" e scrivendo:
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("image/jpeg");
    String relativeWebPath = "/image";
    String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
    File f = new File(absoluteDiskPath, "a.jpg");
    BufferedImage bi = ImageIO.read(f);
    OutputStream out = response.getOutputStream();
    ImageIO.write(bi,"jpg", out);
    out.close();

    adesso devo pensare al problema del Buffered ...... come dovrei sostituire quanto scritto:
    BufferedImage bi = ImageIO.read(f);
    OutputStream out = response.getOutputStream();
    ImageIO.write(bi,"jpg", out);
    out.close();
    per andare a video in modo diretto?
  • Re: Errore 500 in servlet che cerca file in Eclipse

    sergioprogramma ha scritto:


    In verità io ho copiato l'esempio:
    http://www.avajava.com/tutorials/lessons/how-do-i-return-an-image-from-a-servlet-using-imageio.html?page=1
    Non è il massimo della correttezza .....

    sergioprogramma ha scritto:


    adesso devo pensare al problema del Buffered ...... come dovrei sostituire quanto scritto:
    BufferedImage bi = ImageIO.read(f);
    OutputStream out = response.getOutputStream();
    ImageIO.write(bi,"jpg", out);
    out.close();
    per andare a video in modo diretto?
    Innanzitutto ti ripeto che dovresti anche inviare il "Content-Length".
    Poi comunque hai un file, lo devi "aprire" con FileInputStream, leggere a blocchi di byte e buttarli sulla response. Non serve decodifica e poi ricodifica!

    Fai un metodo di "utilità" a parte in un'altra classe per questo (perché è un concetto riutilizzabile).
    Se puoi utilizzare librerie come la Apache Commons IO, essa ha il comodo:

    public static long copyFile(File input, OutputStream output) throws IOException

    nella classe FileUtils. Se non la usi, puoi realizzare una cosa similare.
  • Re: Errore 500 in servlet che cerca file in Eclipse

    Innanzi tutto ringrazio andbin per la risposta, poi vedo di studiare i consigli forniti e mi riprometto di tornare ad aggiornare il post con una soluzione (se mi riesce).
    Vorrei proporre, se possibile, di inserire un flag sui post che hanno ottenuto una soluzione finale positiva (quindi inserire in testata: argomento/risposte/visite/ultimo messaggio/risolto), in tal modo chi poi cercherà l'argomento potrà immediatamente scegliere (se lo desidera) solo quelli che hanno portato a soluzione (il risolto potrebbe essere considerato come la differenza tra i flag positivi e negativi ricevuti dai partecipanti).
  • Re: Errore 500 in servlet che cerca file in Eclipse

    Avrei risolto in tal modo:
    1 - la cartella Images è stata creata dentro WebContent ed è divenuta accessibile come indicato nella servlet .
    2 - il procedimento con l'uso del Buffer è stato tolto e sostituito con un ArraList.
    Ho lasciato nel file anche il collegamento al DB Mysql, visto che era già pronto e funzionante, in tal modo può essere un ulteriore riferimento per altri.
    Attenzione che l'applicazione ha già avuto uno sviluppo che ha portato alla eliminazione dell'elaborazione dell'immagine all'interno della servlet stessa (fatto che impediva di riprendere il controllo dopo il display), a favore dell'uso di jsp per l'interfaccia web e l'uso delle servlet solo per elaborazioni prettamente interne al server, cosa presentata in un altro mio post:
    https://www.iprogrammatori.it/forum-programmazione/java/riprendere-controllo-dopo-servlet-t26130.html
    .
    Colgo l'occasione per ringraziare nuovamente andbin per i consigli sia su questo post che per quello subito sopra linkato.
    Ho variato il titolo del post, aggiungendo la parola -RISOLTO- in tal modo chi cerca consigli può subito vedere i post che hanno avuto una soluzione, certi di trovare all'interno qualcosa di funzionante e non post rimasti appesi senza soluzione.

    import java.io.DataInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;

    @WebServlet("/Xprogrammatori1")
    public class Xprogrammatori1 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public Xprogrammatori1() { super(); }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try{
    String userName = request.getParameter("userField");
    ArrayList<String> array = select(userName);
    for(int i = 0; i<array.size(); i++){
    String scelto =array.get(i) ;
    response.setContentType("image/jpeg");
    ServletOutputStream sos = response.getOutputStream();
    if ( scelto !=null )
    {
    String relativeWebPath = "/Images";
    String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
    File f = new File(absoluteDiskPath, scelto + ".jpg");
    DataInputStream dis = new DataInputStream(new FileInputStream(f));
    byte[] barray = new byte[(int) f.length()];
    try
    {
    dis.readFully(barray);
    }
    catch (Exception e)
    { barray = null; }
    finally
    { dis.close( ); }
    sos.write(barray);
    sos.close();
    }
    }
    }
    catch (Exception e) {
    e.printStackTrace();
    }
    finally{};
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
    }
    public static ArrayList<String> select(String userName) throws Exception{
    Connection con = conn();
    PreparedStatement statement = con.prepareStatement("SELECT * FROM musica.anagra WHERE key_anagra = " + userName);
    ResultSet result = statement.executeQuery();
    ArrayList<String> array = new ArrayList<String>();
    while (result.next()){
    array.add(result.getString("anagra_cognome"));
    }
    return array;
    }
    public static Connection conn()throws ClassNotFoundException, SQLException{
    try{
    String url = "jdbc:mysql://localhost:3306/test";
    String username = "user";
    String password = "password";
    Class.forName("com.mysql.jdbc.Driver");
    Connection connect = DriverManager.getConnection(url, username, password);
    return connect;
    }
    finally {}
    }
    }
  • Re: Errore 500 in servlet che cerca file in Eclipse

    sergioprogramma ha scritto:


    2 - il procedimento con l'uso del Buffer è stato tolto e sostituito con un ArraList.
    Ma usi ancora comunque un grosso byte[] per tenere l'intero contenuto di un file immagine!

    E comunque il codice presenta diverse cose discutibili, tra cui (le prime due più evidenti):

    a) se ho capito bene, la select ti restituisce più nomi. nel doGet tu fai un ciclo for e potenzialmente vai a fare lo streaming sulla response di più immagini, giusto? Concettualmente e tecnicamente questo è sbagliato.
    Comunque vedo che chiudi addirittura il ServletOutputStream dopo la prima immagine. Quindi anche se ce ne fossero di più alla seconda ci sarebbero comunque problemi.

    b) Se userName che concateni alla query è una stringa qualunque (come si immagina), è comunque sbagliato perché: 1) non è quotata come chiesto da SQL e 2) non stai sfruttando correttamente un PreparedStatement.


    In ogni caso il codice è parecchio mal scritto, dubbio e discutibile. Te lo dico cortesemente: è TUTTO da rivedere!
  • Re: Errore 500 in servlet che cerca file in Eclipse

    ....
    In ogni caso il codice è parecchio mal scritto, dubbio e discutibile. Te lo dico cortesemente: è TUTTO da rivedere! ...
    Ne sono convinto anch'io !!!! il gran risultato è che qualcosa funziona!, è chiaro che per uno che è esperto questo può far inorridire, ma per me che annaspo è già un buon risultato.
    Passato il primo momento dovrà essere rivisto, ottimizzato, reso elegante etc.. etc.. ma tra qualcosa che offre un risultato e qualcosa che non funziona (rimanendo comunque sempre brutto) preferisco la prima.
    Vediamo se con il tuo aiuto... e quello di chi vorrà, pian piano riuscirò a far diventare questa "cosa" un pò più accettabile.
    Il "Risolto" non significa che sia bello ed ottimale!, ma che semplicemente ha risposto alle mie aspettative.
  • Re: Errore 500 in servlet che cerca file in Eclipse

    Nuova versione della parte servlet, nella quale ho cercato di correggere, per quel che mi è riuscito, alcune parti sottolineate da andbin:

    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 java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    @WebServlet("/Tutto7")
    public class Tutto7 extends HttpServlet
    {
    private static final long serialVersionUID = 1L;
    public Tutto7() { super(); }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    try
    {
    String userName = request.getParameter("userField");
    String cosamipare = "Note varie";
    String scelto = trova(userName);
    request.setAttribute("message", scelto);
    request.setAttribute("secondo", userName);
    request.setAttribute("terzo", cosamipare);
    RequestDispatcher reqDispatcher =
    getServletConfig().getServletContext().getRequestDispatcher
    ("/Xtutto7.jsp");
    reqDispatcher.forward(request,response);
    }
    catch (Exception e)
    {e.printStackTrace();}
    finally{};
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
    }
    public String trova(String userName) throws Exception {
    System.out.println("il valore di ricerca è = " + userName) ;
    Connection conn = null;
    PreparedStatement statement = null;
    conn = getConnection();
    try {
    statement = conn.prepareStatement("SELECT * FROM musica.anagra WHERE key_anagra = ?" );
    statement.setString(1, userName);
    ResultSet result = statement.executeQuery();
    while (result.next()) {
    userName = result.getString("anagra_cognome");
    System.out.println(" ho trovato nel database " + userName);
    }
    }
    catch (Exception e)
    { e.printStackTrace(); }
    finally {
    try {conn.close();} catch (SQLException e) { e.printStackTrace();}
    }
    return userName;
    }
    public static Connection getConnection() throws Exception {
    try{
    String driver = "com.mysql.jdbc.Driver";
    String url = "jdbc:mysql://localhost:3306/test";
    String username = "root";
    String password = "administrator";
    Class.forName(driver);
    Connection conn = DriverManager.getConnection(url, username, password);
    return conn;
    }
    finally {}
    }
    }
Devi accedere o registrarti per scrivere nel forum
8 risposte