Wednesday, October 27, 2021

Protocal buffer example for communication between SpringBoot application

 Lets say we have two springboot applcation i.e. producerspringboot and consumerspringboot.

We will try to have the proto class as a data transfer object between them.

we are using to use the same our tutorial.proto given below. We had already created the stub for below proto files in our previous example

http://siddharathadhumale.blogspot.com/2021/10/protocolbuffer-and-its-uses-in-java-and.html

1- tutorial.proto

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
syntax = "proto2";
 
    package tutorial;
 
    option java_multiple_files = true;
    option java_package = "com.example.tutorial.protos";
    option java_outer_classname = "AddressBookProtos";
 
    message Person {
      optional string name = 1;
      optional int32 id = 2;
      optional string email = 3;
 
      enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
      }
 
      message PhoneNumber {
        optional string number = 1;
        optional PhoneType type = 2 [default = HOME];
      }
 
      repeated PhoneNumber phones = 4;
    }
 
    message AddressBook {
      repeated Person people = 1;
    }

Now lets create our first Springboot application names as consumberspringboot application. Please follow the below step religiously to create it.

Note:- We are using STS as an IDE.

Now lets add the protobuf dependencies in pom.xml and also the resttemplate dependencies as we are going to send the proto data from this springboot to another springboot application.

Add following in pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>3.19.0</version>
    </dependency>
 
       <plugin>
            <groupId>com.github.os72</groupId>
            <artifactId>protoc-jar-maven-plugin</artifactId>
            <version>3.11.4</version>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <protocVersion>3.19.0</protocVersion>
                        <inputDirectories>
                            <include>src/main/protobuf</include>
                        </inputDirectories>
                        <outputDirectory>src/main/generated</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Now add following method in controller that will perform CRUD operation. Modify your class given belwo

1- Add RestTemplate in main class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package com.siddhu;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
 
@SpringBootApplication
public class ConsumerspringbootApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(ConsumerspringbootApplication.class, args);
    }
 
     @Bean
       public RestTemplate getRestTemplate() {
          return new RestTemplate();
       }
}
 
2- Create controller
 
package com.siddhu;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
 
import com.example.tutorial.protos.Person;
import com.example.tutorial.protos.PersonModel;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 
@RestController
public class ConsumeWebController {
 
    @Autowired
    RestTemplate restTemplate;
 
    @JsonSerialize(using = ProtobufSerializer.class)
    private Person.Builder builder = Person.newBuilder();
 
 
    // GET Method - To Select the data.
    @RequestMapping(value = "/person")
    public String getPerson() {
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        return restTemplate.exchange("http://localhost:8081/person", HttpMethod.GET, entity, String.class).getBody();
    }
 
    // POST Method :- To insert the data.
    @RequestMapping(value = "/person", method = RequestMethod.POST)
    public String createPerson(@RequestBody PersonModel personModel) {
        HttpHeaders headers = new HttpHeaders();
 
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        HttpEntity<PersonModel> entity = new HttpEntity<PersonModel>(personModel,headers);
        return restTemplate.exchange("http://localhost:8081/person", HttpMethod.POST, entity, String.class).getBody();
    }
 
    // PUT Method :- To update the data.
    @RequestMapping(value = "/person/{id}", method = RequestMethod.PUT)
    public String updatePerson(@PathVariable("id") String id, @RequestBody PersonModel personModel) {
        HttpHeaders headers = new HttpHeaders();
 
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        HttpEntity<PersonModel> entity = new HttpEntity<PersonModel>(personModel,headers);
        return restTemplate.exchange("http://localhost:8081/person/"+id, HttpMethod.PUT, entity, String.class).getBody();
    }
 
 
    // DELETE Method :- To delete the data.
    @RequestMapping(value = "/person/{id}", method = RequestMethod.DELETE)
    public String deletePerson(@PathVariable("id") String id) {
        HttpHeaders headers = new HttpHeaders();
 
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        HttpEntity<PersonModel> entity = new HttpEntity<PersonModel>(headers);
        return restTemplate.exchange("http://localhost:8081/person/"+id, HttpMethod.DELETE, entity, String.class).getBody();
    }
     
 
}

3- Add all the files that we create in using proto files in our project.

As you can see we are making a call using rest template on port 8081. This is our second springboot application called as producerspringboot.

In this producerspringboot we will return the request as per the CRUD opeation request from

Lets First we will try to send the response from our consumerspringboot application and check if we are getting values set in our proto generated files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package com.siddhu;
 
import java.util.Arrays;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
 
import com.example.tutorial.protos.AddressBook;
import com.example.tutorial.protos.Person;
import com.example.tutorial.protos.Person.PhoneNumber;
import com.example.tutorial.protos.Person.PhoneType;
import com.example.tutorial.protos.PersonModel;
 
@RestController
public class ConsumeWebController {
     
     @Autowired
       RestTemplate restTemplate;
 
      
     // GET Method - To Select the data.
       @RequestMapping(value = "/person")
       public String getPerson() {
           
          return getData().toString();
          //return restTemplate.exchange("http://localhost:8080/person", HttpMethod.GET, entity, String.class).getBody();
       }
 
    // POST Method :- To insert the data.
       @RequestMapping(value = "/person", method = RequestMethod.POST)
       public String createPerson(@RequestBody PersonModel personModel) {
          HttpHeaders headers = new HttpHeaders();
          headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
          HttpEntity<PersonModel> entity = new HttpEntity<PersonModel>(personModel,headers);
 
          Person.Builder builder = getData();
          builder.setId(entity.getBody().getId());
          builder.setName(entity.getBody().getName());
          return builder.toString();
          //return restTemplate.exchange("http://localhost:8080/person", HttpMethod.POST, entity, String.class).getBody();
       }
        
    // PUT Method :- To update the data.
       @RequestMapping(value = "/person/{id}", method = RequestMethod.PUT)
       public String updatePerson(@PathVariable("id") String id, @RequestBody PersonModel personModel) {
          HttpHeaders headers = new HttpHeaders();
          headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
          HttpEntity<PersonModel> entity = new HttpEntity<PersonModel>(personModel,headers);
           
          Person.Builder builder = getData();
          builder.setName(entity.getBody().getName());
          return builder.toString();
           
          //return restTemplate.exchange("http://localhost:8080/person/"+id, HttpMethod.PUT, entity, String.class).getBody();
       }
        
        
    // DELETE Method :- To delete the data.
       @RequestMapping(value = "/person/{id}", method = RequestMethod.DELETE)
       public String deletePerson(@PathVariable("id") String id) {
         
          Person.Builder builder = getData();
          builder.clearId();
          return builder.toString();
           
          //return restTemplate.exchange("http://localhost:8080/person/"+id, HttpMethod.DELETE, entity, String.class).getBody();
       }
        
       //Data preparation Start[
        
       private Person.Builder getData()
       {
           Person.Builder builder = Person.newBuilder();
            builder.setName("siddhu");
            builder.setId(126);
            builder.setEmail("shdhumale@gmail.com");
 
            System.out.println("builder.toString():-"+builder.toString());
 
            PhoneNumber.Builder PhoneNumberBuilder = PhoneNumber.newBuilder();
            PhoneNumberBuilder.setNumber("1111111");
            PhoneNumberBuilder.setType(PhoneType.HOME);
            //builder.setPhones(0, PhoneNumberBuilder);
 
 
            PhoneNumber.Builder PhoneNumberBuilder1 = PhoneNumber.newBuilder();
            PhoneNumberBuilder1.setNumber("222222222");
            PhoneNumberBuilder1.setType(PhoneType.MOBILE);
            //builder.setPhones(1, PhoneNumberBuilder1);
 
 
            builder.addPhones(PhoneNumberBuilder).addPhones(PhoneNumberBuilder1);
 
 
            System.out.println("builder after adding PhoneNumberBuilder1.toString():-"+builder.toString());
 
 
            AddressBook.Builder AddressBookBuilder = AddressBook.newBuilder();
            //AddressBookBuilder.setPeople(1, builder);
            AddressBookBuilder.addPeople(builder);
 
 
 
            System.out.println("AddressBookBuilder.toString():-"+AddressBookBuilder.toString());
            return builder;
       }
       
       //Data preparation End]
        
}

Create PersonModel class this is use to take the input from the UI browser.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.example.tutorial.protos;
 
public class PersonModel {
     
    public int id;
    public String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "PersonModel [id=" + id + ", name=" + name + "]";
    }
 
}
  • GET CAll

http://localhost:8080/person

Output
name: “siddhu”
id: 126
email: “shdhumale@gmail.com”
phones {
number: “1111111”
type: HOME
}
phones {
number: “222222222”
type: MOBILE
}

  • POST CAll

http://localhost:8080/person

request body :-

{
“id”:”1″,
“name”:”Dhumale”
}

Output:-

name: “Dhumale”
id: 1
email: “shdhumale@gmail.com”
phones {
number: “1111111”
type: HOME
}
phones {
number: “222222222”
type: MOBILE
}

  • PUT CALL

http://localhost:8080/person/126

request body :-

{
“name”:”dhumale”
}

Output:-

name: “dhumale”
id: 126
email: “shdhumale@gmail.com”
phones {
number: “1111111”
type: HOME
}
phones {
number: “222222222”
type: MOBILE
}

  • DELETE CALL

http://localhost:8080/person/126

Output:-

name: “siddhu”
email: “shdhumale@gmail.com”
phones {
number: “1111111”
type: HOME
}
phones {
number: “222222222”
type: MOBILE
}

As you can see from the above iamges all our rest is giving proper data from the proto generated object.

Now lets create the producer and have all the same method but they accept the parameter from url and reply on the same to consumer.

4- Create a producerspringboot application.

Add our Proto depencies in pom.xml of this project

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.19.0</version>
        </dependency>
         
<plugin>
                <groupId>com.github.os72</groupId>
                <artifactId>protoc-jar-maven-plugin</artifactId>
                <version>3.11.4</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <protocVersion>3.19.0</protocVersion>
                            <inputDirectories>
                                <include>src/main/protobuf</include>
                            </inputDirectories>
                            <outputDirectory>src/main/java</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Our pom.xml will be like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?xml version="1.0" encoding="UTF-8"?>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.0-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.siddhu</groupId>
    <artifactId>producerspringboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>producerspringboot</name>
    <description>This example shows the produce data using Proto file </description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.19.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.github.os72</groupId>
                <artifactId>protoc-jar-maven-plugin</artifactId>
                <version>3.11.4</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <protocVersion>3.19.0</protocVersion>
                            <inputDirectories>
                                <include>src/main/protobuf</include>
                            </inputDirectories>
                            <outputDirectory>src/main/java</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </pluginRepository>
    </pluginRepositories>
 
</project>

Add all the Proto created file in src/java as shown below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package com.siddhu;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
 
import com.example.tutorial.protos.AddressBook;
import com.example.tutorial.protos.Person;
import com.example.tutorial.protos.Person.PhoneNumber;
import com.example.tutorial.protos.Person.PhoneType;
import com.example.tutorial.protos.PersonModel;
 
@RestController
public class ProducerWebController {
 
    @Autowired
    RestTemplate restTemplate;
 
 
    // GET Method - To Select the data.
    @RequestMapping(value = "/person", method = RequestMethod.GET)
    public String getPerson() {
        return getData().toString();
 
    }
 
    // POST Method :- To insert the data.
    @RequestMapping(value = "/person", method = RequestMethod.POST)
    public String createPerson(@RequestBody PersonModel personModel) {
        //        HttpHeaders headers = new HttpHeaders();
        //        MediaType mediaType = new MediaType("application", "x-protobuf");
        //        List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
        //        acceptableMediaTypes.add(mediaType);
        //        headers.setAccept(acceptableMediaTypes);
        //        HttpEntity<PersonModel> entity = new HttpEntity<PersonModel>(personModel,headers);
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        HttpEntity<PersonModel> entity = new HttpEntity<PersonModel>(personModel,headers);
        Person.Builder builder = getData();
        builder.setId(entity.getBody().getId());
        builder.setName(entity.getBody().getName());
        return builder.toString();
 
    }
 
    // PUT Method :- To update the data.
    @RequestMapping(value = "/person/{id}", method = RequestMethod.PUT)
    public String updatePerson(@PathVariable("id") String id, @RequestBody PersonModel personModel) {
        HttpHeaders headers = new HttpHeaders();
        MediaType mediaType = new MediaType("application", "x-protobuf");
        List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
        acceptableMediaTypes.add(mediaType);
        headers.setAccept(acceptableMediaTypes);
        HttpEntity<PersonModel> entity = new HttpEntity<PersonModel>(personModel,headers);
 
        Person.Builder builder = getData();
        builder.setName(entity.getBody().getName());
        return builder.toString();
 
 
    }
 
 
    // DELETE Method :- To delete the data.
    @RequestMapping(value = "/person/{id}", method = RequestMethod.DELETE)
    public String deletePerson(@PathVariable("id") String id) {
        HttpHeaders headers = new HttpHeaders();
        MediaType mediaType = new MediaType("application", "x-protobuf");
        List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
        acceptableMediaTypes.add(mediaType);
        headers.setAccept(acceptableMediaTypes);
 
        Person.Builder builder = getData();
        builder.clearId();
        return builder.toString();
 
 
    }
 
    //Data preparation Start[
 
    private Person.Builder getData()
    {
        Person.Builder builder = Person.newBuilder();
        builder.setName("siddhu");
        builder.setId(126);
        builder.setEmail("shdhumale@gmail.com");
 
        System.out.println("builder.toString():-"+builder.toString());
 
        PhoneNumber.Builder PhoneNumberBuilder = PhoneNumber.newBuilder();
        PhoneNumberBuilder.setNumber("1111111");
        PhoneNumberBuilder.setType(PhoneType.HOME);
        //builder.setPhones(0, PhoneNumberBuilder);
 
 
        PhoneNumber.Builder PhoneNumberBuilder1 = PhoneNumber.newBuilder();
        PhoneNumberBuilder1.setNumber("222222222");
        PhoneNumberBuilder1.setType(PhoneType.MOBILE);
        //builder.setPhones(1, PhoneNumberBuilder1);
 
 
        builder.addPhones(PhoneNumberBuilder).addPhones(PhoneNumberBuilder1);
 
 
        System.out.println("builder after adding PhoneNumberBuilder1.toString():-"+builder.toString());
 
 
        AddressBook.Builder AddressBookBuilder = AddressBook.newBuilder();
        //AddressBookBuilder.setPeople(1, builder);
        AddressBookBuilder.addPeople(builder);
 
 
 
        System.out.println("AddressBookBuilder.toString():-"+AddressBookBuilder.toString());
        return builder;
    }
 
    //Data preparation End]
 
}
  • GET CAll

http://localhost:8080/person

Output
name: “siddhu”
id: 126
email: “shdhumale@gmail.com”
phones {
number: “1111111”
type: HOME
}
phones {
number: “222222222”
type: MOBILE
}

  • POST CAll

http://localhost:8080/person

request body :-

{
“id”:”1″,
“name”:”Dhumale”
}

Output:-

name: “Dhumale”
id: 1
email: “shdhumale@gmail.com”
phones {
number: “1111111”
type: HOME
}
phones {
number: “222222222”
type: MOBILE
}

  • PUT CALL

http://localhost:8080/person/126

request body :-

{
“name”:”dhumale”
}

Output:-

name: “dhumale”
id: 126
email: “shdhumale@gmail.com”
phones {
number: “1111111”
type: HOME
}
phones {
number: “222222222”
type: MOBILE
}

  • DELETE CALL

http://localhost:8080/person/126

Output:-

name: “siddhu”
email: “shdhumale@gmail.com”
phones {
number: “1111111”
type: HOME
}
phones {
number: “222222222”
type: MOBILE
}

Note:-You can also create the java file for the given proto files by running project with “clean build” in maven. As we have protoc-jar-maven-plugin in our pom.xml and our protoc in class path it will create java files at the desired location. By creating java file by this we dont even need to remove this @java.lang.Override and it contains another line i.e. @SuppressWarnings({“unused”})

Source code
https://github.com/shdhumale/consumerspringboot.git
https://github.com/shdhumale/producerspringboot.git