Blackberry Java - Fixed length streaming a POST body over a HTTP connect - blackberry

I'm working on some code which POSTs large packets often over HTTP to a REST server on IIS. I'm using the RIM/JavaME HTTPConnection class.
As far as I can tell HTTPConnection uses an internal buffer to "gather" up the output stream before sending the entire contents to the server. I'm not surprised, since this is how HttpURLConnect works by default as well. (I assume it does this so that the content-length is set correctly.) But in JavaSE I could override this behavior by using the method setFixedLengthStreamingMode so that when I call flush on the output stream it would send that "chunk" of the stream. On a phone this extra buffering is too expensive in terms of memory.
In Blackberry Java is there a way to do fixed-length streaming on a HTTP request, when you know the content-length in advance?

So, I never found a way to do this was the base API for HTTPConnection. So instead, I created a socket and wrapped it with my own simple HTTPClient, which did support chunking.
Below is the prototype I used and tested on BB7.0.
package mypackage;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.microedition.io.Connector;
import javax.microedition.io.SocketConnection;
public class MySimpleHTTPClient{
SocketConnection sc;
String HttpHeader;
OutputStreamWriter outWriter;
InputStreamReader inReader;
public void init(
String Host,
String port,
String path,
int ContentLength,
String ContentType ) throws IllegalArgumentException, IOException
{
String _host = (new StringBuffer())
.append("socket://")
.append(Host)
.append(":")
.append(port).toString();
sc = (SocketConnection)Connector.open(_host );
sc.setSocketOption(SocketConnection.LINGER, 5);
StringBuffer _header = new StringBuffer();
//Setup the HTTP Header.
_header.append("POST ").append(path).append(" HTTP/1.1\r\n");
_header.append("Host: ").append(Host).append("\r\n");
_header.append("Content-Length: ").append(ContentLength).append("\r\n");
_header.append("Content-Type: ").append(ContentType).append("\r\n");
_header.append("Connection: Close\r\n\r\n");
HttpHeader = _header.toString();
}
public void openOutputStream() throws IOException{
if(outWriter != null)
return;
outWriter = new OutputStreamWriter(sc.openOutputStream());
outWriter.write( HttpHeader, 0 , HttpHeader.length() );
}
public void openInputStream() throws IOException{
if(inReader != null)
return;
inReader = new InputStreamReader(sc.openDataInputStream());
}
public void writeChunkToServer(String Chunk) throws Exception{
if(outWriter == null){
try {
openOutputStream();
} catch (IOException e) {e.printStackTrace();}
}
outWriter.write(Chunk, 0, Chunk.length());
}
public String readFromServer() throws IOException {
if(inReader == null){
try {
openInputStream();
} catch (IOException e) {e.printStackTrace();}
}
StringBuffer sb = new StringBuffer();
int data = inReader.read();
//Note :: This will also read the HTTP headers..
// If you need to parse the headers, tokenize on \r\n for each
// header, the header section is done when you see \r\n\r\n
while(data != -1){
sb.append( (char)data );
data = inReader.read();
}
return sb.toString();
}
public void close(){
if(outWriter != null){
try {
outWriter.close();
} catch (IOException e) {}
}
if(inReader != null){
try {
inReader.close();
} catch (IOException e) {}
}
if(sc != null){
try {
sc.close();
} catch (IOException e) {}
}
}
}
Here is example usage for it:
MySimpleHTTPClient myConn = new MySimpleHTTPClient() ;
String chunk1 = "ID=foo&data1=1234567890&chunk1=0|";
String chunk2 = "ID=foo2&data2=123444344&chunk1=1";
try {
myConn.init(
"pdxsniffe02.webtrends.corp",
"80",
"TableAdd/234234234443?debug=1",
chunk1.length() + chunk2.length(),
"application/x-www-form-urlencoded"
);
myConn.writeChunkToServer(chunk1);
//The frist chunk is already on it's way.
myConn.writeChunkToServer(chunk2);
System.out.println( myConn.readFromServer() );
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}finally{
myConn.close();
}

