Course – Black Friday 2025 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our Black Friday Sale. All Access and Proare33% off untilnextMonday:

>>EXPLORE ACCESS NOW

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

Modern software architecture is often broken. Slow deliveryleads to missed opportunities, innovation is stalled due toarchitectural complexities, and engineering resources areexceedingly expensive.

Orkes is the leading workflow orchestration platformbuilt to enable teams to transform the way they develop, connect,and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers canfocus on building mission critical applications without worryingabout infrastructure maintenance to meet goals and, simply put,taking new products live faster and reducing total cost ofownership.

Try a14-Day FreeTrial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)
announcement - icon

Modern software architecture is often broken. Slow deliveryleads to missed opportunities, innovation is stalled due toarchitectural complexities, and engineering resources areexceedingly expensive.

Orkes is the leading workflow orchestration platformbuilt to enable teams to transform the way they develop, connect,and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers canfocus on building mission critical applications without worryingabout infrastructure maintenance to meet goals and, simply put,taking new products live faster and reducing total cost ofownership.

Try a14-DayFree Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with SpringCloud:

>> Join Pro and download theeBook

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

Mocking is an essential part of unit testing, and the Mockitolibrary makes it easy to writeclean and intuitive unittests for your Java code.

Get started with mocking and improve your application testsusing ourMockito guide:

Download theeBook

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

Spring 5 added support for reactive programming with the SpringWebFlux module, which has been improved upon ever since. Getstarted with the Reactor project basics andreactive programmingin Spring Boot:

>> Join Pro anddownload the eBook

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

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

But these can also be overused and fall into some commonpitfalls.

Toget a better understanding on how Streams work and howto combine them with other language features, check out our guideto Java Streams:

>> Join Proand download the eBook

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

Do JSON right with Jackson

Download theE-book

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

Get the most out of the Apache HTTP Client

Download theE-book

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

Get Started with Apache Maven:

Download theE-book

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

Working on getting your persistence layer right with Spring?

Explore theeBook

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 theLearnSpring course:

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

Explore Spring Boot 3 and Spring 6 in-depth through building afullREST 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 advancedfunctionality within the Core to the deep OAuth support in theframework.

I built the security material astwo full courses - Core andOAuth, to get practical with these more complex scenarios. Weexplore when and how to use each feature andcode through it onthe backing project.

You can explore the course here:

>> Learn SpringSecurity

Partner – Orkes – NPI EA (cat=Java)
announcement - icon

Modern software architecture is often broken. Slow deliveryleads to missed opportunities, innovation is stalled due toarchitectural complexities, and engineering resources areexceedingly expensive.

Orkes is the leading workflow orchestration platformbuilt to enable teams to transform the way they develop, connect,and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers canfocus on building mission critical applications without worryingabout infrastructure maintenance to meet goals and, simply put,taking new products live faster and reducing total cost ofownership.

Try a14-DayFree Trial of Orkes Conductor today.

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

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

Get started with Spring Data JPA through the guided referencecourse:

>> CHECK OUT THECOURSE

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

Refactor Java code safely — and automatically — withOpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy toput off. That’s where OpenRewrite comes in. The open-sourceframework for large-scale, automated code transformations helpsteams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite atModerne run live, hands-on training sessions — one for newcomersand one for experienced users. You’ll see how recipes work, how toapply them across projects, and how to modernize code withconfidence.

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

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

Regression testing is an important step in the releaseprocess, to ensure that new code doesn't break the existingfunctionality. As the codebase evolves, we want to run these testsfrequently to help catch any issues early on.

The best way to ensure these tests run frequently on anautomated basis is, of course,to include them in the CI/CDpipeline. This way, the regression tests will executeautomatically whenever we commit code to the repository.

In this tutorial, we'll see how to create regression tests usingSelenium, and then include them in our pipelineusing GitHubActions:, to berun on the LambdaTest cloud grid:

>> How to Run SeleniumRegression Tests With GitHub Actions

Course – Black Friday 2025 – NPI (cat=Baeldung)
announcement - icon

Yes, we're now running our Black Friday Sale. All Access and Proare33% off untilnextMonday:

>> EXPLOREACCESS NOW

1. Overview

Nowadays, front-end and back-end components often separate a web application. Usually, we expose APIs as a back-end component for the front-end component or third-party app integrations.

In such a scenario, it is essential to have proper specifications for the back-end APIs. At the same time, the API documentation should be informative, readable, and easy to follow.

