加载中...
eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Overview

When working with Java applications, we may need to convert complex data objects into simpler representations. For example, it’s common to convert data types such as enums, numbers, or nested objects to their String equivalents for display, logging, or API responses. In such a scenario, we can use MapStruct.

In this tutorial, we’ll map different data types to a String.

2. Project Setup

To demonstrate mapping to a String in MapStruct, we can create a simple Maven project mapstructstringmapping.

In the pom.xml file, let’s navigate to the mapstructstringmapping directory and update:

<dependencies>
    <!-- MapStruct -->
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.6.3</version>
    </dependency>

    <!-- JUnit 5 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.14.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Above, we add mapstruct for compile-time mapping, and JUnit 5 for testing.

3. Simple Mapping to String

While working on presentation or even API responses, we may need to convert numeric or boolean values into strings. One good example is when a database entity stores a user’s age as an int, but the API layer needing to expose it as a String.

Let’s examine a straightforward example to show how to use MapStruct to map an int field to a String. First, we define the class Person:

public class Person {
    private String name;
    private int age;
}

Next, let’s create the second class PersonDTO:

public class PersonDTO {
    private String name;
    private String age;
}

In the above examples, the classes have standard getters and setters, which MapStruct will use for mapping.

Now, let’s define the mapper interface PersonMapper.java:

@Mapper
public interface PersonMapper {

    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
    PersonDTO toDTO(Person person);
}

At compile time, MapStruct creates the PersonMapper implementation. In this case, MapStruct automatically changes the int value of age from the source object to a String in the target object when the toDTO() method is called.

Let’s create the PersonMapperUnitTest.java unit test and ensure the mapping functions as intended:

public class PersonMapperUnitTest {

    @Test
    void givenPerson_whenMapsToPersonDTO_thenFieldsAreCorrect() {

        Person person = new Person();
        person.setName("Alice");
        person.setAge(30);

        PersonDTO dto = PersonMapper.INSTANCE.toDTO(person);

        assertEquals("Alice", dto.getName());
        assertEquals("30", dto.getAge());
    }
}

The test confirms that the int value of age is translated to its String representation and that the name field is successfully mapped.

4. Enums to String Conversion

In Java, enums are widely used to define fixed sets of variables, including user roles, order statuses, and system states. However, when data is shown in user interfaces or made accessible through APIs, these enum values are usually rendered as strings.

4.1. Defining the Enum and Domain Classes

Let’s start by defining an enum that represents a user’s status:

public enum Status {
    ACTIVE,
    INACTIVE,
    PENDING
}

To follow this up, let’s create a domain object that uses this enum:

public class User {
    private String username;
    private Status status;
}

Finally, we create a DTO where the enum value is represented as a String:

public class UserDTO {
    private String username;
    private String status;
}

Now, the User class uses an enum for the status field, whereas UserDTO expects the same value as a String.

4.2. Defining the Mapper

Let’s define a mapper interface that converts a User into a UserDTO:

@Mapper
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserDTO toDto(User user);
}

Here, MapStruct automatically detects that the source field is an enum and the target field is a String. We don’t need to define any custom mapping logic. It invokes the enum’s name() method during the mapping process.

In most real-world APIs, this default behavior is sufficient, but it’s important to be aware of it if enum names don’t match the values expected by clients.

4.3. Verifying the Mapping

Let’s write a unit test that confirms the enum-to-string conversion works as expected:

public class UserMapperUnitTest {

    @Test
    void shouldMapEnumToString() {

        User user = new User();
        user.setUsername("Kevin");
        user.setStatus(Status.ACTIVE);

        UserDTO dto = UserMapper.INSTANCE.toDto(user);

        assertEquals("Kevin", dto.getUsername());
        assertEquals("ACTIVE", dto.getStatus());
    }
}

This is what the test verifies:

  • The username field is mapped correctly
  • The enum value Status.ACTIVE is converted to its String representation, “ACTIVE”

Notably, this behavior works out of the box with MapStruct and requires no additional configuration.

5. Mapping Dates to String

When working with date fields, we often need to convert them into formatted string representations before exposing them through APIs or displaying them in user interfaces. MapStruct supports this use case through the dateFormat attribute in the @Mapping annotation.

Using this attribute, we can define the exact date pattern we want MapStruct to apply during the mapping process.

5.1. Defining the Domain and DTO Classes

Let’s start by defining a simple domain entity that contains a LocalDate field:

