javadozer

How to convert URL field using Dozer bean Mapper?


I have the following classes and when I used Dozer Bean Mapper to convert ProductEntity to Product, and vice versa:

public class ProductEntity(){   
    private String name;
    private String description;
    private URL site;
}

public class Product(){
    private String name;
    private String description;
    private URL site;        
}

I get the following error:

Internal error [java.lang.NoSuchMethodException: java.net.URL.<init>()

Is Dozer incompatible with this URL class, or am I doing something wrong?


Solution

  • It's been a while since I've done Dozer, but the reason you're seeing this is due to the way that Dozer maps objects. It's looking to create a new object merely by invoking a no-arg constructor, and since URL doesn't have one, this is why you're getting that exception.

    The way around this is to create an identity conversion: map one instance of an entity to the exact same type of entity.

    The way we do that is in 2 parts:

    First, declare the custom configuration in your dozer.xml file.

    <configuration>
        <custom-converters>
            <converter type="com.stackoverflow.URLConverter">
                <class-a>java.net.URL</class-a>
                <class-b>java.net.URL</class-b>
            </converter>
        </custom-converters>
    </configuration>
    

    Next, create a new URLConverter class which extends from DozerConverter. The reason it extends from DozerConverter and not CustomConverter is for simplicity and type safety.

    public class URLConverter extends DozerConverter<URL, URL> {
    
        public URLConverter() {
            super(URL.class, URL.class);
        }
    
        @Override
        public URL convertTo(URL source, URL destination) {
            URL result = null;
            try {
                result = source.toURI().toURL();
            } catch (MalformedURLException | URISyntaxException e) {
                throw e;
            }
    
            return result;
        }
    
        @Override
        public URL convertFrom(URL source, URL destination) {
            URL result = null;
            try {
                result = source.toURI().toURL();
            } catch (MalformedURLException | URISyntaxException e) {
               throw e;
            }
    
            return result;
        }
    }
    

    The process here is fairly mechanical: