Android ksoap2, data not being post - ksoap2

I am using ksoap2 for communicating with a remote web service. For some reason, the properties I add to soapObject are not being sent. Where have I gotten wrong? I have tried everything, I get a response when I perform direct posting of the request xml but that is not what I want. I also get a response from the server but none of the values I post are being passed. I have read every blog out there, the official documentation and even related SO questions, What have I missed?
Here is a snippet of a method being called from the doInBackground() of Async Task.
public SoapObject getSoapObject() {
// Create request
SoapObject requesty = new SoapObject(NAMESPACE, METHOD_NAME);
// Add the property to request object
requesty.addProperty(getPropertyInfo("PARAMETER_1", "VALUE_1"));
// Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
// Set output SOAP object
envelope.setOutputSoapObject(requesty);
// Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
SoapObject soapObject = null;
try {
// Send to web service
androidHttpTransport.call(SOAP_ACTION, envelope);
soapObject = (SoapObject) envelope.getResponse();
} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (HttpResponseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return soapObject;
}
private PropertyInfo getPropertyInfo(String name, String value) {
PropertyInfo propInfo = new PropertyInfo();
propInfo.setName(name);
propInfo.setValue(value);
propInfo.setType(string.class);
return propInfo;
}

Instead of using ksoap2, I posted directly via HttpPost and manually parsed the different values with a custom XML parser. I know this might not be the best of the choices but SOAP is just old school now.

Related

Why this reator code with block inside Flux.create couldn't work?

I've tried to use a watchService as a Flux generator and it couldn't work, and I also tried some simple block like Thread.sleep in the Flux.create method and it could work.
I wonder why and what's the difference between these situations?
Code which could work,
#Test
public void createBlockSleepTest() throws InterruptedException {
Flux.create(sink->{
while (true) {
try {
for(int i=0;i<2;i++)
sink.next(num++);
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).log().subscribeOn(Schedulers.parallel(),false).log()
.subscribe(System.out::println);
Thread.sleep(100000L);
}
Code which couldn't work,
#Test
public void createBlockTest() throws IOException, InterruptedException {
WatchService watchService = fileSystem.newWatchService();
Path testPath = fileSystem.getPath("C:/testing");
Files.createDirectories(testPath);
WatchKey register = testPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,StandardWatchEventKinds.ENTRY_MODIFY);
Files.write(testPath.resolve("test1.txt"),"hello".getBytes());
Thread.sleep(5000L);
Flux.create(sink->{
while (true) {
try {
WatchKey key = watchService.take();
System.out.println("-----------------"+key);
for(WatchEvent event:key.pollEvents()){
sink.next(event.context());
}
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).log().subscribeOn(Schedulers.parallel(),false).log()
.subscribe(System.out::println);
Files.write(testPath.resolve("test2.txt"),"hello".getBytes());
Thread.sleep(5000L);
Files.write(testPath.resolve("test3.txt"),"hello".getBytes());
Thread.sleep(10000L);
}
I've noticed in the reactor's reference there is a notice for blocking in the create method. But why Thread.sleep works?
create doesn’t parallelize your code nor does it make it asynchronous, even
though it can be used with asynchronous APIs. If you block within the create lambda,
you expose yourself to deadlocks and similar side effects. Even with the use of subscribeOn,
there’s the caveat that a long-blocking create lambda (such as an infinite loop calling
sink.next(t)) can lock the pipeline: the requests would never be performed due to the
loop starving the same thread they are supposed to run from. Use the subscribeOn(Scheduler, false)
variant: requestOnSeparateThread = false will use the Scheduler thread for the create
and still let data flow by performing request in the original thread.
Could anyone solve my puzzle?
This can be fixed by changing
while (true) {
try {
WatchKey key = watchService.take();
System.out.println("-----------------"+key);
for(WatchEvent event:key.pollEvents()){
sink.next(event.context());
}
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
to
while (true) {
try {
WatchKey key = watchService.take();
System.out.println("-----------------"+key);
for(WatchEvent event:key.pollEvents()){
sink.next(event.context());
}
key.reset();
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Thread.sleep(5000L) will only block for 5s, so the create will move on after that delay, whereas WatchService#take blocks indefinitely unless a new WatchKey registers (in this case a new file). Since the code that creates files is after the create, there is a deadlock situation.

how to creat a hyperlink url string in a Java MessageDialog?

a simple MessageDialog(or MessageBox,any method can open a dialog )like follows:
MessageDialog.openInformation(shell, "Test", "Get help form this link www.google.com");
is there any way to make www.google.com a hyperlink? click the url and open browser.
thats not possible out of the box. I created a class of my own, named MyMessageDialog to do this:
https://gist.github.com/andydunkel/8914008
Its basically all the source code from MessageDialog. Then I overwrote the createMessageArea method and added a Link instead of a label and added an event listener:
protected Control createMessageArea(Composite composite) {
// create composite
// create image
Image image = getImage();
if (image != null) {
imageLabel = new Label(composite, SWT.NULL);
image.setBackground(imageLabel.getBackground());
imageLabel.setImage(image);
//addAccessibleListeners(imageLabel, image);
GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.BEGINNING)
.applyTo(imageLabel);
}
// create message
if (message != null) {
linkLabel = new Link(composite, getMessageLabelStyle());
linkLabel.setText(message);
linkLabel.addSelectionListener(new SelectionAdapter(){
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("You have selected: "+e.text);
try {
// Open default external browser
PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(new URL(e.text));
}
catch (PartInitException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
catch (MalformedURLException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
}
});
GridDataFactory
.fillDefaults()
.align(SWT.FILL, SWT.BEGINNING)
.grab(true, false)
.hint(
convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH),
SWT.DEFAULT).applyTo(linkLabel);
}
return composite;
}
The MessageDialog can be called with HTML code in it now:
MyMessageDialog.openError(parent.getShell(), "Hehe", "Google.com Test");
Not a very optimal solution, but it works:
Andy

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.

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

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();
}

Problem while adding a new value to a hashtable when it is enumerated

`hi
I am doing a simple synchronous socket programming,in which i employed twothreads
one for accepting the client and put the socket object into a collection,other thread will
loop through the collection and send message to each client through the socket object.
the problem is
1.i connect to clients to the server and start send messages
2.now i want to connect a new client,while doing this i cant update the collection and add
a new client to my hashtable.it raises an exception "collection modified .Enumeration operation may not execute"
how to add a NEW value without having problems in a hashtable.
private void Listen()
{
try
{
//lblStatus.Text = "Server Started Listening";
while (true)
{
Socket ReceiveSock = ServerSock.Accept();
//keys.Clear();
ConnectedClients = new ListViewItem();
ConnectedClients.Text = ReceiveSock.RemoteEndPoint.ToString();
ConnectedClients.SubItems.Add("Connected");
ConnectedList.Items.Add(ConnectedClients);
ClientTable.Add(ReceiveSock.RemoteEndPoint.ToString(), ReceiveSock);
//foreach (System.Collections.DictionaryEntry de in ClientTable)
//{
// keys.Add(de.Key.ToString());
//}
//ClientTab.Add(
//keys.Add(
}
//lblStatus.Text = "Client Connected Successfully.";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btn_receive_Click(object sender, EventArgs e)
{
Thread receiveThread = new Thread(new ThreadStart(Receive));
receiveThread.IsBackground = true;
receiveThread.Start();
}
private void Receive()
{
while (true)
{
//lblMsg.Text = "";
byte[] Byt = new byte[2048];
//ReceiveSock.Receive(Byt);
lblMsg.Text = Encoding.ASCII.GetString(Byt);
}
}
private void btn_Send_Click(object sender, EventArgs e)
{
Thread SendThread = new Thread(new ThreadStart(SendMsg));
SendThread.IsBackground = true;
SendThread.Start();
}
private void btnlist_Click(object sender, EventArgs e)
{
//Thread ListThread = new Thread(new ThreadStart(Configure));
//ListThread.IsBackground = true;
//ListThread.Start();
}
private void SendMsg()
{
while (true)
{
try
{
foreach (object SockObj in ClientTable.Keys)
{
byte[] Tosend = new byte[2048];
Socket s = (Socket)ClientTable[SockObj];
Tosend = Encoding.ASCII.GetBytes("FirstValue&" + GenerateRandom.Next(6, 10).ToString());
s.Send(Tosend);
//ReceiveSock.Send(Tosend);
Thread.Sleep(300);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
You simply can't modify a Hashtable, Dictionary, List or anything similar while you're iterating over it - whether in the same thread or a different one. There are concurrent collections in .NET 4 which allow this, but I'm assuming you're not using .NET 4. (Out of interest, why are you still using Hashtable rather than a generic Dictionary?)
You also shouldn't be modifying a Hashtable from one thread while reading from it in another thread without any synchronization.
The simplest way to fix this is:
Create a new readonly variable used for locking
Obtain the lock before you add to the Hashtable:
lock (tableLock)
{
ClientTable.Add(ReceiveSock.RemoteEndPoint.ToString(), ReceiveSock);
}
When you want to iterate, create a new copy of the data in the Hashtable within a lock
Iterate over the copy instead of the original table
Do you definitely even need a Hashtable here? It looks to me like a simple List<T> or ArrayList would be okay, where each entry was either the socket or possibly a custom type containing the socket and whatever other information you need. You don't appear to be doing arbitrary lookups on the table.
Yes. Don't do that.
The bigger problem here is unsafe multi-threading.
The most basic "answer" is just to say: use a synchronization lock on the shared object. However this hides a number of important aspects (like understanding what is happening) and isn't a real solution to this problem in my mind.

Resources