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
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Building a CRUD Application With Spring and SimpleJdbcMapper
  • How to Marry MDC With Spring Integration
  • How Spring and Hibernate Simplify Web and Database Management
  • Functional Endpoints: Alternative to Controllers in WebFlux

Trending

  • Identity in Action
  • Jakarta EE 12: Entering the Data Age of Enterprise Java
  • Architecting Proactive IT: NinjaOne Remote Monitoring and Management
  • Metal and Skins
  1. DZone
  2. Coding
  3. Frameworks
  4. Simplified Spring Swagger

Simplified Spring Swagger

Learn more about using Spring Boot Swagger-enabled REST projects.

By 
Raghuraman Ramaswamy user avatar
Raghuraman Ramaswamy
DZone Core CORE ·
Updated Apr. 14, 20 · Tutorial
Likes (41)
Comment
Save
Tweet
Share
81.0K Views

Join the DZone community and get the full member experience.

Join For Free


In this tutorial, we are going to try out a Spring Boot Swagger-enabled REST project and explore how the validation constraints can be utilized automatically for enriching Swagger models.

We are going to refer to https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api and https://spring.io/guides/gs/rest-service/ as starting points.

Prerequisites:

  • Java 8.x

  • Maven 3.x

Steps

Start by creating a Maven JAR project. Below, you will see the initial pom.xml:

Java
 




xxxxxxxxxx
1
56


 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0%20http://maven.apache.org/xsd/maven-4.0.0.xsd">
4
    <modelVersion>4.0.0</modelVersion>
5

          
6
    <groupId>eg</groupId>
7
    <artifactId>sample</artifactId>
8
    <version>0.1.0</version>
9

          
10
    <parent>
11
        <groupId>org.springframework.boot</groupId>
12
        <artifactId>spring-boot-starter-parent</artifactId>
13
        <version>2.0.5.RELEASE</version>
14
    </parent>
15

          
16
    <dependencies>
17
        <dependency>
18
            <groupId>org.springframework.boot</groupId>
19
            <artifactId>spring-boot-starter-web</artifactId>
20
        </dependency>
21

          
22
        <dependency>
23
            <groupId>com.jayway.jsonpath</groupId>
24
            <artifactId>json-path</artifactId>
25
            <scope>test</scope>
26
        </dependency>
27

          
28
        <dependency>
29
<groupId>io.springfox</groupId>
30
<artifactId>springfox-swagger2</artifactId>
31
<version>2.9.2</version>
32
</dependency>
33

          
34
<dependency>
35
<groupId>io.springfox</groupId>
36
<artifactId>springfox-swagger-ui</artifactId>
37
<version>2.9.2</version>
38
</dependency>
39

          
40
    </dependencies>
41

          
42
    <properties>
43
        <java.version>1.8</java.version>
44
    </properties>
45

          
46

          
47
    <build>
48
        <plugins>
49
            <plugin>
50
                <groupId>org.springframework.boot</groupId>
51
                <artifactId>spring-boot-maven-plugin</artifactId>
52
            </plugin>
53
        </plugins>
54
    </build>
55

          
56
</project>



This is the initial POM.xml.

Now, let's create a small Java bean class.

Java
x
98
 
