2012-08-24 8 views
9

Próbuję zwrócić obraz w usłudze sieciowej JAX-RS. Udało mi się sprawnie zadziałać, zwracając FileInputStream, ale wolałbym uniknąć tworzenia File dla każdego żądania.Jak przesłać obraz jako strumień z JAX-RS?

Używam Apache CXF i Jackson (wszystkie inne metody zasobów tworzą aplikację/json).

Kod wygląda następująco:

@GET 
@Produces("image/png") 
public Response getQrCode(@QueryParam("qrtext") String qrtext) { 

    ByteArrayOutputStream out = QRCode.from(qrtext).to(ImageType.PNG).stream(); 

    return Response.ok(out).build(); 
} 

Niestety, ten produkuje bał:

org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor: 376 - No wiadomość ciało pisarz został znaleziono dla klasy odpowiedzi ByteArrayOutputStream.

Here's Link do podobnego wpisu, ale nie wspomina o problemie "Brak treści wiadomości", na który napotykam.

Byłbym wdzięczny za wszelkie pomysły dotyczące rozwiązania tego problemu. Dzięki!

+0

Dlaczego nie zwrócić strumienia bezpośrednio, zamiast owijać go w odpowiedzi? –

Odpowiedz

8

Myślę, że musisz dostarczyć InputStream zawierający obraz w Response.ok (out), a nie OutputStream. (Twój framework JAX-RS odczytałby bajty z InputStream i umieściłby je w odpowiedzi, nie byłby w stanie zrobić nic z OutputStream)

(Wiem, że jesteś na CXF, ale na dokumencie doktora : http://jersey.java.net/nonav/documentation/latest/jax-rs.html#d4e324 i przez specyfikację JAX-RS, framework musi dostarczyć MessageBodyWriter dla InputStream).

Edycja: Najwyraźniej wiesz o wymaganiach InputStreams, d'oh ... Czy masz kontrolę nad klasą QRCode?

krótkoterminowa, może być w stanie to zrobić:

return Response.ok(out.toByteArray()).build(); 
+0

dzięki. twoja odpowiedź była dużą pomocą. Response.ok (out.toByteArray()). Build() działa ładnie. – Justin

19

Wystarczy użyć StreamingOutput opakowanie. Z jakiegoś powodu jest nieznany, ale jest WIELKI dla dostarczania, dobrze, strumieniowego wydruku. :-)

+0

Dzięki Tatu. Zwracając StreamingOutput lepiej jest po prostu zwrócić tablicę bajtów bezpośrednio jako encję Response? – Justin

+0

Jak zwykle "to zależy". Jeśli masz już 'byte []', prawdopodobnie nie robi to różnicy. – StaxMan

+6

Zwykle nie jest dobrym pomysłem użycie opcjiByteArray dla strumieni, ponieważ zasadniczo spowoduje to przeniesienie całego strumienia do pamięci. Więc jeśli twój plik ma 1 GB, będziesz potrzebował co najmniej 1 GB w JVM. Jeśli kilku użytkowników uzyskuje dostęp do Twojej usługi, każdy użytkownik doda dodatkową 1 GB, co obniży twój serwer. Zawsze polecam używanie strumieni bezpośrednio. – apanosa