How to consume Session dependent WCF services using Ksoap2-Android - android

I am using Ksoap2-Android for consuming the WCF Services.
For the dotnet client we keep the allowCookies="true" in our binding configuration and it sends the same sessionid and keeps my sessions intact in my WCF services (My services are
interdependent and use the sessions).
Any one know any such setting for ksoap2-android, that will allow me to consume the
WCF service keeping my session intact on the server.
Currently when i make a new call to the service, the sessionid gets changed and all my
session variables clear out and loose their values.

In C# i do the next, just use the android methods to do this:
1.- Make the Http request,
2.- Make a Cookie Container of the first request.
3.- Put the cookieContainer over the second request, for example you can put in a bundle in a intent for the 2nd activity, and use this cookies for send the second http request...
My C# Code;
protected static void GetData()
{
CookieContainer cookies = new CookieContainer();
HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create("https://any.com/url");
request1.CookieContainer = cookies;
HttpWebResponse response1 = (HttpWebResponse)request1.GetResponse();
StreamReader responseReader1 = new StreamReader(response1.GetResponseStream());
Response1 = responseReader1.ReadToEnd();
responseReader1.Close();
responseReader1.Dispose();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.CookieContainer = cookies;
request.Method = "GET";
request1.KeepAlive = true;
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader responseReader = new StreamReader(response.GetResponseStream());
Response = responseReader.ReadToEnd();
responseReader.Close();
responseReader.Dispose();
if (Response.Contains("Server Error in '/Verification' Application."))
{
Console.WriteLine("Empty Registry" + Url);
}
}
catch (WebException ex)
{
if (ex.Response != null)
{
Console.WriteLine("Failed at: " + Url);
}
if (ex.Status == WebExceptionStatus.ProtocolError)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
{
Console.WriteLine(ex.Status);
}
}
else if (ex.Status == WebExceptionStatus.NameResolutionFailure)
{
Console.WriteLine(ex.Status);
}
}
}
I do That for keep the sesionID of the first request, and later, in the second request, i add the cookieContainer (because the server requires me) (to make a bot search) ;)... hope this give you ideas.

Related

How to make a HTTP/POST request in Kotlin (Android) to simple server?

Hello I am trying to begin an Android app in Kotlin. I have been trying to find a way to simply send and receive data from an android app to a simple HTTP server I made on my computer. The idea I am hoping is just make an app with a text box on it and a send button. When I press the send button it sends it to the simple http server (whether I use IP address or URL isn't Important)
This is just simply a proof of concept that I can make my own simple HTTP Server and get the app to send and receive from it.
I am essentially trying to do a server-client architecture between an android app and a computer. I can get this concept to work between two computer applications (python, java, C++ etc) but not how to do it in android. I keep looking for other answers on here but still come up short.
to be specific do I need enable certain features within the configurations file or a library that will allow the task to be done in the background?
Thank you for your help in advance.
If you want to connect of server for sending requests (POST and GET) then follow this code
public void callApi(String urls,String calledFor) {
try {
HttpGet httppost = new HttpGet(urls);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
JSONObject json = jsono.getJSONObject("data");
}
} catch (ParseException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
ktor is a wonderful HTTP client that you can use for Android. It is developed by JetBrains, who are also authors of Kotlin, so it takes advantage of the features of the language:
You will need to add the ktor client for Android in build.gradle:
implementation "io.ktor:ktor-client-android:$ktor_version"
Then set up your client like this:
val client = HttpClient(Android) {
// setting these properties is optional; you don't need to if you wish to use the defaults
engine {
connectTimeout = 100_000
socketTimeout = 100_000
}
}
At last you can make HTTP requests like so (example from here): (the use method is to automatically close it at the end, make sure you read about releasing resources)
val resp: String = client.use {
val htmlContent = it.get<String>("https://en.wikipedia.org/wiki/Main_Page")
println(htmlContent)
// same as
val content: String = it.get("https://en.wikipedia.org/wiki/Main_Page")
content
}
Post Api request Using okHttp in Kotlin (Android)
follow steps
You will need to add the dependencies in build.gradle(:app)
implementation("com.squareup.okhttp3:okhttp:4.9.0")
request code here
fun runPostApi() {
var url = "https://reqres.in/api/users"
// add parameter
val formBody = FormBody.Builder().add("name", " Parker")
.build()
// creating request
var request = Request.Builder().url(url)
.post(formBody)
.build()
var client = OkHttpClient();
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
println(response.body?.string())
}
override fun onFailure(call: Call, e: IOException) {
println(e.message.toString())
}
})}
for more information link here below
https://square.github.io/okhttp/recipes/

How to access cookie and check if it has expired using okhttp3 and PersistentCookieStore?