1
package sample;
2
3
import javax.validation.constraints.Email;
4
import javax.validation.constraints.Max;
5
import javax.validation.constraints.Min;
6
import javax.validation.constraints.NotBlank;
7
import javax.validation.constraints.NotNull;
8
import javax.validation.constraints.Pattern;
9
import javax.validation.constraints.Size;
10
import javax.xml.bind.annotation.XmlAccessType;
11
import javax.xml.bind.annotation.XmlAccessorType;
12
import javax.xml.bind.annotation.XmlRootElement;
13
14
import org.hibernate.validator.constraints.CreditCardNumber;
15
@XmlRootElement(name="person")
16
@XmlAccessorType(XmlAccessType.FIELD) 
17
public class Person {
18
private long id;
19
20
21
private String firstName;
22
@NotNull
23
@NotBlank
24
@Size(max = 10)
25
private String lastName;
26
@Pattern(regexp = ".+@.+\\..+", message = "Please provide a valid email address")
27
private String email;
28
29
@Email()
30
private String email1;
31
32
@Min(18)
33
@Max(30)
34
private int age;
35
36
@CreditCardNumber
37
private String creditCardNumber;
38
39
public String getCreditCardNumber() {
40
return creditCardNumber;
41
}
42
43
public void setCreditCardNumber(String creditCardNumber) {
44
this.creditCardNumber = creditCardNumber;
45
}
46
47
public long getId() {
48
return id;
49
}
50
51
public void setId(long id) {
52
this.id = id;
53
}
54
55
public String getEmail1() {
56
return email1;
57
}
58
59
public void setEmail1(String email1) {
60
this.email1 = email1;
61
}
62
63
64
65
@Size(min = 2)
66
public String getFirstName() {
67
return firstName;
68
}
69
70
public void setFirstName(String firstName) {
71
this.firstName = firstName;
72
}
73
74
public String getLastName() {
75
return lastName;
76
}
77
78
public void setLastName(String lastName) {
79
this.lastName = lastName;
80
}
81
82
public String getEmail() {
83
return email;
84
}
85
86
public void setEmail(String email) {
87
this.email = email;
88
}
89
90
public int getAge() {
91
return age;
92
}
93
94
public void setAge(int age) {
95
this.age = age;
96
}
97
98
}


This is an example Java bean.

Now, let's create a controller.

Java
 




xxxxxxxxxx
1
18


 
1
package sample;
2

          
3
import javax.validation.Valid;
4

          
5
import org.springframework.web.bind.annotation.RequestBody;
6
import org.springframework.web.bind.annotation.RequestMapping;
7
import org.springframework.web.bind.annotation.RequestMethod;
8
import org.springframework.web.bind.annotation.RestController;
9

          
10
@RestController
11
public class PersonController {
12
   @RequestMapping( path="/person", method=RequestMethod.POST)
13
    public Person person(@Valid @RequestBody Person person) {
14
        return person;
15
    }
16

          
17

          
18
}



Above is a sample REST Controller.

Here is an example Swagger configuration:

Java
 




xxxxxxxxxx
1
28


 
1
package sample;
2

          
3
import org.springframework.context.annotation.Bean;
4
import org.springframework.context.annotation.Configuration;
5

          
6
import com.google.common.base.Predicates;
7

          
8
import springfox.documentation.builders.PathSelectors;
9
import springfox.documentation.builders.RequestHandlerSelectors;
10
import springfox.documentation.spi.DocumentationType;
11
import springfox.documentation.spring.web.plugins.Docket;
12
import springfox.documentation.swagger2.annotations.EnableSwagger2;
13

          
14
@Configuration
15
@EnableSwagger2
16
public class SwaggerConfig {
17

          
18

          
19
@Bean
20
public Docket api() {
21

          
22

          
23
return new Docket(DocumentationType.SWAGGER_2).select()
24
.apis(Predicates.not(RequestHandlerSelectors.
25
basePackage("org.springframework.boot")))
26
.paths(PathSelectors.any()).build();
27
}
28
}



SwaggerConfig

The Spring Boot application class is shown below:

Java
 




xxxxxxxxxx
1
13


 
1
package sample;
2

          
3

          
4
import org.springframework.boot.SpringApplication;
5
import org.springframework.boot.autoconfigure.SpringBootApplication;
6

          
7
@SpringBootApplication
8
public class SampleApplication {
9

          
10
    public static void main(String[] args) {
11
        SpringApplication.run(SampleApplication.class, args);
12
    }
13
}




At this stage, this is what the sample project looks like in Eclipse IDE:

Project Contents

Above are the project contents.


Next, execute the “mvn clean package” from command prompt or terminal. Then, execute “java -jar target\sample-0.1.0.jar.”

You can also launch the application by running the SampleApplication.java class from your IDE.


Now, let's visit the Swagger UI — http://localhost:8080/swagger-ui.html:

Image title


Press “Try it out” button. Then, press the execute button. The validation errors are reported below.

Image title

Showing below the details for more readability.

Image title

Image title

Input

Response


Note: For now, try with Parameter content Type of “application/json.”

