Download a file from a server with a BlackBerry app - blackberry

I want to download a file from a server via the internet with a BlackBerry app.
It is not important which protocol is used: FTP, HTTP or something else would be fine. I just need the user to click "download" button and then the app downloads this file from a server.
I have no idea how it can be done. I have tried a few solutions. In one I need a HttpConnectorFactory but this is not in my API.
I have searched for an answer to my question for days, but I haven't found a solution that works.
Links to solutions I have tried:
How to download an html file in a BlackBerry application
https://stackoverflow.com/questions/6290988/downloading-a-pdf-file-from-a-webserver-in-blackberry-java-application
Networking Helper Class

try this -
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc = connFact.getConnection(your_url);
HttpConnection httpConn = (HttpConnection) connDesc.getConnection();
try {
httpConn.setRequestMethod(HttpConnection.GET);
InputConnection inputConn = (InputConnection) httpConn;
InputStream is = inputConn.openInputStream();
byte[] data =IOUtilities.streamToBytes(is);
//the value in data will be the bytes of your file.
// now if you want to save the file, you can do it here......
} catch (IOException e) {
e.printStackTrace();
}

Related

Download link encodedKeyStore

I've been generated a PKCS12 keystore through a API, but the return of the process is a KeyStore object. I need to send it, directly to the browser to be downloaded when the client send the requisition.
How can I do that?
I'm using java and jboss 5AS.
You can use KeyStore#store() to write it out to an OutputStream.
keyStore.store(outputStream, password);
That's basically it. The OutputStream could be the one of the HTTP response. For a generic kickoff example of how to provide a file download in JSF wherein you need to integrate this line, head to this answer: How to provide a file download from a JSF backing bean? Use a content type of application/x-pkcs12.
Here is the code:
public void cadastrar () throws Exception
{
byte[] encodedKeyStore = controlador.cadastrar(certificadoModel);
java.security.KeyStore keyStore = java.security.KeyStore.getInstance("PKCS12");
keyStore.load(new ByteArrayInputStream(encodedKeyStore), certificadoModel.getPassword().toCharArray());
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.responseReset();
ec.setResponseContentType("application/x-pkcs12");
//ec.setResponseContentLength(contentLength);
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + certificadoModel.getUsername() + ".p12" + "\"");
OutputStream output = ec.getResponseOutputStream();
keyStore.store(output, certificadoModel.getPassword().toCharArray());
fc.responseComplete();
}

Blackberry-not getting soap response xml

I am trying to consume SOAP response xml by passing request xml in a string, using BlackBerry Java plugin for Eclipse. I have been struck on this for the past two days looking for a way to solve it.
I have attached the sample code below.
public String CheckXml()
{
final String requestXml="<SOAP:Envelope xmlns:SOAP=\"http://schemas.xmlsoap.org/soap/envelope/\"><header xmlns=\"http://schemas.cordys.com/General/1.0/\"></header><SOAP:Body><authenticateAgainstOID xmlns=\"http://schemas.cordys.com/OIDAuthentication\"><stringParam>HEMANTS_MUM013</stringParam><stringParam1>TATA2012</stringParam1></authenticateAgainstOID></SOAP:Body></SOAP:Envelope>";
final String HOST_ADDRESS = "http://xyz.com/cordys/com.eibus.web.soap.Gateway.wcp?organization=o=B2C,cn=cordys,cn=cbop,o=tatamotors.com&SAMLart=MDFn+8e5dRDaRMRIwMY7nI84eEccbx+lIiV0VhsOQ7u+SKG6n5+WNB58";
String result="";
try {
HttpConnection url=(HttpConnection)Connector.open(HOST_ADDRESS);
url.setRequestProperty("Content-Type", "text/xml");
url.setRequestMethod(HttpConnection.GET);
OutputStreamWriter writer=new OutputStreamWriter(url.openOutputStream());
writer.write(requestXml);
writer.flush();
writer.close();
StringBuffer buffer1=new StringBuffer();
InputStreamReader reader=new InputStreamReader(url.openInputStream());
StringBuffer buffer=new StringBuffer();
char[] cbuf=new char[2048];
int num;
while (-1 != (num = reader.read(cbuf))) {
buffer.append(cbuf, 0, num);
}
String result1 = buffer.toString();
} catch (Exception e) {
System.out.println(e);
}
return result;
}
I think the main issue that you aren't asking http. getResponseCode(). I think BB doesn't do any interaction until you call it.
I would also be careful with this code on the real devices. Search for correct opening connection on the BlackBerries.
I noticed that you are not including the SoapAction header in the request.
SOAP Web services usually have a fixed URL, and the differents methods are selected with the SoapAction header. You can check the header by opening the WSDL in a browser and inspecting the format for the method you want to invoke.
Once you know which action to select, set it as a regular http header:
url.setRequestProperty("SOAPAction", <your action here>);
Another source of problems in your code is that you are using the old HttpConnection class that requires appending a suffix to the URL depending on the transport type (MDS, BIS, Wi-Fi, etc). You don't need to use this legacy class unless you are targeting OS 4.5 and lower. So have a look at ConnectionFactory class, which is much easier to use. It is available since OS 5.0.

