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.
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'm working project : jsf, richfaces. I has just updated javamail api newest version 1.5.5 at https://java.net/projects/javamail/pages/Home
When i test send email from gmail to my gmail,
Subject : Subject test.
Content : Content test. And config : smtp.gmail.com, 465, SSL.
It has just subject and no content in my inbox receive gmail :
And log :
And my code :
try {
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
// Set the host smtp address
props.put("mail.smtp.host", SMTP_HOST_NAME);
props.put("mail.smtp.port", SMTP_PORT);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
props.put("mail.smtp.socketFactory.port", SMTP_PORT);
props.put("mail.smtp.ssl.trust", "*");
props.put("mail.smtp.ssl.socketFactory", sf);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
.......
.......
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(props, auth);
session.setDebug(true);
// create a message
MimeMessage msg = new MimeMessage(session);
msg.setText("UTF8");
// set the from and to address
InternetAddress addressFrom = new InternetAddress(SMTP_AUTH_USER);
msg.setFrom(addressFrom);
System.out.println(addressFrom);
msg.setSubject(subject, "utf-8");
......
......
try {
String content = replaceCharacterInEmail(cus, null,null, message);
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setContent(content, "text/html; charset=utf-8");
// attach the file to the message
Multipart mp = new MimeMultipart();
int count = 0;
if(files != null){
while (count < files.size()) {
MimeBodyPart mbdp = new MimeBodyPart();
mbdp.attachFile(files.get(count));
mp.addBodyPart(mbdp);
count++;
}
}
// create the Multipart and add its parts to it
mp.addBodyPart(mbp1);
// add the Multipart to the message
msg.setContent(mp);
Transport.send(msg);
} catch (Exception e) {
invalidAddress += (", " + address.trim());
e.printStackTrace();
}finally{
if (!"".equals(emailFails)) {
emailFails = emailFails.substring(1);
}
}
But, when i test above code at another project test (java application) with above lib javamail. It's ok :
.
I don't think problem at version of lib javamail. I don't know different between 2 project, because part send email is similar. How can i fix that error ?
Please observe this email structure:
-- multipart/mixed
-- mutlipart/alternative
-- text/plain
-- text/html
-- application/octet-stream (or any other mimetypes)
I found problem is conflict library at lib of jboss server and lib of app.ear (deploy).
I'm trying to create a way to upload text data (database key) along with an .png image from a Windows 8.1 App, through a multipart/form-data HTTP POST request, to a PHP script hosted on a webserver (which saves the image locally using the database key as a filename)
I've had a look at packet sniffer and it's all coming out the way I think it should, but the problem is that the PHP $_POST value is not passing through and is null on the php script side.
Here is the C# code on the Windows Metro app side:
private async void UploadImage() {
string newLine = Environment.NewLine;
WebRequest request = WebRequest.Create("http://www.mywebsite.com/receiveimage.php");
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = "POST";
string boundary = "---------------------BUIUFBILPQMZ81C12CCC2EVV2RJ";
request.ContentType = "multipart/form-data; boundary=" + boundary;
// Open pre-saved MY_FILE.png file from local disk and store in fh
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile fh = await localFolder.GetFileAsync("MY_FILE.png");
// Header strings and values
string Prefix1 = boundary + newLine + "Content-Disposition: form-data; name=\"SERIAL_NO\"" + newLine + newLine; // SERIAL_NO is the php $_POST variable
string Prefix2 = boundary + newLine + "Content-Disposition: form-data; name=\"MY_FILE\"; filename=\"" + "MY_FILE.png\"" + newLine + "Content-Type: application/base64" + newLine + newLine;
byte[] baPrefix1 = System.Text.Encoding.UTF8.GetBytes(Prefix1);
byte[] baValue1 = System.Text.Encoding.UTF8.GetBytes("C4145-12" + newLine); // (C4145-12 is the database key)
IBuffer buffer = await FileIO.ReadBufferAsync(fh);
byte[] baPrefix2 = System.Text.Encoding.UTF8.GetBytes(Prefix1);
byte[] baValue2 = System.Text.Encoding.UTF8.GetBytes(System.Convert.ToBase64String(buffer.ToArray()).Replace("+", "%2B") + newLine);
byte[] combinedData = new byte[baPrefix1.Length + baValue1.Length + baPrefix2.Length + baValue2.Length];
System.Buffer.BlockCopy(baPrefix1, 0, combinedData, 0, baPrefix1.Length);
System.Buffer.BlockCopy(baValue1, 0, combinedData, baPrefix1.Length, baValue1.Length);
System.Buffer.BlockCopy(baPrefix2, 0, combinedData, baPrefix1.Length + baValue1.Length, baPrefix2.Length);
System.Buffer.BlockCopy(baValue2, 0, combinedData, baPrefix1.Length + baValue1.Length + baPrefix2.Length, baValue2.Length);
Stream dataStream = await request.GetRequestStreamAsync();
dataStream.Write(combinedData, 0, combinedData.Length);
dataStream.Dispose();
using (WebResponse response = await request.GetResponseAsync())
{
// "STATUS" is just a text block
STATUS.Text = (((HttpWebResponse)response).StatusDescription);
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseFromServer = reader.ReadToEnd();
STATUS.Text = responseFromServer;
}
}
The PHP script on the server works with other forms but can't recognize the value passed in from this script, so I know it's not an issue with that. I'm convinced it's a problem with the header formatting. I've experimented with the amount of new lines but to no avail. Any ideas?
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.
I am trying to download a pdf file on my mobile (using Java ME) using SocketConnection Api. The idea is to send the server a HTTP GET request, and it replies back with the data for pdf file. However, the problem I am facing is that the server initially replies back with string data (the HTTP Headers), and then the binary data. I just want to store the binary data (the pdf file).
I have written this code so far, and it works perfectly fine as far as the server replies back with string data. However, when it replies back with binary data, this code still tries to store everything as string, correctly storing the initially returned HTTP Headers (not required) and then garbled bits corresponding to the binary data of my PDF file.
public void FileDownload() {
try {
sc = (SocketConnection) Connector.open("socket://" + hostname + ":" + port);
OutputStream os = sc.openOutputStream();
os.write(("GET " + link_to_file_to_be_downloaded + " HTTP/1.0\r\n").getBytes("UTF-8"));
os.write(("HOST: " + hostname + "\r\n").getBytes("UTF-8"));
os.write(("\r\n").getBytes("UTF-8"));
os.flush();
os.close();
String url = "file:///E:/Data/" + "binary_data.pdf";
FileConnection fconn = (FileConnection) Connector.open(url, Connector.READ_WRITE);
if (!fconn.exists()) {
fconn.create();
}
OutputStream ops = fconn.openOutputStream();
byte data = 0;
in = sc.openInputStream();
data = (byte) in.read();
while (data != -1) {
ops.write(data);
data = (byte) in.read();
}
ops.flush();
ops.close();
fconn.close();
} catch (IOException ex) {
parent_class.main_form.append("Exception occured while "
+ "downloading file: " + ex.toString() + "\n");
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
parent_class.main_form.append("Exception occured while "
+ "downloading file: " + ex.toString() + "\n");
}
}
}
}
This is what gets stored in the file "binary_data.pdf" using this code -
HTTP/1.1 200 OK
Date: Sun, 25 Mar 2012 07:03:10 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Tue, 20 Mar 2012 22:00:45 GMT
ETag: "420050-12bad-4bbb3ce85fd21"
Accept-Ranges: bytes
Content-Length: 76717
Content-Type: application/pdf
Via: 1.0 www.XXX.XXX.org
Connection: close
%PDF-1.4
%????
3 0 obj <<
/Length 4077
/Filter /FlateDecode
>>
stream
x??ZYs?6~????9U.?#??Udg?M*qYJ???T-4?fq? #Z????<FT?}
lt7??n???_???4?s???????"
3????<???^?V?z??M?z??m?^????V???o??S'm6?????.??/Sx??Y?av?MB?*b^?f??/?IO??B??q??/?(??aT?a?##??,?%???Z8? ?]??-?\?]??????nw?2?;?????Z?;?[}??????&J=ml??-??V?|??:??"?(?Gf??D??~?QW?U?Z???cP?b???QX
(This operation might be simpler using the high level HttpConnection api, but I wish to understand how everything works at the most basic level, and hence I am using the SocketConnection api instead.)
In short, what I wish my app to do is simply interpret the data replied by the server correctly, either as string or binary, and then accordingly store the binary file (possibly discarding the string HTTP headers).
I found the solution. Below is the working code.
I am first storing the header response as a string. Headers are terminated by \r\n\r\n, (so, read in bytes upto these characters). Later am storing the (possibly) binary data in a file separately.
public String FileDownloadNonPersistently() {
String server_reply = new String();
try {
sc = (SocketConnection) Connector.open("socket://" + hostname + ":" + port);
os = sc.openOutputStream();
os.write(("GET " + link_to_file_to_be_downloaded +
" HTTP/1.0\r\n").getBytes("UTF-8"));
os.write(("HOST: " + hostname + "\r\n").getBytes("UTF-8"));
os.write(("\r\n").getBytes("UTF-8"));
os.flush();
os.close();
in = sc.openInputStream();
// 1. Read the response header from server separately beforehand.
byte data;
String temp_char = "";
while (!"\r\n\r\n".equals(temp_char)) {
data = (byte) in.read();
server_reply += String.valueOf((char) data);
if (((char) data) == '\r' || ((char) data) == '\n') {
temp_char += String.valueOf((char) data);
} else {
temp_char = "";
}
}
// 2. Recieving the actual data, be it text or binary
current = 0;
mybytearray = new byte[filesize];
bytesRead = in.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead = in.read(mybytearray, current,
(mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
// Store recieved data to file, if set true from options
if (tcp_save_downloaded_file == true) {
// decide an appropriate file name acc. to download link
String url = "file:///E:/Data/" + "tcp_downloaded_file.pdf";
FileConnection fconn = (FileConnection)
Connector.open(url, Connector.READ_WRITE);
if (!fconn.exists()) { // XXX. what if file already present? overwrite or append mode?
fconn.create();
}
OutputStream ops = fconn.openOutputStream();
ops.write(mybytearray, 0 , current);
ops.flush();
ops.close();
}
} catch (Exception ex) {
parent_class.main_form.append("Exception occured while "
+ "downloading file: " + ex.toString() + "\n\n");
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
parent_class.main_form.append("Exception occured while "
+ "closing inputstream "
+ "after downloading file: " + ex.toString() + "\n\n");
}
}
// XXX. see if you need to close the OutputStreams and
// SocketConnection as well.
return server_reply;
}
}
The first 10 lines are the HTTP message headers. For more information on them please go to https://www.rfc-editor.org/rfc/rfc2616#page-31.
The blank line identifies where the body starts.
You can start saving the pdf content from line 12 onwards, but you should do it using a different read method.
Instead of
data = (byte) in.read();
while (data != -1) {
ops.write(data);
data = (byte) in.read();
}
please try
byte buff[] = new byte[1024];
int len = in.read(buff);
while (len > 0) {
ops.write(buff, 0, len);
len = in.read(buff);
}