Binding nested complex objects with KSOAP2 Android - ksoap2

I'm trying to bind a XML response from a WS to a set of POJO's classes using ksoap2-android.
A lot of examples on the internet treat very simple responses like this one.
In my case however, I have a lot of custom classes and they keep a reference of each other, sometimes even inside an arraylist.
Here's what i'm trying to do, i would like to bind this kind of response :
<Car number="35">
<Engine>
[...]
</Engine>
<Passenger id="1">
[...]
</Passenger>
<Passenger id="2">
[...]
</Passenger>
</Car>
To this kind of class :
public class Car {
private int number;
private Engine engine;
private ArrayList<Passenger> passengers;
}
With, if possible, only modifying POJOs files (the Simple XML annotations system is very elegant, too bad there's no equivalent to this in ksoap).
I looked into the KVMSerializable interface, but when I try to override the getPropertyInfo() method, I have no idea of what I should return in the PropertyInfo.type and how will ksoap handle ArrayLists.
I got a huge headache right now, please help me

Please go to the below URL and read it.
http://www.c-sharpcorner.com/UploadFile/88b6e5/how-to-call-web-service-in-android-using-soap/
Thanks
Ashok Parmar
Traction Software Co.

You should read the document from ksoap 2, they have many useful examples in there.
For getting an array of complex type, you can check here
And I have used this approach to parse a complex object.
If all of them not work, you have to map field by field from soap object to your pojo.
Updated:
Thanks a lot for the 3rd link, it's very useful and I'm now able to
map custom objects. However, in the wiki page you provided, the author
is parsing an array of custom classes, wrapped in a parent element. Is
there a way to do this with inline lists like in my example ?
I have never tried it before, but I think you can combine my answer and the wiki.
First, you can try an example from wiki to implement your passengers list (extends Vector). Then you can use my approach to create a complex object with arraylist inside. The important thing is you must register your object with the response from web service. Something like this:
public class PassengerVector extends Vector<Passenger> implements KvmSerializable {
}
envelope.addMapping(NAMESPACE, "Car", Car.class);
envelope.addMapping(NAMESPACE, "Passenger", PassengerVector.class);
But I'm not sure this way can work. For a very complex object like your example, I recommend you should get data field by field by its name, as like the wiki

Related

Get classes that have fields annotated with Redstone's #Field()

I have some Dart classes in my project where I annotate some fields with Redstone Mapper's #Field() annotation.
How can I get all these classes at runtime?
I've seen the private Map _cache in redstone_mapper_factory... but it's private.
I'm aware of that I can use the Reflection package to scan these classes myself, however all of them are already being detected and stored by the Redstone mapper so I'd like to leverage that.
You can use dart:mirror to do that.
But I don't think it's possible to get that by redstone, you should probably ask on github, even do the change yourself if you want and do a pull request, it should not be difficult, it is just a getter on _cache.
https://github.com/redstone-dart/redstone_mapper

How can I add a named property that is not part of the message template?

In some cases, I would like to add contextual information to a message (for instance currently authenticated user), without having to include it in the message template.
I would like to accomplish this :
logger.Information("Doing stuff {Foo} with the thing {Bar}. {User}", foo, bar, user)
but without the {User} in the template.
I already know about LogContext but that seems overkill when adding contextual information to just one event.
I also know I can use the low-level API logger.Write(LogEvent evnt) to actually control which properties are included, but that seems like a bit too much code for what I am trying to accomplish.
I'm pretty sure there is a short and elegant way that is super obvious, but I haven't found it :)
UPDATE :
I found out only afterwards that this question is more or less similar : Add custom properties to Serilog
I could figure it out on my own!
You can use the fluent method .ForContext(propertyName, propertyValue) on a single call to one of the .LogXXX() methods.
For instance :
logger.ForContext("User", user)
.Information("Doing stuff {Foo} with the thing {Bar}", foo, bar)
The property added to the event only apply to the event, and they are no longer present on the next call to the logger.LogXXX() method
UPDATE
The article by Nicholas Blumhardt explains it quite well : Context and correlation – structured logging concepts in .NET (5)
If you're using the generic Microsoft ILogger you can use BeginScope;
using (_logger.BeginScope(new Dictionary<string, object> { { "LogEventType", logEventType }, { "UserName", userName } }))
{
_logger.LogInformation(message, args);
}
This is discussed here; https://blog.rsuter.com/logging-with-ilogger-recommendations-and-best-practices/

