pobieranie sciezki pliku

0

Witam

Mam do wykonania mały projekt: aplikacja webowa w javie mająca pobierać pliki z dysku i dodawać je do bazy MS SQL.

Żeby dodać plik do bazy, będę potrzebował jego adresu na dysku - niestety pole JSP <input type="file" /> zwraca tylko nazwę pliku, a nie całą ścieżkę...

W jaki sposób tą ścieżkę pobrać? Łatwiej będzie to zrobić w czystym JSP czy może używając kodu javy na stronce?

0

No ale co ci da pełna ścieżka do pliku? Z tego co rozumiem, to plik masz wysłać z komputera klienta do serwera z aplikacją. Znacznik <input type="file" /> powoduje przesłanie całego pliku, tylko w jawie nie ma standardowo mechanizmu do odczytu. Trzeba sobie użyć jakąś bibliotekę, np. http://commons.apache.org/fileupload/

0
chodnik napisał(a)

No ale co ci da pełna ścieżka do pliku? Z tego co rozumiem, to plik masz wysłać z komputera klienta do serwera z aplikacją. Znacznik <input type="file" /> powoduje przesłanie całego pliku, tylko w jawie nie ma standardowo mechanizmu do odczytu. Trzeba sobie użyć jakąś bibliotekę, np. http://commons.apache.org/fileupload/

Baza znajduje się na tym samym komputerze co aplikacja, którą odpalam w NetBeans'ie na GlassFishu.
Adres potrzebny mi jest do wywołania poniższego zapytania w tagu sql:update na stronce JSP.

INSERT INTO item 
	(id, nazwa, plik)
	SELECT 1, 'obrazek',
		BulkColumn FROM OPENROWSET(
			Bulk 'C:\temp\pic.jpg', SINGLE_BLOB) AS BLOB

Wydaje mi się, że to najprostsze rozwiązanie - czyżbym się mylił ;) ?

ED:

chodnik napisał(a)

Znacznik <input type="file" /> powoduje przesłanie całego pliku

A czy na takim pliku da się popracować? Np sprawdzić wielkość, rozszerzenie itp? Bo jedną z funkcji aplikacji ma być również walidacja pliku. Potrzeba do tego specjalnych bibliotek?

Wybacz banalne pytania, ale jestem dość zielony w temacie, a czasu coraz mniej ;)

0

Twoje rozwiązanie jest dziwne. Po co robić aplikację webową do czytania lokalnych plików? No ale dobra, chcesz to rób. Nie wiem czemu input file nie zwraca ci całej ścieżki, ale jak wybierze się plik, to w polu jest cała, a nie tylko nazwa pliku. Możesz na submicie dodać akcję javascriptową, która skopiuje tą ścieżkę do jakiegoś ukrytego pola i wtedy sobie odczytasz na serwerze całą.

0

???
uważasz, że będziesz mógł od użytkownika pobrać plik bezpośrednio z dysku, bo input z plikiem poda swoją lokalną (czyli dla serwera zdalną i nie ma tu znaczenia, że klient i serwer działają przypadkiem na tym samym komputerze) ścieżkę do tego pliku?
jest tak, jak napisał chodnik: input type="file" powoduje wysłanie ZAWARTOŚCI pliku i podstawowych informacji o nim (nazwa, rozmiar, ale nigdy ścieżka) na serwer. musisz doinstalować sobie bibliotekę, która umożliwi zapisanie tej zawartości do pliku i dopiero z takim LOKALNYM DLA SERWERA plikiem możesz robić inserta.

0
chodnik napisał(a)

Twoje rozwiązanie jest dziwne. Po co robić aplikację webową do czytania lokalnych plików?

W sumie masz rację.
Pierwszy raz tworzę aplikacje webową i działania poza moim komputerem nigdy nie były brane pod uwagę ...

Eh, chyba będę musiał inaczej do tego podejść w takim razie. Pobranie pliku na serwer i dopiero przesłanie go do bazy, zamiast wysyłania bazie polecenia do pobrania go z dysku.

Proponujesz jakieś proste rozwiązanie? Na jakich mechanizmach się skupić i co będzie przydatne?

0

Przydatna będzie biblioteka, o której wspomniałem. Na stronie są przykłady użycia. Zapewne nie jest to jedyne rozwiązanie, ale jest wystarczające. Jak chcesz inne, to poszukaj.

0

OK, wielkie dzięki za przydatne wskazówki!

Jak widać długa droga przede mną ;) Jutro z rana przyjże się poleconej bibliotece.
Pozdrawiam.

0

Witam ponownie.

oto co udało mi się skręcić w servlecie pobierającym plik:

 

public class fileServlet extends HttpServlet {


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        response.setContentType("text/plain");
        out.println("<h1>Servlet File Upload Example using Commons File Upload</h1>");
        out.println();

        DiskFileItemFactory factory = new DiskFileItemFactory();