I am working on an Android app in which a log in post request is made to a webservice. The request returns a cookie which expires in 20 minutes.
Using okhttp3 and this PersistentCookieStore library, I got the cookie to be stored and subsequently added it as request header to access authentication-required get requests (e.g. personal information that are non-public).
The code goes this way,
CookieJar myCookieJar = new PersistentCookieJar(new SetCookieCache(),
new SharedPrefsCookiePersistor(this));
OkHttpClient client = new OkHttpClient.Builder().cookieJar(HttpRequests.cookieJar).build();
I then call a method like this inside an (after I have gone through another log in Async task to get the cookie) Async task to perform a get request that requires authentication,
public static String PostReq(String url, String json) {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.addHeader("Cookie", "key=value")
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
catch(Exception e){
}
}
The .addHeader("Cookie", "key=value") adds the cookie to the header to tell the webservice that I am authenticated.
Here comes my difficulty. Since the cookie expires after 20 minutes, I would like to be able to access the cookie itself to check for the expiration time and possibly redirect the user to the log in activity by calling the method,
myCookie.expiresAt()
and comparing it to
System.currentTimeMillis()
I tried to look at the PersistentCookieStore codes and found that it uses a SharedPreference with the key "CookiePersistence". I looked inside this file while my emulator was running the app and found it to be empty however.
How would I be able to access this cookie that I have obtained? Much thanks for any advice to be given.
OK, this is old, but I was facing the same problem, and here is how I fixed it.
Hold a reference to your SetCookieCache used to instantiate your CookieJar:
SetCookieCache cookieCache = new SetCookieCache();
CookieJar myCookieJar = new PersistentCookieJar(
cookieCache,
new SharedPrefsCookiePersistor(this)
);
Then use this to find your cookie and check it:
for (Cookie cookie : cookieCache) {
if (cookie.name().equals("cookie_name") && cookie.persistent()) {
//cookie is still good
break;
}
}
Or use cookie.expiresAt() to do your thing.

Spring Rest : Handling POST requests, at server end

I am asking this question based on the answers in this link
POST request via RestTemplate in JSON
I actually wanted to send JSON from client and receive the same at REST server. Since the client part is done in the link I mentioned above. For the same how would I handle that request at server end.
CLIENT:
// create request body
JSONObject request = new JSONObject();
request.put("username", name);
request.put("password", password);
// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);
// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
.exchange(urlString, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK) {
JSONObject userJson = new JSONObject(loginResponse.getBody());
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
// nono... bad credentials
}
SERVER:
#RequestMapping(method=RequestMethod.POST, value = "/login")
public ResponseEntity<String> login(#RequestBody HttpEntity<String> entity) {
JSONObject jsonObject = new JSONObject(entity.getBody());
String username = jsonObject.getString("username");
return new ResponseEntity<>(username, HttpStatus.OK);
}
This gives me 400 bad request error at client side. Hoping for some clues about how to handle this at server side.
HTTPEntity should not be used in your server method. Instead use the argument which is being passed to HTTPEntity from your client. In your case it has to String since you are passing string from client. Below code should work for you.
#RequestMapping(method=RequestMethod.POST, value = "/login")
public ResponseEntity<String> login(#RequestBody String jsonStr) {
System.out.println("jsonStr " + jsonStr);
JSONObject jsonObject = new JSONObject(jsonStr);
String username = jsonObject.getString("username");
return new ResponseEntity<String>(username, HttpStatus.OK);
}
My advice is to create bean class and use it in server and client instead of converting it to String. It will improve readability of the code.
When using the Spring RestTemplate, I usually prefer to exchange objects directly. For example:
Step 1: Declare and define a data holder class
class User {
private String username;
private String password;
... accessor methods, constructors, etc. ...
}
Step 2: Send objects of this class to the server using RestTemplate
... You have a RestTemplate instance to send data to the server ...
// You have an object to send to the server, such as:
User user = new User("user", "secret");
// Set HTTP headers for an error-free exchange with the server.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// Generate an HTTP request payload.
HttpEntity<User> request = new HttpEntity<User>(user, headers);
// Send the payload to the server.
restTemplate.exchange("[url]", [HttpMethod], request, User.class);
Step 3: Configure a ContentNegotiatingViewResolver on the server
Declare a bean of the type ContentNegotiatingViewResolver in the Spring XML or Java configuration. This will help the server automatically bind HTTP requests with bean objects.
Step 4: Receive the request on the server
#RestController
#RequestMapping("/user")
class UserAPI {
#RequestMapping(method = RequestMethod.POST)
#ResponseBody
public User create(User user) {
// Process the user.
// Possibly return the same user, although anything can be returned.
return user;
}
}
The ContentNegotiatingViewResolver ensures that the incoming request gets translated into a User instance without any other intervention.
Step 5: Receive the response on the client
// Receive the response.
HttpEntity<User> response = restTemplate.exchange("[url]", [HttpMethod], request, User.class);
// Unwrap the object from the response.
user = response.getBody();
You will notice that the client and the server both use the same bean class (User). This keeps both in sync as any breaking change in the bean structure would immediately cause a compilation failure for one or both, necessitating a fix before the code is deployed.