How to have structuremap build instance based on type

Ok so this might not be the best title but I am struggling with how to title this. Here is what I have thus far:
I currently have data mappers for my objects. I define them in a registry like so. This allows me to get the type name of the object and combine that with the word Mapper and request it. Here is the code I am using:
this.For<ICategoryMapper>()
.Use<CategoryMapper>()
.Named("CategoryMapper");
But now I am having a problem getting the instance from StructureMap in a form that I can use. Because I can't request it like normal with code like this:
ObjectFactory.GetNamedInstance<T>(namedInstance);
The reason being that I don't really know the type. I just know that it should be DomainType name plus the word mapper. There is probably a better way to achieve this but I am at a lost at what to do.
Any input into a better way to achieve this or fix the problem I am having would be great.
Do you need to use named instances, or was that just an attempt to get it to work?
One approach you could do is add a marker interface that declares the DomainType a mapper works with. For example:
public class PersonMapper : ICategoryMapper, ICategoryMapper<Person>{
}
Register the mappers with the container:
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.TheCallingAssembly();
scan.ConnectImplementationsToTypesClosing(typeof (ICategoryMapper<>));
scan.AddAllTypesOf<ICategoryMapper>();
});
});
You can then retrieve the mapper for your a DomainType (Person, for example):
ObjectFactory.ForGenericType(typeof(ICategoryMapper<>))
.WithParameters(typeof(Person))
.GetInstanceAs<ICategoryMapper>();

Grails internals : Auto mapping and Domain object creation

I am trying to make a taglib to represent an object (to read and display at the UI). When creating an object (save method in the controller), I see the domain class and association are created by the auto assignment of parameter
def Book = new Book(params)
It also maps complex types (for eg: joda time). I wonder about the naming convention necessary to facilitate this mapping. Out of curiosity, can someone also point where in the grails source code I could see how grails handles this mapping. I'm still learning Spring and probably this would be a good exercise.
Thanks,
Babu.
AFAIK the naming conventions are rather straightforward. If there's a field params.foo and the object you are binding to has a field foo, it will bind the value, assuming the type conversion works properly. If there's a params.bar.id set with an Long value and your object has a complex property of type Bar, it will lookup this instance and inject it.
If you need more control over the binding process, you might want to use bindData.
If you are interested into the details of the binding process, have a look at Java's PropertyEditor as this is what is being used in the background. I wrote a blog post on how to create and register PropertyEditors a while ago, maybe it helps you getting started with that stuff.

Guice: Varying the type injected according to how the owner has been injected

I have a guice based app that now needs multiple instances of a given type so I plan on using a named annotation to disambiguate the dependencies. However a dependency of this type also needs to vary based on which one I get.
To illustrate lets say I have
#Singleton
public class FooCache {
private final FooCacheListener listener;
#Inject
public FooCache(FooCacheListener listener) {
this.listener = listener;
}
// do stuff
}
and then lets say I have a need for 2 separate instances so I might have
#ThatOne FooCache
in one class and
#ThisOne FooCache
in another.
Now lets say I want a different listener in each case (maybe one writes something to a database and the other sends a notification over JMS or to some distributed cache). How would I do that? I can't see that I can stick a name on the FooCacheListener as I'd need a different name in one situation vs the other whereas I have just one place here. The only way I can think of doing this is by subclassing FooCache but that seems a really clumsy approach to me.
Cheers
Matt
You might be able to use PrivateModules. Go here and scroll down to How do I build two similar but slightly different trees of objects? It is a way to have two different instances of the same class,which sounds almost exactly what you are trying to do. You could pass in your cachelisteners instead of the "lefty" and "righty" passed in in the example.
There are more links with details from there if it looks like what you want.
Another option might be to inject a factory, which is also discussed in the link above, in the question How do I pass a parameter when creating an object via Guice?

Resources