I have Spring Boot project and I am using Jasper Report. I posted some json data and response return to me this:
%PDF-1.5
%����
1 0 obj
<undefined</Filter/FlateDecode/Length 29>>stream
x�+�r
�26S�00SI�r
�
��13-
endstream
endobj
3 0 obj<undefined</Tabs/S/Group<undefined</S/Transparency/Type/Group/CS/DeviceRGB>>/Contents 1 0 R/Type/Page/Resources<undefined</ColorSpace<</CS/DeviceRGB>>/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]>>/Parent 2 0 R/MediaBox[0 0 595 842]>>
endobj
2 0 obj
<undefined</Kids[3 0 R]/Type/Pages/Count 1/ITXT(2.1.7)>>
endobj
4 0 obj<undefined</Type/Catalog/Pages 2 0 R/ViewerPreferences<undefined</PrintScaling/AppDefault>>>>
endobj
5 0 obj<undefined</ModDate(D:20160710203902+05'00')/Creator(JasperReports Library version 6.2.0)/CreationDate(D:20160710203902+05'00')/Producer(iText 2.1.7 by 1T3XT)>>
endobj
xref
0 6
0000000000 65535 f
0000000015 00000 n
0000000333 00000 n
0000000110 00000 n
0000000396 00000 n
0000000487 00000 n
trailer<undefined</Info 5 0 R/ID [undefined<07942c7c1b5b6068753ddc445ec60abf>undefined<c82bba08c068c3699915ac33668fef92>]/Root 4 0 R/Size 6>>
startxref
654
%%EOF
On my rest controller I added to RequestMapping produces = "application/pdf" but it is not working.
#RequestMapping(value = "/gMapReports", method = RequestMethod.POST, produces = "application/pdf")
public ResponseEntity<InputStreamResource> gMapReports(#RequestBody GMapReportRequest gMapReportRequest) {
return reportService.prepareResponse(reportService.gMapReports(gMapReportRequest));
}
My prepareResponse method:
public ResponseEntity<InputStreamResource> prepareResponse(File reportDocument) {
FileInputStream fileInputStream = fileStreamConverter.getFileInputStream(reportDocument);
return ResponseEntity
.ok()
.contentLength(reportDocument.length())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header("content-disposition", "filename=report")
.body(new InputStreamResource(fileInputStream));
}
Adding code produces = {"application/pdf"} works for me. Full example:
#RequestMapping(value = "/pdfFile", method = RequestMethod.POST, produces = {"application/pdf"})
#ResponseBody
public FileSystemResource getFile(#ModelAttribute PdfFile pdfFile) {
PdfFileGenerator pdfFileGenerator = new PdfFileGeneratorImpl();
File file = pdfFileGenerator.generatePdf(pdfFile);
return new FileSystemResource(file);
}
Just to bring this thread up, if someone is reaching here when getting an error that no suitable converter is found for application/pdf.
Check if you are using the #RepositoryRestController annotation.
If that is the case, try to switch to #RestController.
Related
I'm trying to show a pdf in android app. The response I get from the server is looking like this. I convert it to input stream and pass it to pdf viewer library
%PDF-1.4 %ÓôÌá 1 0 obj << /CreationDate(D:20180403085232+02'00')
/Creator(PDFsharp 1.32.3057-g (www.pdfsharp.net)) /Producer(PDFsharp
1.32.3057-g (www.pdfsharp.net))
endobj 2 0 obj << /Type/Catalog /Pages 3 0 R
endobj 3 0 obj << /Type/Pages /Count 3 /Kids[4 0 R 8 0 R 11 0 R]
endobj 4 0 obj << /Type/Page /MediaBox[0 0 612 792] /Parent 3 0 R /Contents 5 0 R /Resources << /ProcSet
[/PDF/Text/ImageB/ImageC/ImageI] /XObject << /I0 6 0 R
/ExtGState << /GS0 7 0 R
/Group << /CS/DeviceRGB /S/Transparency /I false /K false
endobj 5 0 obj << /Length 260 /Filter/FlateDecode
stream xœíRMK1½÷Wä˜M“&Mî¢àa]oâIEDF‚¿ÞÌ̺²ø¥”4y¯—´C©#¹ŽÆЃáú!ÏDpñZ†2€š
W9#¾gNŽa“/…à4÷}©gåòŠàf§{¾.«õ–àWìÚ¡WÆT4Bµ
†¡O·e[F>g^í=|UEw‡ª‚Ö$å(U‘ôÇ›„L¶ÜÑ™—~¤6•š'Ú9f”Pz›PŽ€¦¨"бv_gly›Û÷Mä~.î]
™Ûë؈?œå€«Ul¡À™y_6þ»Aÿ—ÿ¤|èYòÿX`ìfÈ»ï³ÉõŠ¹·ò endstream endobj 6 0
obj << /Type/XObject /Subtype/Image /Length 5097196
/Filter/FlateDecode /Width 2511 /Height 3531 /BitsPerComponent 8
/ColorSpace/DeviceRGB /Interpolate true
stream xœìÝ œ¤g]'ðïé9rÂáˆJAE%€ Š"ë‚FQ0 Ë!º» ¢‚+^ (h
This is my code:
// get the response as string
val body = response.body?.string()
// convert it to inputstream
val inputStream = ByteArrayInputStream(body.toByteArray(Charsets.UTF_8))
// load it wil pdf viewer
pdf_viewer.fromStream(inputStream).load()
Everything till the last line is ok. I got init FPDF library but there is nothing on the screen. It stays with white background.
If I open the pdf standalone I can see that everything is fine.
I'm using
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
here is the xml file
<com.github.barteksc.pdfviewer.PDFView
android:id="#+id/pdf_viewer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
EDIT:
the working solution was to get the bytes and pass them to PDFViewer
val bodyBytes: ByteArray = response.body!!.bytes()
runOnUiThread {
pdf_viewer.fromBytes(bodyBytes).enableSwipe(true) // allows to block changing pages using swipe
.swipeHorizontal(false)
.enableDoubletap(true)
.defaultPage(0)
.enableAnnotationRendering(false) // render annotations (such as comments, colors or forms)
.password(null)
.scrollHandle(null)
.enableAntialiasing(true) // improve rendering a little bit on low-res screens
// spacing between pages in dp. To define spacing color, set view background
.spacing(0)
.invalidPageColor(Color.WHITE) // color of page that is invalid and cannot be loaded
.load()
}
As the title says, I'd like to store per line(per System.out.print) in an array/arrayList.
So far I have tried ByteArrayOutputStream but it only appends everything into one object. I'd be glad to post snippets of the code if necessary. Sorry for the noob problem
Edit Code :
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
PrintStream old = System.out;
String[] str= new String[10];
System.setOut(ps);
for(int x=0;x<str.length;x++){
ps.println("Test: "+x);
str[x] = baos.toString();
}
System.out.flush();
System.setOut(old);
for(int x=0;x<str.length;x++){
System.out.println(str[x]);
}
Output:
Test: 0
Test: 0
Test: 1
Test: 0
Test: 1
Test: 2
Test: 0
Test: 1
Test: 2
Test: 3
Test: 0
Test: 1
Test: 2
Test: 3
Test: 4
Test: 0
Test: 1
Test: 2
Test: 3
Test: 4
Test: 5
Test: 0
Test: 1
Test: 2
Test: 3
Test: 4
Test: 5
Test: 6
Test: 0
Test: 1
Test: 2
Test: 3
Test: 4
Test: 5
Test: 6
Test: 7
Test: 0
Test: 1
Test: 2
Test: 3
Test: 4
Test: 5
Test: 6
Test: 7
Test: 8
Test: 0
Test: 1
Test: 2
Test: 3
Test: 4
Test: 5
Test: 6
Test: 7
Test: 8
Test: 9
What I would like to have in str array is something like this:
str[0] = "Test: 0"
str[1] = "Test: 1"
str[2] = "Test: 2"
str[3] = "Test: 3"
str[4] = "Test: 4"
str[5] = "Test: 5"
str[6] = "Test: 6"
str[7] = "Test: 7"
str[8] = "Test: 8"
str[9] = "Test: 9"
I also looked for something like deleting the value inside ByteArrayOutputStream but no luck.
Based on the code you post, I made a little modification, see if this is what you are looking for.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
PrintStream old = System.out;
String[] str= new String[10];
System.setOut(ps);
for(int x=0;x<str.length;x++){
ps.println("Test: "+x);
str[x] = baos.toString();
baos.reset();
}
System.out.flush();
System.setOut(old);
for(int x=0;x<str.length;x++){
System.out.println(str[x]);
}
The trick is that every time when the line str[x] = baos.toString() executed, the accumulated output are still there, so you need use reset() to discard the accumulated data, for more details about reset(), please refer to the official document here
I have a JAXB REST Web Service getting in request a POST of a JSON and should return a PDF document in response:
#POST
#Path("getReceipt")
#Consumes({ MediaType.APPLICATION_JSON })
#Produces({ "application/pdf" })
public Response getReceipt(InputStream incomingData, #Context HttpServletRequest httpRequest) {
...
}
I'm trying to test it with Advanced Rest Client (Google Chrome plugin), which is showing the following as response:
%PDF-1.4
%����
3 0 obj
<</C[0 0 1]/Border[0 0 0]/A<</URI(https://www.totalerg.it/)/S/URI>>/Subtype/Link/Rect[491.43 723.5 557 733.5]>>
endobj
4 0 obj
<</C[0 0 1]/Border[0 0 0]/A<</URI(https://www.totalerg.it/)/S/URI>>/Subtype/Link/Rect[256.65 274.5 322.22 284.5]>>
endobj
5 0 obj
<</Length 993/Filter/FlateDecode>>stream
x��U�n�8}�W�[��Ð����lG�j�릲�}Y0kpaK�,%���s�3vHY����"9�̙G/%>�9��gD������ҙ;�( \|:+WP�h�|D�zo�����)������h�������L2CR��a�%L�
���:��&��g L���1ϲ�Oq���9M�[<�-�ǹ����r���
wL�2�:W�m#��J��\*��":��Ld7�]
�3�6�E��Kn_<�}�;���,��g�����uk��D^O��6~��Y����]�=1ٸ�gq:���v�l��"��o��x��ǔ�a�09�3H���VeSY?��,�A����l��^*(��W�BE#J�PKX��Fк�s�^��
�H�)��� ��V��
�k<���FntUj<��!F�/
���U#dU#�q�]ZzUnd�I��Z�w�w'��%��l�4�^!G���~��Ƅ�n��̯�?Ԫ,&�U�1teT"u^���r�P�Bw�:YkLX_:�������ī��Mw��P"���\!%���7����zWO}Yp���h�8�����n�]�� ;x�o�2w�38�ś.��/�~�+e"pC����ڳk�]�c#
�����E�{�}�nZ��8�35T�IC+��6�6����E���">J��AZ���F��#��j*����*7�#Pm]����e�e���U�,�؍�!�j�Z��B�de�ҿ�������A֍i����`\T0�0r������Ȇ �G#A��������϶��f���'���͵�,6c�.�4�O�Y:6C.6�}�!]éy�{E߱?��>�<Ƭ�u�y$��9��L���f�]�T��ܸ�/w���������^qj[�r��U)g1b������W���Ǥ�*1�؆�������Ȁ8�F�c�ٯB^�bk�n=�?u��x�;�]�H0rsg���tI[x�����G�0�����#p�EW��B�������L�
endstream
endobj
7 0 obj
<</Parent 6 0 R/Contents 5 0 R/Type/Page/Resources<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]/Font<</F1 1 0 R/F2 2 0 R>>>>/MediaBox[0 0 595 842]/Annots[3 0 R 4 0 R]>>
endobj
1 0 obj
<</BaseFont/Helvetica/Type/Font/Encoding/WinAnsiEncoding/Subtype/Type1>>
endobj
2 0 obj
<</BaseFont/Helvetica-Bold/Type/Font/Encoding/WinAnsiEncoding/Subtype/Type1>>
endobj
6 0 obj
<</ITXT(2.1.7)/Type/Pages/Count 1/Kids[7 0 R]>>
endobj
8 0 obj
<</Type/Catalog/Pages 6 0 R>>
endobj
9 0 obj
<</Producer(iText 2.1.7 by 1T3XT)/ModDate(D:20150907102806+02'00')/CreationDate(D:20150907102806+02'00')>>
endobj
xref
0 10
0000000000 65535 f
0000001518 00000 n
0000001606 00000 n
0000000015 00000 n
0000000142 00000 n
0000000272 00000 n
0000001699 00000 n
0000001332 00000 n
0000001762 00000 n
0000001807 00000 n
trailer
<</Root 8 0 R/ID [<f16ea10e09183af8aff079f97cfac53f><fe60918ac5b80276ed8a082dedebf230>]/Info 9 0 R/Size 10>>
startxref
1929
%%EOF
This text version of binary file is different (more question marked characters in place of other ones) from the one I can see opening the binary file from file system with a text editor.
My question is: how could I test this service posting the JSON request and being able to open PDF document in the response? Should I use another tool, or build a form?
The "Save response" button help you save your response to a file :
You just need to return the pdf byte array using the proper media type and the browser will do the rest. ie:
#POST
#Path("getReceipt")
#Consumes({ MediaType.APPLICATION_JSON })
#Produces({ "application/pdf" })
public byte[] getReceipt(InputStream incomingData) {
return your_pdf_byte_array;
}
And to open the PDF document use postman chrome extension
I want to read binary data from file and send it to remote Java App.
As I found here:
I can get it like this (part of my code):
else
{
$fp = fopen("binary file","rb");
$vector="";
while (!feof($fp)) {
// Read the file, in chunks of 16 byte
$data = fread($fp,16);
$arr = unpack("C*",$data);
foreach ($arr as $key => $value) {
$vector.=" ".$value;
}
$vector.="\n";
}
}
I send some headers
header("Content-Type: multipart/related; boundary=bounary----I don't know if boundary value is private".$eol);
header("MIME-Version: 1.0".$eol);
header("Connection: Keep-Alive".$eol);
header("Accept-Encoding: gzip, deflate".$eol);
header("Host: host".$eol.$eol);
header("Content-Type: multipart/related; boundary=bounary----I don't know if boundary value is private".$eol);
header("Content-Type: multipart/related; boundary=bounary----I don't know if boundary value is private".$eol);
Then I print it like this:
echo "--".$BOUNDARY.$eol;
echo "Content-Type: application/octet-stream".$eol;
echo "Content-Length: ".strlen($vector).$eol;
echo "Content-Transfer-Encoding: binary".$eol;
echo $eol.$vector.$eol;
echo "--".$BOUNDARY."--".$eol;
I test it in Advanced Rest Client Application and see binary data:
0 0 0 72 0 54 0 55 0 97 0 56 0 51 0 49
0 101 0 56 0 45 0 53 0 102 0 48 0 56 0 45
0 52 0 100 0 49 0 99 0 45 0 97 0 57 0 57
0 52 0 45 0 101 0 101 0 53 0 97 0 51 0 52
0 49 0 52 0 50 0 54 0 57 0 51 0 0 0 1
0 0 0 0 4 0 0 1 0 0 0 0 1 0 0 0...
But Java coder sayas that there is an empty string instead of binary data? How can I echo this binary data in proper way? What can cause this problem?
Update: We've found, that no matter what Content-Length header I set, in his app he receives header: Content-Length: 475
However in Advanced Rest Client I see my value of content-length. Well it can cause the problem. Can it be caused by php somehow?
Perhaps the 2 $eol's in this line is causing the subsequent headers to not be sent:
header("Host: host".$eol.$eol);
Try changing it to 1, or in fact I doubt you even need the EOL char in the string you send to header().
Getting below Exception while trying to read byte array using iText PdfReader,
Below is my code, I'm able to open this file in Acrobat reader
PdfReader reader = new PdfReader(bFile);
Exception:
java.lang.ClassCastException: com.itextpdf.text.pdf.PdfNull cannot be cast to com.itextpdf.text.pdf.PdfDictionary
at com.itextpdf.text.pdf.PdfReader$PageRefs.iteratePages(PdfReader.java:3712)
at com.itextpdf.text.pdf.PdfReader$PageRefs.iteratePages(PdfReader.java:3743)
at com.itextpdf.text.pdf.PdfReader$PageRefs.readPages(PdfReader.java:3548)
at com.itextpdf.text.pdf.PdfReader$PageRefs.<init>(PdfReader.java:3518)
at com.itextpdf.text.pdf.PdfReader$PageRefs.<init>(PdfReader.java:3496)
at com.itextpdf.text.pdf.PdfReader.readPages(PdfReader.java:1142)
at com.itextpdf.text.pdf.PdfReader.readPdf(PdfReader.java:659)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:176)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:244)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:234)
Im using iText 5.4.4, I couldn't find much details in googling. It looks PDF has some issues, couldn't get whats the issue. Below is the excerpts from PDF
%PDF-1.5
%âãÏÓ
1 0 obj
<<
/Type /Catalog
/Lang (en-US)
/StructTreeRoot 39 0 R
/MarkInfo <<
/Marked true
>>
/Pages 187 0 R
/AcroForm 350 0 R
/OCProperties 2131 0 R
/Outlines 2531 0 R
/OpenAction <<
/Type /Action
/S /GoTo
/D [ 3 0 R /XYZ 0 792 0 ]
>>
/ViewerPreferences <<
/HideToolbar false
/HideMenubar false
/HideWindowUI false
/FitWindow false
/CenterWindow false
>>
UPDATE: After debugging I found that /Pages 187 0 R is the problem. If I change to /Pages 2 0 R then it works. Could some please help me what does that /Pages refers ?