Related

Android Studio, downloading image form url/app has stopped working

Hi could you help me find out why my app stops working when I want to download image from url, here is the code
public void getOnClick(View view) throws IOException {
urlAdress = new URL("http://www.cosmeticsurgerytruth.com/blog/wp- content/uploads/2010/11/Capri.jpg");
InputStream is = urlAdress.openStream();
filename = Uri.parse(urlAdress.toString()).getLastPathSegment();
outputFile = new File(context.getCacheDir(),filename);
OutputStream os = new FileOutputStream(outputFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
is.close();
os.close();
I was also trying to use some code from similar topics but I get same message
Your app has stopped working
and it shuts down
Caused by: android.os.NetworkOnMainThreadException
The problem is that you are trying to download the image from the UIThread. You have to create a class which extends to AsyncTask class and make the download on the doInBackground method
private class DownloadAsync extends AsyncTask<Void, Void, Void> {
private Context context;
DownloadAsync(Context context) {
this.context = context;
}
#Override
protected Void doInBackground(Void... params) {
try {
URL urlAdress = urlAdress = new URL("http://www.cosmeticsurgerytruth.com/blog/wp- content/uploads/2010/11/Capri.jpg");
InputStream is = urlAdress.openStream();
String filename = Uri.parse(urlAdress.toString()).getLastPathSegment();
File outputFile = new File(context.getCacheDir(), filename);
OutputStream os = new FileOutputStream(outputFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
is.close();
os.close();
return null;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Then you can execute like this
public void getOnClick(View view){
new DownloadAsync(this).execute();
}

Custom JavaFX WebView Protocol Handler

I am trying to write my own protocol handler for a JavaFX application that uses webview to access a single website. What I have done so far
My custom URLStreamHandlerFactory
public class MyURLStreamHandlerFactory implements URLStreamHandlerFactory {
public URLStreamHandler createURLStreamHandler(String protocol) {
System.out.println("Protocol: " + protocol);
if (protocol.equalsIgnoreCase("http") || protocol.equalsIgnoreCase("https")) {
return new MyURLStreamHandler();
} else {
return new URLStreamHandler() {
#Override
protected URLConnection openConnection(URL u) throws IOException {
return new URLConnection(u) {
#Override
public void connect() throws IOException {
}
};
}
};
}
}
}
My custom URLStreamHandler
public class MyURLStreamHandler extends java.net.URLStreamHandler{
protected HttpURLConnection openConnection(URL u){
MyURLConnection q = new MyURLConnection(u);
return q;
}
}
My custom HttpURLConnection
public class MyURLConnection extends HttpURLConnection {
static int defaultPort = 443;
InputStream in;
OutputStream out;
Socket s;
publicMyURLConnection(URL url) {
super(url);
try {
setRequestMethod("POST");
} catch (ProtocolException ex) {
ex.printStackTrace();
}
}
public void setRequestProperty(String name, String value){
super.setRequestProperty(name, value);
System.out.println("Namee: " + name);
System.out.println("Value: " + value);
}
public String getRequestProperty(String name){
System.out.println("GET REQUEST: ");
return super.getRequestProperty(name);
}
public OutputStream getOutputStream() throws IOException {
OutputStream os = super.getOutputStream();
System.out.println("Output: " + os);
return os;
}
public InputStream getInputStream() throws IOException {
InputStream is = super.getInputStream();
System.out.println("INout stream: " + is);
return is;
}
#Override
public void connect() throws IOException {
}
#Override
public void disconnect() {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public boolean usingProxy() {
throw new UnsupportedOperationException("Not supported yet.");
}
When I run the application I get the following error althouhg it seems to set some headers
Jul 08, 2013 11:09:04 AM com.sun.webpane.webkit.network.URLLoader doRun
WARNING: Unexpected error
java.net.UnknownServiceException: protocol doesn't support input
at java.net.URLConnection.getInputStream(URLConnection.java:839)
at qmed.QMedURLConnection.getInputStream(MyURLConnection.java:67)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at com.sun.webpane.webkit.network.URLLoader.receiveResponse(URLLoader.java:383)
at com.sun.webpane.webkit.network.URLLoader.doRun(URLLoader.java:142)
at com.sun.webpane.webkit.network.URLLoader.access$000(URLLoader.java:44)
at com.sun.webpane.webkit.network.URLLoader$1.run(URLLoader.java:106)
at com.sun.webpane.webkit.network.URLLoader$1.run(URLLoader.java:103)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.webpane.webkit.network.URLLoader.run(URLLoader.java:103)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
All I want to do is get the response back for a given request and reads its binary data. I want the protocol to behave exactly the same way as the default one and only check the binary data of a given respone. What am I doing wrong?
The application is doing all shorts of URLConnections. Is it correct to use a HTTPURLConnection as my custom URLConnection class when the protocol is http or https and start a default URLStreamHandler when other protocols are used like I am doing in MyURLStreamHandlerFactory? Should I just extend the default URLConnection class in MYURLConnection to handle all protocols the same?
Any help would be much appreciated as this is a project threatening problem
Thank you
It might be that all you are missing is a setDoInput(true) or override getDoInput() and return true (that's what i did).
If that does not help check out my working solution:
MyURLStreamHandlerFactory:
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
public class MyURLStreamHandlerFactory implements URLStreamHandlerFactory
{
public URLStreamHandler createURLStreamHandler(String protocol)
{
if (protocol.equals("myapp"))
{
return new MyURLHandler();
}
return null;
}
}
Register Factory:
URL.setURLStreamHandlerFactory(new MyURLStreamHandlerFactory());
MyURLHandler :
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
public class MyURLHandler extends URLStreamHandler
{
#Override
protected URLConnection openConnection(URL url) throws IOException
{
return new MyURLConnection(url);
}
}
MyURLConnection:
import java.io.*;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
/**
* Register a protocol handler for URLs like this: <code>myapp:///pics/sland.gif</code><br>
*/
public class MyURLConnection extends URLConnection
{
private byte[] data;
#Override
public void connect() throws IOException
{
if (connected)
{
return;
}
loadImage();
connected = true;
}
public String getHeaderField(String name)
{
if ("Content-Type".equalsIgnoreCase(name))
{
return getContentType();
}
else if ("Content-Length".equalsIgnoreCase(name))
{
return "" + getContentLength();
}
return null;
}
public String getContentType()
{
String fileName = getURL().getFile();
String ext = fileName.substring(fileName.lastIndexOf('.'));
return "image/" + ext; // TODO: switch based on file-type
}
public int getContentLength()
{
return data.length;
}
public long getContentLengthLong()
{
return data.length;
}
public boolean getDoInput()
{
return true;
}
public InputStream getInputStream() throws IOException
{
connect();
return new ByteArrayInputStream(data);
}
private void loadImage() throws IOException
{
if (data != null)
{
return;
}
try
{
int timeout = this.getConnectTimeout();
long start = System.currentTimeMillis();
URL url = getURL();
String imgPath = url.toExternalForm();
imgPath = imgPath.startsWith("myapp://") ? imgPath.substring("myapp://".length()) : imgPath.substring("myapp:".length()); // attention: triple '/' is reduced to a single '/'
// this is my own asynchronous image implementation
// instead of this part (including the following loop) you could do your own (synchronous) loading logic
MyImage img = MyApp.getImage(imgPath);
do
{
if (img.isFailed())
{
throw new IOException("Could not load image: " + getURL());
}
else if (!img.hasData())
{
long now = System.currentTimeMillis();
if (now - start > timeout)
{
throw new SocketTimeoutException();
}
Thread.sleep(100);
}
} while (!img.hasData());
data = img.getData();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public OutputStream getOutputStream() throws IOException
{
// this might be unnecessary - the whole method can probably be omitted for our purposes
return new ByteArrayOutputStream();
}
public java.security.Permission getPermission() throws IOException
{
return null; // we need no permissions to access this URL
}
}
Some parts of MyURLConnection might not be necessary for it to work, but like this it works for me.
Usage in JavaFX WebView:
<img src="myapp:///pics/image.png"/>
Note about permissions:
I used an applet with AllPermissions for my test with the above code.
In a Sandbox-Applet this won't work, as the setFactory permission is missing.
This is not directly related to the question asked, but might make the question itself obsolete.
With Java SE 6 Update 10 Java Applets support to access resources on any domain and port which is correctly set up with a crossdomain.xml.
With this the reason to register your own protocol might become obsolete, as you can access all resources that you need.
Another idea is: If you are trying to create a kind of network sniffer, why not directly use a network sniffer/analyzer program designed for such a task?
By activating Logging and Tracing in the Java Control-Panel your Java-Console will print all attempts and executed network calls including those from the WebView.
You can see all HTTP & HTTPS calls and their return-code + cookie data.
You might also see other protocol connections, but probably not any data sent over them.
This applies to Applets in a Browser.
If you need this in a different context maybe there is a way to activate the same options by passing command line parameters.

Connection being made, but content is unable to be retrieved from web service

public class ConsumeFactoryThread extends Thread {
private String url;
private HttpConnection httpConn;
private InputStream is;
private CustomMainScreen m;
private JSONArray array;
public ConsumeFactoryThread(String url, CustomMainScreen m){
System.out.println("Connection begin!");
this.url = url;
this.m = m;
}
public void finished(){
m.onFinish(array);
}
public void run(){
myConnectionFactory connFact = new myConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(url);
System.out.println("Connection factory!");
if(connDesc != null)
{
System.out.println("Connection not null!");
httpConn = (HttpConnection) connDesc.getConnection();
is = null;
try
{
final int iResponseCode = httpConn.getResponseCode();
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
System.out.println("Connection in run!");
// Get InputConnection and read the server's response
InputConnection inputConn = (InputConnection) httpConn;
try {
is = inputConn.openInputStream();
System.out.println("Connection got inputstream!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] data = null;
try {
data = IOUtilities.streamToBytes(is);
System.out.println("Connection got data!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String result = new String(data);
System.out.println("Connection Data: "+result);
try {
array = new JSONArray(result);
//finished();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
catch(IOException e)
{
System.err.println("Caught IOException: " + e.getMessage());
}
}
}
}
I'm using the blackberry torch 9800 simulator and hardware device for testing.
In the simulator I cannot retrieve the data over wifi, even though the connection to wifi is found. It works when the mobile network is enabled.
Now, when I replace my web service with the Twitter api, I get the data regardless of transport type. I tried adding ;deviceside=false to my url, but nothing. It's not https or anything.
I just want my web service accessed! I know nothing about this mds,bis,bes,bis_b junk.
EDIT:
Jeez. I'm realizing it may be my site. Not using the web service and just retrieving the page, www.example.com, I get nothing. But, google.com or any other site I use retrieves the html. Am I missing headers!?!
Try appending ;interface=wifi to the end of your URL, this will force the simulator to use your simulated Wi-Fi connection, which is your PC's network connection.
You will need to have setup Wi-Fi on the simulator by going to Manage Connections->Set Up Wi-Fi Network, then connect to Default WLAN Network.

Append to an existing file in a new line

I want to write some texts in a new line into an existing file.I tried following code but failed,Can any one suggest how can I append to file in a new row.
private void writeIntoFile1(String str) {
try {
fc=(FileConnection) Connector.open("file:///SDCard/SpeedScence/MaillLog.txt");
OutputStream os = fc.openOutputStream(fc.fileSize());
os.write(str.getBytes());
os.close();
fc.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
and calling
writeIntoFile1("aaaaaaaaa");
writeIntoFile1("bbbbbb");
Its successfully writing to the file I simulated(SDCard) but its appears in the same line.
How can I write "bbbbbb" to new line?
Write a newline (\n) after writing the string.
private void writeIntoFile1(String str) {
try {
fc = (FileConnection) Connector.open("file:///SDCard/SpeedScence/MaillLog.txt");
OutputStream os = fc.openOutputStream(fc.fileSize());
os.write(str.getBytes());
os.write("\n".getBytes());
os.close();
fc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
N.B. a PrintStream is generally better-suited for printing text, though I'm not familiar enough with the BlackBerry API to know if it's possible to use a PrintStream at all. With a PrintStream you'd just use println():
private void writeIntoFile1(String str) {
try {
fc = (FileConnection) Connector.open("file:///SDCard/SpeedScence/MaillLog.txt");
PrintStream ps = new PrintStream(fc.openOutputStream(fc.fileSize()));
ps.println(str.getBytes());
ps.close();
fc.close();
} catch (IOException e) {
e.printStackTrace();
}
}

send sms from background thread in blackberry using j2me

hey i made a lot of search and found some similar types of code.
I tried for gsm
method 1 gives IllegalArgumentException
try
{
MessageConnection _mc = (MessageConnection)Connector.open("sms://");
TextMessage tm = (TextMessage) _mc.newMessage(MessageConnection.TEXT_MESSAGE);
tm.setPayloadText(smsText);
tm.setAddress("965xxxxxxx");
_mc.send(tm);
_mc.close();
}catch(exception e){}
method 2: gives java.lang.error exception
try
{
MessageConnection _mc = (MessageConnection)Connector.open("sms://");
TextMessage tm = (TextMessage) _mc.newMessage(MessageConnection.TEXT_MESSAGE,
"//9790XXXXXX");
tm.setPayloadText(text);
_mc.send(tm);
_mc.close();
}catch(Exception e){}
I think the problem is with address
i also tried : but no success
+91965xxxxxxx ,
0091965xxxxxxx ,
0965xxxxxxx
How my application works----
i have created 2 applications--
1) Application 1 is a background app that is a System module as well as
startup application.
2) Another is a uiapplication
the background app runs in background.If there comes an incoming call then a flag value is set in persistent object and after checking that value as true the sms is send to that no from whom call is made.
ok try this
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.io.Datagram;
import javax.microedition.io.DatagramConnection;
import javax.wireless.messaging.MessageConnection;
import javax.wireless.messaging.TextMessage;
import net.rim.device.api.system.RadioInfo;
public class SendSMS extends Thread {
private String to;
private String msg;
public SendSMS(String to, String msg) {
this.to = to;
this.msg = msg;
}
public void run() {
if (RadioInfo.getNetworkType() == RadioInfo.NETWORK_CDMA) {
DatagramConnection dc = null;
try {
dc = (DatagramConnection) Connector.open("sms://" + to);
byte[] data = msg.getBytes();
Datagram dg = dc.newDatagram(dc.getMaximumLength());
dg.setData(data, 0, data.length);
dc.send(dg);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
dc.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
} else {
MessageConnection mc = null;
try {
mc = (MessageConnection) Connector
.open("sms://" + to);
TextMessage m = (TextMessage) mc
.newMessage(MessageConnection.TEXT_MESSAGE);
m.setPayloadText(msg);
mc.send(m);
} catch (IOException e1) {
e1.printStackTrace();
} finally {
try {
mc.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
}
and call like this
public void callDisconnected(int callId) {
final PhoneCall call = Phone.getCall(callId);
final String number = call.getDisplayPhoneNumber();
SendSMS sendSMS = new SendSMS(number, "message");
sendSMS.start();
super.callDisconnected(callId);
}

Resources