Moreover, reference documentation should simultaneously describe every change in the API. Accomplishing this manually is a tedious exercise, so automation of the process was inevitable.

In this tutorial, we’ll look atSwagger 2 for a Spring REST web service, using the Springfox implementation of the Swagger 2 specification. If you are not familiar with Swagger, visitits web page to learn more before continuing with this tutorial.

It’s important to mention that the latest version of Swagger specification, now known as OpenAPI 3.0, is better supported by the Springdoc project and should be used fordocumenting Spring REST API. Moreover, Spring Boot 3 doesn’t support this library.

Further reading:

Generate Spring Boot REST Client with Swagger

Learn how you can generate a Spring Boot REST client using Swagger Code generator.

Introduction to Spring REST Docs

This article introduces Spring REST Docs, a test-driven mechanism to generate documentation for RESTful services that is both accurate and readable.

Introduction to Asciidoctor in Java

Learn how to generate documents using AsciiDoctor.

2. Target Project

The creation of the REST service we will use is not within the scope of this article. If you already have a suitable project, use it. If not, these links are a good place to start:

3. Adding the Maven Dependency

As mentioned above, we will use the Springfox implementation of the Swagger specification. The latest version can be found on Maven Central.

To add it to our Maven project, we need a dependency in thepom.xml file:

<dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-swagger2</artifactId>    <version>3.0.0</version></dependency>

3.1. Spring Boot Dependency

For the Spring Boot based projects, it’s enough to add a singlespringfox-boot-starter dependency:

<dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-boot-starter</artifactId>    <version>3.0.0</version></dependency>

We can add any other starters we need, with a version managed by the Spring Boot parent:

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>3.3.2</version></dependency>

4. Integrating Swagger 2 Into the Project

4.1. Java Configuration

The configuration of Swagger mainly centers around theDocket bean:

@Configurationpublic class SpringFoxConfig {                                        @Bean    public Docket api() {         return new Docket(DocumentationType.SWAGGER_2)            .select()                                            .apis(RequestHandlerSelectors.any())                        .paths(PathSelectors.any())                                    .build();                                               }}

After defining theDocket bean, itsselect() method returns an instance ofApiSelectorBuilder, which provides a way to control the endpoints exposed by Swagger.

We can configure predicates for selectingRequestHandlers with the help ofRequestHandlerSelectors andPathSelectors. Usingany() for both will make documentation for our entire API available through Swagger.

4.2. Configuration Without Spring Boot

In plain Spring projects, we need to enable Swagger 2 explicitly. To do so,we have to use the@EnableSwagger2 on our configuration class:

@Configuration@EnableSwagger2public class SpringFoxConfig {                                    }

Additionally, without Spring Boot, we don’t have the luxury of auto-configuration of our resource handlers.

Swagger UI adds a set of resources that we must configure as part of a class that extendsWebMvcConfigurerAdapter and is annotated with@EnableWebMvc:

@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {    registry.addResourceHandler("swagger-ui.html")      .addResourceLocations("classpath:/META-INF/resources/");    registry.addResourceHandler("/webjars/**")      .addResourceLocations("classpath:/META-INF/resources/webjars/");}

4.3. Verification

To verify that Springfox is working, we can visit this URL in our browser:

http://localhost:8080/v2/api-docs

The result is a JSON response with a large number of key-value pairs, which is not very human readable. Fortunately, Swagger providesSwagger UI for this purpose.

5. Swagger UI

Swagger UI is a built-in solution that makes user interaction with the Swagger-generated API documentation much easier.

5.1. Enabling Springfox’s Swagger UI

To use Swagger UI, we need to add an additional Maven dependency:

<dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-swagger-ui</artifactId>    <version>3.0.0</version></dependency>

Now we can test it in our browser by visiting:

http://localhost:8080/swagger-ui/

The result should look something like this:

Screenshot_1

5.2. Exploring Swagger Documentation

Within Swagger’s response is alist of all controllers defined in our application. Clicking on any of them will list the valid HTTP methods (DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT).

Expanding each method provides additional useful data, such as response status, content-type, and a list of parameters. It is also possible to try each method using the UI.

Swagger’s ability to be synchronized with our code base is crucial. To demonstrate this, we can add a new controller to our application:

@RestControllerpublic class CustomController {    @RequestMapping(value = "/custom", method = RequestMethod.POST)    public String custom() {        return "custom";    }}

Now if we refresh the Swagger documentation, we seecustom-controller in the list of controllers. As we know, there is only one method (POST) shown in Swagger’s response.

