Acabei de começar a desenvolver serviços REST, mas me deparei com uma situação difícil: enviar arquivos do meu serviço REST para o meu cliente. Até agora peguei o jeito de enviar tipos de dados simples (strings, inteiros, etc), mas enviar um arquivo é uma questão diferente, já que existem tantos formatos de arquivo que não sei por onde devo começar. Meu serviço REST é feito em Java e estou usando Jersey, estou enviando todos os dados no formato JSON.
Eu li sobre a codificação base64, algumas pessoas dizem que é uma boa técnica, outras dizem que não é por causa de problemas de tamanho de arquivo. Qual é a maneira correta? Esta é a aparência de uma classe de recurso simples em meu projeto:
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;
}
}
Acho que o código para enviar um arquivo seria algo como:
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;
}
}
Que tipo de anotações devo usar? Já vi algumas pessoas recomendarem um @GET
uso @Produces({application/x-octet-stream})
, é esse o jeito correto? Os arquivos que estou enviando são específicos para que o cliente não precise navegar pelos arquivos. Alguém pode me orientar sobre como devo enviar o arquivo? Devo codificá-lo usando base64 para enviá-lo como um objeto JSON? ou a codificação não é necessária para enviá-lo como um objeto JSON? Obrigado por qualquer ajuda que você possa dar.
java.io.File
(ou caminho de arquivo) real em seu servidor ou os dados vêm de alguma outra fonte, como um banco de dados, serviço da web, chamada de método retornando umInputStream
?Respostas:
Não recomendo codificar dados binários em base64 e envolvê-los em JSON. Isso apenas aumentará desnecessariamente o tamanho da resposta e tornará as coisas mais lentas.
Basta fornecer seus dados de arquivo usando GET e
application/octect-stream
usando um dos métodos de fábrica dejavax.ws.rs.core.Response
(parte da API JAX-RS, para que você não fique preso a Jersey):Se você não tem um
File
objeto real , mas umInputStream
,Response.ok(entity, mediaType)
deve ser capaz de lidar com isso também.fonte
ZipOutputStream
junto com retornando umStreamingOutput
degetFile()
. Dessa forma, você obtém um formato de vários arquivos bem conhecido que a maioria dos clientes deve ser capaz de ler facilmente. Use a compactação apenas se fizer sentido para seus dados, ou seja, não para arquivos pré-compactados como JPEGs. Do lado do cliente, éZipInputStream
necessário analisar a resposta.Se você deseja retornar um arquivo para ser baixado, especialmente se você deseja integrar com algumas bibliotecas javascript de upload / download de arquivo, então o código abaixo deve fazer o trabalho:
fonte
Altere o endereço da máquina de localhost para o endereço IP com o qual deseja que seu cliente se conecte para chamar o serviço mencionado abaixo.
Cliente para chamar o serviço da web REST:
Serviço ao cliente de resposta:
JAR necessário:
WEB.XML:
fonte
Como você está usando JSON, gostaria de codificá-lo em Base64 antes de enviá-lo pelo fio.
Se os arquivos forem grandes, tente olhar o BSON ou algum outro formato que seja melhor com transferências binárias.
Você também pode compactar os arquivos, se eles forem bem compactados, antes de codificá-los em base64.
fonte
@Produces
anotação deve conter?