Dopiero co zacząłem rozwijać usługi REST, ale natknąłem się na trudną sytuację: wysyłanie plików z mojej usługi REST do klienta. Do tej pory zrozumiałem, jak wysyłać proste typy danych (ciągi znaków, liczby całkowite itp.), Ale wysyłanie pliku to inna sprawa, ponieważ istnieje tak wiele formatów plików, że nie wiem, od czego powinienem zacząć. Moja usługa REST jest wykonana na Javie i używam Jersey, wszystkie dane wysyłam w formacie JSON.
Czytałem o kodowaniu base64, niektórzy mówią, że to dobra technika, inni mówią, że nie jest to spowodowane problemami z rozmiarem pliku. Jaki jest właściwy sposób? Oto jak wygląda prosta klasa zasobów w moim projekcie:
import java.sql.SQLException;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;
import com.mx.ipn.escom.testerRest.dao.TemaDao;
import com.mx.ipn.escom.testerRest.modelo.Tema;
@Path("/temas")
public class TemaResource {
@GET
@Produces({MediaType.APPLICATION_JSON})
public List<Tema> getTemas() throws SQLException{
TemaDao temaDao = new TemaDao();
List<Tema> temas=temaDao.getTemas();
temaDao.terminarSesion();
return temas;
}
}
Domyślam się, że kod do wysłania pliku wyglądałby tak:
import java.sql.SQLException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("/resourceFiles")
public class FileResource {
@GET
@Produces({application/x-octet-stream})
public File getFiles() throws SQLException{ //I'm not really sure what kind of data type I should return
// Code for encoding the file or just send it in a data stream, I really don't know what should be done here
return file;
}
}
Jakiego rodzaju adnotacji mam używać? Widziałem, jak niektórzy polecają @GET
użycie @Produces({application/x-octet-stream})
, czy to właściwy sposób? Pliki, które wysyłam, są specyficzne, więc klient nie musi ich przeglądać. Czy ktoś może mnie poinstruować, jak mam wysłać plik? Czy powinienem zakodować go przy użyciu base64, aby wysłać go jako obiekt JSON? czy kodowanie nie jest konieczne, aby wysłać go jako obiekt JSON? Dziękuję za wszelką pomoc, której możesz udzielić.
java.io.File
(lub ścieżkę do pliku) na swoim serwerze, czy też dane pochodzą z innego źródła, takiego jak baza danych, usługa sieciowa, wywołanie metody zwracaInputStream
?Odpowiedzi:
Nie polecam kodowania danych binarnych w base64 i zawijania ich w JSON. Po prostu niepotrzebnie zwiększy rozmiar odpowiedzi i spowolni działanie.
Po prostu podaj dane pliku za pomocą GET i
application/octect-stream
używając jednej z fabrycznych metodjavax.ws.rs.core.Response
(część JAX-RS API, więc nie jesteś zamknięty w Jersey):Jeśli nie masz rzeczywisty
File
obiekt, aleInputStream
,Response.ok(entity, mediaType)
powinien być w stanie obsłużyć, że dobrze.źródło
ZipOutputStream
wraz z powrotemStreamingOutput
zgetFile()
. W ten sposób otrzymujesz dobrze znany format wielu plików, który większość klientów powinna łatwo odczytać. Używaj kompresji tylko wtedy, gdy ma to sens w przypadku danych, tj. Nie w przypadku wstępnie skompresowanych plików, takich jak JPEG. Po stronie klientaZipInputStream
trzeba przeanalizować odpowiedź.Jeśli chcesz zwrócić plik do pobrania, szczególnie jeśli chcesz zintegrować z niektórymi bibliotekami javascript do przesyłania / pobierania plików, poniższy kod powinien wykonać zadanie:
źródło
Zmień adres maszyny z localhost na adres IP, z którym ma łączyć się klient, aby wywołać poniższą usługę.
Klient dzwoni do serwisu WWW REST:
Usługa odpowiadająca klientowi:
JAR potrzebny:
WEB.XML:
źródło
Ponieważ używasz JSON, zakodowałbym go w Base64 przed wysłaniem go przez kabel.
Jeśli pliki są duże, spróbuj spojrzeć na BSON lub inny format, który jest lepszy w przypadku transferów binarnych.
Możesz także spakować pliki, jeśli są dobrze skompresowane, przed zakodowaniem ich w base64.
źródło
@Produces
zawierać moja adnotacja?