Vipercold
Vipercold

Reputation: 609

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?

Upvotes: 1

Views: 732

Answers (2)

Peter Collette
Peter Collette

Reputation: 11

Add following statement in the xml configuration :

<configuration>
    <copy-by-references>
        <copy-by-reference>
            java.net.URI
        </copy-by-reference>
    </copy-by-references>
</configuration>

Upvotes: 1

Makoto
Makoto

Reputation: 106389

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:

  • Attempt to convert a URL to a URI, then convert it back to a URL.
  • If there's any malformedness with the URI or the URL, throw it back - we shouldn't be dealing with a malformed URL at this state anyway.
  • Otherwise, return the result of the converted URL.

Upvotes: 1

Related Questions