Add parameter into body with Scribe Library

I'm developing an Android app and I have integrated Scribe library to make http connection with OAuth1.0 with Magento. My problem is that I need to send a request with a parameter into body but without a key. Now I make login correctly and I have my Token authorized, I get products from server, categories, blah blah... but I cannot make checkout because always I get code "401 Authorization require". I think that the problem could be by the parameter in the body.
My code:
...
#Override
protected String doInBackground(String... json) {
String result = null;
org.scribe.model.Response response = null;
String url = Global.BASE_URL + "cart/1";
if(Global.TOKEN_AUTHORIZED != null) {
OAuthRequest request = new OAuthRequest(Verb.POST, url);
//I only need insert a json into body without key
request.addBodyParameter(<I don't need a key>, json[0]);
Global.OAUTH_SERVICE.signRequest(Global.TOKEN_AUTHORIZED, request);
response = request.send();
}
if(response != null && response.getCode() == 200) {
result = response.getBody();
} else {
result = "ERROR";
}
return result;
}
...
How I put only a parameter in the body but without key, value?
Thanks in advance :)
I found the solution:
First is necessary to add a Header to say that content of the request is a json
To add a single parameter into the body without key, value exists a method called addPayload(String)
Now I get a response with code 200 :)
if(Global.TOKEN_AUTHORIZED != null) {
OAuthRequest request = new OAuthRequest(Verb.POST, url);
request.addHeader("Content-Type", "application/json");
request.addPayload(params[0]);
Global.OAUTH_SERVICE.signRequest(Global.TOKEN_AUTHORIZED, request);
response = request.send();
}
I hope to help somebody :)

Https with self-signed certificate in Android over Restlet

I'm trying to implement simple Androd client with RestLet for my thesis.Evrything works well over HTTP but I have to get it to work over HTTPS with self-signed certificate and this is were I have problems.
I was unable to find any helpful articles or anything similar about how to implement this on Android with RestLet. I know how to do this with code from Android Developers but I need to do this with Restlet classes.
I managed to implement some code which will execute GET method ( though very slow, it takes about 20-30 seconds to get data from server) but i have problems with PUT method.
I used the following code to implement HTTPS client
private static ClientResource makeInstance(String url, Context con) {
Reference reference = new Reference(url);
Log.d("URL", url);
String keyStoreFileAbsolutePath = PreferenceManager
.getDefaultSharedPreferences(con).getString(
Constants.PREF_KEY_KEYSTORE_FILE_PATH, "");
System.setProperty("javax.net.ssl.trustStore",keyStoreFileAbsolutePath);
System.setProperty("javax.net.ssl.trustStorePassword", "ks090278d");
System.setProperty("ssl.TrustManagerFactory.algorithm",
javax.net.ssl.KeyManagerFactory.getDefaultAlgorithm());
org.restlet.Context context = new org.restlet.Context();
context.getAttributes().put("hostnameVerifier", new HostnameVerifier() {
#Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
ClientResource resource = new ClientResource(context, reference);
Engine.getInstance().getRegisteredClients().clear();
Engine.getInstance().getRegisteredClients()
.add(new HttpClientHelper(null));
resource.release();
return resource;
}
and I'm using it like this
ClientResource request = new ClientResource(url);
request.setRetryAttempts(0);
Series<Header> responseHeaders = (Series<Header>) request.getResponse()
.getAttributes().get("org.restlet.http.headers");
if (responseHeaders == null) {
responseHeaders = new Series(Header.class);
request.getRequestAttributes().put("org.restlet.http.headers",
responseHeaders);
}
responseHeaders.add(new Header("Accept", "application/json;"));
responseHeaders.add(new Header("Content-Type", "application/json;"));
responseHeaders.add(new Header("Authorization",
"Basic ZXN0dWRlbnQ6YW5kcm9pZA==;"));
try {
request.put(new JsonRepresentation(jsonString));
Response response = request.getResponse();
if (response != null) {
Log.d("Response", "HTTP Response: " + response.toString());
ResponseHandler
.handleResponse(response);
}
} catch (Exception e) {
}
When I execute this request I'm getting "Internal server error - 500". I'm using basically the same code for GET method only insted of
request.put(new JsonRepresentation(jsonString));
I'm doing
request.get();
and it works (though very slow as I mentioned above).
I checked if this is due to some error with the server but I think is not because I managed to get appropriate response when I'm using code similar to the code from Android Developers and also when I'm trying to execute PUT to the same URL from RestClient in Chrome.
Can anyone give me any suggestions how to get this to work? I'm not sure if my aproach is good to begin with, may be that I'm gooing in the wrong direction from the start.
Thnaks in advance.

Categories

Resources