public class Event {
    private String name;
    private LocalDate eventDate;
}

Next, let’s define a corresponding DTO where the eventDate field is represented as a String:

public class EventDTO {
    private String name;
    private String eventDate;
}

Here, the Event class represents the domain model, while EventDTO is the data transfer object used for output. The key difference is that the eventDate field is a LocalDate in the source object and a formatted String in the target object.

5.2. Creating the Mapper

Now, let’s define a mapper interface to convert an Event into an EventDTO:

@Mapper
public interface EventMapper {

    EventMapper INSTANCE = Mappers.getMapper(EventMapper.class);

    @Mapping(source = "eventDate", target = "eventDate", dateFormat = "yyyy-MM-dd")
    EventDTO toEventDTO(Event event);
}

Let’s analyze the mapper:

  • The dateFormat attribute specifies the desired string format
  • MapStruct generates the necessary conversion logic at compile time
  • If the source date is null, MapStruct safely maps it to null in the target

MapStruct uses DateTimeFormatter to perform the date-to-string conversion.

5.3. Verifying the Mapping

Let’s now write a unit test that ensures the date is mapped correctly:

public class EventMapperUnitTest {

    @Test
    public void shouldMapLocalDateToFormattedString() {

        LocalDate date = LocalDate.of(2025, 11, 10);
        Event event = new Event("Tech Meetup", date);

        EventDTO dto = EventMapper.INSTANCE.toEventDTO(event);

        assertNotNull(dto);
        assertEquals("Tech Meetup", dto.getName());
        assertEquals("2025-11-10", dto.getEventDate());
    }
}

The test prepares a LocalDate instance using the same format defined in the mapper. After performing the mapping, the mapping confirms that the event name is mapped correctly and that the LocalDate field is converted to the expected string representation.

6. Handling Null Values

When mapping values to String, handling null properly is essential. Without explicit handling, we may end up with null values in our DTOs or even encounter NullPointerExceptions when applying custom mapping logic.

MapStruct provides multiple ways to control how null values are handled, both globally and at the field level.

6.1. Using nullValueMappingStrategy

MapStruct allows us to define how null source objects are handled using the nullValueMappingStrategy attribute. One commonly used option is RETURN_DEFAULT, which instructs MapStruct to return a default target instance when the source object itself is null.

Let’s edit PersonMapper to demonstrate this:

@Mapper(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
public interface PersonMapper {

    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);

    @Mapping(target = "age", defaultValue = "")
    PersonDTO toDTO(Person person);
}

With this configuration, if the source Person object is null, MapStruct returns a non-null PersonDTO with default values. Additionally, we use defaultValue to control the default output when mapping occurs, without introducing custom conversion logic.

6.2. Handling Nulls in Custom Mapping Methods

When we need more control over how individual fields are mapped, we can define custom mapping methods. This is especially useful when we want to replace null values with meaningful defaults.

For example, let’s map a missing name to “Unknown” instead of null:

@Mapper(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
public interface PersonMapper {

    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);

    @Mapping(target = "name", qualifiedByName = "mapName")
    @Mapping(target = "age", defaultValue = "")
    PersonDTO toDTO(Person person);

    @Named("mapName")
    default String mapName(String name) {
        return name == null ? "Unknown" : name;
    }
}

Let’s break down the modification above:

  • The @Named annotation marks the custom method so it can be referenced in mappings
  • The mapName() method replaces null values with “Unknown”
  • MapStruct automatically invokes this method during the mapping process

With this approach, we gain full control over how individual fields behave when their source values are null, while keeping the mapping logic centralized and reusable.

7. Conclusion

In this tutorial, we explored how to map different types of data to String using MapStruct.

We covered simple numeric conversions, enum-to-string mapping, formatting LocalDate fields, and strategies for handling null values effectively. Each example demonstrated how MapStruct generates type-safe, compile-time mapping code, reducing boilerplate and eliminating potential runtime errors.

By leveraging features such as the dateFormat attribute, nullValueMappingStrategy, and custom mapping methods, developers can create clean and predictable DTO representations tailored to their application’s needs. Overall, MapStruct simplifies complex transformations, making your mapping logic easier to maintain, more readable, and fully testable.

Before using these mappings in production, make sure the DTOs match the API requirements.

The source code is over on GitHub.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – LS – NPI (cat=Java)
announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)
guest
0 Comments
Oldest
Newest
Inline Feedbacks
View all comments