<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Erwan Le Tutour</title>
    <description>The latest articles on DEV Community by Erwan Le Tutour (@erwanlt).</description>
    <link>https://dev.to/erwanlt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F525178%2F3f4898f1-53f6-479c-b4ec-d4a1439bfe6a.png</url>
      <title>DEV Community: Erwan Le Tutour</title>
      <link>https://dev.to/erwanlt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/erwanlt"/>
    <language>en</language>
    <item>
      <title>HTML to PDF — Java</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Sun, 06 Feb 2022 12:33:50 +0000</pubDate>
      <link>https://dev.to/erwanlt/html-to-pdf-java-517a</link>
      <guid>https://dev.to/erwanlt/html-to-pdf-java-517a</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--65HDU_1a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AqbTaTtkKF6qZZ9wyr0xKQA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--65HDU_1a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AqbTaTtkKF6qZZ9wyr0xKQA.jpeg" alt="" width="650" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Case
&lt;/h2&gt;

&lt;p&gt;At the beginning of the year 2020, my wife wanted to redo her CV, so I offered to give her a small &lt;a href="https://github.com/ErwanLT/cv-generator"&gt;tool&lt;/a&gt; where she had only to inform her trainings, her diplomas and her experiences and who would then put them in a document.&lt;br&gt;
At first I wanted to create a document in word format, but I was not satisfied with the rendering, the HTML of the frontend looked better than the final document, that’s when I wondered if there was no way to turn this HTML into PDF.&lt;br&gt;
Which led to the use of &lt;strong&gt;html2pdf&lt;/strong&gt;, my frontend sent me an object corresponding to her CV and I just had to format it and generate the PDF.&lt;/p&gt;
&lt;h2&gt;
  
  
  HTML2PDF
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Dependency
&lt;/h3&gt;

&lt;p&gt;First imported via your favorite dependency manager (here &lt;a href="https://medium.com/javarevisited/6-best-maven-courses-for-beginners-in-2020-23ea3cba89"&gt;maven&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  What is a PDF?
&lt;/h3&gt;

&lt;p&gt;What is a PDF? It’s a file format, so let’s start from the beginning, create a file (thanks captain obvious).&lt;/p&gt;

&lt;h3&gt;
  
  
  Fill the File
&lt;/h3&gt;

&lt;p&gt;To do this, nothing is simpler than to use the &lt;strong&gt;HtmlConverter&lt;/strong&gt; class and its &lt;em&gt;convertToPdf&lt;/em&gt; method which takes as a parameter :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A String : The HTML code as a String&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An OutputStream : The PDF file.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

In the above example, the html variable is a &lt;a href="https://www.java67.com/2014/05/difference-between-stringbuilder-and-StringBuffer-java.html"&gt;StringBuilder &lt;/a&gt;that is built by browsing the properties of a previously populated object.
Warning, tags such as &lt;em&gt;&lt;/em&gt; are not taken into account, so how to insert css?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That simple :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use the style property of the HTML tag&lt;/p&gt;

&lt;p&gt;&amp;lt;&lt;strong&gt;span&lt;/strong&gt; style=”font-weight: bold;”&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;use &lt;em&gt;&lt;/em&gt; tags and feed the content between the two by the content of a css file that you will read before&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

And then use the class property of the HTML tag to add your style

&lt;p&gt;html.append("&lt;/p&gt;")


&lt;p&gt;&lt;strong&gt;&lt;em&gt;Warning&lt;/em&gt;&lt;/strong&gt; : complex file like the &lt;a href="https://medium.com/javarevisited/7-free-courses-to-learn-bootstrap-for-web-designers-and-developers-5135215648f1"&gt;Bootstrap &lt;/a&gt;css can produce some errors in the console of your IDE, but nothing to fear, the file will be generated anyway.&lt;/p&gt;
&lt;h2&gt;
  
  
  pros and cons
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Pro
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Easy to use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Well documented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Converting HTML to PDF is a fraction of the possibility of this library.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Code redundancy if the object in question is already displayed on the frontend side.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complex CSS files can generate console errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintenance difficulty in case of a large file.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>java</category>
      <category>html</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Rock your Github profile</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Fri, 04 Feb 2022 07:09:50 +0000</pubDate>
      <link>https://dev.to/erwanlt/rock-your-github-profile-4f39</link>
      <guid>https://dev.to/erwanlt/rock-your-github-profile-4f39</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nsF5cSpi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4000/1%2Ae7g8DsiUBZK6Ca7i78BdaA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nsF5cSpi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4000/1%2Ae7g8DsiUBZK6Ca7i78BdaA.png" alt="octocat" width="880" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To display a personalize github profile page, you have some steps to follow&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;strong&gt;new Github repository&lt;/strong&gt; named after your username, for exemple if your Github username is GithubRockstar, your repository should be named GithubRockstar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make this repository &lt;strong&gt;public&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Readme.md file in the root of this repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Readme shouldn’t be empty, else you will display nothing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Customizable content
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HRVfHOiI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AI-j9oHpeVc_0-lFkTAcyAw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HRVfHOiI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AI-j9oHpeVc_0-lFkTAcyAw.png" alt="" width="480" height="1376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, I assume that you know how to write markdown, if no I recommend you to read this &lt;a href="https://www.markdownguide.org/basic-syntax/"&gt;manual&lt;/a&gt;, else what can we add in this Readme profile page ?&lt;br&gt;
Pretty much what we can already add in the readme of our different projects repositories.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;badge&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;emote&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;formated text&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;images and gif&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;link&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adding badge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RgPDKOo3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2316/1%2AomV2KyIvcoaXQ-1b_BGEUg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RgPDKOo3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2316/1%2AomV2KyIvcoaXQ-1b_BGEUg.png" alt="" width="880" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;badges are common in Github repository, so how can we add them, simple we will use &lt;a href="https://shields.io/"&gt;**Shield.io&lt;/a&gt; **it permit to build badges and then copy the code to add to your readme.&lt;br&gt;
With that tool you can personalize :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;the logo and it’s color&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the label&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the message and it’s background color&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Github stats
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--33PTH5rh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2764/1%2ADGtxbL_3Y5JVxj8-drpzSw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--33PTH5rh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2764/1%2ADGtxbL_3Y5JVxj8-drpzSw.png" alt="" width="880" height="828"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To add stats card to your readme profile you can :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;use &lt;a href="https://github.com/anuraghazra/github-readme-stats"&gt;github-readme-stats&lt;/a&gt; that let you put link that will transform into card like the badges latter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;use &lt;a href="https://github.com/marketplace/actions/github-profile-summary-cards"&gt;github action&lt;/a&gt; to generate them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Blog post
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k8X0OAN5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2352/1%2A9jTCFM_RnL-QOzBT5NNPPA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k8X0OAN5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2352/1%2A9jTCFM_RnL-QOzBT5NNPPA.png" alt="" width="880" height="889"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are active in writing blog posts, maybe you will want to add them to your readme profil page.&lt;br&gt;
Mine are not generated using some action because I have linked them to the repository concerned, but you can do it using &lt;a href="https://github.com/gautamkrishnar/blog-post-workflow"&gt;blog-post-workflow&lt;/a&gt; (&lt;em&gt;the description of how to use it are in the readme&lt;/em&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  The octocat
&lt;/h3&gt;

&lt;p&gt;Ever wanted to have your own custom octocat to display ? Simple, you just have to go to &lt;a href="https://myoctocat.com/"&gt;my-octocat&lt;/a&gt; to build, personalise and then save it to display it later in your profile page.&lt;/p&gt;

&lt;h2&gt;
  
  
  For the lazy ones
&lt;/h2&gt;

&lt;p&gt;If you don’t have the time to do all the above steps, know that it exist some readme generator that will do the job for you :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://rahuldkjain.github.io/gh-profile-readme-generator/"&gt;https://rahuldkjain.github.io/gh-profile-readme-generator/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://arturssmirnovs.github.io/github-profile-readme-generator/"&gt;https://arturssmirnovs.github.io/github-profile-readme-generator/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://share.streamlit.io/rahulbanerjee26/githubaboutmegenerator/main/__init__.py"&gt;https://share.streamlit.io/rahulbanerjee26/githubaboutmegenerator/main/&lt;strong&gt;init&lt;/strong&gt;.py&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and many more, Google is your friend for finding them.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>github</category>
      <category>readme</category>
      <category>markdown</category>
    </item>
    <item>
      <title>Spring Boot banner</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Thu, 03 Feb 2022 07:49:15 +0000</pubDate>
      <link>https://dev.to/erwanlt/spring-boot-banner-54i9</link>
      <guid>https://dev.to/erwanlt/spring-boot-banner-54i9</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AnPHVux9W1NhTpySv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AnPHVux9W1NhTpySv.png" alt="springboot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usually when you start a Spring Boot application you have something like this in your console output :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;But did you know that you can disable it, or even create a custom one ?&lt;br&gt;
No ? Yes, and it’s simple, so let’s go.&lt;/p&gt;
&lt;h2&gt;
  
  
  Turning banner off
&lt;/h2&gt;

&lt;p&gt;If you don’t want the banner to show during the application launch you have two options :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Setting the property to off in your &lt;em&gt;application.properties&lt;/em&gt; file&lt;/p&gt;

&lt;p&gt;spring.main.banner-mode=off&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In your main class, change the line to run the application from this&lt;/p&gt;

&lt;p&gt;SpringApplication.run(BannerApplication.class, args);&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;to this&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new SpringApplicationBuilder(BannerApplication.class)
        .bannerMode(Banner.Mode.*OFF*)
        .run(args);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Having a custom banner
&lt;/h2&gt;

&lt;p&gt;By default Spring Boot will search a file named banner.txt in your ressources folder to use it, but your banner can also be an image (that will be transformed in ASCII), so if you want to use an image you should add a property in your &lt;em&gt;application.properties&lt;/em&gt; file&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.banner.image.location=**classpath:banner.png**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;here I used a image of Stich as a banner, and had this output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2528%2F1%2Ai8hz-NZtXJqZSV--DLZQDg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2528%2F1%2Ai8hz-NZtXJqZSV--DLZQDg.png" alt="stich"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not very beautiful nor readable, so let’s see what I have if i use a &lt;em&gt;banner.txt&lt;/em&gt; instead of an image.&lt;/p&gt;

&lt;p&gt;So, I created in my ressources folder, a &lt;em&gt;banner.txt&lt;/em&gt; file, in witch i wrote “Hello the World !!” and then started my project&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AUl5OUqtIT82TilDkRIZ4Lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AUl5OUqtIT82TilDkRIZ4Lg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simple and efficace but, we can do better, some site provide you a banner generator that let you choose the text and the font, I have faith in your use of Google to find them, but as an example you can have something like that :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2628%2F1%2AF7npg3HRZBDz0txCNa0sOw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2628%2F1%2AF7npg3HRZBDz0txCNa0sOw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use place holder such as thos to add some informations in your banner.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
In addition, the text can be coloured with variables such as ${AnsiColor.NAME} or ${AnsiBackground.NAME}.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>springboot</category>
      <category>java</category>
      <category>programming</category>
    </item>
    <item>
      <title>JUnit parameterized tests</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Wed, 02 Feb 2022 07:14:48 +0000</pubDate>
      <link>https://dev.to/erwanlt/junit-parameterized-tests-1of9</link>
      <guid>https://dev.to/erwanlt/junit-parameterized-tests-1of9</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AcFCxSe1YVKjn4fa5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AcFCxSe1YVKjn4fa5.jpg" alt="test"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Parameterized test?
&lt;/h2&gt;

&lt;p&gt;Since JUnit4 we can now run the parameterized test, but what does that mean? It means that we can run one test multiple times with different values, great isn’t it?&lt;/p&gt;

&lt;h2&gt;
  
  
  How to?
&lt;/h2&gt;

&lt;p&gt;Yeah that great, but how can I do that?&lt;br&gt;
That simple :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Annotate your test class with &lt;strong&gt;@RunWith(Parameterized.class)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create method annotated with &lt;strong&gt;@Parameters&lt;/strong&gt; that returns an Iterable of Objects as test data set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a constructor that takes as a parameter what is equivalent to one row of your dataset. Or create instance variable that will be equivalent as one parameter and annotate them with &lt;strong&gt;@Parameter(X)&lt;/strong&gt; where X is the parameter index in a row of the dataset.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a test case that will use your &lt;a href="https://javarevisited.blogspot.com/2012/02/difference-between-instance-class-and.html" rel="noopener noreferrer"&gt;instance variable&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok, but concretely can I have an example?&lt;/p&gt;
&lt;h2&gt;
  
  
  Exemple
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Class to test
&lt;/h3&gt;

&lt;p&gt;Let’s take a simple class, that take a &lt;a href="https://javarevisited.blogspot.com/2012/12/how-to-escape-text-when-pasting-as-String-Eclipse-tips.html#axzz5QyeMF7nJ" rel="noopener noreferrer"&gt;String literal&lt;/a&gt; of a calcul as parameter and return the result.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Classique Junit test
&lt;/h3&gt;

&lt;p&gt;In a Classique way I wrote this test class to test each one of my case&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
As you can see, I have one test per test case, here as my class is simple, it doesn’t have that much line, but what if my class was more complexe, it will be a lot more code, redundant isn’t it?

&lt;h3&gt;
  
  
  Parameterized
&lt;/h3&gt;

&lt;p&gt;Here is the same test, but parameterized, you can see all the previous statement established in the How-to section&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The runner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The dataset&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The parameters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The test who use it&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

So with one test, I have my 5 previous test cases tested.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for your reading time, the example in this article are in &lt;a href="https://medium.com/javarevisited/top-10-courses-to-learn-eclipse-junit-and-mockito-for-java-developers-4de1e8d62b96" rel="noopener noreferrer"&gt;Junit4&lt;/a&gt;, if you want an exemple using &lt;a href="https://medium.com/javarevisited/5-courses-to-learn-junit-and-mockito-in-2019-best-of-lot-f217d8b93688?source=---------20------------------" rel="noopener noreferrer"&gt;Junit5&lt;/a&gt;, I will write another article about it.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>java</category>
      <category>programming</category>
      <category>testing</category>
    </item>
    <item>
      <title>Generate API client with OpenApi codegen</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Tue, 01 Feb 2022 07:07:06 +0000</pubDate>
      <link>https://dev.to/erwanlt/generate-api-client-with-openapi-codegen-pei</link>
      <guid>https://dev.to/erwanlt/generate-api-client-with-openapi-codegen-pei</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AQ5BlTDkba1NHrGOO.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AQ5BlTDkba1NHrGOO.jpg" alt="client"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lot of API are documented using &lt;a href="https://swagger.io/" rel="noopener noreferrer"&gt;Swagger&lt;/a&gt;, it’s a good thing that API are documented for us developer for understanding how they work and how to call them.&lt;br&gt;
In this article, I will try my best to help you use this documentation in order to generate a client that will call those API.&lt;/p&gt;
&lt;h2&gt;
  
  
  What you will need
&lt;/h2&gt;

&lt;p&gt;In order to follow this tutorial, you will need a &lt;a href="https://medium.com/javarevisited/top-5-books-and-courses-to-learn-restful-web-services-in-java-using-spring-mvc-and-spring-boot-79ec4b351d12?source=---------17------------------" rel="noopener noreferrer"&gt;REST API&lt;/a&gt;, so you can :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Follow those &lt;a href="https://dev.to/erwanlt/building-a-simple-rest-api-with-springboot-53mc"&gt;tutorial to built your API&lt;/a&gt;, &lt;a href="https://dev.to/erwanlt/documenting-your-api-with-swagger-2-af6"&gt;one to documente it&lt;/a&gt; and then &lt;a href="https://dev.to/erwanlt/migration-from-swagger-2-to-openapi-3-1060"&gt;migrate to openApi&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Having another API documented with openApi 2 ready&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 1 : importe the api json documentation
&lt;/h2&gt;

&lt;p&gt;The easy part of this tutorial is to import the json documentation of the api you want the first one to call an put it in your ressource folder.&lt;br&gt;
In my exemple I will use my clone API and I have created a Jedi one, so in order for my clone to retrieve the jedi, i will import the jedi documentation file for then generate it’s client&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AYsvtAE7hc5lkjajZ5VQJ5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AYsvtAE7hc5lkjajZ5VQJ5g.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Step 2 : Updating our pom.xml
&lt;/h2&gt;

&lt;p&gt;To generate the client we will use the &lt;a href="https://github.com/OpenAPITools/openapi-generator" rel="noopener noreferrer"&gt;openApi codegen maven pluggin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To do that we need to update the build part of our pom.xml and add the pluggin.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
So let’s see what we have here :

&lt;ul&gt;
&lt;li&gt;the goal generate indicate us that the client will be generated during the … generate phase of our build, or can be generated using the maven command &lt;em&gt;mvn generate.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The configuration will hold some option used to customized the generated client like :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;the inputSpec that tell the pluggin where to find your imported file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the generatorName for the case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;sourceFolder will be were my client will be generated in my ressource folder&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can add some more options, I recommend you to read the &lt;a href="https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator-maven-plugin/README.md" rel="noopener noreferrer"&gt;README.md&lt;/a&gt; of the project to have a better understanding of the possible options and choose those that applies to your case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 : Launch a build
&lt;/h2&gt;

&lt;p&gt;Now that we have implemented the pluggin usage, let’s go to &lt;em&gt;clean install&lt;/em&gt; our project.&lt;br&gt;
If all goes right you should have in your target folder, something that look like that :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2APU1b0_CtnQpDqHGEuk5JXA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2APU1b0_CtnQpDqHGEuk5JXA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, at the path described in the pluggin configuration I have my controller JediControllerApi who use ApiClient to call the jedi API and the model described in my documentation Jedi that are generated.&lt;/p&gt;

&lt;p&gt;With that I can directly use this object in my project without having to create my own and then do some mapping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 : exploring the generated files
&lt;/h2&gt;

&lt;p&gt;If you have carefully read the step 1, in my documentation file, the server url was my localhost using port 8082, so in my ApiClient i will also have a field (basepath) that will have this value&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private String basePath = “http://localhost:8082";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;By default the generated client will use Okhttp to make the api call, so you may have to add some more dependencies to your pom.xml in order to run your app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 : using the client
&lt;/h2&gt;

&lt;p&gt;Now that we have gone all the way through the generation of the client, it will be best to use it don’t you think ?&lt;br&gt;
Nothing really hard here, just declare your generated controller and call it to reach the second API&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JediControllerApi jediControllerApi = **new **JediControllerApi();
**return **jediControllerApi.getAllJedi();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Thanks for your reading time, as previously, the code used in this tutorial is findable in &lt;a href="https://github.com/ErwanLT/HumanCloningFacilities" rel="noopener noreferrer"&gt;this Github repository&lt;/a&gt;, branch openApiCodeGen.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>springboot</category>
      <category>openapi</category>
      <category>java</category>
    </item>
    <item>
      <title>Migration from Swagger 2 to OpenAPI 3</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Tue, 01 Feb 2022 07:01:25 +0000</pubDate>
      <link>https://dev.to/erwanlt/migration-from-swagger-2-to-openapi-3-1060</link>
      <guid>https://dev.to/erwanlt/migration-from-swagger-2-to-openapi-3-1060</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AKF_MRwLdyoVL7jQa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AKF_MRwLdyoVL7jQa.png" alt="archives"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lot of API are documented using &lt;a href="https://swagger.io/" rel="noopener noreferrer"&gt;Swagger&lt;/a&gt;, it’s a good thing that API are documented four us dev for understanding how they work and how to call them.&lt;br&gt;
But a lot of these API are documented using Swagger 2, now that &lt;a href="https://swagger.io/specification/" rel="noopener noreferrer"&gt;OpenApi&lt;/a&gt; is released (&lt;a href="https://en.wikipedia.org/wiki/OpenAPI_Specification#Release_dates" rel="noopener noreferrer"&gt;since 2017, the actual version is the 3.1 and is available since 15/02/2021&lt;/a&gt;) some projects didn’t update their documentation tools, I will try in this article to help you do so.&lt;/p&gt;
&lt;h2&gt;
  
  
  What you will need
&lt;/h2&gt;

&lt;p&gt;In order to follow this tutorial, you will need a &lt;a href="https://medium.com/javarevisited/top-5-books-and-courses-to-learn-restful-web-services-in-java-using-spring-mvc-and-spring-boot-79ec4b351d12?source=---------17------------------" rel="noopener noreferrer"&gt;REST API&lt;/a&gt;, so you can :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Follow the &lt;a href="https://dev.to/erwanlt/building-a-simple-rest-api-with-springboot-53mc"&gt;tutorial to built your API&lt;/a&gt; and the &lt;a href="https://dev.to/erwanlt/documenting-your-api-with-swagger-2-af6"&gt;one to documente it&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone the swagger branch of &lt;a href="https://github.com/ErwanLT/HumanCloningFacilities" rel="noopener noreferrer"&gt;this repository&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Having your own API documented using Swagger 2 ready&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 1 : getting ride of SpringFox dependencies
&lt;/h2&gt;

&lt;p&gt;When we first implemented our Swagger, we add these dependencies to have&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The json generated at &lt;a href="http://localhost:8080/v2/api-docs" rel="noopener noreferrer"&gt;http://localhost:8080/v2/api-docs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The UI at &lt;a href="http://localhost:8080/swagger-ui.html" rel="noopener noreferrer"&gt;http://localhost:8080/swagger-ui.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Bean Validation&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

We will not need it anymore, so you can suppress them from your &lt;a href="https://maven.apache.org/guides/introduction/introduction-to-the-pom.html" rel="noopener noreferrer"&gt;pom.xml&lt;/a&gt;.
Those 3 dependencies will be replaced by just one
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

With just this dependency we will have:&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The json generated &lt;a href="http://localhost:8080/v3/api-docs/" rel="noopener noreferrer"&gt;http://localhost:8080/v3/api-docs/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The UI page &lt;a href="http://localhost:8080/swagger-ui.html" rel="noopener noreferrer"&gt;http://localhost:8080/swagger-ui.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The bean validation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, we should have some compilation problems because of some annotations due to the missing dependencies that we have replaced.&lt;br&gt;
We will corrige that now.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: changing the annotations of the endpoints
&lt;/h2&gt;

&lt;p&gt;In the previous tutorial, we documented our API using a configuration class&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Here we have 2 choices

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;declaring a new configuration class&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using annotations in one of our &lt;a href="https://javarevisited.blogspot.com/2017/11/difference-between-component-service.html" rel="noopener noreferrer"&gt;controllers&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will give you 2 equivalent example of the previous code in OpenApi way&lt;/p&gt;
&lt;h3&gt;
  
  
  Configuration class
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  With annotations
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  What it will look like in the UI
&lt;/h3&gt;

&lt;p&gt;The previous example will look the same in the UI page, so it’s up to you to choose what method you want to use&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Acspnv6JdTib09Vhkti8ldg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Acspnv6JdTib09Vhkti8ldg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: changing the annotations of the endpoints
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Swagger 2.0 annotation
&lt;/h3&gt;

&lt;p&gt;Let’s take an example&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Here is a &lt;a href="https://www.java67.com/2016/09/when-to-use-put-or-post-in-restful-web-services.html" rel="noopener noreferrer"&gt;POST method&lt;/a&gt; documented with classique Swagger 2 annotations

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;@ApiOperation&lt;/strong&gt; : Describes an operation or typically a HTTP method against a specific path.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;@ApiResponses&lt;/strong&gt; : A wrapper to allow a list of multiple ApiResponse objects. Here I have 2 &lt;strong&gt;@ApiResponse&lt;/strong&gt; to describe my 200 and 500 HTTP status return code.&lt;br&gt;
I can also describe what my status will return, the 200 will respond with an objet, so I added the object class to &lt;em&gt;response&lt;/em&gt; field.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That will render like the following picture in the UI page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5200%2F0%2AlEy9hNfq7JKeiSXM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5200%2F0%2AlEy9hNfq7JKeiSXM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5200%2F0%2AumcAcTvxyu9sBGZB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5200%2F0%2AumcAcTvxyu9sBGZB.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here a second example with this time a GET method&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Here in addition of the previous annotations, I have added the documentation of the method parameter using &lt;strong&gt;@ApiParam&lt;/strong&gt;.

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5556%2F1%2AXGoQfsjUPQN9mroeA368pA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5556%2F1%2AXGoQfsjUPQN9mroeA368pA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the new dependency, the annotation described are no longer the same.&lt;br&gt;
So let’s see what has changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenAPI annotations
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
With the 2 above example who is the same method that i used previously we can now see some of the changes that was operated.

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;@ApiOperation *&lt;em&gt;-&amp;gt; *&lt;/em&gt;@Operation&lt;/strong&gt;, the &lt;em&gt;value&lt;/em&gt; field become &lt;em&gt;summary&lt;/em&gt; and &lt;em&gt;notes *become *description.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;@ApiResponse&lt;/strong&gt; : the field &lt;em&gt;code&lt;/em&gt; become &lt;em&gt;responseCode&lt;/em&gt; and is no longer an integer but a string, also the field &lt;em&gt;message&lt;/em&gt; become &lt;em&gt;description&lt;/em&gt;.&lt;br&gt;
The biggest change is that the response field is now an annotation. &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/content"&gt;@content&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;@ApiParam&lt;/strong&gt; become &lt;strong&gt;@Parameter&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are other change, but since they are not used here, i recommend you to use the &lt;a href="https://springdoc.org/#Introduction" rel="noopener noreferrer"&gt;openAPI documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: changing the annotations of the models
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Swagger 2.0 annotation
&lt;/h3&gt;

&lt;p&gt;So in Swagger 2 when i wanted to document an object, my class looked somewhere like this&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
As you can see, my classe is annoted with the &lt;strong&gt;@ApiModel&lt;/strong&gt; and it’s properties with &lt;strong&gt;@ApiModelProperty.&lt;br&gt;
*&lt;em&gt;The *&lt;/em&gt;@ApiModelProperty&lt;/strong&gt; allow us to add definitions such as description (value), name, data type, example values, and allowed values.

&lt;h3&gt;
  
  
  OpenAPI annotations
&lt;/h3&gt;

&lt;p&gt;If you look closely at my ApiResponse with status code 200, you will see that the response is now &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/content"&gt;@content&lt;/a&gt;&lt;/strong&gt;, and that we gave the schema field the class that will be returned like this @Schema(implementation = MyClass.class).&lt;br&gt;
With that annotation, OpenApi know which class to load, so i don’t have to annotate my class with an &lt;strong&gt;@ApiModel&lt;/strong&gt; like annotation, but I still can document my property.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
So, what I have done here ?&lt;br&gt;
Like previously, my fields are documented, but I have used 2 differentes method for some validation (size).

&lt;p&gt;I can use the bean validation annotation, or I can use the property of the Schema annotation, the result will be the same.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2112%2F1%2AYhvQOL3wccWxluJrjwLjZQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2112%2F1%2AYhvQOL3wccWxluJrjwLjZQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The position property don’t exist anymore, the fields are in the same order as the class.&lt;/p&gt;

&lt;p&gt;Thanks for your reading time, as previously, the code used in this tutorial is findable in &lt;a href="https://github.com/ErwanLT/HumanCloningFacilities" rel="noopener noreferrer"&gt;this Github repository&lt;/a&gt;, branch toOpenApi.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>openapi</category>
      <category>springboot</category>
      <category>java</category>
    </item>
    <item>
      <title>Monitoring your REST api with Prometheus and Grafana</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Tue, 01 Feb 2022 06:54:39 +0000</pubDate>
      <link>https://dev.to/erwanlt/monitoring-your-rest-api-with-prometheus-and-grafana-23dp</link>
      <guid>https://dev.to/erwanlt/monitoring-your-rest-api-with-prometheus-and-grafana-23dp</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LNtRL-Uc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2800/1%2AsPh4Js8NUp-y-7D0gtl3Hg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LNtRL-Uc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2800/1%2AsPh4Js8NUp-y-7D0gtl3Hg.jpeg" alt="monitoring" width="880" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After having &lt;a href="https://dev.to/erwanlt/building-a-simple-rest-api-with-springboot-53mc"&gt;built&lt;/a&gt;, &lt;a href="https://dev.to/erwanlt/securing-your-rest-api-with-springsecurity-57f7"&gt;secured&lt;/a&gt; and &lt;a href="https://dev.to/erwanlt/documenting-your-api-with-swagger-2-af6"&gt;documented&lt;/a&gt; our API, we will now learn how to monitor it.&lt;br&gt;
To do that we will use &lt;a href="https://prometheus.io/"&gt;Prometheus&lt;/a&gt; and &lt;a href="https://grafana.com/"&gt;Grafana&lt;/a&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prometheus&lt;/strong&gt; will serve to collect the API metrics&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Grafana&lt;/strong&gt; will display it in panel to help to visualise the metrics&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What you will need
&lt;/h2&gt;

&lt;p&gt;If you have followed the previous tutorials, you will only need to &lt;a href="https://docs.docker.com/get-docker/"&gt;install docker&lt;/a&gt; to host our prometheus and grafana.&lt;br&gt;
Else you need a running API, you can do that with these 2 options :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;pull &lt;a href="https://github.com/ErwanLT/HumanCloningFacilities"&gt;this repository&lt;/a&gt; branch master&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create a quickstart project with &lt;a href="https://start.spring.io/"&gt;Spring initializr&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;installing docker&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Importing Grafana and Prometheus images
&lt;/h2&gt;

&lt;p&gt;To add grafana and Prometheus to your docker local registry go to docker-hub to search them :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://hub.docker.com/r/grafana/grafana/"&gt;grafana&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://hub.docker.com/r/prom/prometheus"&gt;prometheus&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then, pull then using the command line.&lt;/p&gt;

&lt;p&gt;Normally you should see something like this in your docker CLI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TgghMMMp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3296/1%2A9VMVIh0WwLeJz_HCBb9g9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TgghMMMp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3296/1%2A9VMVIh0WwLeJz_HCBb9g9w.png" alt="" width="880" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can directly run Grafana in a &lt;a href="https://javarevisited.blogspot.com/2020/11/why-devops-engineer-learn-docker-kubernetes.html#axzz6dXsEfLvJ"&gt;container&lt;/a&gt;, but Prometheus will need further configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exporting our metrics to Prometheus
&lt;/h2&gt;

&lt;p&gt;Firstly to export our API metric, we need to add some new dependencies to the pom.xml&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Spring boot actuator to expose metrics endpoint --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-actuator&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;!-- Micormeter core dependecy  --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.micrometer&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;micrometer-core&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;!-- Micrometer Prometheus registry  --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.micrometer&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;micrometer-registry-prometheus&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Actuators
&lt;/h3&gt;

&lt;p&gt;The first dependency let us know of some usefulls information about our running application.&lt;br&gt;
To read them we only need to start our application go to &lt;a href="http://localhost:8080/actuator"&gt;http://localhost:8080/actuator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jG0ZKYg1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2376/1%2A__DHb1rkwogmMKCBa-IaCg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jG0ZKYg1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2376/1%2A__DHb1rkwogmMKCBa-IaCg.png" alt="" width="880" height="967"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Prometheus
&lt;/h3&gt;

&lt;p&gt;As you can see in the capture upside, with the third dependency, we have a prometheus section in our actuator.&lt;br&gt;
If I follow the link i will see a list of values representing metrics from my application, like :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;jvm information&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;http request status on endpoints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;log event&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;…&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that we expose our metrics to the /prometheus endpoint, we need to configure the prometheus server to collect them.&lt;/p&gt;
&lt;h3&gt;
  
  
  The configuration file
&lt;/h3&gt;

&lt;p&gt;We need to configure our prometheus to collect data from our endpoint, to do that we need to overwrite the prometheus.yml file.&lt;/p&gt;

&lt;p&gt;First we need to create a prometheus.yml file.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;global:
  scrape_interval:     15s 
  evaluation_interval: 15s 

rule_files:
*# - "first_rules.yml"
# - "second_rules.yml"

*scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['127.0.0.1:9090']

  - job_name: 'spring-actuator'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['XXXXXX:8080']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Replace the XXXXXXX by your IP adresse, as prometheus will be running in a &lt;a href="https://medium.com/javarevisited/10-free-courses-to-learn-docker-and-devops-for-frontend-developers-691ac7652cee?source=---------94------------------"&gt;docker container&lt;/a&gt;, he will not know localhost.&lt;/p&gt;

&lt;p&gt;Secondly we will create a docker file to run prometheus with the new configuration file, myApp.dockerfile&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM prom/prometheus
ADD prometheus.yml /etc/prometheus/prometheus.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With that file, we specify to docker to create a copy of the prometheus image and to add our newly created prometheus.yml to the correct directory.&lt;/p&gt;

&lt;p&gt;Now that we collect our metrics on prometheus, we can now configure our datasource in Grafana.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Grafana
&lt;/h2&gt;

&lt;h3&gt;
  
  
  login
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m9_L6aRP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2084/1%2AhxAO_LEab1MIRAipnzTwMw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m9_L6aRP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2084/1%2AhxAO_LEab1MIRAipnzTwMw.png" alt="" width="880" height="915"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you access your Grafana on your container, you arrive to a login page, to pass that page you can use the default credentials &lt;strong&gt;admin/admin.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring the datasource
&lt;/h3&gt;

&lt;p&gt;In the navigation bar on the left, when you click on the gear icon, a submenu named datasource is displayed, click on it.&lt;/p&gt;

&lt;p&gt;Here we want to add our previously configured Prometheus as the datasource.&lt;/p&gt;

&lt;p&gt;In the list of possible datasource, select Prometheus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EXMx-R3T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2588/1%2Aea5bnwcmtbE8oCkHvBl1bQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EXMx-R3T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2588/1%2Aea5bnwcmtbE8oCkHvBl1bQ.png" alt="" width="880" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the URL input, enter your prometheus container ip adresse.&lt;br&gt;
You can test your connexion, if it’s valid you can continue to the next step, if you have error, you can read the grafana documentation to find a way to connect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating dashboard
&lt;/h3&gt;

&lt;p&gt;Now that we have logged into Grafana, we can produce some dashboard to display our metrics&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ycZM286_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3748/1%2ACCgFIJi53M4bOUXPIT1tCA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ycZM286_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3748/1%2ACCgFIJi53M4bOUXPIT1tCA.png" alt="" width="880" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here I have created 4 request to display the number of &lt;a href="https://javarevisited.blogspot.com/2016/04/what-is-purpose-of-http-request-types-in-RESTful-web-service.html"&gt;HTTP request&lt;/a&gt; to my API endpoint by status code.&lt;/p&gt;

&lt;p&gt;Thanks for your reading time, as previously, the code used in this tutorial is findable in &lt;a href="https://github.com/ErwanLT/HumanCloningFacilities"&gt;this Github repository&lt;/a&gt;, branch monitoring.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>programming</category>
      <category>springboot</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Documenting your API with Swagger 2</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Mon, 31 Jan 2022 13:15:43 +0000</pubDate>
      <link>https://dev.to/erwanlt/documenting-your-api-with-swagger-2-af6</link>
      <guid>https://dev.to/erwanlt/documenting-your-api-with-swagger-2-af6</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5B0xhT3K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Ag9tMh-Nn0gocNGwgDvJxhA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5B0xhT3K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Ag9tMh-Nn0gocNGwgDvJxhA.png" alt="Jedi archives" width="880" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So after having &lt;a href="https://dev.to/erwanlt/building-a-simple-rest-api-with-springboot-53mc"&gt;built our API&lt;/a&gt; and then &lt;a href="https://dev.to/erwanlt/securing-your-rest-api-with-springsecurity-57f7"&gt;secured it&lt;/a&gt;, we will now document it to allow others to use it more easily. To do that, we will implement &lt;a href="https://swagger.io/"&gt;Swagger&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will need
&lt;/h2&gt;

&lt;p&gt;In order to follow this tutorial, you will need a REST API, so you can :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Follow the &lt;a href="https://medium.com/javarevisited/building-a-simple-rest-api-with-springboot-3f2e4b123ebb"&gt;tutorial to built your API&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone the master branch of &lt;a href="https://github.com/ErwanLT/HumanCloningFacilities"&gt;this repository&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Having your own API ready&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What il will look like
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7VROPd0F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5424/1%2A-4H-EHMutQSg21bb1g0O-w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7VROPd0F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5424/1%2A-4H-EHMutQSg21bb1g0O-w.png" alt="UML representation" width="880" height="1107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  I document, you document, we document
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The first dependency
&lt;/h3&gt;

&lt;p&gt;So, if we want to use swagger for our API, we first need to add a maven dependency&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.springfox&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;springfox-swagger2&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.9.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  The java configuration
&lt;/h3&gt;

&lt;p&gt;To enable Swagger, we need to configure it, so let's create a configuration class.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
As you can see, in the method apiInfo, I describe the general informations of my API :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The title&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The description&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The version&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The termes of service (url)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Contact to join the API owner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The licence&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The licence url&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The API vendor’s extension&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these informations will be displayed latter.&lt;/p&gt;

&lt;h3&gt;
  
  
  The JSON generated
&lt;/h3&gt;

&lt;p&gt;So if I start my application and go to the &lt;a href="http://localhost:8080/v2/api-docs"&gt;http://localhost:8080/v2/api-docs&lt;/a&gt;, i will see a JSON representation of my documentation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nkTBHBsc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3040/1%2Ar4emRSBTD8z_VhAaAxWVfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nkTBHBsc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3040/1%2Ar4emRSBTD8z_VhAaAxWVfw.png" alt="swagger-json" width="880" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, i find all the informations that I have filled in my configuration class.&lt;br&gt;
But let’s be honest, a json file is good, but an IHM will be better.&lt;br&gt;
So let’s implement this IHM.&lt;/p&gt;

&lt;h3&gt;
  
  
  The swagger-ui IHM
&lt;/h3&gt;

&lt;p&gt;To enable the IHM, we don’t need to do so much work, just adding a maven dependency is enough&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.springfox&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;springfox-swagger-ui&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.9.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;And then, if I restart my application and go to &lt;a href="http://localhost:8080/swagger-ui.html"&gt;http://localhost:8080/swagger-ui.html&lt;/a&gt;, I can see a beautiful (all relative) IHM that display my API information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vbMhZGb8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2176/1%2A6K4tTvp5TZwM0DrwCJj-gg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vbMhZGb8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2176/1%2A6K4tTvp5TZwM0DrwCJj-gg.png" alt="swagger-ui" width="880" height="1090"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now we have our swagger IHM, but there is no true documentation on it, we have our endpoint, and if we extend it we have some informations, but nothing very documented.&lt;br&gt;
So let’s add our documentation.&lt;/p&gt;
&lt;h3&gt;
  
  
  Documenting our controller
&lt;/h3&gt;

&lt;p&gt;with the previous step completed, if I expend the POST endpoint i should see something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MhRwaDfz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5524/1%2AehI0qfCMAsLhmcN7TC7o3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MhRwaDfz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5524/1%2AehI0qfCMAsLhmcN7TC7o3w.png" alt="" width="880" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let’s add some documentation on my &lt;a href="https://javarevisited.blogspot.com/2017/08/difference-between-restcontroller-and-controller-annotations-spring-mvc-rest.html#ixzz6OYNB9oii"&gt;controller&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
With&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;@ApiOperation&lt;/strong&gt; : I can add a more detailed description of my endpoint (value), and specified what it consume and produce.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;@ApiResponses&lt;/strong&gt; : I describe the returns codes of my API, here the 200 and the 500.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if i restart my application (again) I should be able to see the change&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mAQFv4Hg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5524/1%2AjoOGe0LzCYY_a6_cAxwCsw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mAQFv4Hg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5524/1%2AjoOGe0LzCYY_a6_cAxwCsw.png" alt="" width="880" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mOnf6IyB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5524/1%2AUKyScMqmRi5X9NoghiRFYQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mOnf6IyB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5524/1%2AUKyScMqmRi5X9NoghiRFYQ.png" alt="" width="880" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s better.&lt;br&gt;
We have see that in my API documentation, that my endpoints are documented, but I also have a section about my models (what my API produce or consume), and these models can also be documented.&lt;br&gt;
So let’s go and add some documentation on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documenting our models&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I have my Clone class as my model, in here i have few properties that are not documented and it represented in my swagger like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2yT9fKX1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2416/1%2AN--NazNwxdIBKSpWxAYUrQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2yT9fKX1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2416/1%2AN--NazNwxdIBKSpWxAYUrQ.png" alt="" width="880" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Except the type of my properties, I don’t have so much info on it.&lt;br&gt;
To add it we will use the &lt;strong&gt;@ApiModel&lt;/strong&gt; annotation on the class and the **@ApiModelProperty **annotation on properties that will allow us to add definitions such as description (value), name, data type, example values, and allowed values.&lt;/p&gt;

&lt;p&gt;SO now my Clone class will be like this :&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
and in my Swagger-ui, now the model will be like this :

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nlosUqGm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AJ8Te-bmUlMFRvZ59sveHcg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nlosUqGm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AJ8Te-bmUlMFRvZ59sveHcg.png" alt="" width="880" height="539"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see the mandatory field that i have described have a &lt;em&gt;**.&lt;/em&gt;*&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing our API with Swagger
&lt;/h2&gt;

&lt;p&gt;So now that we have our swagger running and well documented, what can we do with it ?&lt;br&gt;
We can test our endpoint !&lt;br&gt;
Scrolling through the swagger-ui page, you should have noticed this button in each one of our endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E5sjkYeK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AdGt-aUiJCsP3yQWe6bK2PA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E5sjkYeK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AdGt-aUiJCsP3yQWe6bK2PA.png" alt="" width="260" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click on it, it will slightly change your page so that you can write the body of the request, or edit some parameter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nlUGwoAF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AB8xlnkzOxrHYyYmpAQEvLQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nlUGwoAF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AB8xlnkzOxrHYyYmpAQEvLQ.png" alt="" width="424" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you can execute the query against your localhost and see the result below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SBMGMpKK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2300/1%2AOcgVtYiEqBe7nfEcC2qkVA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SBMGMpKK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2300/1%2AOcgVtYiEqBe7nfEcC2qkVA.png" alt="" width="880" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for your reading time, as previously, the code used in this tutorial is findable in &lt;a href="https://github.com/ErwanLT/HumanCloningFacilities"&gt;this Github repository&lt;/a&gt;, branch swagger.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>springboot</category>
      <category>java</category>
      <category>programming</category>
    </item>
    <item>
      <title>Securing your rest API with SpringSecurity</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Mon, 31 Jan 2022 13:11:37 +0000</pubDate>
      <link>https://dev.to/erwanlt/securing-your-rest-api-with-springsecurity-57f7</link>
      <guid>https://dev.to/erwanlt/securing-your-rest-api-with-springsecurity-57f7</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gvglxLPX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AvVNRSi6bmrQOYsgW5UgOBA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gvglxLPX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AvVNRSi6bmrQOYsgW5UgOBA.jpeg" alt="order66" width="630" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we will do
&lt;/h2&gt;

&lt;p&gt;After creating our API in &lt;a href="https://dev.to/erwanlt/building-a-simple-rest-api-with-springboot-53mc"&gt;the previous step&lt;/a&gt;, we will now secure it using Spring Security.&lt;br&gt;
In order to do so, we need to add 2 dependencies to our pom.xml file&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-security&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.security&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-security-test&amp;lt;/artifactId&amp;gt;
    &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  What it will look like
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6wUmjVSe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4848/1%2A3nhII1S2DrVWCyljQouUNw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6wUmjVSe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4848/1%2A3nhII1S2DrVWCyljQouUNw.png" alt="UML" width="880" height="1223"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Execute Order 66
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Account Entity
&lt;/h3&gt;

&lt;p&gt;In order to secure our API, we will use some &lt;a href="https://javarevisited.blogspot.com/2013/07/role-based-access-control-using-spring-security-ldap-authorities-mapping-mvc.html"&gt;roles&lt;/a&gt;, so to achieve that, we will create an account entity that will use those roles.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  The Repository
&lt;/h3&gt;

&lt;p&gt;In order to know if the user who will try to use our API exists and have the role associated we also need to create the repository linked to the Account entity.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
When we created the CloneRepository earlier, we didn’t need to create any method in it because all the methods we used were already implemented thanks to &lt;a href="http://www.java67.com/2012/08/what-is-inheritance-in-java-oops-programming-example.html"&gt;inheritance&lt;/a&gt;.&lt;br&gt;
Here we will need a specific method like the one above &lt;em&gt;findOneByUsername&lt;/em&gt;, with that one our repository will know that we search only one result that matches the String username passed on the argument. (see &lt;a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods"&gt;Spring Data JPA&lt;/a&gt; doc if you want to know how it works).
&lt;h3&gt;
  
  
  The controller
&lt;/h3&gt;

&lt;p&gt;Now that we have created the account that will have the roles to connect to our API we can update our controller to make it accept these roles on its method.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
As you can see, our method now avec the @PreAuthorize annotation that indicates the roles who can access it.

&lt;p&gt;So, is my API secured now? The response is &lt;strong&gt;NO&lt;/strong&gt; !&lt;br&gt;
We have created the account entity and its a repository, we have upgraded our controller to indicate the roles that it will use, but we have yet to implement the security configuration.&lt;br&gt;
So now let’s implement it.&lt;/p&gt;
&lt;h2&gt;
  
  
  The configuration
&lt;/h2&gt;

&lt;p&gt;In order to make all the above code run properly, we will implement security.&lt;br&gt;
To do so we will extend &lt;strong&gt;WebSecurityConfigurerAdapter&lt;/strong&gt; in a configuration class.&lt;/p&gt;
&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
As you can see in the first configure method, we indicate the roles who can access the endpoint.&lt;br&gt;
In the second method, we describe the service that will be used to authenticate the user.
&lt;h3&gt;
  
  
  Authentication Service
&lt;/h3&gt;

&lt;p&gt;To authenticate our user we need to create a service that will implement the &lt;strong&gt;UserDetailsService&lt;/strong&gt; from the &lt;a href="https://medium.com/javarevisited/top-10-courses-to-learn-spring-security-and-oauth2-with-spring-boot-for-java-developers-8f0222d6066d?source=---------5-----------------------"&gt;Spring Security&lt;/a&gt; package, especially the method &lt;em&gt;loadUserByUsername&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Testing our API
&lt;/h2&gt;

&lt;p&gt;To test our API we need to first launch our application.&lt;br&gt;
Then we can try to connect to the entry point that we created in our controller using &lt;a href="https://medium.com/javarevisited/7-best-courses-to-learn-postman-tool-for-web-service-and-api-testing-f225c138fa5a?source=---------13------------------"&gt;postman&lt;/a&gt; or any other tool that permits you to make HTTP calls.&lt;/p&gt;

&lt;p&gt;the examples will be the same as when we created the API, but with basic authentication.&lt;br&gt;
In order to test my API, I have created 2 accounts that will be pre-loaded in the database.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
So now if I try to access a datapoint with bad credentials, i will have a &lt;a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Status/401"&gt;401 error&lt;/a&gt;.

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "timestamp": "2021-03-08T09:45:09.332+00:00",
  "status": 401,
  "error": "Unauthorized",
  "message": "Unauthorized",
  "path": "/kamino/order66"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And if i try to access a datapoint when i don’t have the appropriate role, i will have a &lt;a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Status/403"&gt;403 error&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OjmoHe36--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3276/1%2AXoDajP-iUhuuSZyhF9cOFA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OjmoHe36--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3276/1%2AXoDajP-iUhuuSZyhF9cOFA.png" alt="postman" width="880" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have intercepted my 403 error in my exceptions handler to have something more readable than the exception stack trace.&lt;/p&gt;

&lt;p&gt;Thanks for your reading time, as previously, the code used in this tutorial is findable in &lt;a href="https://github.com/ErwanLT/HumanCloningFacilities"&gt;this Github repository&lt;/a&gt;, branch security.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>java</category>
      <category>springboot</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building a simple rest API with SpringBoot</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Mon, 31 Jan 2022 12:59:56 +0000</pubDate>
      <link>https://dev.to/erwanlt/building-a-simple-rest-api-with-springboot-53mc</link>
      <guid>https://dev.to/erwanlt/building-a-simple-rest-api-with-springboot-53mc</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mbd1HpV0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ALdaqZyyNnqBBlJSFOizR8A.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mbd1HpV0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ALdaqZyyNnqBBlJSFOizR8A.jpeg" alt="kamino" width="700" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have read my previous articles, you may know that i like to use an object that symbolises human as example, so I will continue in this tutorial about building a REST API with &lt;a href="https://medium.com/hackernoon/top-5-spring-boot-and-spring-cloud-books-for-java-developers-75df155dcedc"&gt;Spring Boot&lt;/a&gt;, but in order to make it less scholar and more fun, I will use Star Wars reference (because i’m a geek and fan of this film franchise).&lt;br&gt;
So welcome to Kamino.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will need
&lt;/h2&gt;

&lt;p&gt;To begin, you have to choices to initialize your project :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://start.spring.io/"&gt;Spring initializr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;from your IDE&lt;br&gt;
As we will use &lt;a href="https://medium.com/javarevisited/10-advanced-spring-boot-courses-for-experienced-java-developers-5e57606816bd?source=collection_home---4------0-----------------------"&gt;Spring Boot&lt;/a&gt;, you will need to add the following dependency to your project in order to it to work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Spring Web&lt;/strong&gt; : Uses Apache Tomcat as the default embedded container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Spring Data JPA&lt;/strong&gt;: Java Persistence API using &lt;a href="https://www.java67.com/2021/01/spring-data-jpa-interview-questions-answers-java.html"&gt;Spring Data&lt;/a&gt; and &lt;a href="https://medium.com/javarevisited/top-5-hibernate-online-training-courses-for-beginners-and-advance-java-programmers-469460596b2b"&gt;Hibernate&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;H2 Database&lt;/strong&gt;: Embedded in memory database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What il will look like
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IKiaAtnl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4416/1%2AIcV-CFgELE3mcnCqEtJ2pQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IKiaAtnl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4416/1%2AIcV-CFgELE3mcnCqEtJ2pQ.png" alt="UML representation" width="880" height="845"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3, 2, 1 … Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The entity
&lt;/h3&gt;

&lt;p&gt;First we need to declare the object we will use in the rest of this exemple, the definition of the Clone Troopers : &lt;em&gt;Clone.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
In order to persist our object in the &lt;a href="https://medium.com/hackernoon/top-5-sql-and-database-courses-to-learn-online-48424533ac61"&gt;database&lt;/a&gt;, it will need an Id, that will be auto-generated when we will save it.

&lt;h3&gt;
  
  
  The Repository
&lt;/h3&gt;

&lt;p&gt;To manipulate our objects in the database we need a repository&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Our &lt;em&gt;CloneRepository&lt;/em&gt; extends &lt;em&gt;JpaRepository&lt;/em&gt; who extend &lt;em&gt;PagingAndSortingRepository *that permit to use pagination request, who extends *CrudRepository&lt;/em&gt; (CRUD is an acronym to create, read, update, delete).

&lt;p&gt;With ou repository, we can use method like &lt;em&gt;save&lt;/em&gt;, &lt;em&gt;findById&lt;/em&gt;, &lt;em&gt;findAll&lt;/em&gt; (with or without pagination).&lt;/p&gt;

&lt;h3&gt;
  
  
  The controller
&lt;/h3&gt;

&lt;p&gt;Now that we have our object, and the repository to save and retrieve it, we need the entry point to our actions : create, find, delete …&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
As you can read, even with no line of code in ou repository class, we can freely use the method inside.

&lt;p&gt;So let's see what we have here :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://javarevisited.blogspot.com/2017/08/difference-between-restcontroller-and-controller-annotations-spring-mvc-rest.html#ixzz6OYNB9oii"&gt;&lt;strong&gt;@RestController&lt;/strong&gt;:&lt;/a&gt; is to indicate that our data will be returned in the response’s body and not in a template&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We have &lt;strong&gt;@GetMapping&lt;/strong&gt; &lt;strong&gt;@PostMapping&lt;/strong&gt; and &lt;strong&gt;@DeleteMapping&lt;/strong&gt; that indicate the Http method that is linked to our method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We have a &lt;strong&gt;BeanNotFound&lt;/strong&gt; throw by our methods (we will see later how we use it).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Handling the exceptions
&lt;/h3&gt;

&lt;p&gt;What is a proper way to handle exceptions, a try/catch block in every method, or to intercept them in a specific way and then use them in a uniform way?&lt;/p&gt;

&lt;p&gt;The second method is cleaner, as we can have all our exceptions in the same place, and treat them the same way.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
As you can see, our &lt;strong&gt;BeanNotFound&lt;/strong&gt; is intercepted by the &lt;strong&gt;ExceptionHandler&lt;/strong&gt; and then we return our exception message as a &lt;a href="https://en.wikipedia.org/wiki/HTTP_404"&gt;404 error&lt;/a&gt;.

&lt;h2&gt;
  
  
  Testing our API
&lt;/h2&gt;

&lt;p&gt;To test our API we need to first launch our application.&lt;br&gt;
Then we can try to connect to the entry point that we created in our controller using &lt;a href="https://medium.com/javarevisited/7-best-courses-to-learn-postman-tool-for-web-service-and-api-testing-f225c138fa5a?source=---------13------------------"&gt;postman&lt;/a&gt; or any other tool that permits you to make HTTP calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a clone
&lt;/h3&gt;

&lt;p&gt;As described in the controller, we need to use the HTTP POST method a pass in it’s body the information of our clone.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP POST [http://localhost:8080/kamino/](http://localhost:8080/kamino/)

{
  "codeName": "CT-7567 REX",
  "type": "gunner",
  "platoon": 501
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That will return us this response&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "id": 1,
  "birthPlace": "Kamino",
  "codeName": "CT-7567 REX",
  "type": "gunner",
  "platoon": 501,
  "affiliation": "Galactic Republic"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The Id is auto-generated, so if we create another clone, the value will be 2, then 3, and will keep incrementing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding all the created clones
&lt;/h3&gt;

&lt;p&gt;To find the created clones, we will call the GET “/” endpoint that will return us a list of all our created clones&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP GET http://localhost:8080/kamino/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;that will gave us a response like this one :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "id": 1,
    "birthPlace": "Kamino",
    "codeName": "CT-7567 REX",
    "type": "gunner",
    "platoon": 501,
    "affiliation": "Galactic Republic"
  },
  {
    "id": 2,
    "birthPlace": "Kamino",
    "codeName": "CC-3636 WOLFFE",
    "type": "gunner",
    "platoon": 501,
    "affiliation": "Galactic Republic"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Deleting a clone
&lt;/h3&gt;

&lt;p&gt;To delete a clone in the database, we will call the delete endpoint&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP DELETE http://localhost:8080/kamino/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;passing 1 as a parameter, we will delete the clone that has the id : 1. So if we call again the find method we will only have one remaining clone.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "id": 2,
  "birthPlace": "Kamino",
  "codeName": "CC-3636 WOLFFE",
  "type": "gunner",
  "platoon": 501,
  "affiliation": "Galactic Republic"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Thanks for your time, you can find all the source code in the Github repository associated to that article &lt;a href="https://github.com/ErwanLT/HumanCloningFacilities"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>java</category>
      <category>springboot</category>
      <category>programming</category>
    </item>
    <item>
      <title>Strategy design pattern — Java</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Fri, 28 Jan 2022 12:12:23 +0000</pubDate>
      <link>https://dev.to/erwanlt/strategy-design-pattern-java-52bk</link>
      <guid>https://dev.to/erwanlt/strategy-design-pattern-java-52bk</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ryRRyapz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A3dO6sOPoOPwHUOxA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ryRRyapz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A3dO6sOPoOPwHUOxA.jpeg" alt="design-pattern" width="450" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition of the Strategy pattern
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;In &lt;a href="https://en.wikipedia.org/wiki/Computer_programming"&gt;computer programming&lt;/a&gt;, the &lt;strong&gt;strategy pattern **(also known as the **policy pattern&lt;/strong&gt;) is a &lt;a href="https://en.wikipedia.org/wiki/Behavioral_design_pattern"&gt;behavioral&lt;/a&gt; &lt;a href="https://en.wikipedia.org/wiki/Design_pattern_(computer_science)"&gt;software design pattern&lt;/a&gt; that enables selecting an &lt;a href="https://en.wikipedia.org/wiki/Algorithm"&gt;algorithm&lt;/a&gt; at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where to use the Factory pattern
&lt;/h2&gt;

&lt;p&gt;When you want the algorithm to vary independently from clients that use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  UML example
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--poCsEl5_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2180/1%2AtSDptFpU1aazFrlsPHbBeA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--poCsEl5_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2180/1%2AtSDptFpU1aazFrlsPHbBeA.png" alt="" width="880" height="904"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation of the strategy pattern
&lt;/h2&gt;

&lt;p&gt;First, we need to declare an &lt;a href="http://www.java67.com/2012/09/what-is-difference-between-interface-abstract-class-java.html"&gt;Interface or an Abstract clas&lt;/a&gt;s, here I used both but a single abstract class could have done the job.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
what i want to achieve is that depending of the context my code will behave differently so let’s implement some strategy.

&lt;p&gt;For the purpose of this tutorial, i created 2 strategies : PlusOperationStrategy and MinusOperationStrategy, both extending my &lt;a href="https://javarevisited.blogspot.com/2010/10/abstraction-in-java.html#axzz6oOeSmpNw"&gt;abstract class&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
With them being of the same supertype by &lt;a href="https://javarevisited.blogspot.com/2012/10/what-is-inheritance-in-java-and-oops-programming.html"&gt;inheritance&lt;/a&gt;, I can substitute them in the function of the needed behavior.

&lt;p&gt;So now, if I want to use my strategies, and more precisely the &lt;strong&gt;compute method&lt;/strong&gt; implemented in it, I need a context.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
So based on the &lt;a href="https://www.java67.com/2014/12/strategy-pattern-in-java-with-example.html"&gt;strategy &lt;/a&gt;passed as a parameter the context will use the compute method it.

&lt;p&gt;So now, let’s see how it work&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The above snippet will return this result

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5
-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Thanks for your reading time, the code used in this tutorial is findable in &lt;a href="https://github.com/ErwanLT/designPattern"&gt;this Github repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>programming</category>
      <category>java</category>
      <category>designpattern</category>
    </item>
    <item>
      <title>Factory design pattern — Java</title>
      <dc:creator>Erwan Le Tutour</dc:creator>
      <pubDate>Fri, 28 Jan 2022 12:09:02 +0000</pubDate>
      <link>https://dev.to/erwanlt/-factory-design-pattern-java-7m6</link>
      <guid>https://dev.to/erwanlt/-factory-design-pattern-java-7m6</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TL7myLKq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AcpmqYomwpJ_fAZ_p_sxGNQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TL7myLKq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AcpmqYomwpJ_fAZ_p_sxGNQ.jpeg" alt="design-pattern" width="450" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition of the Factory pattern
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;In class-based programming, the &lt;a href="https://javarevisited.blogspot.com/2015/06/difference-between-dependency-injection.html"&gt;**factory method pattern&lt;/a&gt;** is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a &lt;a href="http://javarevisited.blogspot.sg/2011/12/factory-design-pattern-java-example.html#axzz51cvxH5kW"&gt;factory method &lt;/a&gt;— either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes — rather than by calling a constructor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where to use the Factory pattern
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When a class doesn’t know what sub-classes will be required to create&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a class wants that its sub-classes specify the objects to be created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the parent classes choose the creation of objects to its sub-classes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  UML example
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mSJfudYQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3000/1%2A07jwCvFRdb0DivjOLo137g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mSJfudYQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3000/1%2A07jwCvFRdb0DivjOLo137g.png" alt="" width="880" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation of the Factory Pattern
&lt;/h2&gt;

&lt;p&gt;We are going to create a Human &lt;a href="https://www.java67.com/2017/08/difference-between-abstract-class-and-interface-in-java8.html"&gt;abstract class&lt;/a&gt; and then the different periods of age that will implement it, then we will create the factory that will generate it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The human abstract class
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  The implementations
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Each implementation &lt;a href="https://www.java67.com/2015/08/top-10-method-overloading-overriding-interview-questions-answers-java.html"&gt;overrides &lt;/a&gt;the &lt;em&gt;getAge()&lt;/em&gt; method to return a random int that will correspond to the age period.

&lt;h3&gt;
  
  
  The factory
&lt;/h3&gt;

&lt;p&gt;Now we can create the factory that will generate a Human based on the given information, here we will use an &lt;a href="https://javarevisited.blogspot.com/2011/08/enum-in-java-example-tutorial.html"&gt;enum &lt;/a&gt;to be sure that we don’t pass the nonexisting value to the factory&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
now we can generate our humans using the factory

&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
that will give an output like the following one :

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;==============================
age : 8
==============================
==============================
age : 49
==============================
==============================
age : 99
==============================
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here are other **design pattern articles **you may like&lt;br&gt;
&lt;a href="https://medium.com/javarevisited/7-best-online-courses-to-learn-object-oriented-design-pattern-in-java-749b6399af59"&gt;&lt;strong&gt;7 Best Online Courses to learn Object-Oriented Design Pattern in Java&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/javarevisited/10-oop-design-principles-you-can-learn-in-2020-f7370cccdd31"&gt;&lt;strong&gt;10 OOP Design Principles You Can Learn in 2021&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/javarevisited/7-best-books-to-learn-design-patterns-for-java-programmers-5627b93eefdb"&gt;&lt;strong&gt;7 Best books to learn Design Patterns for Java Programmers&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>programming</category>
      <category>java</category>
      <category>designpattern</category>
    </item>
  </channel>
</rss>
