четверг, 22 декабря 2016 г.

Maven Enforcer Plugin

Due to continuous integration sometimes it is difficult to control build environment. Someone can wrongly setup Jenkins job and your project won't build. In order to identify such errors much more faster one can use maven-enforcer-plugin. Just add the following xml to the pom and that's it:

                <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-enforcer-plugin</artifactId>
                <version>${maven.enforcer.plugin.version}</version>
                <executions>
                    <execution>
                        <id>enforce-versions</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>enforce</goal>
                        </goals>
                        <configuration>
                            <rules>
                                <requireMavenVersion>
                                    <!--
                                      Maven 3.0.3 or later. That's the earliest version to enforce
                                      declaration ordering for plugins in the same phase.
                                     -->
                                    <version>[3.0.3,)</version>
                                </requireMavenVersion>
                                <requireJavaVersion>
                                    <!-- Java 1.8 or later. -->
                                    <version>[${java.version},)</version>
                                </requireJavaVersion>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Java Jackson 2. Custom Date deserialization in JSON.

Hi. I want to share receipt with you how to write custom date deserializator for Jackson 2. This could be helpful when you deserialize value into generic Map and want that dates actually were stored like java.util.Date not String.

Deserialization usually done like so:
 Map<String,Object> data = null;
 data = mapper.readValue(someInputStream,Map.class);


In order to create custom serializator one needs to extend the class com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer. Here is the example of custom date deserializator:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DDeserializer extends UntypedObjectDeserializer
   
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");

    @Override
    public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {

        if (jp.getCurrentTokenId() == JsonTokenId.ID_STRING) {
            try {
                LocalDate localDate = LocalDate.parse(jp.getText(),formatter);
                java.util.Date date = java.sql.Date.valueOf(localDate);
                return date;
            } catch (Exception e) {
                return super.deserialize(jp, ctxt);
            }
        } else {
            return super.deserialize(jp, ctxt);
        }
    }

    public static ObjectMapper regObjectMapper(ObjectMapper mapper){
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addDeserializer(Object.class, new DDeserializer());
        mapper.registerModule(simpleModule);
        return mapper;
    }
}

Please note, that here is java 8 Date & Time API is mixed with plain old Date API. But the approach here is important.
Take a note in regObjectMapper method. In order to use custom deserializator it needs to be registered in ObjectMapper. After this you could use it to deserealize strings in to Date.