VOOZH about

URL: https://dzone.com/articles/simplified-spring-swagger

⇱ Simplified Spring Swagger


Related

  1. DZone
  2. Coding
  3. Frameworks
  4. Simplified Spring Swagger

Simplified Spring Swagger

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

Likes
Comment
Save
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 http://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

👁 Image

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.

👁 Image
With spring-swagger-simplified

 👁 Image

 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.

Let's be friends: