skip to Main Content

I had a class like:

public class EmailAddress {
   public String value;

   public String tld() {...}
   public String host() {...}
   public String mailbox() {...}
}

Now I use this class in an Object / Entity:

@Entity
public class Customer {
    public String name;
    public EmailAddress mail;
}

Now, when I do a rest service for Customer, I get this format:

{
    "id": 1,
    "name": "Test",
    "email": {
        "value": "[email protected]"
    }
}

But I only want "email": "[email protected]"

{
    "id": 1,
    "name": "Test",
    "email": "[email protected]"
}

What I must do? I use Spring Boot and Hibernate Entities.

Thank you for any support

3

Answers


  1. Chosen as BEST ANSWER

    I found an other easier solution, use a JsonSerializer on the entity Property:

    @JsonSerialize(using = EmailAddressSerializer.class)
    private EmailAddress email;
    

    The serializer class:

    public class EmailAddressSerializer extends StdSerializer<EmailAddress> {
    
        public EmailAddressSerializer() {
            super(EmailAddress.class);
        }
    
        protected EmailAddressSerializer(Class<EmailAddress> t) {
            super(t);
        }
    
        @Override
        public void serialize(EmailAddress email,
                              JsonGenerator jsonGenerator,
                              SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeString(email.value);
        }
    }
    

  2. You should use DTO class in request handling and make mappings from DTO to Entity and backwards, e.g.:

    public class CustomerDTO {
        private Integer id;
        private String name;
        private String email;
    }
    
    Login or Signup to reply.
  3. You should use DataTransferObjects for your (REST) APIs.
    The DTOs only contain the fields the interface should provide (or receive).

    When receiving objects from the client and before returning the object from your Controller you can convert the DTOs to your domain model (Which could be your JPA entites classes).

    Example for a controller method. We assume you get an object from an user-editor which contains all data you want to update in your database-objects and return the updated company DTO:

    @PutMapping
    public CustomerDto updateCustomer(CustomerEditorDto updatedCustomerDto) {
        Customer updatedCustomer = CustomerConverter.convert(updatedCustomerDto);
        updatedCustomer = customerService.updateCustomer(updatedCustomer);
        return CustomerConverter.convert(updatedCustomer);
    }
    

    and your Converter class:

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public class CustomerConverter {
    
        public static CustomerDto convert(Customer customer) {
            CustomerDto result = null;
            if (customer != null) {
                // TODO: set fields in result-dto
            }
            return result;
        }
    
        public static Customer convert(CustomerEditorDto customer) {
            Customer result = null;
            if (customer != null) {
                // TODO set fields in result;
            }
            return result;
        }
    }
    

    and here are the DTOs

    @Getter
    @Setter
    public class CustomerDto {
        private Integer id;
        private String name;
        private String email;
    }
    
    @Getter
    @Setter
    public class CustomerEditorDto {
        private Integer id;
        private String firstName;
        private String lastName;
        private String email;
        private String otherPropertyOrStuff; 
    }
    

    This way you can separate the API modell from your JPA entites. You can use the same models for input/output. And you can even use a different model to work with inside your services and the finally convert them into your JPA entites, before persisting the data (or after reading the data).

    There are tools which can take care of the conversion, like mapstruct.

    * The above annotations @Getter, @Setter, … are from project lombok and very are handy to generate boiler-plate code automatically.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search