I'm doing a very simple thing that should just work, IMO. I've got a resource like:
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("{nodeType}/{uuid}")
public Object getResourceInfo(#PathParam("nodeType") String nodeType,
#PathParam("uuid") String uuid,
#Context SecurityContext authority) { ...
Note I'm returning type Object. This is because depending on the call (here depending on the nodeType argument) I want to return a different concrete class (which will always be #XmlRootElement) and have that get marshalled out into the response.
However, this does not work. I get exception like:
Exception Description: A descriptor for class com.mycompany.XmlElementTypeInstance was not found in the project. For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.
If I change Object to a single subclass, it works. But I want it to be able to handle any subclass, XmlElementTypeInstance, XmlElementTypeInstance2, etcetc.
I tried making a common interface from which all of the XmlElementTypeInstance subclasses derive, but then I only get those properties in the interface, not the extra properties in the subclasses. Playing with #XmlElementRef and adding all possible properties to the common interface is extremely ugly and can't work quite correctly to generate the JSON I want, so please don't suggest that. =)
Is there any way to do this? It seems like simple, basic, necessary functionality... any other REST framework I've used, no problem...
The solution it turns out is simple (had to read the JSR instead of the actual Jersey docs, however!)
Instead of returning Object, returning Response (section 3.3.3 of JSR 339) with the object set as the entity forces the implementation to pick an appropriate MessageBody{Writer,Reader} at runtime.
return Response.ok().entity(<the object>).build();
Lost way too much time on this. Hope it helps someone later. =/
Related
Is it possible to serialize an object with no fields in Jackson using only annotations? When I attempt to serialize such an object with no annotations I get:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class [redacted].SubjectObjectFeatureExtractor and no properties discovered to create BeanSerializer
I have examined the list of Jackson annotations without seeing a way to annotate the class as having no serializable data. I tried putting #JsonCreator on the empty constructor (not expecting it to work, since it's a deserialization annotation), and I got the same error. There are no accessors or fields to put #JsonProperty on. Any ideas?
Update: The reason for this is that I have a list of objects which represent transformations which can be applied to a certain type of data. Some of these transformations are defined by parameters which needs to be serialized, but some of these are parameter-less (the data-less objects in question). I'd like to be able to serialize and deserialize a sequence of these transformations. Also, I'm using DefaultTyping.NON_FINAL so that the class name will be serialized.
Update: An example class would be
class ExtractSomeFeature implements FeatureExtractor<SomeOtherType> {
public void extractFeature(SomeOtherType obj, WeightedFeatureList output) {
// do stuff
}
}
I don't particularly care how the JSON for this looks like, as long as I can deserialize List<FeatureExtractor>s properly. My impression is that using default typing, the expected JSON would be something like:
['com.mycompany.foo.ExtractSomeFeature', {}]
Other sub-classes of FeatureExtractor would have real parameters, so they would presumably look something like:
[`com.mycompany.foo.SomeParameterizedFeature', {some actual JSON stuff in here}]
I think I could use #JsonValue on some toJSONString() method to return {}, but if possible I'd like to hide such hackery from end-users who will be creating FeatureExtractor sub-classes.
You have to configure your object mapper to support this case.
ObjectMapper objectMapper = ...
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
The documentation of this feature can be found here : Fail on empty beans
Feature that determines what happens when no accessors are found for a
type (and there are no annotations to indicate it is meant to be
serialized). If enabled (default), an exception is thrown to indicate
these as non-serializable types; if disabled, they are serialized as
empty Objects, i.e. without any properties.
The answer to disable SerializationFeature.FAIL_ON_EMPTY_BEANS is global, and you therefore might not wish to apply it.
The answer to add any serialisation annotation showed the correct (as in: the Javadoc of SerializationFeature.FAIL_ON_EMPTY_BEANS suggests it) way to fix it, but only with a hackish or an unrelated annotation.
By merely adding…
#JsonSerialize
… to my class (not even parenthesēs after it, lest alone arguments!) I was able to produce the same effect (as, again, indicated by the Javadoc of SerializationFeature.FAIL_ON_EMPTY_BEANS).
Adding the following annotation onto the class seems to solve the problem:
#JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.NONE)
Adding an unrelated annotated like
#JsonRootName("fred")
also seems to fix it. This seems to match the claim in the JIRA ticket that adding any Jackson annotation to the class will prevent the exception. However, it appears adding annotations within the class does not.
Not sure I get your question, but perhaps you want JsonInclude.Include.NON_DEFAULT, JsonInclude.Include.NON_NULL, or JsonInclude.Include. NON_EMPTY.
I'm looking to have some conditional marshalling completed with jaxb. Something like this:
Class A{
//Only marshall when condition X applies
public String fieldOne;
//Only marshall when condition Y applies
public String fieldTwo;
//Always marshall
public String fieldThree;
}
Essentially I have 2 different Web Service methods which use the same model, but I need the information sent to be different on each of these web service methods.
My best option so far would be to create a custom XMLJavaTypeAdapter which verifies some conditional logic. The adapter would return null when I don't want the object, when I do need it marshalled it would return itself.
I'm looking to see if anyone has a better alternative. My jaxb context is quite complex and already has a few layer of adapters.
Thanks in advance.
My best option so far would be to create a custom XMLJavaTypeAdapter
which verifies some conditional logic. The adapter would return null
when I don't want the object, when I do need it marshalled it would
return itself.
I've been there and done that, it gets very messy very fast. If you can use MOXy (I see your post is tagged with moxy), you can can use the XmlNamedObjectGraph annotation to create named profiles of elements that are included when you instance is serialized.
Blaise Doughan (team lead for the MOXy project) explains it better than I can.
Blaise's blog post shows how to use annotations, but he also wrote a page on the EclipseLink wiki that shows how to do it programmatically.
I'm using Jersey 1.x here and I have a #POST method that requires sending over a deeply nested, complex object. I'm not sure of all my options, but it seems like a lot are described in this documentation:
In general the Java type of the method parameter may:
Be a primitive type;
Have a constructor that accepts a single String argument;
Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String) and
java.util.UUID.fromString(String)); or
Be List, Set or SortedSet, where T satisfies 2 or 3 above. The resulting collection is read-only.
Ideally, I wish that I could define a method like this:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Path("complexObject")
public void complexObject(#FormParam("complexObject") ComplexObject complexObject) throws Exception {
But I guess I can only do that if my object satisfies the requirements above (which in my case, it does not). To me it seems that I have a choice.
Option 1: Implement fromString
Implement item #3 above.
Option 2: Pass in the complexObject in pieces
Break up the complexObject into pieces so the parameters become this:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Path("complexObject")
public void complexObject(#FormParam("piece1") LessComplexPiece lessComplexPiece1,
#FormParam("piece2") LessComplexPiece lessComplexPiece2,
#FormParam("piece3") LessComplexPiece lessComplexPiece3) throws Exception {
This may not be enough if LessComplexPiece does not satisfy the requirements above. I'm wondering what the best option is here. What do people usually do in this situation? Here are the pros and cons I can think of:
Cons of Implement fromString
Have to maintain a custom deserializer. Every time the class is modified, this deserializer may break. There's more risk for bugs in general.
It will probably be impossible to generate documentation that describes the pieces of the complex object. I'll have to write that by hand.
For each piece of the complex object, I'll have to write my own casting and validation logic.
I'm not sure what the post data would look like. But, this may make it very difficult for someone to call the API from a web page form. If the resource accepted primitives, it would be easy. EG: complexObject=seralizedString vs firstName=John and lastName=Smith
You may not be able to modify the class for various reasons (thankfully, this is not a limitation for me)
Pros of Implementing fromString
This could avoid a method with a ton of parameters. This will make the API less intimidating to use.
This argument is at the level of abstraction I want to work at in the body of my method:
I won't have to combine the pieces together by hand (well technically I will, it'll just have to be in the deserializer method)
The deserializer can be a library that automates the process (XStream, gensen, etc.) and save me a lot of time. This can mitigate the bug risk.
You may run into "namespace" clashes if you flatten the object to send over pieces. For example, imagine sending over an Employee. If he has a Boss, you now have to provide a EmployeeFirstName and a BossFirstName. If you were just deserializing an object, you could nest the data appropriately and not have to include context in your parameter names.
So which option should I choose? Is there a 3rd option I'm not aware of?
I know that this question is old but in case anybody has this problem there is new better solution since JAX-RS 2.0. Solution is #BeanParam. Due to documentation:
The annotation that may be used to inject custom JAX-RS "parameter aggregator" value object into a resource class field, property or resource method parameter.
The JAX-RS runtime will instantiate the object and inject all it's fields and properties annotated with either one of the #XxxParam annotation (#PathParam, #FormParam ...) or the #Context annotation. For the POJO classes same instantiation and injection rules apply as in case of instantiation and injection of request-scoped root resource classes.
If you are looking for extended explanation on how this works please look at article I've found:
http://java.dzone.com/articles/new-jax-rs-20-%E2%80%93-beanparam
For complex object models, you may want to consider using JSON or XML binding instead of URL-encoded string to pass your objects to your resource call so you can rely on JAXB framework?
The Jersey Client library is compatible with JAXB and can handle all the marshaling transparently for you if you annotate your classes #XmlElementRoot.
For documentation, XSDs are a good starting point if you choose the XML binding.
Other REST documentation tools like enunciate can take the automatic generation to the next level.
What about special handler which transforms object to e.g. json - kryo if you would prefer performance? You got couple options
Look also at persistence ignorance.
I've been using AutoBeans to map JSON data coming from a non GWT-RPC Java based web service. Everything has been working so far except for one mapping.
On the server side, the Class has a property of type Map where MyAbstractParentObject is the parent class of about 15 different child classes.
When I map that to a corresponding AutoBean interface on the client I'm not able to downcast MyAbstractParentObject to its child type after it's been decoded. I looked all over the GWT docs and 'the Googles' to see if AutoBeans even has polymorphic support but couldn't get an answer either way. Interceptors and Categories don't seem to be able handle this, just methods they want to exist in the interface that aren't getters/setters.
I was attempting to do a workaround using the type field in the JSON data to create an instance of the child class but the AutoBean does not give me access to the raw JSON, even though in the debugger I can see it as a protected field called 'data'. If I try to decode the original bean it will only have the fields in the MyAbstractParentObject.
The only alternatives I can see are to:
Extend or create my own AutoBeanCodex that can properly handle the
children of MyAbstractParentObject when it decodes the JSON.
Find a way to get to the raw JSON in the MyAbstractParentObject AutoBean
and use that to create and instance of the child class on the fly.
Switch to some other JSON-GWT Serialization framework like
GWTProJSONSerializer or piriti.
Any help would be appreciated.
I know this was asked a long time ago, but I struggled to find an answer too. I realized that the AutoBeans, since they're basically just fancy wrappers for the JSON, still contain all the data for the fields of the child object you want to downcast it to. So I wrote a method like this:
public <A, B> B cast( A sourceObject, Class<B> targetClass )
{
AutoBean<A> sourceBean = AutoBeanUtils.getAutoBean( sourceObject ); // Get the corresponding AutoBean.
HasSplittable splittableBean = ( HasSplittable ) sourceBean; // Implementation (if still AbstractAutoBean) supports this interface ;)
Splittable splittable = splittableBean.getSplittable().deepCopy(); // If you don't copy it, decode() tries to be clever and returns
// the original bean!
AutoBean<B> targetBean = AutoBeanCodex.decode( typeFactory, targetClass, splittable ); // Create new AutoBean of
// the target type.
return targetBean.as(); // Get the proxy for the outside world.
}
--Where typeFactory extends AutoBeanFactory, as you can see.
It's worked well enough for me. The trickiest bit was the cast to HasSplittable, since AutoBean doesn't extend that interface, but AbstractAutoBean (which implements AutoBean) does -- and a subclass of that is what's returned by calls to getAutoBean().
You also need to copy the Splittable, otherwise AutoBeanCodex thinks, "hey, I already have an AutoBean for that Splittable! Here you go!" -- and just gives you the original. ;)
Anyway, you can cast downwards, upwards...sideways! :P
Late edit: Stumbling upon this again months later, I figured I'd add a small caveat about something Jonathan mentioned below. The method I've described here is designed to be used on an AutoBean that hasn't been modified since it was deserialized. That's because (AFAIK) there's no guarantee that any setters you call will actually update the JSON (needed for the casting). This probably isn't a big deal, since typically you'll use this when you have an incoming DTO and you want to cast it to its real type ASAP, before doing anything else with it. In our case, none of our AutoBeans even had setters, so it wasn't really an issue. ;)
After you've cast it, you can do whatever you want with the resulting bean, which is fresh out of the factory after all!
I'm not very familiar with AutoBean but you probably can use the serializer/deserializer from RestyGWT. It supports polymorphism by making use of annotation.
link to the documentation:
http://restygwt.fusesource.org/documentation/restygwt-user-guide.html#Polymorphic_Sub_Types
I'm currently working on a project which allows users to book (via the web) the use of a chosen resource for a given period of time. In this program I am trying to keep with Spring's philosophy (and the general best practice) of programming to interfaces and as such I try to use interfaces anywhere where functionality is repeated among concrete classes.
One interface I have created is called a BookableResourceController which specifies the methods needed by a controller to handle the minimum required functionality for any type of resource to be booked. I also make use of a second interface, BookableResource, which identifies which objects model a resource that is allowed to be booked through the application.
The problem I am currently running into is that a few of the methods defined by BookableResourceController use the #RequestBody mapping to convert a JSON object into a method parameter, and since Jackson can only convert JSON into "SimpleType" objects, I receive an error if I specify the input parameter to be a BookableResource.
#RequestMapping(value="/delete.html", method = RequestMethod.POST)
public ModelAndView processDeleteResource(
#RequestBody BookableResource resource);
Can not construct instance of
org.codehaus.jackson.map.type.SimpleType,
problem: abstract types can only be
instantiated with additional type
information
From what I can tell this error means that I will need to define a specific implementation of BookableResource, meaning I will most likely need to exclude these methods from the interface even though any controller that is to be used for this purpose will require those methods.
What I am asking is if anyone knows a way to define an interface as the object that is expected from an #RequestBody mapping using JSON, or does anyone have any suggestions of how to structure my contoller interface in order to include these methods?
Cheers
I'm not sure it would work, but you can try to make it generic:
public interface BookableResourceController<R extends BookableResource> {
#RequestMapping(value="/delete.html", method = RequestMethod.POST)
public ModelAndView processDeleteResource(#RequestBody R resource);
}
Additional way to go that can be used is to annotate interface with Jackson annotation:
#JsonDeserialize(as=BookableResourceImp.class)
(possibly using mix-in annotations if one does not want to add it directly in interface class)
EDIT: Another possibility is to use SimpleModule method addAbstractTypeMapping() to specify implementation type. This avoids linkage from interface to implementation, and may (or may not) be more convenient way to register this aspect.