Getting 401 Unauthorized from Google API Resumable Update

I am trying to integrate upload of arbitrary files to Google Docs into an existing application. This used to work before using resumable upload became mandatory. I am using Java client libraries.
The application is doing the upload in 2 steps:
- get the resourceId of the file
- upload the data
To get the resourceId I am uploading a 0-size file (i.e. Content-Length=0). I am passing ?convert=false in the resumable URL (i.e. https://docs.google.com/feeds/upload/create-session/default/private/full?convert=false).
I am passing "application/octet-stream" as content-type. This seems to work, though I do get different resourcesIds - "file:..." resourceIds for things like images, but "pdf:...." resourceIds for PDFs.
The second step constructs a URL based on the resourceId obtained previously and performs a search (getEntry). The URL is in the form of https://docs.google.com/feeds/default/private/full/file%3A.....
Once the entry is found the ResumableGDataFileUploader is used to update the content (0-byte file) with the actual data from the file being uploaded. This operation fails with 401 Unauthorized response when building ResumableGDataFileUploader instance.
I've tried with ?convert=false as well as ?new-revision=true and both of these at the same time. The result is the same.
The relevant piece of code:
MediaFileSource mediaFile = new MediaFileSource(
tempFile, "application/octet-stream");
final ResumableGDataFileUploader.Builder builder =
new ResumableGDataFileUploader.Builder(client, mediaFile, documentListEntry);
builder.executor(MoreExecutors.sameThreadExecutor());
builder.requestType(ResumableGDataFileUploader.RequestType.UPDATE);
// This is where it fails
final ResumableGDataFileUploader resumableGDataFileUploader = builder.build();
resumableGDataFileUploader.start();
return tempFile.length();
The "client" is an instance of DocsService, configured to use OAuth. It is used to find "documentListEntry" immediately before the given piece of code.
I had to explicitly specify request type, since it seems the client library code contains a bug causing NullPointerException for "update existing entry" case.
I have a suspicion that the issue is specifically in the sequence of actions (upload 0-byte file to get the resourceId, then update with actual file) but I can't figure out why it doesn't work.
Please help?
This code snippet works for me using OAuth 1.0 and OAuth 2.0:
static void uploadDocument(DocsService client) throws IOException, ServiceException,
InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(10);
File file = new File("<PATH/TO/FILE>");
String mimeType = DocumentListEntry.MediaType.fromFileName(file.getName()).getMimeType();
DocumentListEntry documentEntry = new DocumentListEntry();
documentEntry.setTitle(new PlainTextConstruct("<DOCUMENT TITLE>"));
int DEFAULT_CHUNK_SIZE = 2 * 512 * 1024;
ResumableGDataFileUploader.Builder builder =
new ResumableGDataFileUploader.Builder(
client,
new URL(
"https://docs.google.com/feeds/upload/create-session/default/private/full?convert=false"),
new MediaFileSource(file, mimeType), documentEntry).title(file.getName())
.requestType(RequestType.INSERT).chunkSize(DEFAULT_CHUNK_SIZE).executor(executor);
ResumableGDataFileUploader uploader = builder.build();
Future<ResponseMessage> msg = uploader.start();
while (!uploader.isDone()) {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
throw ie; // rethrow
}
}
DocumentListEntry uploadedEntry = uploader.getResponse(DocumentListEntry.class);
// Print the document's ID.
System.out.println(uploadedEntry.getId());
System.out.println("Upload is done!");
}

