I am working on a blackberry application. I need to call soap webservices, but I am unable to do so, and am getting null as a response. Following is my code:
private static final String CONNECTION_PARAMS = ";deviceside=true";
SoapObject request = new SoapObject("http://service.action.com/",
"findActiveSecurities");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = request;
HttpTransportBasicAuth ht =
new HttpTransportBasicAuth("http://myurl.com/ebclient/services/MobileClientService?wsdl"+CONNECTION_PARAMS,
"myusername",
"mypassword");
PropertyInfo propInfo=new PropertyInfo();
propInfo.type=PropertyInfo.INTEGER_CLASS;
//adding parameters
request.addProperty("arg0","NSE");
request.addProperty("arg1","0");
request.addProperty("arg2","100");
envelope.setOutputSoapObject(request);
try {
ht.call(SOAP_ACTION, envelope);
result = (SoapObject)envelope.getResponse();
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
I am getting null as a result.Please have a look at the code and help me to correct it.
Thanks in advance
Actually the problem was instead of passing 0 and 100 as String ...
request.addProperty("arg0","NSE");
request.addProperty("arg1","0");
request.addProperty("arg2","100");
I use
request.addProperty("arg0","NSE");
request.addProperty("arg1",new Integer(0));
request.addProperty("arg2",new Integer(1000));
also this link helped me.
also before asking this question I was facing some problem that the Simulator was not recognizing a Library. It shows error message something like "there is no library Ksoap2_j2me.jar" - resolved from this link.
Sorry for poor English but I think this can save time of some other developer.
It's hard to tell from what you're posted, but my guess is that you're having some kind of network problem. I'm guessing that you initialize result = null;, and then your call to ht.call() throws an IOException, leaving result null.
You're using ksoap2, which is a library written for generic J2ME clients. However, BlackBerry networking doesn't work exactly like all other J2ME platforms.
You are controlling the BlackBerry network transport with your connection params string, which is hardcoded:
private static final String CONNECTION_PARAMS = ";deviceside=true";
Unfortunately, this string suffix may not be right for all network conditions (or any, if you don't have device APN settings correct).
I think you have a couple choices:
1. Connection Suffix Strings
You can try dynamically choosing the right suffix string, depending on conditions when your app runs. This can allow the device, for example, to connect via Wi-Fi if it's available, or via BES if that's available. Developers new to BlackBerry may be surprised that app code needs to worry about this (read here for more, or watch this).
If you want to simply replace CONNECTION_PARAMS with a dynamic string, you might check out the implementation here.
2. ConnectionFactory
In OS 5.0, BlackBerry added the ConnectionFactory class, which was a big improvement over the old way of having to assemble connection strings. If you only need to support OS 5.0 and greater, you might choose to rewrite the code to use ConnectionFactory.
Since you have access to the ksoap source code, you could change it. It looks like the connection code is in ServiceConnectionMidp.java:
public ServiceConnectionMidp(String url) throws IOException {
connection = (HttpConnection) Connector.open(url, Connector.READ_WRITE, true);
}
Instead of attaching connection parameters to the url passed to this class, you could change the class to get the connection from a ConnectionFactory, customized to support the network transports you want.
Doing this means that if you ever want to update your code to use a new version of ksoap2, you'll need to make these modifications again. However, given the future of BlackBerry Java, that seems like a reasonable compromise to make.
Related
I hope it is ok to ask two somehow related Questions in one.
I am using a camel route to send a SOAP message to a webservice using Reliable Messaging. Now there is two Problems i ran into, first the WS-Addressing version that is used is wrong, i need to have 2005/08 but instead it is using 2004/08.
For setting up the endpoint i am using (shortend a bit)
CxfEndpoint cxfEndpoint = new CxfEndpoint();
cxfEndpoint.setWsdlURL(getWsdlURL());
cxfEndpoint.setDataFormat(DataFormat.CXF_MESSAGE);
cxfEndpoint.setCamelContext(camelContext);
camelContext.addEndpoint(outEndpoint.getId(), cxfEndpoint);
I also set up a cxfbus in the camel-context.xml file and a seperate http-conduit.xml
now my question for the WS-Addressing is, how can i change it to use WS-Addressing 2005/08? i already tried to add following to my route, before the endpoint is called, but it did not change the Addressing Namespace.
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
AddressingPropertiesImpl addrProps =
new AddressingPropertiesImpl("http://www.w3.org/2005/08/addressing");
Map<String, Object> requestContext = new HashMap<String, Object>();
requestContext.put("javax.xml.ws.addressing.context", addrProps);
exchange.getIn().setHeader(Client.REQUEST_CONTEXT, requestContext);
}
})
Regarding the Offer in the CreateSequence added the following before the endpoint is added to the CamelContext:
RMManager rmManager = cxfEndpoint.getBus().getExtension(RMManager.class);
rmManager.getSourcePolicy().setIncludeOffer(false);
Although this worked fine it had the nasty side effect that my http-conduit was no longer used. I fixed this with following:
cxfEndpoint.setBus(bus);
where bus is being #Autowired
but in my opinion this broke the WS-Reliable Messaging for my incoming CXF Endpoint that are created in a similiar way. It still sends the correct messages but before the CreateSequenceResponse is send, there is an empty SOAP message sent, that causes the client to drop out of the Sequence creation.
Now my question would be, is there a better way to remove the Offer from the CreateSequence?
There are some similar questions for earlier versions of Jetty (pre 9) but none that address this specific problem :
Server server = new Server();
System.setProperty("com.sun.net.httpserver.HttpServerProvider",
JettyHttpServerProvider.class.getName());
JettyHttpServer jettyServer = new JettyHttpServer(server, true);
Endpoint endpoint = Endpoint.create(new SOAPService()); // this class to handle all ws requests
endpoint.publish(jettyServer.createContext("/service")); // access by path
server.start()
Simplified code example above to show the only way that I have found to bridge between Jetty and incoming soap requests to my jax-ws service. All settings are in code with no web.xml, this is part of a larger solution that has multiple contexts and connections for different purposes (servlets etc..)
I have tried to add a handler class to the jettyServer.createContext("/service",new handler()) to see if I can perform a header extraction to simulate basic auth but it never gets executed.
My problem is that i cannot find a way to specify, by code against the Jetty server, to use basic authentication. Using the setSecurityHandler method of a ServletContextHandler is easy and works great for other contexts, i just can't figure out how to use this concept for the jax-ws service.
Any help would be much appreciated.
p.s. SSL is already implemented, I just need to add http basic auth.
For anyone else that may of come across the same problem here is the answer that i stumbled on eventually.
final HttpContext httpContext = jettyServer.createContext("/service");
com.sun.net.httpserver.BasicAuthenticator a = new com.sun.net.httpserver.BasicAuthenticator("") {
public boolean checkCredentials (String username, String pw)
{
return username.equals("username") && pw.equals("password");
}
};
httpContext.setAuthenticator(a);
endpoint.publish(httpContext);//access by path
You can expand the checkCredentials for something a bit more sophisticated of course, but this shows the basic working method.
I am using play framework 1.2.5 jobs - after await, I send a message to the web UI in JSON format. The same JSON logic works fine when not using jobs - however, after using jobs and await, the JSON message appears to contain invalid characters (client side javascript does not recognize it as valid JSON anymore). The browser does not render the garbled/invalid characters - I will try using wireshark and see if I can add more details. Any ideas on what could be causing this and how best to prevent this? Thanks in advance (I'm reasonably sure its my code causing the problem since I can't be the first one doing this). I will also try to test using executors/futures instead of play jobs and see how that goes.
Promise<String> testChk = new TestJobs(testInfo, "validateTest").now(); //TestJobs extends Job<String> & I'm overriding doJobWithResult. Also, constructor for TestJobs takes two fields (type for testInfo & String)
String testChkResp = await(testChk);
renderJSON(new TestMessage("fail", "failure message")); //TestMessage class has two String fields and is serializable
Update: I am using gson & JDK1.6
Update It seems that there is a problem with encoding whenever I use play jobs and renderJSON.
TestMessage: (works when not using jobs)
import java.io.Serializable;
public class TestMessage {
public String status;
public String response;
public TestMessage() {
}
public TestMessage(String status, String response) {
this.status = status;
this.response = response;
}
}
Update:
Even using the following results in utf-8 impact when using while relying on jobs.
RenderJSON("test");
Sounds like it could be a bug. It may be related to your template - does it specify the encoding explicitly?
What format is the response? You can determine this by using the inspector in chrome or Web Console in Firefox.
(Though I certainly agree the behaviour should be consistent - it may be worth filing a bug here: http://play.lighthouseapp.com/projects/57987-play-framework/tickets )
It's a workaround; first reset the outputstream then render.
response.reset();
response.contentType="application/json; charset=utf-8";
renderJSON("play has some bugs")
I was able to use futures & callables with executors and the same code as mentioned above works (using play 1.2.5). The only difference was that I was not explicitly using play jobs (and hence the issue does not appear to be related to gson).
I am new to C# and would be really grateful if someone could provide some insight on the following problem: I have written a c# app that gets the html content of a website, quite simply using a webclient. The problem is that if I run it for multiple websites I see that sometimes I get no results for some of them, like it was never connected to that website at that instance. I initially thought it was my internet connection but the same happened when I tried on a different wifi. It is worth mentioning that I have the same prob on another of my appcs when trying to connect to a webservice. My question is: does anybody know how can this be fixed? Does it have to do with the timeout time of something like that?
Thank you very much in advance
This is the code but it's not really an issue of coding:
var client = new WebClient();
try
{
var htmlcode = client.DownloadString(site);
int NumberOfTrues = Regex.Matches(htmlcode.ToLower(), key).Count;
}
catch (Exception)
{
messagebox.show("could not be loaded");
}
This was solved by defining the default proxy server in app config.
I'am use next code for authorization on server by service, and get other service'methods using cookie identifer for authorizathion.
TerminalControllerBinding soapObj;
soap_init1(soapObj.soap, SOAP_C_UTFSTRING);
soapObj.endpoint = "http://192.168.*.*/path/to/service";
ns1__getTemplatesResponse *response = new ns1__getTemplatesResponse;
std::string auth_res = "";
soapObj.ns1__auth("user", "password", auth_res);
QString sessid = QString::fromStdString(auth_res);
qDebug() << sessid;
soapObj.soap->cookies = soap_cookie(soapObj.soap, "sessid", sessid.toAscii().data(), ".");
Server not getting cookie "sessid"
I am kind of confused by the code you posted: You allocate memory for ns1__getTemplatesResponse, then do some apparently unrelated stuff; in fact you do not reference it again at all. Furthermore soap_cookie is a struct and soap->cookies is basically a list. So there is no magic that transfers the cookies to the server here.
I think what you want is soap_set_cookie. You can find a little more information on client side cookies here, but there isn't any example code. Much more helpful however is actually the server side documentation (the handling of cookies doesn't differ much).
Also notice that you either need to compile with -DWITH_COOKIES or define the macro yourself in stdsoap.h if you haven't done so already.