Home > other >  Spring Boot Java map Entity to DTO: array literal (strings) INSTEAD of array of objects
Spring Boot Java map Entity to DTO: array literal (strings) INSTEAD of array of objects

Time:10-14

sample get request: http://localhost:3000/contact/1

What I got:

{
  "id": 1,
  "firstname": "First Name",
  "lastname": "Last Name",
  "emailaddresses": [
    {
      "emailaddress": "[email protected]"
    },
    {
      "emailaddress": "[email protected]"
    }
  ]
}

What I want:

{
  "id": 1,
  "firstname": "First Name",
  "lastname": "Last Name",
  "emailaddresses": ["[email protected]","[email protected]"]
}

The code below:

PersonDto

public class PersonDto {
    
    private Long id;
    private String firstname;
    private String lastname;
    private List<EmailAddressDto> emailaddresses;
    //getters setters
}

EmailAddressDto

public class EmailAddressDto {

    private String emailaddress;
    //getters and setters
}

the Service class

public PersonDto getPerson(Long personId) { //this is the method inside the class

        Optional<PersonEntity> p = peopleRepository.findById(personId);
        var dto = modelMapper.map(p.get(), PersonDto.class);
        return dto;
}

I also have a PersonEntity class mapped one-to-many to an EmailAddressesEntity class.

I'm really new to spring/java - I couldn't figure out how to get the JSON structure I want.

CodePudding user response:

I'd suggest that you use a List of Strings instead of a List of EmailAddressDto's.

Following reasons:

  • Since you only have one attribute in your Dto, you can easily just directly use a List of Strings instead.
  • You get the second JSON-Layout as a response to your GET-Request.

When using variant number 1 (with the List of EmailAddressDto), you will achieve a JSON-Response with multiple objects for your different E-Mail addresses. Otherwise when you use variant number 2 (with the List of String), you will achieve a JSON-Response which looks like what you want to have.

So don't forget to change your entities aswell.

public class PersonDto {

private Long id;
private String firstname;
private String lastname;
private List<String> emailAddresses;
//getters setters
}

CodePudding user response:

If you can change your PersonDto that would be the easiest and cleanest way to do it.

public class PersonDto {
    
    private Long id;
    private String firstname;
    private String lastname;
    private List<String> emailaddresses;
    //getters setters
}

While mapping your entities you would need to map EmailAddressesEntity to a String representing it (emailaddress).


If this is not possible you will need a custom converter for EmailAddressDto as follows:

public class ListEmailAddressDtoConverter extends StdConverter<List<EmailAddressDto>, List<String>> {
    @Override
    public List<String> convert(List<EmailAddressDto> emailAddresses) {
        return emailAddresses.stream().map(EmailAddressDto::getEmailaddress).collect(Collectors.toList());
    }
}

Then you need to tell Jackson to use it:

public class PersonDto {
    
    private Long id;
    private String firstname;
    private String lastname;
    
    @JsonSerialize(converter = ListEmailAddressDtoConverter.class)
    private List<EmailAddressDto> emailaddresses;
    //getters setters
}

CodePudding user response:

You can just annotate emailaddress field of EmailAddressDto with @JsonValue and leave everything as is.

public class EmailAddressDto {
    
    @JsonValue
    private String emailaddress;
    //getters and setters
}

Using the above the output of a sample:

    PersonDto personDto = new PersonDto();
    personDto.setId(1L);
    personDto.setFirstname("John");
    personDto.setLastname("Doe");
    personDto.setEmailaddresses(Arrays.asList(new EmailAddressDto("[email protected]"), new EmailAddressDto("[email protected]")));

    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(personDto);
    System.out.println(json);

is:

{"id":1,"firstname":"John","lastname":"Doe","emailaddresses":["[email protected]","[email protected]"]}
  • Related