Using ConnectionFactory and retrieve the data from url

public class ConsumeFactoryThread extends Thread {
private String url;
public ConsumeFactoryThread(String url){
this.url = url;
}
public void run(){
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(url);
if(connDesc != null)
{
HttpConnection httpConn;
httpConn = (HttpConnection) connDesc.getConnection();
try
{
final int iResponseCode = httpConn.getResponseCode();
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
//data retrieved
}
});
}
catch(IOException e)
{
System.err.println("Caught IOException: " + e.getMessage());
}
}
}
}
I got the above code from one of Blackberry's articles, but I'm not entirely sure as to how I get the raw String of the contents of the url, which in my case is going to be a json string.
I know when I was not using ConnectionFactory I used an inputstream to get the data, but I don't know if it is the same with the newer api.
Thanks
I believe what you are looking to do is the following:
is = ((Connection) httpConn).openInputStream();
byte[] data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
String result = new String(data);
This will grab the input stream the HttpConnection object has gathered, use the RIM IOUtils class to nicely put it into an array then finally create a String from the data. It should be possible from their to use the JSON libraries that RIM include in their SDK to work on the JSON.
Note: Not sure if the cast is required, btw this is untested code.
You should also note there are 3 different APIs which you can use to create a network connection on BlackBerry.
Using the Generic Connection Framework
The oldest methed (OS 5 below) is a basic J2ME implementation with additional transport descriptors appended to the end of the URL. It uses the J2ME GCF. A great explanation is given here, describing how to always reliably open a HTTPConnection.
Using the Network API
Introduced in OS 5 and above. This is the current method you are using. It wraps over the nasty descriptor Strings that are added to the end of the URL in the GCF through the use of the ConnectionFactory and ConnectionDescriptor classes.
Using the Communications API
Introduced into OS 6 and above. This is the newest possible method, it is an even higher abstraction on the Network API. These API's abstract how the actual data is gathered and try to not bother you with the details of the protocol. The useful thing about this API is you just get the resulting data and don't have to worry about the implementation details.
You should note that as you are working with JSON it even will wrap around the details of converting the resulting data and convert it into the format you wanted. An example is shown here.

how to upload the file through http to the website? (Blackberry)

I need to upload a file through http or ftp to the website in blackberry jde.
High level view: You open an OutputStream from an HttpConnection and write your data into that output stream. The main problem is going to be choosing which network connection to use (I recommend looking at this, unless you're on OS 5.0 which has a similar feature built in). As to uploading through FTP that will be somewhat more difficult as there is no support for FTP built into the BlackBerry API instead you'll have to look at using a SocketConnection and implementing part of FTP yourself.
Here's some code to get you started:
HttpConnection httpConn = (HttpConnection) Connector.open("<URL>");
FileConnection fileConn = (FileConnection) Connector.open("file:///<path>");
InputStream in = fileConn.openInputStream();
OutputStream out = httpConn.openOutputStream();
byte[] buffer = new byte[100];
int bytesRead = 0;
while((in.read(buffer) = bytesRead) > 0)
{
out.write(buffer, 0, bytesRead);
}
Of course you'll need to deal with exceptions, close the streams, check that it was uploaded successfully, etc

Resources