DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Integrate Spring With Open AI
  • Secure Spring Boot Application With Keycloak
  • Spring Config Integration With a PCF Application: A Step-by-Step Guide
  • Integration Between Java and Slack With Webhooks

Trending

  • Next Evolution in Integration: Architecting With Intent Using Model Context Protocol
  • Building an AI/ML Data Lake With Apache Iceberg
  • Is Agile Right for Every Project? When To Use It and When To Avoid It
  • Unlocking the Potential of Apache Iceberg: A Comprehensive Analysis
  1. DZone
  2. Coding
  3. Frameworks
  4. OpenAPI (Swagger) and Spring Boot Integration

OpenAPI (Swagger) and Spring Boot Integration

In this article, take a look at OpenAPI (Swagger) and Spring Boot integration.

By 
Amanuel G. Shiferaw user avatar
Amanuel G. Shiferaw
DZone Core CORE ·
Dec. 18, 19 · Tutorial
Likes (11)
Comment
Save
Tweet
Share
45.8K Views

Join the DZone community and get the full member experience.

Join For Free

Laptop with code on screen

Recently. while working on a requirement, there came a need to upload a file for further processing. Mostly in REST APIs, we are accustomed to using JSON input and output while it is XML for SOAP web services. 

This leads us to research how to satisfy the requirement. In Spring, and mainly in Spring Boot, the auto-configuration feature gives us big-time help even though sometimes we have to disable some features to add custom once or to change the order they are sorted in.

The @Order annotation defines the sorting order of an annotated component or bean. It has an optional value argument that determines the order of the component. The default value is Ordered.LOWEST_PRECEDENCE. This marks that the component has the lowest priority among all other similar components. 

In this article, I will describe how we can integrate OpenAPI (Swagger) specification to a spring boot project, particularly focusing on handling multipart/form-data. In the demo app, we will try to upload a document, particularly an avatar for a user account. We are going to use  MultipartResolver, particularly CommonsMultipartResolver for an added advantage. There is no default resolver implementation used for Spring DispatcherServlets, as an application might choose to parse its multipart requests itself. To define an implementation, create a bean with the id "multipartResolver" in a DispatcherServlet's application context. Such a resolver gets applied to all requests handled by the DispatcherServlet. 

As it has been mentioned in the documentation, there are two concrete implementations included in Spring, as of Spring 3.1:  

  • CommonsMultipartResolver for Apache Commons FileUpload



To use CommonsMultipartResolver to handle the file upload, we need to add the following dependency:

XML
 




xxxxxxxxxx
1


 
1
<dependency>
2
    <groupId>commons-fileupload</groupId>
3
    <artifactId>commons-fileupload</artifactId>
4
    <version>1.3.3</version>
5
</dependency>



And define CommonsMultipartResolver  bean:

Java
 




xxxxxxxxxx
1


 
1
@Bean(name = "multipartResolver")
2
public CommonsMultipartResolver multipartResolver() {
3
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
4
    multipartResolver.setMaxUploadSize(100000);
5
    return multipartResolver;
6
}



StandardServletMultipartResolver for the Servlet 3.0+ Part API   

For more flexibility and configurability, I choose to use CommonsMultipartResolver. Among the advantages, it provides "maxUploadSize", "maxInMemorySize", and "defaultEncoding" settings as bean properties.

Let’s get practical:

  1. Create swagger definition 

  2. Create the Spring Boot Project (I will follow 3 tier model)

  3. Define Database configurations and entity classes

  4. Create JPA Data Repository layer

  5. Create Services and Rest Controllers

  6. Build and run the Project

