Is it possible to write custom Yaml Deserializer in Jackson? - jackson

How to write custom Yaml Deserializer using Jackson ?
I can write the JSON Deserializer like below:
public class CustomDeserializer extends JsonDeserializer<SortedMap<String, Object>> {}
is there any way to write Yaml Deserializer in same way ?

Related

How to implement Custom Deserializer

I have written a custom serializer and attached it to my RestClient. I am trying to also implement a custom deserializer as well. I noticed in my code that the serializer gets called when i added it to my client like so :RestClient Client = new RestClient(options).UseSerializer<CustomJsonSerializer>();
However, I am not sure what code to add to point to my custom deserializer and where to add it.
I am trying to call a method that essentially hijack's the response content, changes the string, and then sends the modified string back as the new response content to then be deserialized.
Where would i add the code to call my custom deserializer? What would the code snippet look like? And is it possible to even alter the response.content before the deserialization happens? And if so, how do i implement that?
The UseSerializer<T> expects T to be IRestSerializer, which has properties for ISerializer and IDeserializer. The Deserializer property needs to return your custom deserializer.
public interface IRestSerializer {
ISerializer Serializer { get; }
IDeserializer Deserializer { get; }
...

How do I create hypermedia links in custom serializer with Spring Data Rest

I have a abstract class and two implementations:
public abstract class Attribute {
// some properties
}
public class CustomAttribute extends Attribute{
private String property1;
}
public class DefaultAttribute extends Attribute{
private String property2;
}
There's another class, which includes these attributes:
public class Step{
private List<Attribute> attributes;
}
Now when Step gets serialized, the self link is missing. I need the self reference, since I want to update the attributes. According to the documentation, jackson needs a little help deciding which class to use. But that does not help, because I need to use both classes. So I build a custom serializer (and registered with a module) for Step and now I wonder how I can construct the link myself. I couldn't find anything in the Spring Data Rest docs regarding this. Since Spring Data Rest adds these links automatically, I think there might be a way to have the protocol/hostname/port information available in the JsonSerializer. How do I get the information in my custom serializer?
Ok, now I use the linkTo() function to get the hostname and port and I manually set the rest of the resource URL in my custom serializer.
final Link attributeLink = linkTo(CustomAttributeRepository.class)
.slash("/api")
.slash("customAttributes")
.slash(attribute.getIdentifier()).withSelfRel();
//#formatter:off
jsonGenerator.writeFieldName("_links");
jsonGenerator.writeStartObject();
jsonGenerator.writeFieldName("self");
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("href", attributeLink.getHref());
jsonGenerator.writeEndObject();
jsonGenerator.writeEndObject();
//#formatter:on

Register JodaModule in Jax-RS Application

I'm writing a Jax-RS application using Jersey, and Jackson2 under the hood to facilitate JSON i/o. The service itself works fine, but I'd like to improve it by having the Jackson mapper automagically serialize/deserialize date and date-times to JodaTime objects.
I'm following the documentation here and have added the relevant jars, but I'm lost on this instruction:
Registering module
To use Joda datatypes with Jackson, you will first need to register the module first (same as with all Jackson datatype modules):
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
I've tried to do this in the custom class that extends jax.ws.rs.core.Application, but I'm not at all confident in that solution. I'm currently getting this error:
Can not instantiate value of type [simple type, class org.joda.time.DateTime] from String value ('2014-10-22'); no single-String constructor/factory method
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream#3471b6d5; line: 7, column: 25]
Other than the general impression that this module registration needs to happen at application (servlet?) startup, I have no idea what to do with this information. Do I need to annotate a custom class with something in particular to have it picked up ? Should I be extending some class ?
The examples I find on StackOverflow usually stick it in main() and call the mapper directly, but I'm relying on Jackson Databinding so the examples aren't relevant. Any direction is appreciated.
You'll basically want to create/configure/return the ObjectMapper in a ContextResolver. Something like
#Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
final ObjectMapper mapper = new ObjectMapper();
public ObjectMapperContextResolver() {
mapper.registerModule(new JodaModule());
}
#Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
If you are using package scanning to discover your resources, then the #Provider annotation should allow this class to be discovered and registered also.
Basically what happens, is the the MessageBodyReader and MessageBodyWriter provided by Jackson, used for unmarshalling and marshalling, respectively, will call the getContext method in the ContextResolver, to determine the ObjectMapper to use. The reader/writer will pass in the class (in a reader it will be the type expected in a method param, in a writer it will be the type returned as-a/in-a response), meaning we are allowed to use differently configured ObjectMapper for different classes, as seen here. In the above solution, it is used for all classes.

EDI conversion using mule

I would like to know if there is a way to convert EDI files to other format in mule. I have a requirement to convert from EDI to XML . I am able to do it using smooks plugin withing Mule. Wondering if there is more cleaner way to do it inside Mule, something like using datamapper. Please suggest.
I'm afraid the smooks comunity extension looks pretty much abandoned, however you could easily transform using a Java transformer like this:
public abstract class EdiSmooksTransformer extends AbstractTransformer
{
private Smooks smooks;
public EdiSmooksTransformer() throws IOException, SAXException
{
smooks = new Smooks();
smooks.setReaderConfig(new EDIReaderConfigurator("MY_EDI_CONFIG_FILE_PATH_HERE"));
}
#Override
protected Object doTransform(Object src, String enc) throws TransformerException
{
StringResult stringResult = new StringResult();
smooks.filterSource(new StreamSource((BufferedReader) src), stringResult);
return stringResult.getResult();
}
}

Converting Oject to custom string format using Jackson Serializer

I would like to convert an object into a string representation which is like JSON without the fieldnames
for instance the following class
public class Employee{
private String name;
private int age;
private boolean married;
}
Employee = new objEmp();
objEmp.Name = "Mickey Mouse";
objEmp.age = 24;
objEmp.married = false;
the above object i would like to convert into string as
{"Mickey Mouse", 24, false}
and the array of this object must look like
[
{"Mickey Mouse", 24, false}
,{"Robin Hood" , 24, false}
]
I am looking for a solution that can be applied constantly for every java Objects (POJO).
so overriding toString() method of each object or solutions on the similar lines are not desired
I prefer it to do with jackson as i am all ready using it to convert Objects into JSON in Spring 3
I am looking for some jackson ObjectMapper configurations that can help me to achieve this
or if not i can create my own Object Mapper and use it in Spring View
thanks
I don't think ObjectMapper has the flexibility to do this, since what you are trying to generate is not actually JSON.
How about using reflection to get a list of the field values, and then serializing this as an Object array?
Something like:
List<Object> vals = new ArrayList<>();
for (Field field : Employee.class.getDeclaredFields()) {
field.setAccessible(true);
vals.add(field.get(emp));
}
ObjectMapper om = new ObjectMapper();
System.out.println(om.writeValueAsString(vals));
This gives you
["Mickey Mouse",24,false]
which has square brackets instead of curly braces. Is this good enough?