i'm using the Restlet library for a WS server and i've recently switched from XStream/Jettison to Jackson as a JSON serializer/deserializer because of some issues.
A first drawback is that my ArrayList< Profile > (previously a Vector with Jettison) it doesn't wrap the list of Profiles when serialized and the JSON instead of "Profile:[{firstProfile}, {secondProfile}]" it looks like: [{firstProfile}, {secondProfile}]
I can overcome to this issue in the client telling manually which is the correct mapping but i would prefer to use a KVC approach.
I've looked around and it seems that it's a known issue: http://wiki.fasterxml.com/JacksonPolymorphicDeserialization (5.1 Missing type information on Serialization) that it suggest to:
Use arrays instead of Lists
Sub-class list, using class MyPojoList extends ArrayList { }
Force use of specific root type
the simplest way it should be to return an "Profile[] profile" array but it seems not working, before trying the other solutions i've rechecked around and it seems that you can use a #XmlRootElement(name = "Profile") to wrap the JSON root element: http://jira.codehaus.org/browse/JACKSON-163?focusedCommentId=213588&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-213588
so for using JAXB annotations with Jackson you need to configure the objectMapper: http://wiki.fasterxml.com/JacksonJAXBAnnotations
but in restlet to do so you need to override createObjectMapper to pass a Custom converter (see: http://restlet-discuss.1400322.n2.nabble.com/Set-custom-objectMapper-to-Jackson-Extension-td6287812.html and http://restlet-discuss.1400322.n2.nabble.com/Jackson-Mix-in-Annotations-td6211060.html#a6231831)
this is what i'm trying now! the question is there a more straightforward way to achieve this??
Thanks!!
the solution for me is to annotate the Profile class with:
#JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT)
public class Profile extends Element implements Serializable {
and now the json now looks like:
{"Profile":{ ... }}
and the return type is a Sub-classed list:
public class ProfileList extends ArrayList<Profile>
{}
see http://wiki.fasterxml.com/JacksonPolymorphicDeserialization 5.1
I think what you want is not really available in a sense that JAX-B seems to have some rules on how to deal with lists. See this converstation on the RESTeasy mailing list
Related
Using LifeRay portal and ElasticSearch, Serializing custom object composed from ServiceModel Objects, Serialisation goes fine:
public String toJSON(){
return JSONFactoryUtil.looseSerializeDeep(this);
}
I index this into ES which is also fine, it contains list of those objects as well as single object, no problem.
When I Deserialize this I get this Error:
10:10:53,972 ERROR [ExceptionHandlerBridgeImpl:78] jodd.json.JsonException: Default ctor not found for: eu.project.drives.platform.model.model.TainingProvider
For each parameter which is Object from Service Model.
Code (should be ok as well, example for one field):
JSONObject obj = JSONFactoryUtil.createJSONObject(h.getSourceAsString());
TainingProvider t = JSONFactoryUtil.looseDeserialize(obj.getString("provider"), TainingProvider.class);
I cannot simply induce the Default constructor since it is generated by service builder nor I can do the "TainingProviderImpl.class" since it is different project but the Impl class should be what is called through the "TainingProvider.class" and it includes the default constructor.
Thank you.
The provided type when doing a deserialize is an interface in your example, so the internal Parser (here Jodd) might not find an implementation class to use as a bean class.
I did not find a nice solution, but used the internal Jodd parser directly.
When you subclass jodd.json.JsonParser you can overwrite the protected method for instantiation.
#Override
protected Object newObjectInstance(Class targetType) {
if (targetType.isAssignableFrom(TainingProvider.class)) {
return TainingProviderLocalServiceUtil.createTainingProvider(0L);
}
return super.newObjectInstance(targetType);
}
Now you can use the parser directly via parser.parse(obj.getString("provider"), TainingProvider.class)
I am not sure if it possible to hook in this instantiation hints to Liferays JSONFactoryUtil, which would be nicer instead of having a direct dependency to the jodd Parser in your module.
I have a few model classes that extend LinkedHashMap<String, Object>: they define getters and setters which wrap the Map's get and put methods. I am trying to serialize instances of these classes using Jackson (with RESTEasy), but Jackson refuses to pay attention to my getters, which are annotated with #JsonProperty. Instead, it is only serializing the key-value pairs of the backing map. I tried using #JsonAutoDetect to disable auto-detection for all methods and fields, but that didn't change anything. Is there a way to prevent Jackson from automatically serializing a Map, or must I create new model classes that don't extend LinkedHashMap<String, Object>?
I agree with #skaffman's response. But if you could not easily change inheritance structure drastically, there may be ways around this.
One possibility is that if you do have an interface that defines getters/setters, you could add
#JsonSerialize(as=MyInterface.class)
#JsonDeserialize(as=MyInterface.class)
which would force Jackson to only use whatever is available via specific interface.
Custom serializers/deserializers are also a possibility, but that's quite a bit of work.
I have a few model classes that extend LinkedHashMap<String, Object>: they define getters and setters which wrap the Map's get and put methods
This is a classic example of when not to use inheritance: you're finding that some other piece of code (i.e. Jackson) is treating your class like an instance of its superclass, which isn't what you want it to do. In cases like these (and also in general), it's usually better to use composition rather than inheritance.
I recommend rewriting your model class to contain a map, rather than extending one. You get much more control than way, and the resulting model is less brittle. If you need to view your model as a Map, then implement an asMap method (or something similar) which renders that view.
You can implement your own org.codehaus.jackson.map.DeserializerProvider which extends Jackson's org.codehaus.jackson.map.deser.StdDeserializerProvider and overwrite method _createDeserializer:
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.deser.StdDeserializerProvider;
import org.codehaus.jackson.map.DeserializationConfig;
...
class MyDeserializerProvider extends StdDeserializerProvider {
#Override
protected JsonDeserializer<Object> _createDeserializer(DeserializationConfig config, JavaType type, BeanProperty property) throws JsonMappingException {
if (type.isMapLikeType()) { // (1)
return this._factory.createBeanDeserializer(config, this, type, property);
} else {
return super._createDeserializer(config, type, property);
}
}
}
(1) use if-condition that meets your needs
The custom deserializer is registered directly at the ObjectMapper:
ObjectMapper om = new ObjectMapper();
om.setDeserializerProvider(new MyDeserializerProvider());
I tested this with Jackson 1.9.11.
In newer versions of jackson (>= 2.9, I guess) simply annotate your class with
#JsonFormat(shape = JsonFormat.Shape.OBJECT)
I'm using Spring MVC to handle JSON POST requests. Underneath the covers I'm using the MappingJacksonHttpMessageConverter built on the Jackson JSON processor and enabled when you use the mvc:annotation-driven.
One of my services receives a list of actions:
#RequestMapping(value="/executeActions", method=RequestMethod.POST)
public #ResponseBody String executeActions(#RequestBody List<ActionImpl> actions) {
logger.info("executeActions");
return "ACK";
}
I have found that Jackson maps the requestBody to a List of java.util.LinkedHashMap items (simple data binding). Instead, I would like the request to be bound to a List of typed objects (in this case "ActionImpl").
I know this is easy to do if you use Jackson's ObjectMapper directly:
List<ActionImpl> result = mapper.readValue(src, new TypeReference<List<ActionImpl>>() { });
but I was wondering what's the best way to achieve this when using Spring MVC and MappingJacksonHttpMessageConverter. Any hints?
Thanks
I have found that you can also work around the type erasure issue by using an array as the #RequestBody instead of a collection. For example, the following would work:
public #ResponseBody String executeActions(#RequestBody ActionImpl[] actions) { //... }
I suspect problem is due to type erasure, i.e. instead of passing generic parameter type, maybe only actions.getClass() is passed; and this would give type equivalent of List< ?>.
If this is true, one possibility would be to use an intermediate sub-class, like:
public class ActionImplList extends ArrayList<ActionImpl> { }
because this will the retain type information even if only class is passed.
So then:
public #ResponseBody String executeActions(#RequestBody ActionImplList actions)
would do the trick. Not optimal but should work.
I hope someone with more Spring MVC knowledge can shed light on why parameter type is not being passed (perhaps it's a bug?), but at least there is a work around.
For your information, the feature will be available in Spring 3.2 (see https://jira.springsource.org/browse/SPR-9570)
I just tested it on current M2 and it works like a charm out of the box (no need to provide additionnal annotation to provide the parameterized type, it will be automatically resolved by new MessageConverter)
This question is already old, but I think I can contribute a bit anyway.
Like StaxMan pointed out, this is due to type erasure. It definitely should be possible, because you can get the generic arguments via reflection from the method definition. However, the problem is the API of the HttpMessageConverter:
T read(Class<? extends T> clazz, HttpInputMessage inputMessage);
Here, only List.class will be passed to the method. So, as you can see, it is impossible to implement a HttpMessageConverter that calculates the real type by looking at the method parameter type, as that is not available.
Nevertheless, it is possible to code your own workaround - you just won't be using HttpMessageConverter. Spring MVC allows you to write your own WebArgumentResolver that kicks in before the standard resolution methods. You can for example use your own custom annotation (#JsonRequestBody?) that directly uses an ObjectMapper to parse your value. You will be able to provide the parameter type from the method:
final Type parameterType= method.getParameterTypes()[index];
List<ActionImpl> result = mapper.readValue(src, new TypeReference<Object>>() {
#Override
public Type getType() {
return parameterType;
}
});
Not really the way TypeReference was intended to be used I presume, but ObjectMapper doesn't provide a more suitable method.
Have you tried declaring the method as:
executeActions(#RequestBody TypeReference<List<ActionImpl>> actions)
I haven't tried it, but based on your question it's the first thing I would try.
I have a Domain Specific Language, and I would like to register objects that can be instantiated inside.
For instance a class that can do httprequests.
[IoC("HttpRequest", typeof(DslScriptObject), IoCAttribute.IoCLifestyleType.Transient)]
internal class WebRequestDslObj : DslScriptObject
{
[DslNew]
public WebRequestDslObj() : this(null, null)
{}
[DslNew]
public WebRequestDslObj([DslParam("uri")]string uristring, [DslOptionalParam("contenttype")] string contenttype) : this(uristring, null)
{}
}
I then have a class that maps types from my dsl datatypes to c# datatypes (I have them as an IList if that makes any difference), and this works ok, if I do not use Castle to instantiate the object.
But as soon as I want to use IoC to autoregister the various types, then I dont know what to do about the constructors. I have tried to look at setting a CustomComponentActivator, but I got stuck at not being able to find any good example or documentation. Is that a viable path to take? (and will I be able to get around the funny special case for null parameters?)
Anyone have an example of where I can start?
So what are you trying to do with Windsor, because I'm not sure I see where you're going with it...
If you want to affect how component gets register in Windsor, for example rename parameters, you can write custom ComponentModel construction contributor to do it.
Please retag this question to include languages to which it is relevant
So my java book had a whole chapter on nested classes, but ended on the note that you should only really use them when it comes to "modeling composition relationships and implementing internals of a class you want to hide". So lets discuss when you would want to use nested classes and some examples.
A nested/inner class is just a class that's only ever used specifically in the context of another class, which doesn't have it's own class file. If it's linked to an instance, it can only be instantiated in the context of a parent class instance; it can see private data, or only private static data if it's a static class.
The java developer site has a nested classes tutorial with one example:
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
A couple examples of usage:
Hide a concrete implementation of an
interface:
(Thinking of a database session for a tool like Hibernate): Suppose you have a Session interface, and a SessionFactory which returns an instance of a Session. The SessionImpl concrete class that implements the Session interface could be an innner class of the factory that knows how to construct and initialize it.
Supply information by implementing an
interface:
In the Wicket web framework, each GUI component has an associated "model", whose job is to wire data to the component. The interface looks something like:
public interface IModel extends IDetachable {
public Object getObject();
public Object setObject();
}
Suppose you have some special logic to retrieve data for a custom GUI component that you've written. Since no other component retrieves data the same way, you could use an anonymous class at the point where the IModel is supplied to take care of the data retrieval. If you have another point in the same class where you need to reuse your IModel implementation, you could make it an inner class. Later, if you need the model elsewhere, you could convert it to a top-level class.
Generally you use an inner class in a situation where you need a class definition, but that class is only usable or only makes sense in the context of the parent class.
A real life usage i had with nested classes, was in a global settings object.
The parent class was a Singleton, with nested classes as settings categories.
Settings
File settings
Print settings
Etc.
There was no real point in making the inner object as separate classes, as their would be no use for them outside the settings class scope.
I use nested classes for encapsulating algorithms that would be usually done as a method with lots of arguments. I use class that has raw data and I put algorithms into separate file in nested class (using partial keyword). That way I can put properties for that algorithm and its (working) data lives after algorithm is done.
I know that can be easily done without nested classes but this feels right because algorithm is purposely built for parent class.
public partial class Network
{
partial void initFDLF()
{
fdlf=new FDLF(this);
}
public FDLF fdlf;
public class FDLF
{
internal bool changed=true;
internal bool pvchange=true;
public double epsilon = 0.001;
public bool fdlfOk=false;
public void init(){...}
public void run(){...}
...