Tools and Technologies Used

  1. Eclipse (you can use your preferred editor) 

  2. Swagger editor (https://editor.swagger.io/) — Swagger - 2.0

  3. Spring Boot — 2.0.4.RELEASE, Spring Data Jpa (https://thoughts-on-java.org/what-is-spring-data-jpa-and-why-should-you-use-it/)

  4. JDK — 1.8 or later 

  5. Maven

Audience: It is expected that you have a basic understanding of Spring Boot.

Step 1: Why Swagger, You May Ask? 

Earlier, there were no industry standards for developing APIs or documenting them. Swagger emerged as an approach to building APIs and soon became the most popular framework for this purpose. Swagger is the largest framework for designing APIs using a common language and enabling the development across the whole API lifecycle, including documentation, design, testing, and deployment. The framework provides a set of tools that help programmers generate client or server code and many more. For more details, I recommend checking out swagger.io. 

I have created a minimal definition that serves enough for this post. Please refer to the definition file included in the project. I will not go in details of how to define Swagger specs. For details, I recommend referring to https://swagger.io/.

The following are the endpoints for our demo app:

  • Create a user(avatar should be updated later)

  • Get user information by user id

  • Update avatar image (uses multipart/form-data)

Step 2: Create and Import Project

Let's create and import our application in your favorite IDE. There are many ways to create a Spring Boot application, the simplest way is to use Spring Initializr http://start.spring.io/.

You can also import the sample project from here.

Step 3: Define Database Configurations and Entity Classes

There is a single entity for which we will be adding user-name and avatar image. For my convenience, the avatar will only be a string reference to the location/path on the server where the files are located (can also be saved in a database column).

Java
 




xxxxxxxxxx
1
59


 
1
package dzone.aman.restapidemo.dal.models;
2

          
3
import javax.persistence.Column;
4
import javax.persistence.Entity;
5
import javax.persistence.GeneratedValue;
6
import javax.persistence.GenerationType;
7
import javax.persistence.Id;
8
import javax.persistence.Table;
9

          
10
@Entity
11
@Table(name = "users")
12
public class User {
13

          
14
    @Id
15
    @GeneratedValue(strategy=GenerationType.AUTO) 
16
    long id;
17
    
18
    @Column(name = "first_name")
19
    private String firstName;
20
    
21
    @Column(name = "last_name")
22
    private String lastName;
23
    
24
    @Column(name = "avatar")
25
    private String avatar;
26

          
27
    public long getId() {
28
        return id;
29
    }
30

          
31
    public void setId(long id) {
32
        this.id = id;
33
    }
34

          
35
    public String getFirstName() {
36
        return firstName;
37
    }
38

          
39
    public void setFirstName(String firstName) {
40
        this.firstName = firstName;
41
    }
42

          
43
    public String getLastName() {
44
        return lastName;
45
    }
46

          
47
    public void setLastName(String lastName) {
48
        this.lastName = lastName;
49
    }
50

          
51
    public String getAvatar() {
52
        return avatar;
53
    }
54

          
55
    public void setAvatar(String avatar) {
56
        this.avatar = avatar;
57
    }
58

          
59
}



And persistence config (the code is self-explanatory):

Java
 




xxxxxxxxxx
1
65


 
1
package dzone.aman.restapidemo.config;
2
import java.util.Properties;
3
import javax.persistence.EntityManagerFactory;
4
import javax.sql.DataSource;
5
import org.springframework.context.annotation.Bean;
6
import org.springframework.context.annotation.Configuration;
7
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
8
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
9
import org.springframework.jdbc.datasource.DriverManagerDataSource;
10
import org.springframework.orm.jpa.JpaTransactionManager;
11
import org.springframework.orm.jpa.JpaVendorAdapter;
12
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
13
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
14
import org.springframework.transaction.PlatformTransactionManager;
15
import org.springframework.transaction.annotation.EnableTransactionManagement;
16

          
17
@Configuration
18
@EnableJpaRepositories(basePackages = { "dzone.aman.restapidemo.dal.repositories" })
19
@EnableTransactionManagement
20
public class PersinstenceConfig {
21

          
22
    @Bean
23
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
24
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
25
        em.setDataSource(dataSource());
26
        em.setPackagesToScan("dzone.aman.restapidemo.dal.models");
27

          
28
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
29
        em.setJpaVendorAdapter(vendorAdapter);
30
        em.setJpaProperties(additionalProperties());
31

          
32
        return em;
33
    }
34

          
35
    @Bean
36
    public DataSource dataSource() {
37
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
38
        dataSource.setDriverClassName("org.h2.Driver");
39
        dataSource.setUrl("jdbc:h2:file:C:\\Users\\prg\\Desktop\\projects\\testdb"); // temporary database location
40
        dataSource.setUsername("sa");
41
        dataSource.setPassword("");
42
        return dataSource;
43
    }
44

          
45
    @Bean
46
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
47
        JpaTransactionManager transactionManager = new JpaTransactionManager();
48
        transactionManager.setEntityManagerFactory(emf);
49

          
50
        return transactionManager;
51
    }
52

          
53
    @Bean
54
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
55
        return new PersistenceExceptionTranslationPostProcessor();
56
    }
57

          
58
    Properties additionalProperties() {
59
        Properties properties = new Properties();
60
        properties.setProperty("hibernate.hbm2ddl.auto", "update"); //hibernate entity to db generation strategy
61
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
62

          
63
        return properties;
64
    }
65
}




Step 4: Create Repository 

Spring Data makes it very easy to work with entities by merely defining repository interfaces. It takes the domain class to manage as well as the id type of the domain class as type arguments. It comes with a set of predefined methods and allows for the possibility of adding custom methods in each interface, which we will not cover in this post. 

Java
 




xxxxxxxxxx
1


 
1
package dzone.aman.restapidemo.dal.repositories;
2
import org.springframework.data.repository.CrudRepository;
3
import org.springframework.stereotype.Repository;
4
import dzone.aman.restapidemo.dal.models.User;
5
@Repository
6
public interface UserRepository extends CrudRepository<User, Long> {}


 

Step 5: Create Services and Rest Controllers

I won’t go into describing how to create services and controllers since I assume that you have enough knowledge.

Let’s put all together and check what we have done so far. 

  • Run the project with: mvn clean spring-boot:run

  • From postman (or other tools), try to call “http://localhost:8080/v1/user” as the following. You should see resultCode = 200 if everything goes as expected.

  • Update avatar:

  • Check if it has been saved:


Note: Don’t forget to create a folder named  “images” or name it how you like in application.yaml.

You can get the complete example from GitHub.

Thank for following this to the end :)

Further Reading

Swagger Generation With Spring Boot

Spring Boot and Swagger: Documenting RESTful Services

Spring Framework Spring Boot Integration

Opinions expressed by DZone contributors are their own.

Related

  • Integrate Spring With Open AI
  • Secure Spring Boot Application With Keycloak
  • Spring Config Integration With a PCF Application: A Step-by-Step Guide
  • Integration Between Java and Slack With Webhooks

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!