Android Studio Webservice call "HTTP request failed, HTTP status: 401" Unauthorized - android

i try to connect my Android application to a Webservice.
I wrote a new class and defined some Variables:
I´ve got the Async Class to use the Network
class GetValueTask extends AsyncTask<ApiConnector,Long,String> {
#Override
protected String doInBackground(ApiConnector... params) {
//wird im Background Thread ausgeführt
return params[0].getValue();
}
#Override
protected void onPostExecute(String s) {
//wird im Mainthread ausgeführt
MainActivity.this.setText(s);
}
}
And I have a Class where i want to call the Webservice
public class ApiConnector
{
private static final String SOAP_ACTION ="urn:microsoft-dynamics-schemas/codeunit/AddService:Add";
private static final String METHOD_NAME ="Add";
private static final String NAMESPACE ="urn:microsoft-dynamics-schemas/codeunit/AddService";
private static final String URL ="http://192.168.0.154:9047/DynamicsNAV80/WS/CRONUS%20AG/Codeunit/AddService";
private static final String USERNAME="B.Denger";
private static final String PASSWORD ="TestPW123!";
public String getValue() {
SoapObject request = new SoapObject(NAMESPACE,METHOD_NAME);
request.addProperty("no","10");
PropertyInfo unamePI = new PropertyInfo();
PropertyInfo passPI = new PropertyInfo();
// Set Username
unamePI.setName("username");
// Set Value
unamePI.setValue(USERNAME);
// Set dataType
unamePI.setType(String.class);
// Add the property to request object
request.addProperty(unamePI);
//Set Password
passPI.setName("password");
//Set dataType
passPI.setValue(PASSWORD);
//Set dataType
passPI.setType(String.class);
//Add the property to request object
request.addProperty(passPI);
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
soapEnvelope.setOutputSoapObject(request);
HttpTransportSE aht= new HttpTransportSE(URL);
try {
aht.call(SOAP_ACTION, soapEnvelope);
SoapPrimitive resultString = (SoapPrimitive) soapEnvelope.getResponse();
return resultString.toString();
}catch(Exception e ) {
e.printStackTrace();
return "Fail at Call";
}
}
}
I have set the using-permission in the Manifest file
<uses-permission android:name="android.permission.INTERNET"/>
in my MainActivity do i execute the AsynkTask with a Button
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
GetValueTask getValueTask = new GetValueTask();
getValueTask.execute(new ApiConnector());
}
});
after execution i get following Logcat entry:
W/System.err﹕ org.ksoap2.transport.HttpResponseException: HTTP request failed, HTTP status: 401
i googled a whole Day for it, but i did not solved the problem yet.
is there anybody who could help me, or could give me a hint where i have to search?

I found the solution here:
Android Consuming Dynamics NAV SOAP Web Service
but it didnt Work with the jcif 1.3.17 jar
at https://jcifs.samba.org/src/ can you download the latest version.

In my case I fixed same problem by adding this code:
List<HeaderProperty> llstHeadersProperty = new ArrayList<>();
llstHeadersProperty.add(new HeaderProperty("Authorization", "Basic " + org.kobjects.base64.Base64.encode("user:password".getBytes())));
loHttpTransport.call(sSOAP_ACTION, loEnvelope, llstHeadersProperty);
Complete task:
private class fnAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params)
{
//for linear parameter
SoapObject loRequest = new SoapObject(sNAMESPACE, sMETHOD_NAME);
// adding method property here serially
// loRequest.addProperty("CountryName", "france");
SoapSerializationEnvelope loEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
loEnvelope.implicitTypes = true;
loEnvelope.setOutputSoapObject(loRequest);
loEnvelope.dotNet = true;
HttpTransportSE loHttpTransport = new HttpTransportSE(_sURL);
loHttpTransport.debug = true;
try
{
List<HeaderProperty> llstHeadersProperty = new ArrayList<>();
llstHeadersProperty.add(new HeaderProperty("Authorization", "Basic " + org.kobjects.base64.Base64.encode("user:password".getBytes())));
loHttpTransport.call(sSOAP_ACTION, loEnvelope, llstHeadersProperty);
}
catch (HttpResponseException e)
{
// TODO Auto-generated catch block
Log.e("HTTPLOG", e.getMessage());
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("IOLOG", e.getMessage());
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
Log.e("XMLLOG", e.getMessage());
e.printStackTrace();
} //send request
Object result = null;
try {
result = (Object )loEnvelope.getResponse();
//See output in the console
Log.i("RESPONSE",String.valueOf(result));
} catch (SoapFault e) {
// TODO Auto-generated catch block
Log.e("SOAPLOG", e.getMessage());
e.printStackTrace();
}
return null;
}
}
Full example
http://www.nascenia.com/consuming-soap-web-services-from-android/

Related

android - connect to web service

I'm try to connect android application to a web service uploaded on somee.
I have the following problem :
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo: java.lang.NullPointerException
the web service code :
[WebService(Namespace = "http://www.n-m.somee.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class WebService1 : System.Web.Services.WebService
{
SqlConnection con = new SqlConnection(#"workstation id=WSDatabase.mssql.somee.com;packet size=4096;user id=***;pwd=***;data source=WSDatabase.mssql.somee.com;persist security info=False;initial catalog=WSDatabase ");
[WebMethod]
public string get_name(String pssw)
{
con.Open();
SqlCommand cmd = new SqlCommand("select username from users where pssw="+pssw, con);
string rd =(string) cmd.ExecuteScalar();
con.Close();
return rd;
}
}
I added the following line to manifest file:
** MainActivity.java file**
public class MainActivity extends AppCompatActivity {
protected String namespace="http://www.n-m.somee.com/";
protected String url="http://www.n-m.somee.com/WebService1.asmx";
protected String SOAPAction="http://www.n-m.somee.com/get_name";
protected String method_name= "get_name";
TextView user_name;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
public void goButton(View v)
{
user_name=(TextView)findViewById(R.id.textView1);
//allow internet
if(Build.VERSION.SDK_INT>9)
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
//create soap object
SoapObject soapObject=new SoapObject(namespace,method_name);
soapObject.addProperty("pssw", "1234");
//create envelop
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(soapObject);
//Rrquest get data from webservice and set it into soapobject
HttpTransportSE transport = new HttpTransportSE(url);
try {
transport.call(SOAPAction, envelope);
// get data
SoapPrimitive output=(SoapPrimitive) envelope.getResponse();
//set data into control
user_name.setText("pssw: "+output.toString());
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
}
}
I appreciate any help
thank you
Your urls were a bit wrong. This is what I used,
protected String namespace = "http://www.nourhan-m.somee.com/";
protected String url = "http://www.nourhan-m.somee.com/WebService1.asmx";
protected String SOAPAction = "http://www.nourhan-m.somee.com/get_name";
protected String method_name = "get_name";
I made some modification to your code to make it work.
public String callService(String username) {
//create soap object and add params to it
SoapObject request = new SoapObject(namespace, method_name);
request.addProperty("pssw", username);
//create envelop
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
//set request to envelope
envelope.bodyOut = request;
HttpTransportSE transport = new HttpTransportSE(url);
transport.debug = true;
try {
transport.call(SOAPAction, envelope);
Log.e("OUT", transport.requestDump);
return transport.responseDump;
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
return "";
}
This is how I invoked the method,
You can invoke it as follows,
final String username = (TextView) findViewById(R.id.textView1)
new Thread(new Runnable() {
#Override
public void run() {
Log.e("OUT", callService(username));
}
}).start();
I got an empty response, maybe it's because I didn't give a valid username. Have a look at it. Cheers :)

Getting error in Android using kSOAP2

Error I am getting is this
org.ksoap2.SoapFault cannot be cast to org.ksoap2.serialization.SoapObject
public final static String URL = "http://23.253.164.20:8096/login.asmx";
public static final String NAMESPACE = "http://23.253.164.20:8096";
public static final String SOAP_ACTION_PREFIX = "http://23.253.164.20:8096/getName";
private static final String METHOD = "getName";
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
private String resp;
#Override
protected String doInBackground(String... params) {
publishProgress("Loading contents..."); // Calls onProgressUpdate()
try {
// SoapEnvelop.VER11 is SOAP Version 1.1 constant
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
SoapObject request = new SoapObject(NAMESPACE, METHOD);
//bodyOut is the body object to be sent out with this envelope
envelope.bodyOut = request;
HttpTransportSE transport = new HttpTransportSE(URL);
try {
transport.call(NAMESPACE + SOAP_ACTION_PREFIX + METHOD, envelope);
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
//bodyIn is the body object received with this envelope
if (envelope.bodyIn != null) {
//getProperty() Returns a specific property at a certain index.
SoapPrimitive resultSOAP = (SoapPrimitive) ((SoapObject) envelope.bodyIn)
.getProperty(0);
resp=resultSOAP.toString();
}
} catch (Exception e) {
e.printStackTrace();
resp = e.getMessage();
}
return resp;
}
/**
*
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
// In this example it is the return value from the web service
textView.setText(result);
}
Possibility checked
1) Internet permission given
2) Ksoap2 library imported
3) server side method is running (you can the URL)
4) Not running on the emulator instead on the mobile phone
You have some bugs in whole code.
there is no method "getName" - it looks like You meant "getGreetingForName" but i'm not sure becouse You have'nt provided param "stringName",
NAMESPACE = "http://23.253.164.20:8096/"; - add slash on the end,
transport.call(NAMESPACE + SOAP_ACTION_PREFIX + METHOD, envelope);
that is not proper - becouse method called here is "http://23.253.164.20:8096http://23.253.164.20:8096/getNamegetName"
see also my answer to Your second posting - there is working code of login:
getting parameter error in ksoap 2 android
Regards,
Marcin

How can i check the return value from web service using asynctask

What i have is an asynctask that i use it to send data to web service which work just fine , and here is my web service code :
public class WebServiceDetails {
//Namespace of the Webservice - can be found in WSDL
private static String NAMESPACE = "http://tempuri.org/";
//Webservice URL - WSDL File location
//URL = "http://80.90.161.246:70/erP_Reporting/OrderAndroid.asmx";
private static String URL = "http://192.168.1.124/alibabanewwebservice/AliBabaWebService.asmx";//Make sure you changed IP address
//private static String URL = "http://192.168.1.103/webservicejal6ah/OrderAndroid.asmx";//Make sure you changed IP address
//SOAP Action URI again Namespace + Web method name
private static String SOAP_ACTION = "http://tempuri.org/InsertOrderDetails";
public static boolean invokeLoginWS(String DeviceId, String Item_id, String Item_Quantity,String Bounce,String webMethName)
{
boolean loginStatus = false;
// Create request
SoapObject request = new SoapObject(NAMESPACE, webMethName);
// Property which holds input parameters
PropertyInfo deviceid = new PropertyInfo();
PropertyInfo itemid = new PropertyInfo();
PropertyInfo quantity = new PropertyInfo();
PropertyInfo bounce= new PropertyInfo();
deviceid.setName("DeviceId");
deviceid.setValue(DeviceId);
deviceid.setType(String.class);
request.addProperty(deviceid);
itemid.setName("Item_id");
itemid.setValue(Item_id);
itemid.setType(String.class);
request.addProperty(itemid);
quantity.setName("Item_Quantity");
quantity.setValue(Item_Quantity);
quantity.setType(String.class);
request.addProperty(quantity);
bounce.setName("Bounce");
bounce.setValue(Bounce);
bounce.setType(String.class);
request.addProperty(bounce);
// extra.setName("Extra");
// extra.setValue(Extra);
// extra.setType(String.class);
// request.addProperty(extra);
// Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(1);
envelope.dotNet = true;
// Set output SOAP object
envelope.setOutputSoapObject(request);
// Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
// Invoke web service
androidHttpTransport.call(SOAP_ACTION, envelope);
// Get the response
// SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
Object response = (Object) envelope.getResponse();
// Assign it to boolean variable variable
loginStatus = Boolean.parseBoolean(response.toString());
} catch (Exception e) {
//Assign Error Status true in static variable 'errored'
e.printStackTrace();
}
//Return booleam to calling object
return loginStatus;
}
}
And here is my asynctask :
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.e("Customer_Name","sereen");
//Make Progress Bar invisible
//AddToCart.cartlist.clear();
try{
//Log.e(" Customer_Id=masterrs.get(m).getCustomerId()", rs.get(m).getCustomerId());
Toast.makeText(CartList.this, "order has been send ", Toast.LENGTH_LONG).show();
}
catch(Exception e){
e.printStackTrace();
}
}
//Make Progress Bar visible
protected void onPreExecute() {
super.onPreExecute();
pd.setTitle("sending");
pd.setMessage("waiting...");
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
loginStatus2 = WebServiceDetails.invokeLoginWS(Device_ID,Item_Id,Quantity,Bounce,"InsertOrderDetails");
Log.e("Device_ID details",Device_ID+"");
// try{
//Log.e(" Customer_Id=masterrs.get(m).getCustomerId()", rs.get(m).getCustomerId());
// }
// catch(Exception e){
// e.printStackTrace();
// }
//
// }
}
return null;
}
}
well , the problem is as you can see my asynctask return null value and i want it after i send value to return true for (loginStatus2) but the thing is when i tried to do it , it didn't work .. can anyone help me , what shall i change to get the value true when success post on web service and false when it fails?
Try this code for AsyncTask. Use result and check if it is null or not.
If null, there is no response else you can have response in form of result from Asynctask() method.
private class AsyncCallWS extends AsyncTask<Void, Void, String> {
String response;
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result==null){
Toast.makeText(CartList.this, "result is null", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(CartList.this, "Result is: "+ result, Toast.LENGTH_LONG).show();
}
try{ //Your code here
//Log.e(" Customer_Id=masterrs.get(m).getCustomerId()", rs.get(m).getCustomerId());
Toast.makeText(CartList.this, "order has been send ", Toast.LENGTH_LONG).show();
}
catch(Exception e){
e.printStackTrace();
}
}
//Make Progress Bar visible
protected void onPreExecute() {
super.onPreExecute();
pd.setTitle("sending");
pd.setMessage("waiting...");
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
loginStatus2 = WebServiceDetails.invokeLoginWS(Device_ID,Item_Id,Quantity,Bounce,"InsertOrderDetails");
response = loginStatus2;
Log.e("Device_ID details",Device_ID+"");
}
return response;
}
}

SoapObject result of service call is always null

I have implemented my SOAP webservice following the tutorial found on google developers website, and now i'm writing a android app that call an available service and show result (for now in a textview) using ksoap2 libraries.
That's the code:
public class DownloadDataTask extends AsyncTask<Void, Void, SoapObject> {
private static String METHOD_NAME = "getData";
private static String SOAP_ACTION = "http://example.com/getData";
private static String WSDL_URL = "http://arduino-data-server.appspot.com/FunctionsService.wsdl";
private static String NAMESPACE = "http://example.com/";
private MainActivity caller_activity;
public DownloadDataTask(MainActivity a) {
caller_activity = a;
}
#Override
protected SoapObject doInBackground(Void... arg0) {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER12);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(WSDL_URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject result = (SoapObject) envelope.getResponse();
return result;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(SoapObject result) {
TextView tw = (TextView) caller_activity.findViewById(R.id.text_view);
if (result == null) {
tw.setText("NULL");
} else {
tw.setText(result.getName());
}
}
}
but everytime, the result SoapObject it's null. what's wrong? on appengine server log, i can see that android app ask for wsdl file, but no request for service was sent. What's wrong (wsdl file is available ad url write inside my code)?
Ksoap doesn't use wsdl (and so doesn't request it). You should pass service url instead of wsdl url. Service url you can find in wsdl (attribute location of the address element in the service description section).

Handle the result of a AsynTask in an android application

I've an android application.
I need to execute a code on a separate task because it fives me android.os.NetworkOnMainThreadException .
This is my code:
public class AccesoCuentaActivity extends Activity{
public void validacion(View v) throws IOException, XmlPullParserException
{
try {
String usuario=((EditText)findViewById(R.id.etUsu)).getText().toString();
String pass=((EditText)findViewById(R.id.etPass)).getText().toString();
String[] pars = new String[2];
String[] = new String[2];
pars[0] = usuario;
pars[1] = pass;
new ValidacionThread().execute(pars);
Intent intent=new Intent(this, MainActivity.class);
intent.putExtra("idBoton",12);
intent.putExtra("usuario",usu);
startActivityForResult(intent, 0);
} }
Task:
public class ValidacionThread extends AsyncTask<String, Void, Usuario> {
private final String NAMESPACE = "http://webservices.pcp/";
private final String URL = "http://127.0.0.1:8080/webServices/pcpWS?wsdl";
private final String SOAPACTION = "";
private final String METHOD = "ValidarUsuario";
protected Usuario doInBackground(String[] pars) {
String user = pars[0];
String password = pars[1];
SoapObject request = new SoapObject(NAMESPACE, METHOD);
SoapSerializationEnvelope sobre = new SoapSerializationEnvelope(SoapEnvelope.VER11);
sobre.dotNet = false;
request.addProperty("login", user);
request.addProperty("password", password);
sobre.setOutputSoapObject(request);
HttpTransportSE transporte = new HttpTransportSE(URL);
try {
transporte.call(SOAPACTION, sobre);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SoapObject resultado = null;
try {
resultado = (SoapObject)sobre.getResponse();
} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Usuario usu = new Usuario();
usu.IdUsuario= resultado.getProperty(0).toString();
usu.Nombre = resultado.getProperty(1).toString();
usu.Apellidos = resultado.getProperty(2).toString();
usu.Rol = resultado.getProperty(3).toString();
usu.Centro=resultado.getProperty(4).toString();
return usu;
}
protected void onPostExecute(ValidacionThread vt) {
}
}
It gives me two problems:
1) In class AccesoCuentaActivity :
I want to save the variable "usuario" return in ValidationThread.doInBackground(). But how do I do it?
Indeed if I just write: new ValidacionThread().execute(pars); it tells me that the variable "usu" (intent.putExtra("usuario",usu);) has not been initialized
while with code (in main code) Usuario usu = new ValidacionThread().execute(pars); it says type mismatch
2) In doInBackground() line eclipse gives the warning:
Varargs methods should only override or be overridden by other varargs methods unlike ValidacionThread.doInBackground(String[]) and AsyncTask<String,Void,Usuario>.doInBackground(String...)
Since this is Async task you need to create a return way for that data.
I would recomend creating an interface like:
interface{
public void parseData(Usuario data);
}
and implementing it in your activity class.
I would then pass and instance of activity to that async task in constructor.
Then in your ValidationThread:
protected void onPostExecute(Usuario vt) {
activityInstance.parseData(vt);
}
As for the second part change String[] to String..

Categories

Resources