I have an AsyncTask which calls a webservice method and sends the returned data back to the main thread. This task does not affect any UI elements yet throws CalledFromWrongThreadException on the line calling onResultSuccess. I have many other AsyncTask which work in basically the exact same way, changing the called web service method and parameters, etc, but this is the only one that fails. Anyone spot what might be the problem? The AsyncTask looks like:
public static class ClockOff extends AsyncTask<String, Void, Void>
{
public OnAsyncResultClockOff onAsyncResultClockOff;
public void setOnResultListener(OnAsyncResultClockOff onAsyncResultClockOff) {
if(onAsyncResultClockOff != null) {
ResultClockOff = onAsyncResultClockOff;
}
}
private static final String SOAP_ACTION = "http://tempuri.org/ClockOff";
private static final String METHOD_NAME = "ClockOff";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = GlobalFunction.URL;
#Override
protected Void doInBackground(String... strArgs)
{
try
{
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
Request.addProperty("Items", strArgs[0]);
Request.addProperty("ID", strArgs[1]);
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(Request);
HttpTransportSE transport= new HttpTransportSE(URL);
transport.call(SOAP_ACTION, soapEnvelope);
SoapObject result = (SoapObject) soapEnvelope.bodyIn;
String ReturnMessage = ((SoapObject) result.getProperty(0)).getPropertyAsString(0);
String ReturnMessageHeader = ((SoapObject) result.getProperty(0)).getPropertyAsString(1);
String ActionType = ((SoapObject) result.getProperty(0)).getPropertyAsString(2);
String SelectedCompleted = ((SoapObject) result.getProperty(0)).getPropertyAsString(3);
String ClockOffItems = ((SoapObject) result.getProperty(0)).getPropertyAsString(4);
//Exception thrown on the below line
onAsyncResultClockOffItem.onResultSuccess(ReturnMessage, ReturnMessageHeader, ActionType, SelectedCompleted, ClockOffItems);
return null;
}
catch (Exception e)
{
onAsyncResultClockOffItem.onResultFail();
return null;
}
}
}
OnAsyncResultClockOff is simply:
public interface OnAsyncResultClockOff {
public abstract void onResultFail();
public abstract void onResultSuccess(String returnMessage,
String returnMessageHeader, String actionType,
String selectedCompleted, String clockOffItems);
}
And it is called via:
ClockOff co= new ClockOffItem();
co.setOnResultListener(onAsyncResultClockOff);
co.execute(items, ID);
Where onAsyncResultClockOff implements the OnResultFail() and OnResultSuccess methods.
Related
In Android is there a better way than using a single AsyncTask with a parameter to work out which REST endpoint to call?
e.g. I need to call:
www.test.com/api/room/id
www.test.com/api/room/id/booking
AsyncTask is designed for a single doInBackground() method that does a single thing, e.g. call:
www.test.com/api/room/id
I don't want to create multiple AsyncTasks instances, one for each REST endpoint.
The back end would use:
RoomClient = new RoomClient();
roomClient.getID()
roomClient.getBookingForRoom()
In Android it looks like I'd need
class RoomFromId extends AsyncTask
...
call www.test.com/api/room/id
class BookingForRoom extends AsyncTask
..
call www.test.com/api/room/id/booking
What I'd ideally like in the Android app is the idiom of writing a rest client that can call all REST endpoints in the background, without having to do each one in its own AsyncTask. I'd prefer to use what Android has, rather than a 3rd party library.
Create a generic Class extends from AsyncTask that return response in a generic type that extends from YourBaseModel (I called it M)
public class HttpRequest<M extends BaseModel> extends AsyncTask<Object, Integer, M> {
public enum RequestMethod {
GET("GET"), POST("POST");
private final String requestMethod;
RequestMethod(String requestMethod) {
this.requestMethod = requestMethod;
}
public String getValue() {
return requestMethod;
}
}
private Context context = null;
private String url;
private OnResponseCallback onResponseCallback;
private OnFailureCallback onFailureCallback;
private RequestMethod method;
private int statusCode;
private String message;
private Class<M> responseModel;
private Object body = null;
private String token;
private HttpRequest() {
}
#Override
protected M doInBackground(Object... voids) {
try {
HttpURLConnection connection = getHttpConnection();
connection.connect();
int statusCode = connection.getResponseCode();
if (connection.getResponseCode() / 100 != 2) {
this.statusCode = statusCode;
this.message = connection.getResponseMessage();
return JsonParser.getErrorBodyAs(responseModel, statusCode,
message);
}
InputStreamReader streamReader = new
InputStreamReader(connection.getInputStream());
return JsonParser.getErrorBodyAs(responseModel, statusCode,
convertInputStreamToString(streamReader));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private HttpURLConnection getHttpConnection() throws IOException {
URL url = new URL(this.url);
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
connection.setRequestMethod(method.getValue());
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Bearer " + token);
connection.setReadTimeout(30000);
connection.setConnectTimeout(30000);
if (method == RequestMethod.POST) {
connection.setDoInput(true);
connection.setDoOutput(true);
if (body != null) {
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write(new Gson().toJson(body));
writer.flush();
}
}
return connection;
}
#Override
protected void onPostExecute(M m) {
if (m == null) {
if ((message != null && !message.equals("") && statusCode != 0)) {
HttpException httpException = new HttpException(statusCode, message);
onFailureCallback.onFailure(httpException);
} else {
onFailureCallback.onFailure("unknown error");
}
} else {
onResponseCallback.onResponse(m);
}
}
public static String convertInputStreamToString(InputStreamReader inputStreamReader) throws IOException {
if (inputStreamReader == null) {
return "";
}
BufferedReader reader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String inputLine;
String result;
while ((inputLine = reader.readLine()) != null) {
stringBuilder.append(inputLine);
}
reader.close();
inputStreamReader.close();
return stringBuilder.toString();
}
static public class Builder {
HttpRequest t = new HttpRequest();
public Builder setContext(Context context) {
t.context = context;
return this;
}
public Builder setUrl(String url) {
t.url = url;
return this;
}
public Builder setRequestMethod(RequestMethod method) {
t.method = method;
return this;
}
public Builder setBody(Object body) {
t.body = body;
return this;
}
public Builder setToken(String token) {
t.token = token;
return this;
}
public HttpRequest get() {
return t;
}
public HttpRequest run(Class<?> responseTypeClass,
OnResponseCallback onResponseCallback,
OnFailureCallback onFailureCallback) {
t.responseModel = responseTypeClass;
t.onResponseCallback = onResponseCallback;
t.onFailureCallback = onFailureCallback;
t.execute();
return t;
}
public Builder() {
}
}
}
You can use it like this:
HttpRequest.Builder builder = new HttpRequest.Builder();
builder.setContext(context)
.setRequestMethod(HttpRequest.RequestMethod.POST)
.setBody(body)
.setUrl("http://url")
.run(YourResponeModel.class, new OnResponseCallback() {
#Override
public void onResponse(Object response) {
},
new OnFailureCallback() {
#Override
public void onFailure(Object throwable) {
}
});
In the class you create that extends AsyncTask you can create a constructor and pass whatever you want/need.
In this case you can define a class ApiManager that extends AsyncTask and pass a constant that defines the method to call.
In that constructor you can save the variable to your ApiManager object and then check it in the doInBackground method.
So, to call the room/id you could do something like:
new ApiManager(ROOM_FROM_ID).execute(...
And to call the room/id/booking:
new ApiManager(BOOKING_FOR_ROOM).execute(...
And the ApiManager class should be something like:
class ApiManager extends AsyncTask... {
private int method;
public ApiManager(int method) {
this.method = method;
}
...
}
I am trying to consume data from local web service in an android emulator using ksoap2 library, I test the same app with a online webservice http://www.webservicex.net/New/Home/ServiceDetail/17 and It works,
the webService has been made it on Csharp, it has a method to return a column from a DB, call neptuno(spanish adventure works),when execute dont show the data and after a moment show the error message programmed, I change the localhost for my local IP
[WebService(Namespace = "http://testapi.idat/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class Service : System.Web.Services.WebService
{
SqlConnection cn = new SqlConnection("data source=.;initial catalog = neptuno; integrated security=true");
public Service () {
//InitializeComponent();
}
[WebMethod]
public string HelloWorld() {
return "Hello World";
}
[WebMethod]
public DataSet mostrar(){
DataSet ds = new DataSet();
cn.Open();
String sql = "select idProducto from productos";
SqlDataAdapter da = new SqlDataAdapter(sql,cn);
da.Fill(ds);
return ds;
}
}
the service works and return the column IDProduct, the problem is call with the method, I already add the permission on manifest, and the layout is just a textview for error message and edittext multiline for show the data
package com.example.webservice;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
import android.os.AsyncTask;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class MainActivity extends Activity {
EditText resultMultiline;
TextView message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resultMultiline = (EditText)findViewById(R.id.editText1);
message = (TextView) findViewById(R.id.textView);
CallWebservice webservice = new CallWebservice();
webservice.execute();
}
public class CallWebservice extends AsyncTask<Integer,Integer,Boolean>{
String resultText = "";
protected Boolean doInBackground(Integer... params){
boolean result = true;
final String SOAP_ACTION = "http://testapi.idat/mostrar";
final String NAMESPACE = "http://testapi.idat/";
final String METHOD_NAME = "mostrar";
final String URL = "http://192.168.1.45:51582/Webservice/Service.asmx?WSDL";
HttpTransportSE transport = new HttpTransportSE(URL);
SoapObject request = new SoapObject(NAMESPACE,METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
try {
transport.call(SOAP_ACTION,envelope);
SoapPrimitive respSoap = (SoapPrimitive)envelope.getResponse();
resultText = respSoap.toString();
}catch (Exception e){
result = false;
Log.d("Debug", e.getMessage().toString());
}
return result;
}
protected void onPostExecute(Boolean result){
if (result){
resultMultiline.setText(resultText);
Log.d("Debug","Web service works");
}else{
message.setText("ERROR");
}
}
}
}
Use the Following function it is working in my case this is normal Login soap call you need to add internet permission in your menifest
/*
* Vishal Mokal 05-MAR-2015
* soapCALL() function returns String Array.
* Make A sope call and returns response.
* if responce is success full then user will get responce array
* first element status = 1 if syccessfull 0 = if any exception of faliur
* second element = response srtring if successful or error message.
* */
public String[] soapCALL(RequestDetails requestDetails, String wsdlUserName, String wsdlPassword , String headerName) {
String url = requestDetails.getUrl().toString();
String nameSpace = requestDetails.getNameSpace().toString();
String methodName = requestDetails.getMethodName().toString();
String soapAction = requestDetails.getSoapAction().toString();
String[] responses = new String[2];
Element[] header = new Element[1];
// header[0] = new Element().createElement(nameSpace, "AuthenticationHeader");
header[0] = new Element().createElement(nameSpace, headerName);
try {
Element UserName = new Element().createElement(nameSpace, "UserName");
UserName.addChild(Node.TEXT, wsdlUserName);
header[0].addChild(Node.ELEMENT, UserName);
Element Password = new Element().createElement(nameSpace, "Password");
Password.addChild(Node.TEXT, wsdlPassword);
header[0].addChild(Node.ELEMENT, Password);
SoapObject request = requestDetails.getSoapObject();
SoapSerializationEnvelope soapSerilizationEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapSerilizationEnvelope.dotNet = true;
soapSerilizationEnvelope.headerOut = header;
soapSerilizationEnvelope.setOutputSoapObject(request);
Object env = soapSerilizationEnvelope.bodyOut;
HttpTransportSE httptransport = new HttpTransportSE(url);
httptransport.call(soapAction, soapSerilizationEnvelope);
SoapPrimitive response = (SoapPrimitive) soapSerilizationEnvelope.getResponse();
responses[0] = "1";
responses[1] = response.toString();
Log.d("Respons", response.toString());
return responses;
}
catch (SocketTimeoutException e)
{
responses[0] = "0";
responses[1] = "Sorry!Unable To Connect Server Please Check Your Internet Connection Or Try After Some Time.";
return responses;
}
catch (SocketException e)
{
responses[0] = "0";
responses[1] = "Sorry!Unable To Connect Server Please Try After Some Time.";
return responses;
}
catch (Exception e) {
responses[0] = "0";
responses[1] = "Sorry!Unable To Connect Server Please Try After Some Time.";
return responses;
}
}
Following is the structure for the Requestdetail class
public class RequestDetails {
private String nameSpace;
private String url;
private String methodName;
private String SoapAction;
private SoapObject soapObject;
public RequestDetails(String nameSpace, String url, String methodName, String soapAction) {
this.nameSpace = nameSpace;
this.url = url;
this.methodName = methodName;
SoapAction = soapAction;
}
public String getNameSpace() {
return nameSpace;
}
public String getUrl() {
return url;
}
public String getMethodName() {
return methodName;
}
public String getSoapAction() {
return SoapAction;
}
public SoapObject getSoapObject() {
return soapObject;
}
public void setSoapObject(SoapObject soapObject) {
this.soapObject = soapObject;
}
}
I'm trying to simply make objects out of a Twitter stream I download from a user. I am using the information provided from https://github.com/Rockncoder/TwitterTutorial. Can someone help determine if this code actually works? Some of the classes are kind of sketchy, as in the Twitter.java class is just an ArrayList and it only has what's listed below in it.
Is my process correct? Any help is appreciated.
public class MainActivity extends ListActivity {
private ListActivity activity;
final static String ScreenName = "riddlemetombers";
final static String LOG_TAG = "rmt";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activity = this;
downloadTweets();
}
// download twitter timeline after first checking to see if there is a network connection
public void downloadTweets() {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
new DownloadTwitterTask().execute(ScreenName);
} else {
Log.v(LOG_TAG, "No network connection available.");
}
}
// Uses an AsyncTask to download a Twitter user's timeline
private class DownloadTwitterTask extends AsyncTask<String, Void, String> {
final String CONSUMER_KEY = (String) getResources().getString(R.string.api_key);
final String CONSUMER_SECRET = (String)getResources().getString(R.string.api_secret);
final static String TwitterTokenURL = "https://api.twitter.com/oauth2/token";
final static String TwitterStreamURL = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=";
#Override
protected String doInBackground(String... screenNames) {
String result = null;
if (screenNames.length > 0) {
result = getTwitterStream(screenNames[0]);
}
return result;
}
// onPostExecute convert the JSON results into a Twitter object (which is an Array list of tweets
#Override
protected void onPostExecute(String result) {
Twitter twits = jsonToTwitter(result);
// lets write the results to the console as well
for (Tweet tweet : twits) {
Log.i(LOG_TAG, tweet.getText());
}
// send the tweets to the adapter for rendering
ArrayAdapter<Tweet> adapter = new ArrayAdapter<Tweet>(activity, R.layout.items, twits);
setListAdapter(adapter);
}
// converts a string of JSON data into a Twitter object
private Twitter jsonToTwitter(String result) {
Twitter twits = null;
if (result != null && result.length() > 0) {
try {
Gson gson = new Gson();
twits = gson.fromJson(result, Twitter.class);
if(twits==null){Log.d(LOG_TAG, "Twits null");}
else if(twits!=null) {Log.d(LOG_TAG, "Twits NOT null");}
} catch (IllegalStateException ex) {
// just eat the exception
}
}
return twits;
}
// convert a JSON authentication object into an Authenticated object
private Authenticated jsonToAuthenticated(String rawAuthorization) {
Authenticated auth = null;
if (rawAuthorization != null && rawAuthorization.length() > 0) {
try {
Gson gson = new Gson();
auth = gson.fromJson(rawAuthorization, Authenticated.class);
} catch (IllegalStateException ex) {
// just eat the exception
}
}
return auth;
}
private String getResponseBody(HttpRequestBase request) {
StringBuilder sb = new StringBuilder();
try {
DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams());
HttpResponse response = httpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
String reason = response.getStatusLine().getReasonPhrase();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
String line = null;
while ((line = bReader.readLine()) != null) {
sb.append(line);
}
} else {
sb.append(reason);
}
} catch (UnsupportedEncodingException ex) {
} catch (ClientProtocolException ex1) {
} catch (IOException ex2) {
}
return sb.toString();
}
private String getTwitterStream(String screenName) {
String results = null;
// Step 1: Encode consumer key and secret
try {
// URL encode the consumer key and secret
String urlApiKey = URLEncoder.encode(CONSUMER_KEY, "UTF-8");
String urlApiSecret = URLEncoder.encode(CONSUMER_SECRET, "UTF-8");
// Concatenate the encoded consumer key, a colon character, and the
// encoded consumer secret
String combined = urlApiKey + ":" + urlApiSecret;
// Base64 encode the string
String base64Encoded = Base64.encodeToString(combined.getBytes(), Base64.NO_WRAP);
// Step 2: Obtain a bearer token
HttpPost httpPost = new HttpPost(TwitterTokenURL);
httpPost.setHeader("Authorization", "Basic " + base64Encoded);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
httpPost.setEntity(new StringEntity("grant_type=client_credentials"));
String rawAuthorization = getResponseBody(httpPost);
Authenticated auth = jsonToAuthenticated(rawAuthorization);
// Applications should verify that the value associated with the
// token_type key of the returned object is bearer
if (auth != null && auth.token_type.equals("bearer")) {
// Step 3: Authenticate API requests with bearer token
HttpGet httpGet = new HttpGet(TwitterStreamURL + screenName);
// construct a normal HTTPS request and include an Authorization
// header with the value of Bearer <>
httpGet.setHeader("Authorization", "Bearer " + auth.access_token);
httpGet.setHeader("Content-Type", "application/json");
// update the results with the body of the response
results = getResponseBody(httpGet);
}
} catch (UnsupportedEncodingException ex) {
} catch (IllegalStateException ex1) {
}
return results;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
TWITTER CLASS
import java.util.ArrayList;
// a collection of tweets
public class Twitter extends ArrayList<Tweet> {
private static final long serialVersionUID = 1L;
}
TWEET CLASS
import com.google.gson.annotations.SerializedName;
public class Tweet {
#SerializedName("created_at")
private String DateCreated;
#SerializedName("id")
private String Id;
#SerializedName("text")
private String Text;
#SerializedName("in_reply_to_status_id")
private String InReplyToStatusId;
#SerializedName("in_reply_to_user_id")
private String InReplyToUserId;
#SerializedName("in_reply_to_screen_name")
private String InReplyToScreenName;
#SerializedName("user")
private TwitterUser User;
public String getDateCreated() {
return DateCreated;
}
public String getId() {
return Id;
}
public String getInReplyToScreenName() {
return InReplyToScreenName;
}
public String getInReplyToStatusId() {
return InReplyToStatusId;
}
public String getInReplyToUserId() {
return InReplyToUserId;
}
public String getText() {
return Text;
}
public void setDateCreated(String dateCreated) {
DateCreated = dateCreated;
}
public void setId(String id) {
Id = id;
}
public void setInReplyToScreenName(String inReplyToScreenName) {
InReplyToScreenName = inReplyToScreenName;
}
public void setInReplyToStatusId(String inReplyToStatusId) {
InReplyToStatusId = inReplyToStatusId;
}
public void setInReplyToUserId(String inReplyToUserId) {
InReplyToUserId = inReplyToUserId;
}
public void setText(String text) {
Text = text;
}
public void setUser(TwitterUser user) {
User = user;
}
public TwitterUser getUser() {
return User;
}
#Override
public String toString(){
return getText();
}
}
I've done several Log.d(LOG_TAG, Stuff) to see if I'm getting stuff, and it indicates I'm getting some kind of content back. Maybe the problem is in making objects of the data.
Not sure why you want to use the code from https://github.com/Rockncoder/TwitterTutorial.
Why don't use use http://twitter4j.org. They have give sample example to use it.
Moreover it support Twitter 1.1 as well. Just include twitter-core.jar and you are ready write your code.
Hope it helps.
I have written custom soaphandler class which extends javax.xml.rpc.GenericHandler. And my requirement is to pass a primitive variable into this handler class from my other caller java class. This variable should pass at run time and should be thread safe because multiple thread is going to access that handler same time.
I tried to store the value into HandlerConfig object and injected it to the HandlerInfo, but I couldn't found this value in my handler.
This Soap Handler concept is new for me, so please help me to fix this issue.
below I'm posting my raw code for handler class and the class from where I'm calling it.
public class MilerHandler extends GenericHandler {
private HandlerInfo info;
private static final String AUTHORIZATION = "Authorization";
private static final String DATE = "Date";
private static final String URI = "http://-----.com";
public MilerHandler() {
}
public void init(HandlerInfo info) {
this.info = info;
}
public QName[] getHeaders() {
return info.getHeaders();
}
public boolean handleRequest(MessageContext context) {
SOAPMessageContext smc = (SOAPMessageContext)context;
SOAPMessage message = smc.getMessage();
try {
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPFactory factory = SOAPFactory.newInstance();
SOAPElement authorization = factory.createElement(AUTHORIZATION, PCMilerClientService.PREFIX, URI);
SOAPElement date = factory.createElement(DATE, PCMilerClientService.PREFIX, URI);
authorization.addTextNode((String)value1); //Value1 need to be pass from my business class.
date.addTextNode((int)value2); //Value2 need to be pass from my business class.
SOAPElement authHeader = factory.createElement(PCMilerClientService.AUTH_HEADER, PCMilerClientService.PREFIX, URI);
authHeader.addChildElement(authorization);
authHeader.addChildElement(date);
SOAPHeader header = envelope.getHeader();
header.addChildElement(authHeader);
message.saveChanges();
if(log.debug()) {
log.debug(message);
}
}
catch (Exception ex) {
log.error(ex);
}
return true;
}
public boolean handleResponse(javax.xml.rpc.handler.MessageContext context) {
SOAPMessageContext smc = (SOAPMessageContext)context;
SOAPMessage message = smc.getMessage();
if(log.debug()) {
log.debug(message);
}
return true;
}
public boolean handleFault(javax.xml.rpc.handler.MessageContext context) {
SOAPMessageContext smc = (SOAPMessageContext)context;
SOAPMessage message = smc.getMessage();
if(log.debug()) {
log.debug(message);
}
return true;
}
}
public class MilerDistanceLookupWorker {
public void run() {
IService_Stub stub = null;
Service_Impl impl = null;
try {
impl = new Service_Impl();
setPCMilerHandler(impl);
stub = (IService_Stub) impl.getBasicHttpBinding_IService();
} catch (ServiceException e) {
-----------------
}
}
private void setMilerHandler(Service_Impl impl) {
HandlerInfo handlerInfo = new HandlerInfo();
handlerInfo.setHandlerClass(MilerHandler.class);
QName authHeader = new QName(NAMESPACE, AUTH_HEADER, PREFIX);
List<HandlerInfo> headerList = impl.getHandlerRegistry().getHandlerChain(authHeader);
headerList.add(handlerInfo);
impl.getHandlerRegistry().setHandlerChain(authHeader, headerList);
}
}
If you are trying to implement SOAP auth handler then you need to do something like this:
public class SOAPAuthenticationHandler implements SOAPHandler<SOAPMessageContext> {
private String username;
private String password;
public SOAPAuthenticationHandler (String username, String password) {
this.username = username;
this.password = password;
}
#Override
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!outboundProperty) {
return outboundProperty;
}
try {
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
security.addNamespaceDeclaration("common", "some xmlns");
SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement usernameElement = usernameToken.addChildElement("Username", "wsse");
usernameElement.addTextNode(username);
SOAPElement passwordElement = usernameToken.addChildElement("PasswordSaltedDigest", "common");
passwordElement.setAttribute("Type", "http://www.w3.org/2001/04/xmldsig-more#gostr341194");
passwordElement.addTextNode(password);
} catch (SOAPException | DOMException e) {
getLogger().error(e.getMessage());
}
return outboundProperty;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
return false;
}
#Override
public void close(MessageContext context) {
}
#Override
public Set<QName> getHeaders() {
return null;
}
}
And after that you need to add this handler to port' HandlerChain:
List handlerChain = ((BindingProvider) port).getBinding().getHandlerChain();
if (handlerChain == null) {
handlerChain = new ArrayList();
}
handlerChain.add(new SOAPAuthenticationHandler(username, password));
((BindingProvider) port).getBinding().setHandlerChain(handlerChain);
I have a class that controls my http communications, as well as keeps track of the http session. The problem i'm running into is, i would like to use this class from several activities.
The only option i have found so far is making it static in the main view, but if the app sits to long in a secondary view, the static class becomes null.
I have also tried making it parcelable, but i can't pass my CookieStore or my httpContext. This means every time I go into a view, or out of a view, i have to re-authenticate against the server, causing much unnecessary traffic.
How can i pass an object via Parcelable, or is there another type of class extension that would allow me to create a persistent class that all Activity's can view?
public class JSON implements Parcelable {
private String URL;
private String HOSTNAME;
private Context f_context;
private DefaultHttpClient httpClient;
private CookieStore cookieStore;
private HttpContext httpContext;
protected boolean Authenticated = false;
protected long Authenticate_timeout = 0;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
Bundle b = new Bundle();
b.putString("URL",URL);
b.putString("HOSTNAME", HOSTNAME);
b.putBoolean("Authenticated", Authenticated);
b.putLong("Authenticate_timeout", Authenticate_timeout);
out.writeBundle(b);
Object[] o = new Object[4];
o[0] = httpClient;
o[1] = cookieStore;
o[2] = httpContext;
o[3] = f_context;
out.writeArray(o);
}
public static final Parcelable.Creator<JSON> CREATOR = new Parcelable.Creator<JSON>() {
public JSON createFromParcel(Parcel in) {
return new JSON(in);
}
public JSON[] newArray(int size) {
return new JSON[size];
}
};
private JSON(Parcel in) {
Object[] o = in.readArray(null);
httpClient = (DefaultHttpClient) o[0];
cookieStore = (CookieStore) o[1];
httpContext = (HttpContext) o[2];
f_context = (Context) o[3];
Bundle b = in.readBundle();
URL = b.getString("URL");
HOSTNAME = b.getString("HOSTNAME");
Authenticated = b.getBoolean("Authenticated");
Authenticate_timeout = b.getLong("Authenticate_timeout");
}
public JSON(Context context) {
f_context = context;
updateSettings();
HttpParams myParams = new BasicHttpParams();
HttpConnectionParams
.setConnectionTimeout(myParams, Consts.http_timeout);
HttpConnectionParams.setSoTimeout(myParams, Consts.http_timeout);
httpClient = new DefaultHttpClient(myParams);
cookieStore = new BasicCookieStore();
httpContext = new BasicHttpContext();
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
}