If you are trying the application/XML parameter content type, adjust manually the <Person> tag to <Person>.

While this is great, what about the validation constraints? Is it possible to bring them out automatically in the Swagger specifications of this sample project?

Now, add the spring-swagger-simplified dependency into the pom.xml:

XML
 




xxxxxxxxxx
1


 
1
<dependency>
2
<groupId>org.bitbucket.tek-nik</groupId>
3
<version>1.0.9</version>
4
<artifactId>spring-swagger-simplified</artifactId>
5
</dependency>



Then, add this dependency and make one additional change.


Java
 




xxxxxxxxxx
1
15


 
1
package sample;
2

          
3

          
4
import org.springframework.boot.SpringApplication;
5
import org.springframework.boot.autoconfigure.SpringBootApplication;
6
import org.springframework.context.annotation.ComponentScan;
7

          
8
@SpringBootApplication
9
@ComponentScan(basePackages = { "org.bitbucket.tek.nik.simplifiedswagger", "sample" })
10
public class SampleApplication {
11

          
12
    public static void main(String[] args) {
13
        SpringApplication.run(SampleApplication.class, args);
14
    }
15
}



Above is the updated main application class

Note: the change is in line 7 and line 9.


Note: in case you used a different package name, please replace "sample” with the package name used just above in the @ComponentScan.

Stop and relaunch the application.

Revisit the Swagger UI — http://localhost:8080/swagger-ui.html

The difference is in how the model is reported.

Image title

Earlier

Now


Also note that if you are trying the application/XML parameter content type, now there is no need to adjust manually the <Person> tag to <person>. These are some of the additional benefits offered by above spring-swagger-simplified maven jar.

Note: Instead of this approach you can get similar benefits also by using springfox-bean-validators dependency instead of spring-swagger-simplified.

However lets explore spring-swagger-simplified a little more.

In PersonController lets add one more method.

Java
 




x
18


 
1
@RequestMapping(path = "/personByLastName", method = RequestMethod.GET)
2
    public Collection<Person> findByLastName(@NotNull
3
            @NotBlank
4
            @Size(max = 10)String lastName){
5
        List<Person> hardCoded= new ArrayList<>();
6
        Person person= new Person();
7
        person.setAge(20);
8
        person.setCreditCardNumber("4111111111111111");
9
        person.setEmail("[email protected]");
10
        person.setEmail1("[email protected]");
11
        person.setFirstName("Somefirstname");
12
        person.setLastName(lastName);
13
        person.setId(1);
14
        hardCoded.add(person);
15
        return hardCoded;
16
        
17
    }
18

          



The swagger documentation corresponding to this method will now look like this.

With spring-swagger-simplified

 

 Without spring-swagger-simplified

 

Even parameters show the constraints- see the green text and some of the other differences – eg body vs query- query being definitely the correct representation in this method. Adding springfox-bean-validators does cause the *required and that’s all it offers in this scenario. Using spring-swagger-simplified causes overall better documentation in this scenario.

This was only a brief introduction to the capabilities of this jar. For a more complete understanding of the various features, please try out this more detailed example project with many more fetaures — https://bitbucket.org/tek-nik/simplified-swagger-examples/.

Please also refer to https://dzone.com/articles/doing-more-with-swaggger-and-spring  where we discuss global exception handling amongst other details as part II of this article.

Troubleshooting Tips

  • Ensure prerequisites
  • If using the Eclipse IDE, we might need to do a Maven update on the project after creating all the files.
  • In the SampleApplication main class, make sure you have the correct package name in @ComponentScan. Avoid typos in the package name there.
  • In the Swagger UI, if you are unable to access the “Model” definitions link, it might be because you need to come out of the “try it out “ mode. Click on one or two Cancel buttons that might be visible.


Spring Framework

Opinions expressed by DZone contributors are their own.

Related

  • Building a CRUD Application With Spring and SimpleJdbcMapper
  • How to Marry MDC With Spring Integration
  • How Spring and Hibernate Simplify Web and Database Management
  • Functional Endpoints: Alternative to Controllers in WebFlux

Partner Resources

×

Comments

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

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

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 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook