Mapping in Dozer Mapper fails - spring

I am using Dozer mapper in Spring boot. If I map Data from Entity to EntityDTO, then work of dozer maper is to copy the data from entity class to EntityDTO and it does the same in case of primitives. But suppose I have a class like this
Class Entity{
public EntityChild entityChild; //leaving getter and setter here.
}
and DTO with name EntityDTO
Class EntityDTO{
public EntityChildDTO entityChildDTOs; //leaving getter and setter here.
}
then it doesn't map the data from entityChild to entityChildDTOs, Can anyone please help me how to resolve this issue ?

The attribute names have to be the same for Dozer to automatically map it. So EntityDTO's attribute has to be named entityChild too, for example.

Part of mapping for this two entities, based on the official manual:
<mapping>
<class-a>Entity</class-a>
<class-b>EntityDTO</class-b>
<field>
<!-- this is the same for all sub classes -->
<a>entityChild</a>
<b>entityChildDTOs</b>
</field>
</mapping>
<!--Add mapping for EntityChild and EntityChildDTO here-->
You task is very basic and it definitely works in Dozer.

Related

Jackson deserializer priority?

I have a Spring Boot app that is modeling ActityStreams objects and for the most part Jackson's Polymorphic Deserialization works well.
There are 'objects' in the JSON which are references (links) and not JSON objects with type information. For instance
"actor":"https://some.actors.href/ rather than
"actor":{
"type":"Actor",
"name":"SomeActor"
}
I've written custom deserializers and and placed them on the fields to deal with this
#JsonDeserialize (using = ActorOrLinkDeserializer.class)
private Actor actor;
However my ActorOrLinkDeserializer is instantiated but never called and Jackson complains with Missing type id when trying to resolve subtype of [simple type, class org.w3.activity.streams.Actor]: missing type id property 'type' (for POJO property 'actor') which is from the polymorphic deserializer.
It appears that the polymorphic deserialization code takes precedence over my local #JsonDeserialize annotation and I need a way to force my code to run first.
I've tried using my own ObjectMapper rather than Boot's and there's no difference.
I'd appreciate pointers and suggestions.
It turns-out there's a fairly simple solution to this problem using a DeserializationProblemHandler.
What I've implemented that works for all test cases so far is
1.
objectMapper.addHandler(new DeserProblemHandler());
or register with Spring Boot.
2.
public class DeserProblemHandler extends DeserializationProblemHandler {
public JavaType handleMissingTypeId(DeserializationContext ctxt, JavaType baseType, TypeIdResolver idResolver, String failureMsg) {
return TypeFactory.defaultInstance().constructType(baseType.getRawClass());
}
}
Add a constructor to each of the polymorphic classes that takes a string argument which is the href.

Jersey JSON POJO Mapping with Moxy

I am working with Jersey Web services (2.23) and use POJO mapping for the JSON-to-Object mapping (Jersey-media-moxy). I created a class as follows:
public class DataPush {
public String asset;
public String timestamp;
public Map<String,String> aspects;
}
I expected that instances of this object have the following structure:
{"asset":"abc","timestamp":"xxx","aspects":[{"key":"sdfasd","value":"sdfsd"},{"key":"sdddfasd","value":"sdfddsd"}]}
Indeed, a further element "entry" is generated:
{"asset":"sdf","timestamp":"sdfsd","aspects":{"entry":[{"key":"sdfasd","value":"sdfsd"},{"key":"sdddfasd","value":"sdfddsd"}]}}
What is the most easiest way to get rid of the "entries" element?
I know I could write my own mapping, however I hope that there is a easy solution to manage this..
You can go to topic :
Jackson JSON – Converting JSON to Map on journaldev.com.
https://www.journaldev.com/2324/jackson-json-java-parser-api-example-tutorial

How to serialize POJO to xml with namespace prefix

Spring offers several ways to convert POJO to XML through HttpMessageConverter. However, I am having quite a bit of difficulty finding one that supports custom namespace with prefix.
For example from
public class Student {
String name;
String address;
Integer score;
}
To
<?xml version="1.0" encoding="UTF-8"?>
<foo:Student xmlns:foo="http://schemas.foo.com/student">
<foo:name>Some Name</foo:name>
<foo:address>Address</foo:address>
<foo:score>95</foo:score>
</foo:Student>
I was happily using MappingJackson2HttpMessageConverter with jackson-dataformat-xml until I realized that it does not support custom prefix.
Then I looked into using MarshallingHttpMessageConverter with XStreamMarshaller, only to find out that XStream does not support custom prefix either.
Can anyone refer me to a example how I can serialize POJO to xml with custom namespace prefix? Thanks.
I have managed to resolve similar problem for Jackson. First you have to use woodstox XML processor.
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
<version>4.4.0</version>
</dependency>
Than I have added namespace perfix/uri mapping this way:
XmlMapper mapper = new XmlMapper();
// override default instance of WstxOutputFactory
mapper.getFactory().setXMLOutputFactory(new WstxOutputFactory() {
#Override
public XMLStreamWriter createXMLStreamWriter(Writer w) throws XMLStreamException {
mConfig.setProperty(WstxInputProperties.P_RETURN_NULL_FOR_DEFAULT_NAMESPACE, true);
XMLStreamWriter result = super.createXMLStreamWriter(w);
result.setPrefix("xlink", "http://www.w3.org/1999/xlink");
return result;
}
});
For sure this is not elegant soultion but I am not sure if there is any other way. I hope Jackson will add api support for prefixes in future release.
I guess however in your case default namespace with prefix is needed and this seems to be more difficult because Jackson does not support default namespace (https://github.com/FasterXML/jackson-dataformat-xml/issues/18) and even using class inheritance with #JacksonXmlRootElement(namespace="http://xmlns.uri.com") you still would need to annotate each property with #JacksonXmlProperty(namespace="http://xmlns.uri.com")

How do #value annotations work in Spring?

I've never worked with Spring before, and I've run into a configuration object that looks somewhat like this
public class Config {
#Value("${app.module.config1}")
private String config1;
#Value("${app.module.config2}")
private String config2
...
public String getConfig1() {
return config1;
}
...
Can anyone explain what is happening here? I'm assuming this is some type of code injection, but I can't find where these values are coming from!
They allow you to direct inject a Value from a properties file (system or declared property) in the variable. Using the util:properties tag you can add something like this in your applicationContext.xml
<util:properties id="message" location="classpath:com/your/program/resources/message.properties" />
Pointing for a properties file named "message.properties" with some content:
application.hello.message = Hello World!
And then, in your java source file, inject a direct value from this properties file using the #Value annotation:
#Value("#{message['application.hello.message']}")
private String helloWorldMessage;
#Value("${app.module.config1}")
This is part of the spring expression language where the spring framework would look for app.module.config1 JVM property from System.getProperties() and injects the value of that property into config1 attribute in that class. Please see this reference for more details in Spring 3.0.x and this reference for the current docs.

How to inject a value to bean constructor using annotations

My spring bean have a constructor with an unique mandatory argument, and I managed to initialize it with the xml configuration :
<bean name="interfaceParameters#ota" class="com.company.core.DefaultInterfaceParameters">
<constructor-arg>
<value>OTA</value>
</constructor-arg>
</bean>
Then I use this bean like this and it works well.
#Resource(name = "interfaceParameters#ota")
private InterfaceParameters interfaceParameters;
But I would like to specify the contructor arg value with the annocations, something like
#Resource(name = "interfaceParameters#ota")
#contructorArg("ota") // I know it doesn't exists!
private InterfaceParameters interfaceParameters;
Is this possible ?
Thanks in advance
First, you have to specify the constructor arg in your bean definition, and not in your injection points. Then, you can utilize spring's #Value annotation (spring 3.0)
#Component
public class DefaultInterfaceParameters {
#Inject
public DefaultInterfaceParameters(#Value("${some.property}") String value) {
// assign to a field.
}
}
This is also encouraged as Spring advises constructor injection over field injection.
As far as I see the problem, this might not suit you, since you appear to define multiple beans of the same class, named differently. For that you cannot use annotations, you have to define these in XML.
However I do not think it is such a good idea to have these different beans. You'd better use only the string values. But I cannot give more information, because I dont know your exact classes.
As Bozho said, instead of constructor arg you could set the property...#PostConstruct will only get called after all the properties are set...so, you will still have your string available ...

Resources