I have a button in the UI that calls method for downloading a file which takes an InpuStream type. This is my code
<p:commandButton value="Download" actionListener="#{cc.attrs.noteAndFileBean.downloadFileAttached(noteAndFile)}" />
and the bean
public void downloadFileAttached(final GridFSDBFile noteAndFile)
{
try
{
PortletResponse portletResponse = (PortletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
HttpServletResponse response = PortalUtil.getHttpServletResponse(portletResponse);
response.setContentType(noteAndFile.getContentType());
response.setHeader("Content-Disposition", "attachment; filename=\"" + noteAndFile.getFilename());
response.setHeader("Content-Transfer-Encoding", "binary");
response.getOutputStream().write(IOUtils.toByteArray(noteAndFile.getInputStream()));
response.flushBuffer();
}
catch (IOException excpetion)
{
LOGGER.error("An error occurred downloading the file: " + excpetion.getMessage(), excpetion);
showMessage(ERROR, "Problemas al descargar el archivo");
}
}
The GridFSDBFile type is an object that stores files in mongo then for get the InputStream I call getInputStream() then I pass it to byte array.
When I call this method I receive a big exception (Part of it)
Caused by: java.lang.IllegalStateException
at com.liferay.portal.servlet.filters.gzip.GZipResponse.getWriter(GZipResponse.java:150)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
at com.liferay.portal.kernel.servlet.MetaInfoCacheServletResponse.getWriter(MetaInfoCacheServletResponse.java:315)
at com.liferay.portlet.MimeResponseImpl.getWriter(MimeResponseImpl.java:102)
at com.liferay.faces.bridge.context.BridgeContextImpl.getResponseOutputWriter(BridgeContextImpl.java:1197)
at com.liferay.faces.bridge.context.BridgeContextWrapper.getResponseOutputWriter(BridgeContextWrapper.java:251)
at com.liferay.faces.bridge.context.ExternalContextCompat_2_0_Impl.getResponseOutputWriter(ExternalContextCompat_2_0_Impl.java:629)
at com.sun.faces.context.PartialViewContextImpl.createPartialResponseWriter(PartialViewContextImpl.java:429)
at com.sun.faces.context.PartialViewContextImpl.access$300(PartialViewContextImpl.java:72)
at com.sun.faces.context.PartialViewContextImpl$DelayedInitPartialResponseWriter.getWrapped(PartialViewContextImpl.java:573)
at com.liferay.faces.util.context.PartialResponseWriterWrapper.<init>(PartialResponseWriterWrapper.java:31)
at com.liferay.faces.util.context.PartialViewContextCleanupImpl$PartialResponseWriterCleanupImpl.<init>(PartialViewContextCleanupImpl.java:198)
at com.liferay.faces.util.context.PartialViewContextCleanupImpl.getPartialResponseWriter(PartialViewContextCleanupImpl.java:177)
at org.primefaces.context.PrimePartialViewContext.getPartialResponseWriter(PrimePartialViewContext.java:71)
at com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:197)
at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:124)
at javax.faces.context.ExceptionHandlerWrapper.handle(ExceptionHandlerWrapper.java:97)
at com.liferay.faces.bridge.context.ExceptionHandlerAjaxImpl.handle(ExceptionHandlerAjaxImpl.java:85)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at com.liferay.faces.bridge.BridgePhaseResourceImpl.execute(BridgePhaseResourceImpl.java:107)
... 136 more
How can I download the file?
I found the solution, It's important get Liferay's ServletResponse and pass it the InputStream in byte array.
public StreamedContent getDownloadFileStreamContent(final GridFSDBFile noteAndFile)
{
try
{
PortletResponse portletResponse = (PortletResponse) FacesContext.getCurrentInstance().getExternalContext()
.getResponse();
HttpServletResponse res = PortalUtil.getHttpServletResponse(portletResponse);
res.setHeader("Content-Disposition", "attachment; filename=\"" + noteAndFile.getFilename() + "\"");//
res.setHeader("Content-Transfer-Encoding", "binary");
res.setContentType(noteAndFile.getContentType());
res.getOutputStream().write(IOUtils.toByteArray(noteAndFile.getInputStream()));
res.flushBuffer();
showMessage(SUCCESS, "Archivo descargado");
}
catch (IOException ioe)
{
showMessage(ERROR, "Problemas al descargar el archivo");
LOGGER.error("An error occurred uploading the file: " + ioe.getMessage(), ioe);
}
return null;
}
Adicionaly I use the primefaces's component
<p:commandButton value="Nuevo Download" ajax="false" update="growl">
<p:fileDownload value="#{cc.attrs.noteAndFileBean.getDownloadFileStreamContent(noteAndFile)}" />
</p:commandButton>
Related
Reference: java.io.IOException: Attempted read from closed stream
Reference: https://github.com/karatelabs/karate/blob/master/karate-core/src/main/java/com/intuit/karate/http/ApacheHttpClient.java
KarateCore - class file: ApacheHttpClient.java is unable to process the Response its failing at the code line
CloseableHttpClient client = clientBuilder.build();
CloseableHttpResponse httpResponse;
byte [] bytes;
try {
httpResponse = client.execute(requestBuilder.build());
HttpEntity responseEntity = httpResponse.getEntity();
if (responseEntity == null || responseEntity.getContent() == null) {
bytes = Constants.ZERO_BYTES;
} else {
**InputStream is = responseEntity.getContent();**
bytes = FileUtils.toBytes(is);
}
request.setEndTimeMillis(System.currentTimeMillis());
} catch (Exception e) {
if (e instanceof ClientProtocolException && e.getCause() != null) { // better error message
throw new RuntimeException(e.getCause());
} else {
throw new RuntimeException(e);
}
}
The Code is failing at line InputStream is = responseEntity.getContent(); when trying to read from a closed stream. The exception message displayed
Error com.intuit.karate - Runtimejava.io.IOException: Attempted read from closed stream.
May be the InputStream need to updated.
I am able read the Http Response content using below code
BufferedReader br = new BufferedReader(
new InputStreamReader((httpResponse.getEntity().getContent())));
String output;
while ((output = br.readLine()) != null){
output = br,readLine();
System.out.println(output);
}
Also the able to read the response using EntityUtils as a string content
String content = EntityUtils.toString(responseEntity);
System.out.println(content);
Not sure if i am missing something in the feature:scenario file response or the ApacheHttpClient.java file need to updated to read InputStream and then convert to bytes.
Feature: Hello
Scenario: Rest API Post
Given url 'some url path'
And header Content-Type = 'application/json'
And request { username: 'abc', password: 'pwd' }
When method POST
Then status 200
And print 'Response is:', response
The expected Response is a JSON format as:
{
"accessToken": "akjdoioikf",
"expires":"2020-01-29T01:09:48Z"
}
Any suggestions, appreciated!
I've been trying to track down why my Russian translations are not appearing correctly in the GWT version of my game. I've narrowed it down to something going wrong with the decoding of the file. This code works correctly outside of the GWT environment.
I create the UTF-8 byte array from a string for this test. The method below outputs two instances of the text to the log. The first uses new String(bytes) and gives the correct output, the second uses the BufferedReader and produces incorrect output. The diff of the two files can be seen here.
The classes I'm using for localisation are using the ByteBuffer approach and are therefore outputting incorrect text for the Russian translation and I'm struggling to understand why.
public void test(){
String text = "# suppress inspection \"UnusedProperty\" for whole file\n" +
"\n" +
"# Notes\n" +
"# I used the phrase \"Power Flower\" in English as it rhymes. They can be called something else in other languages.\n" +
"# They're \"fleurs magiques\" (Magic Flowers) in French.\n" +
"\n" +
"# Tutorials\n" +
"#-----------\n" +
"Tutorial_1_1=Составляй слова, проводя пальцем по буквам.Сейчас попробуй создать слово 'СОТЫ'\n" +
"Tutorial_1_2=Ты можешь складывать слова справа налево. Попробуй составить слово 'ЖАЛО' справа налево\n" +
"Tutorial_1_3=Слова могут распологаться сверху вниз, снизу вверх, справа налево, слева направо, а также по диагонали.\n" +
"Tutorial_1_4=Создавая слова, ты можешь изменять направление.Составь слово 'ВОСК'\n" +
"Tutorial_1_5=Ты даже можешь пересекать свое собственное слово. Тем не менее, используй каждую букву только один раз. А сейчас, сложи слово 'УЛЕЙ'\n" +
"Tutorial_1_6=Чем длиннее окажется твоё слово, тем больше у тебя шансов получить много очков и возможность заработать Чудо-Цветок. Составь слово 'ПЧЕЛА'\n" +
"Tutorial_1_7=Получи Чудо-Цветы за каждое слово из пяти или более букв. Они могут быть использованы в качестве любой из букв.\n" +
"Tutorial_1_8=Составь слово 'СТЕБЕЛЬ'\n" +
"Tutorial_1_9=Из разных по длине и форме слов получаются разные Чудо-Цветы.\n" +
"Tutorial_1_10=Теперь ты справишься сам. Составь еще четыре слова, чтобы уровень был пройден";
// This defaults to the default charset, which in my instance, and most probably yours is UTF-8
byte[] bytes = new byte[0];
try {
bytes = text.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String test = new String(bytes);
// This is correct
Gdx.app.log("File1", test);
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
InputStreamReader reader = null;
try {
reader = new InputStreamReader(is, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
BufferedReader br = new BufferedReader(reader);
StringBuilder fileContents = new StringBuilder();
String line;
try {
while ((line = br.readLine()) != null) {
fileContents.append(line + "\r\n");
}
} catch (IOException e) {
e.printStackTrace();
}
// This is incorrect
Gdx.app.log("File2", fileContents.toString());
}
It would appear the ByteArrayInputStream and the BufferedReader partial strings are being decoded by the UTF-8 decoder which is corrupting the result. This would appear to be a GWT issue.
In wicket project I use request handler for file downloading. Everything is works good until I have file with non standard encoding like utf-8.
I use this code for generate response
#Override
public void respond(IRequestCycle requestCycle)
{
WebResponse response = (WebResponse) requestCycle.getResponse();
response.setAttachmentHeader(briefcaseDocument.getName());
response.setContentType(briefcaseDocument.getMimeType());
response.setContentLength(briefcaseDocument.getSize());
InputStream inputStream = null;
OutputStream outputStream = null;
try
{
inputStream = briefcaseDocument.getInputStream();
outputStream = response.getOutputStream();
IOUtils.copyLarge(inputStream, outputStream);
}
catch (Exception e)
{
throw new RuntimeException("unable to push file content", e);
}
finally
{
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
}
}
but if document has special characketrs I get empty file name. For example:
ćććć is:
Content-Disposition attachment; filename=" ";
ćwiek is:
Content-Disposition attachment; filename=" wiek";
I read this stack topic and change code like this:
String fileName = briefcaseDocument.getName();
String encoded = URLEncoder
.encode(briefcaseDocument.getName(), "UTF-8");
response.setHeader("Content-Disposition","attachment" +
((!Strings.isEmpty(fileName)) ? ("; filename=\"" + fileName + "\"; filename*=UTF-8''"+encoded) : "" ));
and then I get as result:
Content-Disposition attachment; filename=" "; filename*=UTF-8''%C4%87%C5%BC
and file name present good, but I don't feel good with this solution ;) How to make wicket set file name properly?
According to http://greenbytes.de/tech/tc2231/ this is the proper way.
Since 7.0.0-M1 (https://issues.apache.org/jira/browse/WICKET-4934) Wicket does this automatically for you.
I am making my first attempt at writing a BlackBerry App that consumes SOAP web services that embed JSON data, and have hit a challenge that's taking longer than I have to solve. I'd appreciate assistance on this. Thank you.
Below is the structure of the Web Service Request:
<logonrequest>
{
"userid":"username",
"password":"password",
"Timestamp":""
}
</logonrequest>
Below is the structure of the Web Service Response:
<return>
{
"userid":"username",
"displayName":"Firstname Lastname",
"accountBalance":0.0,
"statusCode":"0|SUCCESS",
"statusDesc":"Logon Success",
"sessionid":"12047CC560484D21BD328EC8F22814ED",
"lastTransactionTime":"20131130234326"
}
</return>
Below is my BlackBerry Java Code:
package com.abc.app;
import java.io.IOException;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransport;
import org.xmlpull.v1.XmlPullParserException;
import a1.org2b.json.me.JSONException;
import a1.org2b.json.me.JSONObject;
public class MySoapAttempt extends MainScreen {
String serviceUrl = "http://www.abcappserver.tk:30740/abcJSONWebApp/abcJSONWebServiceV1?wsdl";
String serviceNamespace = "http://webapps.abc.abcConnect.com/";
String soapAction = "http://webapps.abc.abcConnect.com/logonrequest";
HttpTransport transport = new HttpTransport(serviceUrl + "/;deviceside=false;ConnectionType=mds-public");
SoapObject rpc = new SoapObject(serviceNamespace, "logonrequest");
// SoapObject result;
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
public MySoapAttempt() {
envelope.bodyOut = rpc;
JSONObject container = new JSONObject();
try {
container.put("userid", "username");
container.put("password", "password");
container.put("Timestamp", "");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rpc.addProperty("logonrequest", container.toString());
envelope.setOutputSoapObject(rpc);
try {
envelope.dotNet = false;
envelope.encodingStyle = SoapSerializationEnvelope.XSD;
transport.debug = true;
transport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
transport.call(soapAction, envelope);
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
Dialog.alert(result.toString());
System.out.println("------=========-------- "+result);
} catch (IOException e) {
System.out.println("======= IOException =======");
System.out.println(e.getMessage());
e.printStackTrace();
} catch (XmlPullParserException e) {
System.out.println("======= XmlPullParserException =======");
System.out.println(e.getMessage());
System.out.println(e.toString());
e.printStackTrace();
} catch (Exception e) {
System.out.println("======= General Exception =======");
System.out.println(e.getMessage());
System.out.println(e.toString());
e.printStackTrace();
} finally {
System.out.println("=== >>> REQUEST: " + transport.requestDump);
System.out.println("===========================================");
System.out.println("=== >>> REQUEST: " + transport.responseDump);
add(new LabelField("Welcome To My SOAP Attempt"));
}
}
}
Below is the structure of the Web Service Console:
[127779.77] AM: Starting abc
[127779.79] AM: Started abc(483)
[127779.79] AM: Foreground is set: abc(483)
...
[127793.06] ======= XmlPullParserException =======
[127793.06] expected: END_TAG {http://schemas.xmlsoap.org/soap/envelope/}Body (position:END_TAG </{http://schema
[127793.06] s.xmlsoap.org/soap/envelope/}S:Fault>#1:324 in java.io.InputStreamReader#267621d3)
[127793.06] org.xmlpull.v1.XmlPullParserException: expected: END_TAG {http://schemas.xmlsoap.org/soap/envelope/}
[127793.06] Body (position:END_TAG </{http://schemas.xmlsoap.org/soap/envelope/}S:Fault>#1:324 in java.io.InputS
[127793.06] treamReader#267621d3)
[127793.06] No stack trace
[127793.06] === >>> REQUEST: <?xml version="1.0" encoding="UTF-8"?><v:Envelope xmlns:i="http://www.w3.org/2001/X
[127793.06] MLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/so
[127793.06] ap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/
[127793.06] envelope/"><v:Header /><v:Body><n0:logonrequest id="o0" c:root="1" xmlns:n0="http://webapps.abc.
[127793.06] abcConnect.com/"><logonrequest i:type="d:string">{"userid":"username","password":"password","Timesta
[127793.06] mp":""}</logonrequest></n0:logonrequest></v:Body></v:En
[127793.06] velope>
[127793.06]
[127793.06] ===========================================
[127793.07] === >>> REQUEST: <?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.o
[127793.07] rg/soap/envelope/"><S:Body><S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope"><faultcode>S
[127793.07] :Client</faultcode><faultstring>Cannot find dispatch me
[127793.07] thod for {http://webapps.abc.abcConnect.com/}logonrequest</faultstring></S:Fault></S:Body></S:E
[127793.07] nvelope>
I notice from the console output that my request string seems to be malformed. How can I have it send a request that looks exactly like the required sample request above? Thank you.
I can't answer this question from a SOAP perspective as I know nothing about SOAP. And I am not great on XML. But from an XML perspective, your XML appears to be badly formed. If you want to pass data that should NOT be interpreted as XML, then use CDATA. Otherwise the XML parser will try to interpret the JSON characters as XML which is it not.
For further information see here:
http://www.w3schools.com/xml/xml_cdata.asp
As I understood it, when you are using SOAP, you are expected to use XML, so another option would be to format your data for XML. It should be possible to create an equivalent XML structure to contain your JSON data and that will be parsed correctly.
I am trying to upload a file to google drive using google service account.
Driver Service
public static Drive getDriveService(String secretKeyFile) throws GeneralSecurityException,
IOException, URISyntaxException {
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(DriveScopes.DRIVE)
.setServiceAccountPrivateKeyFromP12File(
new java.io.File(secretKeyFile))
.build();
Drive service = new Drive.Builder(httpTransport, jsonFactory, null)
.setHttpRequestInitializer(credential).setApplicationName("appl name").build();
return service;
}
Insert File
private static File insertFile(Drive service, String title, String description,String mimeType, String filename) {
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
Main Method
Drive service=null;
try {
String secretFile= "somedigit-privatekey.p12";
service = getDriveService(secretFile);
} catch (URISyntaxException ex) {
ex.printStackTrace();
}
File insertFile = insertFile(service, "test title", "File description", "text/plain", "c:\\test.txt");
List list = service.files().list();
System.out.println("Files Id : "+insertFile.getId());
System.out.println("Count Files : "+list.size());
Now, my questions is :
How and where can i check that file was uploaded?
Why it returns the file ID but list.size() is zero.
It returns the download link also but when i paste that link in
browser it doesn't download any file.
You are creating a listing request but not executing it. Use execute method to make the request:
service.files().list().execute();
If you paste the download link into the browser, it will respond with 401, because your download request should also contain a valid Authorization header. Use the following snippet to download the file programmatically.
HttpResponse resp = service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
InputStream stream = resp.getContent();
stream is an input stream for the file content.
Or add an Authorization: Bearer <access token> to the request you're making elsewhere.