        try {
            //pobranie sample ze strumienia
            ServletFileUpload servletUpload = new ServletFileUpload(factory);
            List fileItems = servletUpload.parseRequest(request);
            byte[] imageBytes = null;
         
            for (Iterator iter = fileItems.iterator(); iter.hasNext();) {
                FileItem fileItem = (FileItem) iter.next();
                if (!fileItem.isFormField()) {
                    
                    //binarna zawartosc pliku
                    imageBytes = fileItem.get();
                   
                    // LACZENIE Z BAZA
                    String baza = "jdbc:sqlserver://localhost;instance=SQLEXPRESS;DatabaseName=test;";
                    String user = "tester";
                    String pass = "qwe123";

                    java.sql.Connection conn = null;
                    try {
                        conn = DriverManager.getConnection(baza, user, pass);
                    } catch (SQLException e) {
                        out.println("Blad przy laczeniu z baza!");
                        out.println(e.toString());
                        System.exit(1);
                    }

                    //DODAWANIE PLIKU
                    Statement s = null;
                    try {
                        s = conn.createStatement();

                        s.executeQuery("INSERT INTO item (nazwa, typ, rozmiar, plik) VALUES ('"
                                + fileItem.getName() + "','" + fileItem.getContentType() + "',"
                                + fileItem.getSize() + /*"," + fileItem.get() +*/ ")");

                    } catch (SQLException e) {
                        out.println("Blad odczytu z bazy! " + e.toString());
                        System.exit(3);
                    }

                   out.println("Field Name = " + fileItem.getFieldName()
                            + ", File Name = " + fileItem.getName()
                            + ", Content type = " + fileItem.getContentType()
                            + ", File Size = " + fileItem.getSize());
                }
            }
        } catch (FileUploadException e) {
            e.getMessage();
        }

    }
}

Mam teraz dwa problemy.
1.Po wybraniu pliku i przejściu do servleta wyświetla się błąd połączenia przeglądarki

Nie udało się nawiązać połączenia

Firefox nie może nawiązać połączenia z serwerem localhost:8080.

mimo że doszło do wykonania kodu i przesłania danych do bazy - sprawdzam to insertem w oknie połączenia z bazą

  1. Jak na razie udaje mi się przesyłać tylko dane tekstowe/liczbowe, nie wiem jak dokładnie sformułować inserta, aby przesłać do bazy przechwyconą przez funkcję fileItem.get(); zawartość pliku. Usunięcie zakomentowanego wywołania nie pomaga - do bazy nie ładuje się wtedy nic.

Jakieś pomysły?

0
  1. A co ci się wypisuje na konsolę? Masz kilka sysoutów, to może tam coś widać.
  2. A jak masz zdefiniowaną tabelę? To pole na plik powinno móc przechowywać dane binarne, a nie tekstowe, czyli typ BLOB.
0
chodnik napisał(a)
  1. A co ci się wypisuje na konsolę? Masz kilka sysoutów, to może tam coś widać.
  2. A jak masz zdefiniowaną tabelę? To pole na plik powinno móc przechowywać dane binarne, a nie tekstowe, czyli typ BLOB.

SQLException e zwracał brak result'a po wykonaniu zapytania sql - podobny błąd miałem kiedy w JSP zamiast

 <sql:update>

używałem sql:query

 do wywołania inserta. Analogiczna zamiana <code class="csharp">s.executeQuery

na s.executeUpdate

rozwiązała problem.

Pole na plik zdefiniowane jako 
```sql
 plik	VARBINARY(max)
działało wcześniej podczas wrzucania pliku przy użyciu ścieżki z dysku.
Przy wgrywaniu pliku do bazy SQLException zwraca</li> </ul>

unclosed quotation mark at the end ...

czyli problem wynika z błędnej składni. Właśnie doczytuje, że wygodniej takie zapytania przechowywać w specjalnych kontenerach - może ktoś chciałby to przyblizyć? Zaoszczędzi mi to kolejnego dnia z googlem ;)

ED:
aha, no i jak powinien wyglądać taki poprawny insert do bloba z danymi przechwyconymi w zmiennej?

0
 out.println(imageBytes);

zwraca [B@c88f97
Czy dane wczytane funkcja .get() są niepoprawne do podania jako argument inserta i trzeba je jeszcze jakoś sformatować, czy po prostu w ten sposób println wyświetla tablice bajtów?

0
insertString = "INSERT INTO item (plik) VALUES (0x" + imageBytes +  ") ";
s.executeUpdate(insertString);

SQLException zwraca:

unclosed quotation mark after the character string

Czemu?
Wykonując to samo zapytanie w managerze bazy dostaje pozytywny rezultat

INSERT INTO item (plik) VALUES (0x10011711297)

Jak przenieść bajty z tablicy do stringa polecenia?

0

Ktoś już miał taki problem jak twój tutaj:
http://192.9.162.102/thread.jspa?threadID=5445068&tstart=-2
Gdzieś tak w połowie strony jest rozwiązanie.

0
"INSERT INTO item (plik) VALUES (0x" + imageBytes +  ") "

Tylko konkatenuje ze sobą 3 Stringi, gdzie drugi to imageBytes.toString() (czyli na pewno nie żadna konkretna, binarna wartość). Możesz Stringa zrobić z bajtów (new String(imageBytes)), ale są pewnie normalniejsze sposoby.
Luknij PreparedStatement.setBytes, PreparedStatement.setBinaryStream.

0

@up & @upup; wielkie dzięki za pomoc i wskazówki - udało mi się w końcu uporać z dodawanie pliku do bazy :)

Wygląda to mnie więcej tak:

 
 //binarna zawartosc pliku
imageBytes = fileItem.get();

//DODAWANIE PLIKU
 try {
      PreparedStatement ps = conn.prepareStatement(
            "INSERT INTO item (nazwa, typ, rozmiar, data, plik) VALUES (?,?,?,?,?)");
      ps.setString(1, fileItem.getName());
      ps.setString(2, fileItem.getContentType());
      ps.setLong(3, fileItem.getSize());
      ps.setDate(4, sqlDate);
      ps.setBytes(5, imageBytes);
      ps.executeUpdate();

Wystarczyło wybrać odpowiedni input .setBytes() i wskazac na tablice bajtow - czyli banalnie proste, ale wymagało trochę czasu i lektury ;)
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1