6. Spring Data REST

Springfox provides support forSpring Data REST through itsspringfox-data-rest library.

Spring Boot will take care of the auto-configuration if it discovers thespring-boot-starter-data-rest on the classpath.

Now let’s create an entity namedUser:

@Entitypublic class User {    @Id    private Long id;    private String firstName;    private int age;    private String email;    // getters and setters}

Then we’ll create theUserRepository to add CRUD operations on theUser entity:

@Repositorypublic interface UserRepository extends CrudRepository<User, Long> {}

Last, we’ll import theSpringDataRestConfiguration class to theSpringFoxConfigclass:

@EnableSwagger2@Import(SpringDataRestConfiguration.class)public class SpringFoxConfig {    //...}

Note: We’ll use the@EnableSwagger2annotation to enable Swagger since@EnableSwagger2WebMvc is deprecated inversion 3 of the libraries.

Let’s restart the application to generate the specifications for the Spring Data REST APIs:

swagger_user_1

We can see that Springfox has generated the specifications for theUser entity with HTTP methods likeGET,POST, PUT, PATCH, andDELETE.

7. Bean Validations

Springfox also supports thebean validation annotations through itsspringfox-bean-validators library.

First, we’ll add the Maven dependency to ourpom.xml:

<dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-bean-validators</artifactId>    <version>3.0.0</version></dependency>

Again,if we use Spring Boot, we don’t have to provide the above dependency explicitly.

Next, let’s add a few validation annotations like@NotNull and@Min to theUser entity:

@Entitypublic class User {    //...        @NotNull(message = "First Name cannot be null")    private String firstName;        @Min(value = 15, message = "Age should not be less than 15")    @Max(value = 65, message = "Age should not be greater than 65")    private int age;}

Finally, we’ll import theBeanValidatorPluginsConfiguration class to theSpringFoxConfigclass:

@EnableSwagger2@Import(BeanValidatorPluginsConfiguration.class)public class SpringFoxConfig {    //...}

Let’s take a look at the changes in the API specifications:

swagger_user_2

Here, we can observe that theUser model has* required on thefirstName. Also, theminimum andmaximum values are defined for theage.

8. Plugin

In order to add specific features to the API specifications, we can create a Springfox plugin. A plugin can offer various features, from enriching the models and properties to the custom API listings and defaults.

Springfox supports the plugin creation through itsspi module. The spi module provides a few interfaces like theModelBuilderPlugin,ModelPropertyBuilderPlugin, andApiListingBuilderPlugin that act as an extensibility hook to implement a custom plugin.

To demonstrate the capabilities, let’s create a plugin to enrich theemail property of theUser model. We’ll use theModelPropertyBuilderPlugininterface and set the values of thepattern andexample.

First, let’s create theEmailAnnotationPlugin class and override thesupports method to allow anydocumentation type, such as Swagger 1.2 and Swagger 2:

@Component@Order(Validators.BEAN_VALIDATOR_PLUGIN_ORDER)public class EmailAnnotationPlugin implements ModelPropertyBuilderPlugin {    @Override    public boolean supports(DocumentationType delimiter) {        return true;    }}

Then we’ll override theapply method of theModelPropertyBuilderPluginto set the values of the builder properties:

@Overridepublic void apply(ModelPropertyContext context) {    Optional<Email> email = annotationFromBean(context, Email.class);     if (email.isPresent()) {        context.getSpecificationBuilder().facetBuilder(StringElementFacetBuilder.class)          .pattern(email.get().regexp());        context.getSpecificationBuilder().example("[email protected]");    }}

So, the API specifications will show thepattern andexample values of the property annotated with the@Emailannotation.

Next, we’ll add the@Email annotation to theUser entity:

@Entitypublic class User {    //...    @Email(regexp=".*@.*\\..*", message = "Email should be valid")    private String email;}

Last, we’ll enable theEmailAnnotationPlugin in the SpringFoxConfigclass by registering as a bean:

@Import({BeanValidatorPluginsConfiguration.class})public class SpringFoxConfig {    //...    @Bean    public EmailAnnotationPlugin emailPlugin() {        return new EmailAnnotationPlugin();    }}

Let’s check out theEmailAnnotationPlugin in action:

swagger_user_3

We can see the value of thepattern is the same regex (.*@.*\\..*) from theemail property of theUser entity.

Similarly, the value of theexample([email protected]) is the same, as defined in theapply method of theEmailAnnotationPlugin.

9. Advanced Configuration

TheDocket bean of our application can be configured to give us more control over the API documentation generation process.

9.1. Filtering API for Swagger’s Response

It is not always desirable to expose the documentation for the entire API. We can restrict Swagger’s response by passing parameters to theapis() andpaths() methods of theDocket class.

As seen above,RequestHandlerSelectors allows using theany ornone predicates but can also be used to filter the API according to the base package, class annotation, and method annotations.

PathSelectors provides additional filtering with predicates, which scan the request paths of our application. We can useany(),none(),regex(), orant().

In the example below, we will instruct Swagger to include only controllers from a particular package, with specific paths, using theant() predicate:

@Beanpublic Docket api() {                    return new Docket(DocumentationType.SWAGGER_2)                .select()                                             .apis(RequestHandlerSelectors.basePackage("com.baeldung.web.controller"))      .paths(PathSelectors.ant("/foos/*"))                           .build();}

9.2. Custom Information

Swagger also provides some default values in its response, which we can customize, such as “Api Documentation”, “Created by Contact Email”, and “Apache 2.0”.

To change these values, we can use theapiInfo(ApiInfo apiInfo)method — theApiInfo class that contains custom information about the API:

@Beanpublic Docket api() {                    return new Docket(DocumentationType.SWAGGER_2)                .select()      .apis(RequestHandlerSelectors.basePackage("com.example.controller"))      .paths(PathSelectors.ant("/foos/*"))      .build()      .apiInfo(apiInfo());}private ApiInfo apiInfo() {    return new ApiInfo(      "My REST API",       "Some custom description of API.",       "API TOS",       "Terms of service",       new Contact("John Doe", "www.example.com", "[email protected]"),       "License of API", "API license URL", Collections.emptyList());}

9.3. Custom Methods Response Messages

Swagger allowsglobally overriding response messages of HTTP methods throughDocket’sglobalResponses()method.

First, we need to instruct Swagger not to use default response messages. Suppose we want to override500 and403 response messages for allGET methods.

To achieve this, some code must be added to theDocket’s initialization block (original code is excluded for clarity):

.useDefaultResponseMessages(false).globalResponses(HttpMethod.GET, newArrayList(    new ResponseBuilder().code("500")        .description("500 message").build(),    new ResponseBuilder().code("403")        .description("Forbidden!!!!!").build()));
Screenshot_2

10. Swagger UI With an OAuth-Secured API

The Swagger UI provides a number of very useful features that we’ve covered well so far here. But we can’t really use most of these if our API is secured and not accessible.

Let’s see how we can allow Swagger to access an OAuth-secured API using the Authorization Code grant type in this example.

We’ll configure Swagger to access our secured API using theSecurityScheme andSecurityContext support:

@Beanpublic Docket api() {    return new Docket(DocumentationType.SWAGGER_2).select()        .apis(RequestHandlerSelectors.any())        .paths(PathSelectors.any())        .build()        .securitySchemes(Arrays.asList(securityScheme()))        .securityContexts(Arrays.asList(securityContext()));}

10.1. The Security Configuration

We’ll define aSecurityConfiguration bean in our Swagger configuration and set some defaults:

@Beanpublic SecurityConfiguration security() {    return SecurityConfigurationBuilder.builder()        .clientId(CLIENT_ID)        .clientSecret(CLIENT_SECRET)        .scopeSeparator(" ")        .useBasicAuthenticationWithAccessCodeGrant(true)        .build();}

10.2.SecurityScheme

Next, we’ll define ourSecurityScheme; this is used to describe how our API is secured (Basic Authentication, OAuth2, …).

In our case here, we’ll define an OAuth scheme used to secure ourResource Server:

private SecurityScheme securityScheme() {    GrantType grantType = new AuthorizationCodeGrantBuilder()        .tokenEndpoint(new TokenEndpoint(AUTH_SERVER + "/token", "oauthtoken"))        .tokenRequestEndpoint(          new TokenRequestEndpoint(AUTH_SERVER + "/authorize", CLIENT_ID, CLIENT_SECRET))        .build();    SecurityScheme oauth = new OAuthBuilder().name("spring_oauth")        .grantTypes(Arrays.asList(grantType))        .scopes(Arrays.asList(scopes()))        .build();    return oauth;}

Note that we used the Authorization Code grant type, for which we need to provide a token endpoint and the authorization URL of our OAuth2 Authorization Server.

And here are the scopes we need to have defined:

private AuthorizationScope[] scopes() {    AuthorizationScope[] scopes = {       new AuthorizationScope("read", "for read operations"),       new AuthorizationScope("write", "for write operations"),       new AuthorizationScope("foo", "Access foo API") };    return scopes;}

These sync up with the scopes we actually have defined in our application, for the/foos API.

10.3.SecurityContext

Finally, we need to define aSecurityContext for our example API:

private SecurityContext securityContext() {    return SecurityContext.builder()      .securityReferences(        Arrays.asList(new SecurityReference("spring_oauth", scopes())))      .forPaths(PathSelectors.regex("/foos.*"))      .build();}

Note how the name we used here in the reference —spring_oauth — syncs up with the name we used previously in theSecurityScheme.

10.4. Test

Now that we have everything set up and ready to go, let’s take a look at our Swagger UI and try access the Foo API.

We can access the Swagger UI locally:

http://localhost:8082/spring-security-oauth-resource/swagger-ui.html

As we can see, a new Authorize button now exists due to our security configurations:

swagger_1

When we click the Authorize button, we can see the following pop-up to authorize our Swagger UI to access the secured API:

swagger_2

Note that:

  • We can already see the CLIENT_ID and CLIENT_SECRET, as we’ve pre-configured them earlier (but we can still change them).
  • We can now select the scopes we need.

Here’s how the secured API is marked:

swagger_3

And now, finally, we can hit our API!

Of course, it almost goes without saying that we need to be careful how we expose Swagger UI externally, now that this security configuration is active.

11. Conclusion

In this article, we set up Swagger 2 to generate documentation for a Spring REST API. We also explored ways to visualize and customize Swagger’s output. And finally, we looked at a simple OAuth configuration for Swagger.

The code backing this article is available on GitHub. Once you'relogged in as aBaeldung Pro Member, start learning and coding on the project.

And if you’re a studentof REST With Spring, go to Lesson 1 from Module 7 for a deep dive into setting up Swagger with Spring and Spring Boot.

Course – Black Friday 2025 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our Black Friday Sale. All Access and Proare33% off untilnextMonday:

>>EXPLORE ACCESS NOW

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

Modern software architecture is often broken. Slow deliveryleads to missed opportunities, innovation is stalled due toarchitectural complexities, and engineering resources areexceedingly expensive.

Orkes is the leading workflow orchestration platformbuilt to enable teams to transform the way they develop, connect,and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers canfocus on building mission critical applications without worryingabout infrastructure maintenance to meet goals and, simply put,taking new products live faster and reducing total cost ofownership.

Try a14-Day FreeTrial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)
announcement - icon

Modern software architecture is often broken. Slow deliveryleads to missed opportunities, innovation is stalled due toarchitectural complexities, and engineering resources areexceedingly expensive.

Orkes is the leading workflow orchestration platformbuilt to enable teams to transform the way they develop, connect,and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers canfocus on building mission critical applications without worryingabout infrastructure maintenance to meet goals and, simply put,taking new products live faster and reducing total cost ofownership.

Try a14-DayFree Trial of Orkes Conductor today.

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

TheApache HTTP Client is a very robust library, suitablefor both simple and advanced use cases whentesting HTTPendpoints. Check out our guide covering basic request andresponse handling, as well as security, cookies, timeouts, andmore:

>> Downloadthe eBook

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

Handling concurrency in an application can be a tricky processwith manypotential pitfalls. A solid grasp of thefundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications withourJava 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 astaple of Java development. The basic operations like iterating,filtering, mapping sequences of elements are deceptively simple touse.

But these can also be overused and fall into some commonpitfalls.

Toget a better understanding on how Streams work and howto combine them with other language features, check out our guideto Java Streams:

>> Join Proand 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 theLearn Spring course:

>> CHECK OUTTHE COURSE

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

Modern Java teams move fast — but codebasesdon’t always keep up. Frameworks change, dependencies drift, andtech debt builds until it starts to drag on delivery. OpenRewritewas built to fix that: an open-source refactoring engine thatautomates repetitive code changes while keeping developer intentintact.

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

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

Course – Black Friday 2025 – NPI (All)
announcement - icon

Yes, we're now running our Black Friday Sale. All Access and Proare33% off untilnextMonday:

>> EXPLOREACCESS NOW

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

Get started with Spring Boot and with core Spring,through theLearn Spring course:

>> CHECK OUT THECOURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)
Do JSON right with Jackson - book cover
Do JSON right with Jackson - icon
Do JSON right with Jackson
Download the E-book