entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Obtener la ruta de un input file

Hola que tal,

Dentro de un proyecto que estoy realizando necesito obtener una imagen del ordenador y guardarla en una base de datos, para ello utilicé el campo input type=file.

Para guardarla utilizo la siguiente función:

public boolean guardarfoto(int idProducto, String imagen) {
        FileInputStream fis = null;

        try {
            File file = new File("C:\\" + imagen);
            fis = new FileInputStream(file);
            cpsql.conectar();
            connection = ConexionPgSQL.getCn();
            PreparedStatement pstm = connection.prepareStatement("UPDATE productos SET imagen_producto = ?, nombre_imagen = ? where id_producto = ?");
            pstm.setBinaryStream(1, fis, (int) file.length());
            pstm.setString(2, imagen);
            pstm.setInt(3, idProducto);
            pstm.execute();
            System.out.println("Agregando imagen: " + pstm.toString());
            pstm.close();
            return true;
        } catch (FileNotFoundException | SQLException e) {
            Logger.getLogger(ControladorProducto.class.getName()).
                    log(Level.SEVERE, null, e);
        }

        return false;
    }

Mi problema es que esta funcion solo me permite guardar una imagen que se encuentre dentro del directorio especificado, en este caso C:\, pues si en la funcion reemplazo el File file = new File("C:\\" + imagen); por File file = new File(imagen); al parecer trata de buscar la ruta internamente en el proyecto, y no en el directorio del ordenador, y quisiera por lo tanto reemplazar ese directorio estático por uno dinámico para no limitar al cliente a que tenga que mover la imagen a la ruta especificada para que no marque error al guardar.

Para esto, estoy trabajando en un projecto Web usando NetBeans 8.0.2, JSPs y Servlets.

1 Respuesta

2votos

GusGarsaky Puntos5480

Usando Servlet 3.0, no es muy difícil. Por ejemplo:

Supongamos que tienes un formulario para subir archivos:

<form method="POST" action="upload" enctype="multipart/form-data" >
    File:
    <input type="file" name="file" id="file" /> <br/>
    <input type="submit" value="Upload" name="upload" id="upload" />
</form>

Ahora veamos la petición HTTP:

POST /fileupload/upload HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; 
boundary=---------------------------263081694432439
Content-Length: 441
-----------------------------263081694432439
Content-Disposition: form-data; name="file"; filename="sample.txt"
Content-Type: text/plain
...

Vemos que hemos subido el archivo sample.txt, y la cabecera es Content-Disposition. Esta cabecera es importante, porque de aquí obtendremos el nombre del archivo a subir desde nuestro Servlet.

Servlet

@WebServlet(name="FileUploadServlet", urlPatterns = {"/upload"})
@MultipartConfig
public class FileUploadServlet extends HttpServlet {
    final String output = "/uploads"; // carpeta donde se guardarán los archivos subidos

    protected void doPost(HttpServletRequest req, HttpServletRequest res) throws ServletException, IOException {
        // obtiene la parte 'file', que es el Content-Disposition(header) con el atributo 'name', del cual obtendremos el nombre del archivo.
        final Part filePart = request.getPart("file");
        final String fileName = getFileName(filePart);
        ...
    }

El método getFileName recibe el Part para obtener el nombre del archivo:

private String getFileName(final Part part) {
    for (String content : part.getHeader("content-disposition").split(";")) {
        if (content.trim().startsWith("filename")) {
            return content.substring(
                    content.indexOf('=') + 1).trim().replace("\"", "");
        }
    }
    return null;
}

Primero, obtenemos la cabecera "content-disposition" y dividimos su contenido, que en la petición se divide en partes separadas por punto y coma (;).

En éste punto, ya tenemos lo siguiente:

  • form-data
  • name="file"
  • filename="sample.txt"

Ahora, lo que sigue es evaluar si el trozo actual comienza con filename, lo que indica que luego del '=', estará el nombre del archivo. Si es así, devolvemos todo lo que hay después del '=', eliminando los espacios al inicio/final y con reemplazando las comillas por nada, dicho de otra manera, eliminando las comillas.

Una vez entendido ésto, solo toca escribir el archivo recibido en la carpeta, en nuestro caso, 'uploads'.

try (out = new FileOutputStream(new File(OUTPUT + File.separator + fileName);
    filecontent = filePart.getInputStream()) {

    int read = 0;
    final byte[] buffer = new byte[1024];

    while((read = filecontent.read(bytes)) !== null) {
        out.write(bytes, 0, read);
    }
} catch(FileNotFoundException fne) {
    // mostrar el error al usuario, etc
}

Eso es todo, ya tienes tu archivo subido.

0voto

Guadalupe Frausto comentado

Hola Gus Garsaky, gracias por responder, pero mi problema no es subir o guardar el archivo en BD, pus esto ya lo puedo hacer.

Mi problema es que en el campo input, al seleccionar la imagen y rescatar el valor que tiene me devuelve nombre_imagen.jpg, sin embargo yo lo que necesito que me devuelva es C:\ruta\de\imagen\nombre_imagen.jpg, ya que en la funcion el C:\ruta\de\imagen\ yo se lo estoy poniendo estaticamente para que no marque error al hacer la operación de guardar, pues si no le especifico esa ruta la imagen la busca intermente en el proyecto, y no en el directorio del cliente.

He estado investigando en Internet y muchos coinciden que esto no es posible hacerlo debido a politicas de seguridad. Y lo que no quiero es que cuando la aplicacion salga a produccion, tener que restringir a los usuarios que la usen a crear una carpeta para que allí coloquen cada una de las imagenes que tendran que subir, pues siento que como usuario seria algo tedioso.

No se si ahora si me llegues a comprender.

2votos

GusGarsaky comentado

No podrás. Por seguridad, no se puede acceder a información del sistema de archivos local. Es decir, no podrás saber la ruta del archivo que subió el cliente.

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta