Yavuz Tas Senior Software Developer https://yavuztas.dev/ Sat, 02 Jul 2022 18:28:37 +0000 Sat, 02 Jul 2022 18:28:37 +0000 Jekyll v3.9.2 Consuming Variable Responses in Jackson <p>In addition to being another popular library of <i>JSON</i> in Java, <strong>the <a href="https://github.com/FasterXML/jackson">Jackson Library</a> is very well known for its ability to offer deep customization in an opinionated way.</strong></p> <p>In this article, we are going to show an alternate way with the <em>Jackson Library</em> for the same solution which was about <a href="https://yavuztas.dev/java/gson/2019/10/12/consuming-variable-responses-in-gson.html">how to handle variable responses in Gson</a>.</p> <h3 id="adding-dependencies">Adding Dependencies</h3> <p>Before we start, we need to add the Maven dependencies into our project’s <em>pom.xml:</em></p> <figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;dependency&gt;</span> <span class="nt">&lt;groupId&gt;</span>com.fasterxml.jackson.core<span class="nt">&lt;/groupId&gt;</span> <span class="nt">&lt;artifactId&gt;</span>jackson-core<span class="nt">&lt;/artifactId&gt;</span> <span class="nt">&lt;version&gt;</span>2.9.9<span class="nt">&lt;/version&gt;</span> <span class="nt">&lt;/dependency&gt;</span> <span class="nt">&lt;dependency&gt;</span> <span class="nt">&lt;groupId&gt;</span>com.fasterxml.jackson.core<span class="nt">&lt;/groupId&gt;</span> <span class="nt">&lt;artifactId&gt;</span>jackson-databind<span class="nt">&lt;/artifactId&gt;</span> <span class="nt">&lt;version&gt;</span>2.9.9<span class="nt">&lt;/version&gt;</span> <span class="nt">&lt;/dependency&gt;</span></code></pre></figure> <p>We should note that if we already use <strong>Spring Boot</strong> and <strong>Spring Web Starter</strong> module enabled in our project then simply, we don’t need to add any extra dependency for Jackson.</p> <h3 id="sample-response">Sample Response</h3> <p>Let’s use the sample API response:</p> <figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w"> </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"sample article"</span><span class="p">,</span><span class="w"> </span><span class="nl">"comments"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="nl">"id"</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nl">"text"</span><span class="p">:</span><span class="s2">"some comment text"</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"id"</span><span class="p">:</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nl">"text"</span><span class="p">:</span><span class="s2">"some another comment text"</span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span></code></pre></figure> <p>Also, the response changes from <em>Array</em> to <em>Object</em> notation when there is only a single <em>comment:</em></p> <figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w"> </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"sample article"</span><span class="p">,</span><span class="w"> </span><span class="nl">"comments"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"id"</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nl">"text"</span><span class="p">:</span><span class="s2">"some comment text"</span><span class="p">}</span><span class="w"> </span><span class="p">}</span></code></pre></figure> <h3 id="response-models">Response Models</h3> <p>We’ll also use the same models from the <a href="https://yavuztas.dev/java/gson/2019/10/12/consuming-variable-responses-in-gson.html">previous article</a>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ArticleModel</span> <span class="o">{</span> <span class="kd">private</span> <span class="nc">Long</span> <span class="n">id</span><span class="o">;</span> <span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span> <span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">comments</span><span class="o">;</span> <span class="c1">// standard getters and setters</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">CommentModel</span> <span class="o">{</span> <span class="kd">private</span> <span class="nc">Long</span> <span class="n">id</span><span class="o">;</span> <span class="kd">private</span> <span class="nc">String</span> <span class="n">text</span><span class="o">;</span> <span class="c1">// standard getters and setters</span> <span class="o">}</span></code></pre></figure> <h3 id="consuming-the-response">Consuming the Response</h3> <p>We defined a collection type for the <em>comment</em> field as <em>List&lt;CommentModel&gt;</em>. Thus, we can map multiple comments into a single field automatically because <em>Jackson</em> already does the heavy lifting for us:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">String</span> <span class="n">jsonString</span> <span class="o">=</span> <span class="s">"{ "</span><span class="n">id</span><span class="s">": 1, "</span><span class="n">name</span><span class="s">": "</span><span class="n">sample</span> <span class="n">article</span><span class="s">", "</span><span class="n">comments</span><span class="s">": [ {"</span><span class="n">id</span><span class="s">":1, "</span><span class="n">text</span><span class="s">":"</span><span class="n">some</span> <span class="n">comment</span> <span class="n">text</span><span class="s">"}, {"</span><span class="n">id</span><span class="s">":2, "</span><span class="n">text</span><span class="s">":"</span><span class="n">some</span> <span class="n">another</span> <span class="n">comment</span> <span class="n">text</span><span class="s">"} ] }"</span><span class="o">;</span> <span class="nc">ObjectMapper</span> <span class="n">mapper</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ObjectMapper</span><span class="o">();</span> <span class="nc">ArticleModel</span> <span class="n">model</span> <span class="o">=</span> <span class="n">mapper</span><span class="o">.</span><span class="na">readValue</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">mockResponseMultiValue</span><span class="o">,</span> <span class="nc">ArticleModel</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="nc">ArticleModel</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getClass</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">getClass</span><span class="o">(),</span> <span class="nc">CommentList</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">).</span><span class="na">getClass</span><span class="o">(),</span> <span class="nc">CommentModel</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getId</span><span class="o">().</span><span class="na">longValue</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="s">"sample article"</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">size</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">).</span><span class="na">getId</span><span class="o">().</span><span class="na">longValue</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="s">"some comment text"</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">).</span><span class="na">getText</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">1</span><span class="o">).</span><span class="na">getId</span><span class="o">().</span><span class="na">longValue</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="s">"some another comment text"</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">1</span><span class="o">).</span><span class="na">getText</span><span class="o">());</span></code></pre></figure> <p>Certainly, this configuration resolves the multiple comment values unless the response changes to a single value structure. Otherwise, it simply doesn’t work.</p> <p>Consequently, we need to define a custom deserializer to handle both single and multiple values at once.</p> <h3 id="custom-deserializers-for-jackson">Custom Deserializers for Jackson</h3> <p><em>StdDeserializer</em> is an abstract type and also the base class for common deserializers in Jackson.</p> <p>Therefore, to implement a custom deserialization behavior, we will create an implementation of <em>StdDeserializer</em>. This behavior will be responsible for adding any single value to the list as the same as multiple values are being added automatically by Jackson.</p> <p>So, let’s create <em>CommentListDeserializer</em> which inherits the base class <em>StdDeserializer</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CommentListDeserializer</span> <span class="kd">extends</span> <span class="nc">StdDeserializer</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&gt;</span> <span class="o">{</span> <span class="kd">public</span> <span class="nf">CommentListDeserializer</span><span class="o">()</span> <span class="o">{</span> <span class="k">this</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span> <span class="o">}</span> <span class="kd">private</span> <span class="nf">CommentListDeserializer</span><span class="o">(</span><span class="nc">JavaType</span> <span class="n">valueType</span><span class="o">)</span> <span class="o">{</span> <span class="kd">super</span><span class="o">(</span><span class="n">valueType</span><span class="o">);</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="nc">List</span> <span class="nf">deserialize</span><span class="o">(</span><span class="nc">JsonParser</span> <span class="n">p</span><span class="o">,</span> <span class="nc">DeserializationContext</span> <span class="n">ctxt</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span><span class="o">,</span> <span class="nc">JsonProcessingException</span> <span class="o">{</span> <span class="k">return</span> <span class="kc">null</span><span class="o">;</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>We need a <em>TypeReference</em> for Jackson to specify the <em>Collection</em> type and the type of elements in which are involved as well.</p> <p>So, let’s define a constant for a type of <em>List&lt;CommentModel&gt;</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="nc">TypeReference</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;&gt;</span> <span class="no">LIST_OF_COMMENTS_TYPE</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">TypeReference</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;&gt;()</span> <span class="o">{};</span></code></pre></figure> <p>Next, we implement the <em>deserialize</em> method to come up with the expected behavior:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span> <span class="kd">public</span> <span class="nc">List</span> <span class="nf">deserialize</span><span class="o">(</span><span class="nc">JsonParser</span> <span class="n">p</span><span class="o">,</span> <span class="nc">DeserializationContext</span> <span class="n">ctxt</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span><span class="o">,</span> <span class="nc">JsonProcessingException</span> <span class="o">{</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">commentList</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;();</span> <span class="nc">JsonToken</span> <span class="n">token</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="na">currentToken</span><span class="o">();</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">START_ARRAY</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">token</span><span class="o">))</span> <span class="o">{</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">listOfArticles</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="na">readValueAs</span><span class="o">(</span><span class="no">LIST_OF_COMMENTS_TYPE</span><span class="o">);</span> <span class="n">commentList</span><span class="o">.</span><span class="na">addAll</span><span class="o">(</span><span class="n">listOfArticles</span><span class="o">);</span> <span class="o">}</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">START_OBJECT</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">token</span><span class="o">))</span> <span class="o">{</span> <span class="nc">CommentModel</span> <span class="n">article</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="na">readValueAs</span><span class="o">(</span><span class="nc">CommentModel</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="n">commentList</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">article</span><span class="o">);</span> <span class="o">}</span> <span class="k">return</span> <span class="n">commentList</span><span class="o">;</span> <span class="o">}</span></code></pre></figure> <h3 id="deserialization-features-in-jackson">Deserialization Features in Jackson</h3> <p>Although writing a custom deserializer offers us great flexibility, there are lots of features bundled in the Jackson Library for conversions. <strong>Jackson predefined features provide practical ways to customize both serialization and deserialization.</strong></p> <p>Hopefully, <em>ACCEPT_SINGLE_VALUE_AS_ARRAY</em> feature does the exact job for our use-case. Certainly, we could use it for the sake of simplicity:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">ObjectMapper</span> <span class="n">mapper</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ObjectMapper</span><span class="o">();</span> <span class="n">mapper</span><span class="o">.</span><span class="na">enable</span><span class="o">(</span><span class="nc">DeserializationFeature</span><span class="o">.</span><span class="na">ACCEPT_SINGLE_VALUE_AS_ARRAY</span><span class="o">);</span></code></pre></figure> <p>Also, <strong>an alternate way is to configure the <em>@JsonFormat</em> annotation.</strong> In our example, we’ll go with the <em>@JsonFormat</em> annotation to set the <em>ACCEPT_SINGLE_VALUE_AS_ARRAY</em> feature.</p> <p>Let’s remove our custom deserializer and add a simple <em>@JsonFormat</em> annotation to our <em>comments</em> field in <em>ArticleModel</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@JsonFormat</span><span class="o">(</span><span class="n">with</span> <span class="o">=</span> <span class="nc">Feature</span><span class="o">.</span><span class="na">ACCEPT_SINGLE_VALUE_AS_ARRAY</span><span class="o">)</span> <span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">comments</span><span class="o">;</span></code></pre></figure> <p>Thus, this will automatically add any single value of <em>CommentModel</em> to our list as if it were already inside an array. <strong>Unless we have any further requirement using Jackson features can be the most elegant solution for our use-case.</strong></p> <p>We can always have a chance to check the full list of features over on the <a href="https://fasterxml.github.io/jackson-annotations/javadoc/2.9/com/fasterxml/jackson/annotation/JsonFormat.Feature.html">source code</a>.</p> <h3 id="going-further-with-generic-deserializers">Going Further with Generic Deserializers</h3> <p>We can write generic deserializers for different requirements that we couldn’t handle by predefined features. Besides, for the benefit of reusability, we can go further to refactor our code not to create new deserializers for each element type.</p> <p>So, we’ll implement a new class as <em>SingleAwareListDeserializer</em> to handle the deserialization in a more customizable way:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SingleAwareListDeserializer</span> <span class="kd">extends</span> <span class="nc">StdDeserializer</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&gt;</span> <span class="kd">implements</span> <span class="nc">ContextualDeserializer</span> <span class="o">{</span> <span class="kd">private</span> <span class="nc">Class</span><span class="o">&lt;?&gt;</span> <span class="n">contentClassType</span><span class="o">;</span> <span class="kd">public</span> <span class="nf">SingleAwareListDeserializer</span><span class="o">()</span> <span class="o">{</span> <span class="k">this</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span> <span class="o">}</span> <span class="kd">private</span> <span class="nf">SingleAwareListDeserializer</span><span class="o">(</span><span class="nc">JavaType</span> <span class="n">valueType</span><span class="o">)</span> <span class="o">{</span> <span class="kd">super</span><span class="o">(</span><span class="n">valueType</span><span class="o">);</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="nc">JsonDeserializer</span><span class="o">&lt;?&gt;</span> <span class="n">createContextual</span><span class="o">(</span> <span class="nc">DeserializationContext</span> <span class="n">ctxt</span><span class="o">,</span> <span class="nc">BeanProperty</span> <span class="n">property</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">JsonMappingException</span> <span class="o">{</span> <span class="c1">// we use ContextualDeserializer to obtain content class type</span> <span class="n">contentClassType</span> <span class="o">=</span> <span class="n">property</span><span class="o">.</span><span class="na">getType</span><span class="o">().</span><span class="na">getContentType</span><span class="o">().</span><span class="na">getRawClass</span><span class="o">();</span> <span class="k">return</span> <span class="k">this</span><span class="o">;</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="nc">List</span> <span class="nf">deserialize</span><span class="o">(</span><span class="nc">JsonParser</span> <span class="n">p</span><span class="o">,</span> <span class="nc">DeserializationContext</span> <span class="n">ctxt</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span><span class="o">,</span> <span class="nc">JsonProcessingException</span> <span class="o">{</span> <span class="nc">List</span> <span class="n">list</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;();</span> <span class="nc">JsonToken</span> <span class="n">token</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="na">currentToken</span><span class="o">();</span> <span class="c1">// if token is array type</span> <span class="c1">// then perform object deserialization to each element element</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">START_ARRAY</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">token</span><span class="o">))</span> <span class="o">{</span> <span class="k">while</span> <span class="o">(</span><span class="n">p</span><span class="o">.</span><span class="na">nextToken</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">START_OBJECT</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">p</span><span class="o">.</span><span class="na">currentToken</span><span class="o">()))</span> <span class="o">{</span> <span class="n">list</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">deserializeObject</span><span class="o">(</span><span class="n">p</span><span class="o">));</span> <span class="o">}</span> <span class="o">}</span> <span class="o">}</span> <span class="c1">// if token is object type</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">START_OBJECT</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">token</span><span class="o">))</span> <span class="o">{</span> <span class="n">list</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">deserializeObject</span><span class="o">(</span><span class="n">p</span><span class="o">));</span> <span class="o">}</span> <span class="k">return</span> <span class="n">list</span><span class="o">;</span> <span class="o">}</span> <span class="kd">private</span> <span class="nc">Object</span> <span class="nf">deserializeObject</span><span class="o">(</span><span class="nc">JsonParser</span> <span class="n">p</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span> <span class="c1">// just use jackson default object deserializer by using element type</span> <span class="k">return</span> <span class="n">p</span><span class="o">.</span><span class="na">readValueAs</span><span class="o">(</span><span class="n">contentClassType</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>Now, we can use the same deserializer for different types as well.</p> <p>Certainly, we should notice the challenge here which is about how to obtain the class type of the element inside our collection. <strong>Without the element’s type information, it is not possible for Jackson to initialize the concrete type but only <em>LinkedHashMap</em>.</strong></p> <p>However, there is a workaround to obtain type-related information inside our deserializer.</p> <p><strong>We used the <em>ContextualDeserializer</em> interface to inform Jackson that we need information about the bean we are dealing with.</strong> Thus, an instance of <em>BeanProperty</em> is automatically injected and we obtained the class type of the collection element.</p> <p>Finally, to use our generic deserializer, let’s change our <em>comments</em> field:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@JsonDeserialize</span><span class="o">(</span><span class="n">using</span> <span class="o">=</span> <span class="nc">SingleAwareListDeserializer</span><span class="o">.</span><span class="na">class</span><span class="o">)</span> <span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">comments</span><span class="o">;</span></code></pre></figure> <p>As a result, we can provide the same behavior by the <em>SingleAwareListDeserializer</em> generically for all types as well.</p> <h3 id="finally">Finally</h3> <p>In this tutorial, <strong>we learned how to handle variable responses in Jackson by using the builtin features and custom deserializers as well</strong>.</p> <p>All the source code for the examples shown in this tutorial are available <a href="https://github.com/yavuztas/java-jackson-multivalue">over on GitHub</a>.</p> Tue, 10 Dec 2019 22:00:00 +0000 https://yavuztas.dev/java/jackson/2019/12/10/consuming-variable-responses-in-jackson.html https://yavuztas.dev/java/jackson/2019/12/10/consuming-variable-responses-in-jackson.html featured java jackson Type Based Global Events in Vue.js <p>In one of the latest freelance projects of mine, my client prefers <a href="https://vuejs.org/v2/guide/">Vue Framework</a> which is recently super popular on the frontend side.</p> <p>So, I dived into <strong>Vue</strong>. I can say that it is very practical and effective on the very first sight.</p> <p>Besides, when we compare it with other predominant competitors like Angular and Aurelia, <strong>we can easily notice Vue has a very slight learning curve.</strong></p> <p>However, it didn’t take so long for me to stumble on a bad feeling that my code is getting unmanageable and becoming unable to be followed.</p> <p>Undoubtfully, it wasn’t a big surprise to me because <strong>this is mostly what dynamic-typed languages make us resent the harsh trade-off along with their super cool advantages.</strong></p> <p>Today, I am going to show a practical and effective way of using global events in <strong>Vue Framework.</strong></p> <h3 id="a-simple-event-bus-in-vue">A Simple Event Bus in Vue</h3> <p>The typical way of implementing a global event bus in Vue is just using the <em>Vue</em> object itself:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// create a Vue instance somewhere you can access globally</span> <span class="kd">let</span> <span class="nx">eventBus</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">()</span> <span class="c1">// register an event handler</span> <span class="nx">eventBus</span><span class="p">.</span><span class="nx">$on</span><span class="p">(</span><span class="dl">"</span><span class="s2">onAppStarted</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">App Started!</span><span class="dl">"</span><span class="p">))</span> <span class="c1">// publish an event</span> <span class="nx">eventBus</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="dl">"</span><span class="s2">onAppStarted</span><span class="dl">"</span><span class="p">)</span> <span class="c1">// Super easy, right?</span></code></pre></figure> <h3 id="the-problem-coming-from-strings">The Problem Coming From Strings</h3> <p>As long as our application has more than a couple of lines, sooner or later, we start stressing to follow which components publish and which others listen to them.</p> <p>Therefore, we can imagine how hard to identify a simple typo like <em>onApStarted</em> instead of <em>onAppStarted</em> as an event name in a large project:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">eventBus</span><span class="p">.</span><span class="nx">$on</span><span class="p">(</span><span class="dl">"</span><span class="s2">onApStarted</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="c1">// some business logic here </span> <span class="p">})</span></code></pre></figure> <h3 id="implicit-event-parameters">Implicit Event Parameters</h3> <p>Moreover, because we don’t define any corresponding type or interface for our event parameters <strong>only God knows what and how many parameters might be for the <em>onAppStarted</em> event.</strong></p> <p>In order to identify we resent doing this kind of tests everytime we confuse:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">eventBus</span><span class="p">.</span><span class="nx">$on</span><span class="p">(</span><span class="dl">"</span><span class="s2">onAppStarted</span><span class="dl">"</span><span class="p">,</span> <span class="p">(...</span><span class="nx">args</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="nx">args</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">e</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span><span class="p">))</span> <span class="p">})</span></code></pre></figure> <h3 id="a-proper-solution-comes-from-es6">A Proper Solution Comes From ES6+</h3> <p>As being a fan of static-typed Java world, whatever language I do, I prefer using types clearly unless it’s super unconventional for the specific language.</p> <p>Thus, I will show a solution to get rid of these string-based event names by using the capabilities <strong>ECMAScript 6</strong> and later offers.</p> <h4 id="defining-event-types">Defining Event Types</h4> <p>Let’s create a separate file called <em>app-events.js</em> to define our <strong>event types:</strong></p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="cm">/** * Event type to publish when app loads * ProducedBy: components/preload.js * ConsumedBy: App.vue, views/MainPanel.vue **/</span> <span class="k">export</span> <span class="kd">class</span> <span class="nx">AppStartEvent</span> <span class="p">{</span> <span class="kd">constructor</span><span class="p">(){</span> <span class="c1">// An event type with no arguments</span> <span class="p">}</span> <span class="p">}</span> <span class="cm">/** * Event type to publish when code changes * ProducedBy: views/CodePanel.vue * ConsumedBy: views/MainPanel.vue * @param {object} editor editor instance * @param {string} code changed code value inside the editor **/</span> <span class="k">export</span> <span class="kd">class</span> <span class="nx">CodeChangeEvent</span> <span class="p">{</span> <span class="kd">constructor</span><span class="p">(</span><span class="nx">editor</span><span class="p">,</span> <span class="nx">code</span><span class="p">){</span> <span class="k">this</span><span class="p">.</span><span class="nx">editor</span> <span class="o">=</span> <span class="nx">editor</span> <span class="k">this</span><span class="p">.</span><span class="nx">code</span> <span class="o">=</span> <span class="nx">code</span> <span class="p">}</span> <span class="p">}</span></code></pre></figure> <p>As we can notice, <strong>defining event type classes and parameters in constructor explicitly offers us great readability.</strong></p> <p>Although it is optional, we recommend keeping comments updated. This provides a way to follow the components which deal with a certain event type.</p> <h4 id="importing-event-types">Importing Event Types</h4> <p>When we want to use our events, we should import them into our components:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">import</span> <span class="p">{</span><span class="nx">AppStartEvent</span><span class="p">,</span> <span class="nx">CodeChangeEvent</span><span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@/app-events</span><span class="dl">"</span></code></pre></figure> <p>As we specify explicitly every event type we need, <strong>it brings us another important benefit that we can easily identify what events are involved in a component.</strong></p> <h4 id="registering-an-event">Registering an Event</h4> <p>In order to register our event, simply we use our event types and their static <em>name</em> properties:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">import</span> <span class="p">{</span><span class="nx">AppStartEvent</span><span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@/app-events</span><span class="dl">"</span> <span class="nx">eventBus</span><span class="p">.</span><span class="nx">$on</span><span class="p">(</span><span class="nx">AppStartEvent</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">App Started!</span><span class="dl">"</span><span class="p">))</span></code></pre></figure> <p>Plus, we can expect the event type instance itself as a single argument instead of more than one arguments:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">import</span> <span class="p">{</span><span class="nx">AppStartEvent</span><span class="p">,</span> <span class="nx">CodeChangeEvent</span><span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@/app-events</span><span class="dl">"</span> <span class="c1">// we can access the event type instance as a single argument</span> <span class="nx">eventBus</span><span class="p">.</span><span class="nx">$on</span><span class="p">(</span><span class="nx">AppStartEvent</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">event</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">event</span><span class="p">))</span> <span class="c1">// also can access to event parameters</span> <span class="nx">eventBus</span><span class="p">.</span><span class="nx">$on</span><span class="p">(</span><span class="nx">CodeChangeEvent</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">event</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">editor</span><span class="p">)</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">code</span><span class="p">)</span> <span class="p">})</span></code></pre></figure> <h4 id="publishing-an-event">Publishing an Event</h4> <p>Now we can publish our events by creating a new instance of that event type:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// no parameters</span> <span class="nx">eventBus</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="nx">AppStartEvent</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="k">new</span> <span class="nx">AppStartEvent</span><span class="p">())</span> <span class="c1">// with parameters</span> <span class="nx">eventBus</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="nx">CodeChangeEvent</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="k">new</span> <span class="nx">CodeChangeEvent</span><span class="p">(</span><span class="nx">editor</span><span class="p">,</span> <span class="dl">"</span><span class="s2">some code here...</span><span class="dl">"</span><span class="p">))</span></code></pre></figure> <h3 id="implementing-a-wrapper-class">Implementing a Wrapper Class</h3> <p>Certainly, we may proceed to define a class as <em>EventBus</em> and wrap the basic methods of <em>Vue</em> instance.</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">class</span> <span class="nx">EventBus</span> <span class="p">{</span> <span class="nx">$eventbus</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">()</span> <span class="nx">listen</span> <span class="p">(</span><span class="nx">eventClass</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$eventBus</span><span class="p">.</span><span class="nx">$on</span><span class="p">(</span><span class="nx">eventClass</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span> <span class="p">}</span> <span class="nx">publish</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$eventBus</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="kd">constructor</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">event</span><span class="p">)</span> <span class="p">}</span> <span class="p">}</span></code></pre></figure> <p>Therefore, we can use it in a more practical way:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// register an event handler</span> <span class="nx">EventBus</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">AppStartEvent</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">App Started!</span><span class="dl">"</span><span class="p">))</span> <span class="c1">// publish an event</span> <span class="nx">EventBus</span><span class="p">.</span><span class="nx">publish</span><span class="p">(</span><span class="k">new</span> <span class="nx">AppStartEvent</span><span class="p">())</span></code></pre></figure> <h3 id="using-as-a-plugin">Using as a Plugin</h3> <p>We may prefer to use our <em>EventBus</em> as a <strong>Vue Plugin</strong>:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">export</span> <span class="k">default</span> <span class="p">{</span> <span class="na">$eventBus</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">install</span> <span class="p">(</span><span class="nx">Vue</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$eventBus</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">()</span> <span class="p">},</span> <span class="nx">listen</span> <span class="p">(</span><span class="nx">eventClass</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$eventBus</span><span class="p">.</span><span class="nx">$on</span><span class="p">(</span><span class="nx">eventClass</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span> <span class="p">},</span> <span class="nx">listenOnce</span> <span class="p">(</span><span class="nx">eventClass</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$eventBus</span><span class="p">.</span><span class="nx">$once</span><span class="p">(</span><span class="nx">eventClass</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span> <span class="p">},</span> <span class="nx">remove</span> <span class="p">(</span><span class="nx">eventClass</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nx">handler</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$eventBus</span><span class="p">.</span><span class="nx">$off</span><span class="p">(</span><span class="nx">eventClass</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$eventBus</span><span class="p">.</span><span class="nx">$off</span><span class="p">(</span><span class="nx">eventClass</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="p">}</span> <span class="p">},</span> <span class="nx">removeAll</span> <span class="p">()</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$eventBus</span><span class="p">.</span><span class="nx">$off</span><span class="p">()</span> <span class="p">},</span> <span class="nx">publish</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$eventBus</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="kd">constructor</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">event</span><span class="p">)</span> <span class="p">}</span> <span class="p">}</span></code></pre></figure> <p>In order to use the plugin, we should import and register to our <em>Vue</em> instance:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">import</span> <span class="nx">EventBus</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@/plugin/vue-event-bus</span><span class="dl">'</span><span class="p">;</span> <span class="nx">Vue</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">EventBus</span><span class="p">)</span></code></pre></figure> <p>Consequently, we can simply import and use in any other Vue component as well:</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">import</span> <span class="nx">EventBus</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@/plugin/vue-event-bus</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">AppStartEvent</span><span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@/app-events</span><span class="dl">"</span> <span class="c1">// register an event handler</span> <span class="nx">EventBus</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">AppStartEvent</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">App Started!</span><span class="dl">"</span><span class="p">))</span> <span class="c1">// publish an event</span> <span class="nx">EventBus</span><span class="p">.</span><span class="nx">publish</span><span class="p">(</span><span class="k">new</span> <span class="nx">AppStartEvent</span><span class="p">())</span></code></pre></figure> <h3 id="finally">Finally</h3> <p>In this short tutorial, <strong>I explained how to implement type-based global events and use them in Vue.js</strong>.</p> <p>You can find the code of the sample plugin <a href="https://gist.github.com/yavuztas/d1300752057de9314c8614d6a82ccc39">over on GitHub</a>.</p> Sun, 10 Nov 2019 22:30:00 +0000 https://yavuztas.dev/javascript/vuejs/2019/11/10/type-based-global-events-in-vuejs.html https://yavuztas.dev/javascript/vuejs/2019/11/10/type-based-global-events-in-vuejs.html regular javascript vuejs Consuming Variable Responses in Gson <p>No matter being public or private, <em>Restful APIs</em> are the most popular way to integrate our applications with the world outside. This means you do not have a chance to alter the services you consume, instead, you should adapt to them most of the time.</p> <p>Since Java is a static-typed language, it can be a challenge while you are consuming and mapping the data into your model objects, especially if the response data changes depending on the use case.</p> <p>In this article, we will show how to handle variable response structures with the <a href="https://code.google.com/p/google-gson/">Gson Library</a>.</p> <h3 id="maven-dependency">Maven Dependency</h3> <p>Before we start, we need to add the Gson dependency into our project’s <em>pom.xml:</em></p> <figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;dependency&gt;</span> <span class="nt">&lt;groupId&gt;</span>com.google.code.gson<span class="nt">&lt;/groupId&gt;</span> <span class="nt">&lt;artifactId&gt;</span>gson<span class="nt">&lt;/artifactId&gt;</span> <span class="nt">&lt;version&gt;</span>2.8.5<span class="nt">&lt;/version&gt;</span> <span class="nt">&lt;/dependency&gt;</span></code></pre></figure> <h3 id="sample-response">Sample Response</h3> <p>Let’s pick a sample API for a blog which services detailed information about its articles along with the comments which may be more than one:</p> <figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w"> </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"sample article"</span><span class="p">,</span><span class="w"> </span><span class="nl">"comments"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="nl">"id"</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nl">"text"</span><span class="p">:</span><span class="s2">"some comment text"</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"id"</span><span class="p">:</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nl">"text"</span><span class="p">:</span><span class="s2">"some another comment text"</span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span></code></pre></figure> <p>However, if there is only one single comment then its structure changes into object hash form:</p> <figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w"> </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"sample article"</span><span class="p">,</span><span class="w"> </span><span class="nl">"comments"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"id"</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nl">"text"</span><span class="p">:</span><span class="s2">"some comment text"</span><span class="p">}</span><span class="w"> </span><span class="p">}</span></code></pre></figure> <h3 id="writing-a-response-model">Writing a Response Model</h3> <p>In order to map the data, we need a POJO as a response model. Let’s start by defining a simple class that matches the main response structure:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ArticleModel</span> <span class="o">{</span> <span class="nd">@Expose</span> <span class="kd">private</span> <span class="nc">Long</span> <span class="n">id</span><span class="o">;</span> <span class="nd">@Expose</span> <span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span> <span class="nd">@Expose</span> <span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">comments</span><span class="o">;</span> <span class="c1">// standard getters and setters</span> <span class="o">}</span></code></pre></figure> <p>And we need to define another class corresponds to <em>comment</em> response structure:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CommentModel</span> <span class="o">{</span> <span class="nd">@Expose</span> <span class="kd">private</span> <span class="nc">Long</span> <span class="n">id</span><span class="o">;</span> <span class="nd">@Expose</span> <span class="kd">private</span> <span class="nc">String</span> <span class="n">text</span><span class="o">;</span> <span class="c1">// standard getters and setters</span> <span class="o">}</span></code></pre></figure> <h3 id="consuming-the-response">Consuming the Response</h3> <p>Since we use <em>List&lt;CommentModel&gt;</em> for the <em>comments</em> field, we can easily map multiple values which Gson already does the heavy lifting for us:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">String</span> <span class="n">responseText</span> <span class="o">=</span> <span class="s">"{ "</span><span class="n">id</span><span class="s">": 1, "</span><span class="n">name</span><span class="s">": "</span><span class="n">sample</span> <span class="n">article</span><span class="s">", "</span><span class="n">comments</span><span class="s">": [ {"</span><span class="n">id</span><span class="s">":1, "</span><span class="n">text</span><span class="s">":"</span><span class="n">some</span> <span class="n">comment</span><span class="s">"}, {"</span><span class="n">id</span><span class="s">":2, "</span><span class="n">text</span><span class="s">":"</span><span class="n">some</span> <span class="n">another</span> <span class="n">comment</span><span class="s">"} ]}"</span><span class="o">;</span> <span class="nc">Gson</span> <span class="n">gson</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Gson</span><span class="o">();</span> <span class="nc">ArticleModel</span> <span class="n">model</span> <span class="o">=</span> <span class="n">gson</span><span class="o">.</span><span class="na">fromJson</span><span class="o">(</span><span class="n">responseText</span><span class="o">,</span> <span class="nc">ArticleModel</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getId</span><span class="o">().</span><span class="na">longValue</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="s">"sample article"</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">size</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">).</span><span class="na">getId</span><span class="o">().</span><span class="na">longValue</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="s">"some comment"</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">).</span><span class="na">getText</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">1</span><span class="o">).</span><span class="na">getId</span><span class="o">().</span><span class="na">longValue</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="s">"some another comment"</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">1</span><span class="o">).</span><span class="na">getText</span><span class="o">());</span></code></pre></figure> <p>Although this configuration works for the multiple values of comments, if it changes to a single value then we need to define a custom <em>TypeAdapter</em> in order to handle both single and multiple values.</p> <h3 id="custom-typeadapter-in-gson">Custom <em>TypeAdapter</em> in Gson</h3> <p>In order to achieve a custom JSON deserialization behavior, we need to create a <em>TypeAdapter</em>. This behavior will be responsible for adding any single value to the list as the same as multiple values are being added automatically by Gson.</p> <p>For the beginning, let’s create a Gson <em>TypeAdapter</em> for this purpose:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CommentListTypeAdapter</span> <span class="kd">extends</span> <span class="nc">TypeAdapter</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&gt;</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">write</span><span class="o">(</span><span class="nc">JsonWriter</span> <span class="n">out</span><span class="o">,</span> <span class="nc">List</span> <span class="n">list</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="nc">List</span> <span class="nf">read</span><span class="o">(</span><span class="nc">JsonReader</span> <span class="n">in</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span> <span class="k">return</span> <span class="kc">null</span><span class="o">;</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>We need to access <em>Gson</em> instance inside our <em>TypeAdapter</em> to preserve and reuse default deserialization behavior for <em>Object</em> and <em>Collection</em> types.</p> <p>So, let’s define a constructor and fields of <em>Gson</em> instance and some default adapters:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="nc">Gson</span> <span class="n">gson</span><span class="o">;</span> <span class="kd">private</span> <span class="nc">TypeAdapter</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">objectTypeAdapter</span><span class="o">;</span> <span class="kd">private</span> <span class="nc">TypeAdapter</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;&gt;</span> <span class="n">listTypeAdapter</span><span class="o">;</span> <span class="kd">public</span> <span class="nf">CommentListTypeAdapter</span><span class="o">(</span><span class="nc">Gson</span> <span class="n">gson</span><span class="o">)</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">gson</span> <span class="o">=</span> <span class="n">gson</span><span class="o">;</span> <span class="k">this</span><span class="o">.</span><span class="na">objectTypeAdapter</span> <span class="o">=</span> <span class="n">gson</span><span class="o">.</span><span class="na">getAdapter</span><span class="o">(</span><span class="nc">CommentModel</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="k">this</span><span class="o">.</span><span class="na">listTypeAdapter</span> <span class="o">=</span> <span class="n">gson</span><span class="o">.</span><span class="na">getAdapter</span><span class="o">(</span><span class="k">new</span> <span class="nc">TypeToken</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;&gt;()</span> <span class="o">{});</span> <span class="o">}</span></code></pre></figure> <p>Since we aim to deserialize only, we can omit the <em>write</em> method of our adapter. However, we can implement in any case by simply delegating it to the default adapters.</p> <p>Next, let’s implement <em>write</em> method by using <em>listTypeAdapter</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">write</span><span class="o">(</span><span class="nc">JsonWriter</span> <span class="n">out</span><span class="o">,</span> <span class="nc">List</span> <span class="n">list</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span> <span class="n">listTypeAdapter</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="n">out</span><span class="o">,</span> <span class="n">list</span><span class="o">);</span> <span class="o">}</span></code></pre></figure> <p>Then, we implement the <em>read</em> method of our adapter to come up with our expected deserialization behavior:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span> <span class="kd">public</span> <span class="nc">List</span> <span class="nf">read</span><span class="o">(</span><span class="nc">JsonReader</span> <span class="n">in</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">deserializedObject</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;();</span> <span class="c1">// type of next token</span> <span class="nc">JsonToken</span> <span class="n">peek</span> <span class="o">=</span> <span class="n">in</span><span class="o">.</span><span class="na">peek</span><span class="o">();</span> <span class="c1">// if the json field is single object just add this object to list as an</span> <span class="c1">// element</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">BEGIN_OBJECT</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">peek</span><span class="o">))</span> <span class="o">{</span> <span class="n">deserializedObject</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">deserializeObject</span><span class="o">(</span><span class="n">in</span><span class="o">));</span> <span class="o">}</span> <span class="c1">// if the json field is array then implement normal array deserialization</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">BEGIN_ARRAY</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">peek</span><span class="o">))</span> <span class="o">{</span> <span class="n">deserializedObject</span><span class="o">.</span><span class="na">addAll</span><span class="o">(</span><span class="n">deserializeList</span><span class="o">(</span><span class="n">in</span><span class="o">));</span> <span class="o">}</span> <span class="k">return</span> <span class="n">deserializedObject</span><span class="o">;</span> <span class="o">}</span></code></pre></figure> <h3 id="typeadapterfactory-in-gson"><em>TypeAdapterFactory</em> in Gson</h3> <p>We may consider using <em>TypeAdapterFactory</em> in Gson. There are two benefits of this; one of them is we can implement a generic factory method to create different <em>TypeAdapter</em> classes for different types. The other one is <strong>we can access the underlying <em>Gson</em> instance and reuse it</strong> which we are primarily looking for now.</p> <p>So, let’s create a custom <em>TypeAdapterFactory</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CommentListTypeAdapterFactory</span> <span class="kd">implements</span> <span class="nc">TypeAdapterFactory</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">TypeAdapter</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">create</span><span class="o">(</span><span class="nc">Gson</span> <span class="n">gson</span><span class="o">,</span> <span class="nc">TypeToken</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">type</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="o">(</span><span class="nc">TypeAdapter</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;)</span> <span class="k">new</span> <span class="nc">CommentListTypeAdapter</span><span class="o">(</span><span class="n">gson</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>As we can see, we delegated the existing <em>Gson</em> instance to our <em>CommentListTypeAdapter</em> by the help of our custom <em>TypeAdapterFactory</em>.</p> <h3 id="registering-typeadapterfactory-into-gson">Registering <em>TypeAdapterFactory</em> into Gson</h3> <p>Finally, we need to register our custom <em>TypeAdapterFactory</em> into the <em>Gson</em> context to make it work.</p> <p>Let’s update our <em>ArticleModel</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@JsonAdapter</span><span class="o">(</span><span class="nc">CommentListTypeAdapterFactory</span><span class="o">.</span><span class="na">class</span><span class="o">)</span> <span class="nd">@Expose</span> <span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">comments</span><span class="o">;</span></code></pre></figure> <p>Now we can consume single value structures like multiple values with the same <em>ArticleModel</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">String</span> <span class="n">responseText</span> <span class="o">=</span> <span class="s">"{ "</span><span class="n">id</span><span class="s">": 1, "</span><span class="n">name</span><span class="s">": "</span><span class="n">sample</span> <span class="n">article</span><span class="s">", "</span><span class="n">comments</span><span class="s">": {"</span><span class="n">id</span><span class="s">":1, "</span><span class="n">text</span><span class="s">":"</span><span class="n">some</span> <span class="n">comment</span><span class="s">"} }"</span><span class="o">;</span> <span class="nc">Gson</span> <span class="n">gson</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Gson</span><span class="o">();</span> <span class="nc">ArticleModel</span> <span class="n">model</span> <span class="o">=</span> <span class="n">gson</span><span class="o">.</span><span class="na">fromJson</span><span class="o">(</span><span class="n">responseText</span><span class="o">,</span> <span class="nc">ArticleModel</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getId</span><span class="o">().</span><span class="na">longValue</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="s">"sample article"</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">size</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">).</span><span class="na">getId</span><span class="o">().</span><span class="na">longValue</span><span class="o">());</span> <span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="s">"some comment"</span><span class="o">,</span> <span class="n">model</span><span class="o">.</span><span class="na">getComments</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">).</span><span class="na">getText</span><span class="o">());</span></code></pre></figure> <h3 id="further-improvements-with-the-power-of-generics">Further Improvements With the Power of Generics</h3> <p>We can go further by refactoring our code with the help of <strong>generics</strong> and <strong>reflection</strong> in the benefit of reusability. To prevent creating a new adapter for each type it might be essential to follow this method on some occasions.</p> <p>Similarly, we implement another <em>TypeAdapter</em> because we need to handle it in a generic way:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SingleAwareListTypeAdapter</span> <span class="kd">extends</span> <span class="nc">TypeAdapter</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&gt;</span> <span class="o">{</span> <span class="kd">private</span> <span class="nc">Gson</span> <span class="n">gson</span><span class="o">;</span> <span class="kd">private</span> <span class="nc">TypeAdapter</span><span class="o">&lt;?&gt;</span> <span class="n">objectTypeAdapter</span><span class="o">;</span> <span class="kd">private</span> <span class="nc">TypeAdapter</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&gt;</span> <span class="n">listTypeAdapter</span><span class="o">;</span> <span class="kd">public</span> <span class="nf">SingleAwareListTypeAdapter</span><span class="o">(</span><span class="nc">Gson</span> <span class="n">gson</span><span class="o">,</span> <span class="nc">Class</span> <span class="n">elementClassType</span><span class="o">)</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">gson</span> <span class="o">=</span> <span class="n">gson</span><span class="o">;</span> <span class="c1">// we need to carry element's type by passing the element class type to object</span> <span class="c1">// type adapter otherwise gson deserialize our objects as LinkedTreeSet which we</span> <span class="c1">// do not expect that.</span> <span class="k">this</span><span class="o">.</span><span class="na">objectTypeAdapter</span> <span class="o">=</span> <span class="n">gson</span><span class="o">.</span><span class="na">getAdapter</span><span class="o">(</span><span class="n">elementClassType</span><span class="o">);</span> <span class="c1">// list adapter for only serializing do not need the type of element inside list</span> <span class="c1">// here since all the output will be String at the end.</span> <span class="k">this</span><span class="o">.</span><span class="na">listTypeAdapter</span> <span class="o">=</span> <span class="n">gson</span><span class="o">.</span><span class="na">getAdapter</span><span class="o">(</span><span class="nc">List</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">write</span><span class="o">(</span><span class="nc">JsonWriter</span> <span class="n">out</span><span class="o">,</span> <span class="nc">List</span> <span class="n">list</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span> <span class="c1">// Since we do not serialize our comment list with gson we can omit this part</span> <span class="c1">// but anyway we can simply implement by reusing gson list type adapter</span> <span class="n">listTypeAdapter</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="n">out</span><span class="o">,</span> <span class="n">list</span><span class="o">);</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="nc">List</span> <span class="nf">read</span><span class="o">(</span><span class="nc">JsonReader</span> <span class="n">in</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span> <span class="nc">List</span> <span class="n">deserializedObject</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;();</span> <span class="c1">// type of next token</span> <span class="nc">JsonToken</span> <span class="n">peek</span> <span class="o">=</span> <span class="n">in</span><span class="o">.</span><span class="na">peek</span><span class="o">();</span> <span class="c1">// if the json field is single object just add this object to list as an</span> <span class="c1">// element</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">BEGIN_OBJECT</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">peek</span><span class="o">))</span> <span class="o">{</span> <span class="n">deserializedObject</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">deserializeObject</span><span class="o">(</span><span class="n">in</span><span class="o">));</span> <span class="o">}</span> <span class="c1">// if the json field is array then deserialize the objects inside</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">BEGIN_ARRAY</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">peek</span><span class="o">))</span> <span class="o">{</span> <span class="n">in</span><span class="o">.</span><span class="na">beginArray</span><span class="o">();</span> <span class="k">while</span> <span class="o">(</span><span class="n">in</span><span class="o">.</span><span class="na">hasNext</span><span class="o">())</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="nc">JsonToken</span><span class="o">.</span><span class="na">BEGIN_OBJECT</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">in</span><span class="o">.</span><span class="na">peek</span><span class="o">()))</span> <span class="o">{</span> <span class="n">deserializedObject</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">deserializeObject</span><span class="o">(</span><span class="n">in</span><span class="o">));</span> <span class="o">}</span> <span class="o">}</span> <span class="n">in</span><span class="o">.</span><span class="na">endArray</span><span class="o">();</span> <span class="o">}</span> <span class="k">return</span> <span class="n">deserializedObject</span><span class="o">;</span> <span class="o">}</span> <span class="kd">private</span> <span class="nc">Object</span> <span class="nf">deserializeObject</span><span class="o">(</span><span class="nc">JsonReader</span> <span class="n">in</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span> <span class="c1">// just use gson object type adapter</span> <span class="k">return</span> <span class="n">objectTypeAdapter</span><span class="o">.</span><span class="na">read</span><span class="o">(</span><span class="n">in</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>Thus, we can use the same adapter for different element types when we need the same behavior.</p> <p>We should also create another <em>TypeAdapterFactory</em> implementation which will use our new generic <em>SingleAwareListTypeAdapter</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SingleAwareListTypeAdapterFactory</span> <span class="kd">implements</span> <span class="nc">TypeAdapterFactory</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">TypeAdapter</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">create</span><span class="o">(</span><span class="nc">Gson</span> <span class="n">gson</span><span class="o">,</span> <span class="nc">TypeToken</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">type</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// proceed only if the incoming type is a parameterized type</span> <span class="k">if</span> <span class="o">(!</span><span class="nc">ParameterizedType</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">isInstance</span><span class="o">(</span><span class="n">type</span><span class="o">.</span><span class="na">getType</span><span class="o">()))</span> <span class="o">{</span> <span class="k">return</span> <span class="kc">null</span><span class="o">;</span> <span class="o">}</span> <span class="nc">ParameterizedType</span> <span class="n">parameterizedType</span> <span class="o">=</span> <span class="nc">ParameterizedType</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">cast</span><span class="o">(</span><span class="n">type</span><span class="o">.</span><span class="na">getType</span><span class="o">());</span> <span class="nc">Type</span> <span class="n">elementType</span> <span class="o">=</span> <span class="n">parameterizedType</span><span class="o">.</span><span class="na">getActualTypeArguments</span><span class="o">()[</span><span class="mi">0</span><span class="o">];</span> <span class="nc">Class</span> <span class="n">rawElementType</span> <span class="o">=</span> <span class="nc">Class</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">cast</span><span class="o">(</span><span class="n">elementType</span><span class="o">);</span> <span class="k">return</span> <span class="o">(</span><span class="nc">TypeAdapter</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;)</span> <span class="k">new</span> <span class="nc">SingleAwareListTypeAdapter</span><span class="o">(</span><span class="n">gson</span><span class="o">,</span> <span class="n">rawElementType</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>It is important to <strong>let the Gson know the list element’s type information in runtime otherwise our models are deserialized as <em>LinkedTreeSet</em> by default.</strong></p> <p>Since we need the runtime class of incoming list elements, first we obtained the <em>ParameterizedType</em>, then the runtime <em>Class</em> type of the element inside the <em>Collection</em>.</p> <p>In this way, we passed the type information of the element into the <em>SingleAwareListTypeAdapter</em> as a parameter in the constructor.</p> <p>Finally, let’s change our <em>ArticleModel</em> to use our new generic adapter factory:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@JsonAdapter</span><span class="o">(</span><span class="nc">SingleAwareListTypeAdapterFactory</span><span class="o">.</span><span class="na">class</span><span class="o">)</span> <span class="nd">@Expose</span> <span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">CommentModel</span><span class="o">&gt;</span> <span class="n">comments</span><span class="o">;</span></code></pre></figure> <p>As a result, with the help of <strong>generics</strong> and <strong>reflection</strong>, we can use the same adapter, <em>SingleAwareListTypeAdapterFactory</em>, for the other properties with different element types as well.</p> <p>Consequently, this will provide an effective way of <strong>reusability</strong> and lead us to our goal.</p> <h3 id="conclusion">Conclusion</h3> <p>In this tutorial, <strong>we learned how to implement custom adapters to handle variable responses in Gson</strong>.</p> <p>All the source code of examples shown in this tutorial are available <a href="https://github.com/yavuztas/java-gson-multivalue">over on GitHub</a>.</p> Sat, 12 Oct 2019 18:30:00 +0000 https://yavuztas.dev/java/gson/2019/10/12/consuming-variable-responses-in-gson.html https://yavuztas.dev/java/gson/2019/10/12/consuming-variable-responses-in-gson.html featured java gson ApplicationContext in Spring Framework <h3 id="overview">Overview</h3> <p>This is the <strong>third</strong> article of the series <a href="https://github.com/yavuztas/java-spring-fundamentals" target="blank">Spring Framework Fundamentals</a>.</p> <p>When we deal with the <strong>business requirements</strong> in enterprise world, <strong>IoC containers</strong> can be a life saver in software development. They provide us a frictionless orchestration for our application components by default.</p> <p>However, most of the time developers need more than just <strong>containers</strong>. Separating property sources and configuration files, application-wide event publishing mechanisms, loosely coupled pre/post processors and many more can be a grind of our daily work unless we choose a modern application framework to properly delegate this heavy lifting.</p> <p>Hopefully, today’s IoC containers in most of the modern frameworks <strong>bring us the remedy for many enterprise-level requirements</strong>.</p> <p>In this article, we are going to explain <em>ApplicationContext</em> in <strong>Spring Framework</strong>.</p> <h3 id="what-is-meant-by-applicationcontext">What is meant by <em>ApplicationContext</em>?</h3> <p><em>ApplicationContext</em> is a central Spring container that provides many ready to use business features for enterprise-level applications.</p> <p>The basic service of <em>ApplicationContext</em> is exposing another container <strong>BeanFactory</strong>, which are managing the lifecycle of a <strong>Spring Bean</strong> such as creating, wiring, assembling and accessing them up to their destruction.</p> <p><em>ApplicationContext</em> is a higher-level container than <em>BeanFactory</em>, already contains its features by implementing the various <em>BeanFactory</em> interfaces.</p> <p>Beyond these bean-related abilities, <em>ApplicationContext</em> provides more features like;</p> <ul> <li>Providing application level configurations</li> <li>Reading textual messages from convenient <em>MessageSource</em> properties</li> <li>Publishing application events</li> <li>Providing automatic pre/post processor registrations like <em>BeanPostProcessor</em> and <em>BeanFactoryPostProcessor</em>.</li> </ul> <p>On some occasions, like mobile environments where you have limited memory resources and performance requirements, you may consider using <em>BeanFactory</em> instead of <em>ApplicationContext</em>. However, the latter is more appropriate and we prefer for server-based applications in most cases.</p> <p>You can check the description over on <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContext.html">spring java doc</a> for more details.</p> <h3 id="creating-an-applicationcontext">Creating an <em>ApplicationContext</em></h3> <p>Spring Framework has many special <em>ApplicationContext</em> implementations for different needs but creating a new <em>ApplicationContext</em> is as simple as initializing just a simple java class.</p> <p>Let’s give an example of creating a <em>FileSystemXmlApplicationContext</em> instance:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">FileSystemXmlApplicationContext</span> <span class="n">appContext</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FileSystemXmlApplicationContext</span><span class="o">(</span> <span class="s">"src/main/resources/beans.xml"</span><span class="o">);</span> <span class="nc">SampleBean</span> <span class="n">sampleBean</span> <span class="o">=</span> <span class="n">appContext</span><span class="o">.</span><span class="na">getBean</span><span class="o">(</span><span class="s">"sampleBean"</span><span class="o">,</span> <span class="nc">SampleBean</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="n">sampleBean</span><span class="o">.</span><span class="na">saySomething</span><span class="o">(</span><span class="s">"Hello World!"</span><span class="o">);</span></code></pre></figure> <p>Also, there are different <em>ApplicationContext</em> implementations like:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">ClassPathXmlApplicationContext</span> <span class="n">appContext</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ClassPathXmlApplicationContext</span><span class="o">(</span> <span class="s">"beans.xml"</span><span class="o">);</span> <span class="nc">SampleBean</span> <span class="n">sampleBean</span> <span class="o">=</span> <span class="n">appContext</span><span class="o">.</span><span class="na">getBean</span><span class="o">(</span><span class="s">"sampleBean"</span><span class="o">,</span> <span class="nc">SampleBean</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="n">sampleBean</span><span class="o">.</span><span class="na">saySomething</span><span class="o">(</span><span class="s">"Hello World!"</span><span class="o">);</span></code></pre></figure> <p>And this is the XML file for our configuration:</p> <figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;beans</span> <span class="na">xmlns=</span><span class="s">"http://www.springframework.org/schema/beans"</span> <span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span> <span class="na">xsi:schemaLocation=</span><span class="s">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"</span><span class="nt">&gt;</span> <span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">"sampleBean"</span> <span class="na">class=</span><span class="s">"dev.yavuztas.spring.context.SampleBean"</span><span class="nt">&gt;</span> <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"message"</span> <span class="na">value=</span><span class="s">"Initial value"</span> <span class="nt">/&gt;</span> <span class="nt">&lt;/bean&gt;</span> <span class="nt">&lt;/beans&gt;</span></code></pre></figure> <h3 id="lifecycle-of-a-spring-bean-in-an-applicationcontext">Lifecycle of a Spring Bean in an <em>ApplicationContext</em></h3> <p>Spring beans are managed and orchestrated by the IoC container <em>BeanFactory</em> which is already available in <em>ApplicationContext</em>. There are many stages for a spring bean from creation to destruction when we go through deep.</p> <p>However, we keep it simple by grouping into <strong>5 sections</strong>.</p> <p>These sections are;</p> <ul> <li><em>Aware</em> interfaces for injecting infrastructure components</li> <li><em>@PostConstruct</em> and <em>@PreDestroy</em> annotations</li> <li><em>InitializingBean</em> and <em>DisposableBean</em> for callback execution</li> <li><em>init-method</em> and <em>destroy-method</em> configurations</li> <li><em>BeanPostProcessor</em> for altering beans before or after initialization</li> </ul> <p>After constructor execution and setting properties, <strong>first of all</strong> <em>Aware</em> interfaces come into play like <em>BeanNameAware</em>, <em>BeanFactoryAware</em>.</p> <p>Let’s give an example of how to use these <em>Aware</em> interfaces:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SampleBean</span> <span class="kd">implements</span> <span class="nc">BeanNameAware</span><span class="o">,</span> <span class="nc">BeanFactoryAware</span> <span class="o">{</span> <span class="kd">private</span> <span class="nc">String</span> <span class="n">message</span><span class="o">;</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setBeanName</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- setBeanName executed ---"</span><span class="o">);</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setBeanFactory</span><span class="o">(</span><span class="nc">BeanFactory</span> <span class="n">beanFactory</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">BeansException</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- setBeanFactory executed ---"</span><span class="o">);</span> <span class="o">}</span> <span class="c1">// getters and setters</span> <span class="o">}</span></code></pre></figure> <p>When we initialize the spring context we will see that <em>setBeanName</em> method executed before the <em>setBeanFactory</em> method. This indicates that there is also an execution order between <em>Aware</em> interfaces. For more details and a full list of them, you may check over on <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/Aware.html">spring docs</a></p> <p>For the <strong>second</strong> step, the bean methods which are marked by <em>@PostConstruct</em> annotation are executed.</p> <p>Let’s define another method for our bean configured as <em>@PostConstruct</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@PostConstruct</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">postConstruct</span><span class="o">()</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- @PostConstruct executed ---"</span><span class="o">);</span> <span class="o">}</span></code></pre></figure> <p>To make <em>@PostConstruct</em> and <em>@PreDestroy</em> annotations work, we need to define <em>CommonAnnotationBeanPostProcessor</em> as registered in our spring configuration.</p> <figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;beans</span> <span class="na">xmlns=</span><span class="s">"http://www.springframework.org/schema/beans"</span> <span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span> <span class="na">xsi:schemaLocation=</span><span class="s">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"</span><span class="nt">&gt;</span> <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">"org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"</span> <span class="nt">/&gt;</span> <span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">"sampleBean"</span> <span class="na">class=</span><span class="s">"dev.yavuztas.spring.context.SampleBean"</span><span class="nt">&gt;</span> <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"message"</span> <span class="na">value=</span><span class="s">"Initial value"</span> <span class="nt">/&gt;</span> <span class="nt">&lt;/bean&gt;</span> <span class="nt">&lt;/beans&gt;</span></code></pre></figure> <p>Another way to make it out is configuring <em>&lt;context:annotation-config/&gt;</em> either in XML or Java configuration.</p> <p>As for the <strong>third</strong> step, <em>InitializingBean</em> interface comes in with its single <em>afterPropertiesSet</em> callback function.</p> <p>Let’s make our bean to implement <em>InitializingBean</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SampleBean</span> <span class="kd">implements</span> <span class="nc">BeanNameAware</span><span class="o">,</span> <span class="nc">BeanFactoryAware</span><span class="o">,</span> <span class="nc">InitializingBean</span> <span class="o">{</span> <span class="c1">// rest of the class omitted</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">afterPropertiesSet</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- afterPropertiesSet executed ---"</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>As the step <strong>four</strong>, <em>init-method</em> configuration shows up. We can define any method and mark it in our bean configuration.</p> <p>Let’s create another method for our bean:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">initMethod</span><span class="o">()</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- init-method executed ---"</span><span class="o">);</span> <span class="o">}</span></code></pre></figure> <p>And mark it as <em>init-method</em>:</p> <figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">"sampleBean"</span> <span class="na">init-method=</span><span class="s">"initMethod"</span> <span class="na">class=</span><span class="s">"dev.yavuztas.spring.context.SampleBean"</span><span class="nt">&gt;</span> <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"message"</span> <span class="na">value=</span><span class="s">"Initial value"</span> <span class="nt">/&gt;</span> <span class="nt">&lt;/bean&gt;</span></code></pre></figure> <p>As for the <strong>last</strong> step, we can define a <em>BeanPostProcessor</em> to run a custom operation before a spring bean initializes or after. We should pay attention that <em>BeanPostProcessor</em> classes are executed for every bean defined in our spring context.</p> <p>Let’s create a <em>BeanPostProcessor</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CustomBeanPostProcessor</span> <span class="kd">implements</span> <span class="nc">BeanPostProcessor</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="nc">Object</span> <span class="nf">postProcessBeforeInitialization</span><span class="o">(</span><span class="nc">Object</span> <span class="n">bean</span><span class="o">,</span> <span class="nc">String</span> <span class="n">beanName</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">BeansException</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- postProcessBeforeInitialization executed ---"</span><span class="o">);</span> <span class="k">return</span> <span class="nc">BeanPostProcessor</span><span class="o">.</span><span class="na">super</span><span class="o">.</span><span class="na">postProcessBeforeInitialization</span><span class="o">(</span><span class="n">bean</span><span class="o">,</span> <span class="n">beanName</span><span class="o">);</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="nc">Object</span> <span class="nf">postProcessAfterInitialization</span><span class="o">(</span><span class="nc">Object</span> <span class="n">bean</span><span class="o">,</span> <span class="nc">String</span> <span class="n">beanName</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">BeansException</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- postProcessAfterInitialization executed ---"</span><span class="o">);</span> <span class="k">return</span> <span class="nc">BeanPostProcessor</span><span class="o">.</span><span class="na">super</span><span class="o">.</span><span class="na">postProcessAfterInitialization</span><span class="o">(</span><span class="n">bean</span><span class="o">,</span> <span class="n">beanName</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>Of course, we need to register our new post-processor as a spring bean to make it work:</p> <figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">"dev.yavuztas.spring.context.CustomBeanPostProcessor"</span> <span class="nt">/&gt;</span></code></pre></figure> <p>When we boot our spring context, we will see that our <em>CustomBeanPostProcessor</em>’s <em>postProcessBeforeInitialization</em> method is executed right before the <em>@PostConstruct</em> and the other method <em>postProcessAfterInitialization</em> is executed after <em>init-method</em>.</p> <p>For the <strong>destruction</strong> stage of spring beans, we can also configure <em>@PreDestroy</em>, <em>DisposableBean</em> and <em>destroy-method</em>.</p> <p>Let’s define these methods for our bean:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SampleBean</span> <span class="kd">implements</span> <span class="nc">BeanNameAware</span><span class="o">,</span> <span class="nc">BeanFactoryAware</span><span class="o">,</span> <span class="nc">InitializingBean</span><span class="o">,</span> <span class="nc">DisposableBean</span> <span class="o">{</span> <span class="c1">// rest of the class omitted</span> <span class="nd">@PreDestroy</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">preDestroy</span><span class="o">()</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- @PreDestroy executed ---"</span><span class="o">);</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">destroy</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- destroy executed ---"</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">destroyMethod</span><span class="o">()</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"--- destroy-method executed ---"</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>And do not forget to configure <em>destroy-method</em> in our bean config:</p> <figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">"sampleBean"</span> <span class="na">init-method=</span><span class="s">"initMethod"</span> <span class="na">destroy-method=</span><span class="s">"destroyMethod"</span> <span class="na">class=</span><span class="s">"dev.yavuztas.spring.context.SampleBean"</span><span class="nt">&gt;</span> <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"message"</span> <span class="na">value=</span><span class="s">"Initial value"</span> <span class="nt">/&gt;</span> <span class="nt">&lt;/bean&gt;</span></code></pre></figure> <p><strong>Finally</strong>, if we close our running spring-context, we will see our destruction methods are executed in the order as;</p> <ul> <li><em>@PreDestroy</em></li> <li><em>DisposableBean</em></li> <li><em>destroy-method</em></li> </ul> <h3 id="closing-an-applicationcontext">Closing an <em>ApplicationContext</em></h3> <p>We can close Spring’s <em>ApplicationContext</em> by simply calling the method <em>close</em> of the context:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">appContext</span><span class="o">.</span><span class="na">close</span><span class="o">();</span></code></pre></figure> <p>Besides, we do not have to manually close, instead, we can easily configure <em>ApplicationContext</em> to automatically close itself on JVM shutdown:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">appContext</span><span class="o">.</span><span class="na">registerShutdownHook</span><span class="o">();</span></code></pre></figure> <p>Furthermore, if we are using <strong>Spring Boot</strong>, we do not need to do anything to close our application context because it is automatically configured to be closed in the shutdown stage.</p> <h3 id="conclusion">Conclusion</h3> <p>In this article of our series, <strong>we learned what the <em>ApplicationContext</em> is and how it works in Spring Framework.</strong></p> <p>As always, you can check the related code examples <a href="https://github.com/yavuztas/java-spring-fundamentals/tree/master/src/main/java/dev/yavuztas/spring/context" target="blank">over on Github</a>.</p> <p>After we talked about <em>ApplicationContext</em>, in our <a href="javascript:void(0)">next article</a>, we will go on with the <strong>Component Scanning and Auto-Injection</strong> of spring beans.</p> Mon, 26 Aug 2019 15:15:00 +0000 https://yavuztas.dev/java/spring/2019/08/26/application-context-in-spring.html https://yavuztas.dev/java/spring/2019/08/26/application-context-in-spring.html featured java spring Writing a Utility Class for Collections in Java 8 <p>One of the fluent APIs that Java 8 brings us, is the <a href="https://www.baeldung.com/java-8-streams">Java 8 Stream API</a>, which provides a practical and minimal interface to code, especially with the help of <a href="https://www.baeldung.com/java-8-lambda-expressions-tips">Java 8 Lambdas</a>.</p> <p>Today, we are going to write a simple utility class to convert and modify java collections with ease, by using the power of <strong>Java 8 Streams</strong>.</p> <h3 id="utility-classes">Utility Classes</h3> <p>Utility classes are structures that contain reusable and stateless helper methods. We implement these methods for handling any kind of specific operations for specific purposes. Because of their stateless nature, we mostly prefer to define them as <em>static</em>.</p> <p>First of all, let’s define a simple class:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">UtilsForCollections</span> <span class="o">{</span> <span class="o">}</span></code></pre></figure> <h3 id="static-classes-in-java">Static Classes in Java</h3> <p>Static classes are classes that cannot be instantiated. As utility classes do not need to hold any state, it is appropriate to define them as static to prevent creating instances of them.</p> <p>Unlike some other languages, in Java, we cannot use the <em>static</em> modifier for classes. Instead, we will use a <strong>private constructor</strong> to give the same ability to our utility classes:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">UtilsForCollections</span> <span class="o">{</span> <span class="kd">private</span> <span class="nf">UtilsForCollections</span><span class="o">()</span> <span class="o">{</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <h3 id="array-to-collection-conversion">Array to Collection Conversion</h3> <p>The first method of our utility class will be a <em>generic</em> method that simply converts a given <em>array</em> structure to <em>java.util.Collection</em> type.</p> <p>We have two different behavioral types to return as java collections, one of them is <em>List</em> that is used when we need to preserve the <strong>order</strong> of the elements, the other one is <em>Set</em> that is used when we need to preserve the <strong>uniqueness</strong> of the elements.</p> <p>First, let’s define a generic method that handles <em>array</em> to <em>List</em> conversion:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">List</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">toList</span><span class="o">(</span><span class="no">T</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// TODO implement but how?</span> <span class="o">}</span></code></pre></figure> <h3 id="power-of-java-8-stream-api">Power of Java 8 Stream API</h3> <p>Normally to implement this kind of method, we need to traverse the elements of an array and populate each of them to a newly created <em>ArrayList</em> object. However, thanks to the <strong>Java 8 Stream API</strong>, we can easily get rid of this sort of boilerplates.</p> <p>So let’s implement our <em>toList</em> method:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">List</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">toList</span><span class="o">(</span><span class="no">T</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toList</span><span class="o">());</span> <span class="o">}</span></code></pre></figure> <p>We use the <em>Arrays.stream()</em> method to open a stream over the given array. Once we acquire the stream instance, we may operate over the stream by many provided methods like <em>collect</em>, <em>filter</em>, <em>map</em>, etc. We choose the method <em>collect</em> here to copy elements from an array to another structure with the help of predefined <strong>stream collectors</strong>.</p> <p>Like <em>toList</em> method, let’s define a separate method for <em>array</em> to <em>Set</em> conversion:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">Set</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">toSet</span><span class="o">(</span><span class="no">T</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toSet</span><span class="o">());</span> <span class="o">}</span></code></pre></figure> <h3 id="handling-primitive-types">Handling Primitive Types</h3> <p>With the help of <em>generics</em> we successfully handled for all object types but when it comes to primitive types of java we cannot use our generic methods. We see an error when we try to use with primitive-typed arrays and our java compiler complains about the argument types which are not applicable:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">intArray</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[]</span> <span class="o">{</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">,</span> <span class="mi">3</span> <span class="o">};</span> <span class="nc">UtilsForCollections</span><span class="o">.</span><span class="na">toList</span><span class="o">(</span><span class="n">intArray</span><span class="o">);</span> <span class="c1">// this line gives us a compile error!</span></code></pre></figure> <p>One of the ways of solving this problem is simply defining separate methods with primitive-typed arguments. We will use <em>boxed</em> method of <em>streams</em> to box every primitive element to its wrapper objects:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Integer</span><span class="o">&gt;</span> <span class="nf">toList</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">boxed</span><span class="o">().</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toList</span><span class="o">());</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Long</span><span class="o">&gt;</span> <span class="nf">toList</span><span class="o">(</span><span class="kt">long</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">boxed</span><span class="o">().</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toList</span><span class="o">());</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Double</span><span class="o">&gt;</span> <span class="nf">toList</span><span class="o">(</span><span class="kt">double</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">boxed</span><span class="o">().</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toList</span><span class="o">());</span> <span class="o">}</span></code></pre></figure> <p>Similarly, we can define more methods in the same way for other remaining primitives like <em>boolean</em>, <em>byte</em>, <em>char</em>, <em>short</em>, <em>float</em>, etc.</p> <p>And also we can define their <em>Set</em> versions that are pretty same:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="nc">Set</span><span class="o">&lt;</span><span class="nc">Integer</span><span class="o">&gt;</span> <span class="nf">toSet</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">boxed</span><span class="o">().</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toSet</span><span class="o">());</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Set</span><span class="o">&lt;</span><span class="nc">Long</span><span class="o">&gt;</span> <span class="nf">toSet</span><span class="o">(</span><span class="kt">long</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">boxed</span><span class="o">().</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toSet</span><span class="o">());</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Set</span><span class="o">&lt;</span><span class="nc">Double</span><span class="o">&gt;</span> <span class="nf">toSet</span><span class="o">(</span><span class="kt">double</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">boxed</span><span class="o">().</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toSet</span><span class="o">());</span> <span class="o">}</span></code></pre></figure> <h3 id="ordered-sets">Ordered Sets</h3> <p>Sometimes it might be important to preserve both the order and the uniqueness of the elements and we need to handle this with a single collection type. If we encounter this problem in java the <em>LinkedHashSet</em> collection type comes to rescue.</p> <p>Let’s add an optional parameter to our <em>ToSet</em> method in order to return <em>LinkedHashSet</em> type instead of unordered <em>HashSet</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">Set</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">toSet</span><span class="o">(</span><span class="no">T</span><span class="o">[]</span> <span class="n">array</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">UtilsForCollections</span><span class="o">.</span><span class="na">toSet</span><span class="o">(</span><span class="n">array</span><span class="o">,</span> <span class="kc">false</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">Set</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">toSet</span><span class="o">(</span><span class="no">T</span><span class="o">[]</span> <span class="n">array</span><span class="o">,</span> <span class="kt">boolean</span> <span class="n">preserveOrder</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">preserveOrder</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">)</span> <span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toCollection</span><span class="o">(</span><span class="nl">LinkedHashSet:</span><span class="o">:</span><span class="k">new</span><span class="o">));</span> <span class="o">}</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toSet</span><span class="o">());</span> <span class="o">}</span></code></pre></figure> <p>The former method here simply uses the overloaded method of itself. By doing this, we not only provide a default value for <em>preserveOrder</em> parameter but also protect the backward compatibility of our utility methods. We set <em>false</em> to <em>preserveOrder</em> as default value here.</p> <h3 id="collection-to-collection-conversions">Collection to Collection Conversions</h3> <p>Conversion from a collection type to another collection type is also easily possible with streams. We can get streams from collections as well and we can perform <em>List</em> to <em>Set</em> conversion and vice versa.</p> <p>Let’s define some methods to add this ability to our utility class:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">List</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">toList</span><span class="o">(</span><span class="nc">Collection</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">collection</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="n">collection</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toList</span><span class="o">());</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">Set</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">toSet</span><span class="o">(</span><span class="nc">Collection</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">collection</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">UtilsForCollections</span><span class="o">.</span><span class="na">toSet</span><span class="o">(</span><span class="n">collection</span><span class="o">,</span> <span class="kc">false</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">Set</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">toSet</span><span class="o">(</span><span class="nc">Collection</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">collection</span><span class="o">,</span> <span class="kt">boolean</span> <span class="n">preserveOrder</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">preserveOrder</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="n">collection</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span> <span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toCollection</span><span class="o">(</span><span class="nl">LinkedHashSet:</span><span class="o">:</span><span class="k">new</span><span class="o">));</span> <span class="o">}</span> <span class="k">return</span> <span class="n">collection</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toSet</span><span class="o">());</span> <span class="o">}</span></code></pre></figure> <h3 id="filtering-arrays-and-collections">Filtering Arrays and Collections</h3> <p>One of the handy methods of Stream API is <em>filter</em> method. This provides a comfortable way of filtering an array or collection and creating subsets of theirs. With the power of <strong>lambdas</strong> we can also customize the behavior.</p> <p>Let’s define two methods to perform filtering on arrays or collections:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">List</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">filterArray</span><span class="o">(</span><span class="no">T</span><span class="o">[]</span> <span class="n">array</span><span class="o">,</span> <span class="nc">Predicate</span><span class="o">&lt;?</span> <span class="kd">super</span> <span class="no">T</span><span class="o">&gt;</span> <span class="n">predicate</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">filter</span><span class="o">(</span><span class="n">predicate</span><span class="o">)</span> <span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toCollection</span><span class="o">(</span><span class="nl">ArrayList:</span><span class="o">:</span><span class="k">new</span><span class="o">));</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">List</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">filterCollection</span><span class="o">(</span><span class="nc">Collection</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">collection</span><span class="o">,</span> <span class="nc">Predicate</span><span class="o">&lt;?</span> <span class="kd">super</span> <span class="no">T</span><span class="o">&gt;</span> <span class="n">predicate</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="n">collection</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">filter</span><span class="o">(</span><span class="n">predicate</span><span class="o">)</span> <span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">toCollection</span><span class="o">(</span><span class="nl">ArrayList:</span><span class="o">:</span><span class="k">new</span><span class="o">));</span> <span class="o">}</span></code></pre></figure> <p>Next, let’s use this method to filter an array of strings by their first letters as the character <strong>” a “</strong>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">String</span><span class="o">[]</span> <span class="n">array</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">String</span><span class="o">[]</span> <span class="o">{</span> <span class="s">"apple"</span><span class="o">,</span> <span class="s">"banana"</span><span class="o">,</span> <span class="s">"orange"</span><span class="o">,</span> <span class="s">"avocado"</span><span class="o">,</span> <span class="s">"mango"</span> <span class="o">};</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">filtered</span> <span class="o">=</span> <span class="nc">UtilsForCollections</span><span class="o">.</span><span class="na">filterArray</span><span class="o">(</span><span class="n">array</span><span class="o">,</span> <span class="n">v</span> <span class="o">-&gt;</span> <span class="n">v</span><span class="o">.</span><span class="na">startsWith</span><span class="o">(</span><span class="s">"a"</span><span class="o">));</span> <span class="n">filtered</span><span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">);</span></code></pre></figure> <p>Now, by running this code, we will see the outputs of the filtered elements:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="o">[</span><span class="n">apple</span><span class="o">,</span> <span class="n">avocado</span><span class="o">]</span></code></pre></figure> <h3 id="concatenate-elements-into-a-string">Concatenate Elements into a String</h3> <p>Another ability that may be useful is printing the elements of collections or arrays. Most of the time, we use it for debugging purposes.</p> <p>We can extend our utility class by adding some methods to simply joining the string representations of the elements. Plus, a custom separator and an optional limit parameter may be useful.</p> <p>So, let’s define our join methods:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">String</span> <span class="nf">join</span><span class="o">(</span><span class="no">T</span><span class="o">[]</span> <span class="n">array</span><span class="o">,</span> <span class="nc">String</span> <span class="n">separator</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">UtilsForCollections</span><span class="o">.</span><span class="na">join</span><span class="o">(</span><span class="n">array</span><span class="o">,</span> <span class="n">separator</span><span class="o">,</span> <span class="mi">0</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">String</span> <span class="nf">join</span><span class="o">(</span><span class="no">T</span><span class="o">[]</span> <span class="n">array</span><span class="o">,</span> <span class="nc">String</span> <span class="n">separator</span><span class="o">,</span> <span class="kt">int</span> <span class="n">limit</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">limit</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">array</span><span class="o">.</span><span class="na">length</span> <span class="o">&gt;</span> <span class="n">limit</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">limit</span><span class="o">(</span><span class="n">limit</span><span class="o">).</span><span class="na">map</span><span class="o">(</span><span class="nl">String:</span><span class="o">:</span><span class="n">valueOf</span><span class="o">)</span> <span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">joining</span><span class="o">(</span><span class="n">separator</span><span class="o">))</span> <span class="o">+</span> <span class="n">separator</span> <span class="o">+</span> <span class="s">"..."</span><span class="o">;</span> <span class="o">}</span> <span class="k">return</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">array</span><span class="o">).</span><span class="na">map</span><span class="o">(</span><span class="nl">String:</span><span class="o">:</span><span class="n">valueOf</span><span class="o">)</span> <span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">joining</span><span class="o">(</span><span class="n">separator</span><span class="o">));</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">String</span> <span class="nf">join</span><span class="o">(</span><span class="nc">Collection</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">collection</span><span class="o">,</span> <span class="nc">String</span> <span class="n">separator</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nc">UtilsForCollections</span><span class="o">.</span><span class="na">join</span><span class="o">(</span><span class="n">collection</span><span class="o">,</span> <span class="n">separator</span><span class="o">,</span> <span class="mi">0</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">String</span> <span class="nf">join</span><span class="o">(</span><span class="nc">Collection</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">collection</span><span class="o">,</span> <span class="nc">String</span> <span class="n">separator</span><span class="o">,</span> <span class="kt">int</span> <span class="n">limit</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">limit</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">collection</span><span class="o">.</span><span class="na">size</span><span class="o">()</span> <span class="o">&gt;</span> <span class="n">limit</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="n">collection</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">limit</span><span class="o">(</span><span class="n">limit</span><span class="o">).</span><span class="na">map</span><span class="o">(</span><span class="nl">String:</span><span class="o">:</span><span class="n">valueOf</span><span class="o">)</span> <span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">joining</span><span class="o">(</span><span class="n">separator</span><span class="o">))</span> <span class="o">+</span> <span class="n">separator</span> <span class="o">+</span> <span class="s">"..."</span><span class="o">;</span> <span class="o">}</span> <span class="k">return</span> <span class="n">collection</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">map</span><span class="o">(</span><span class="nl">String:</span><span class="o">:</span><span class="n">valueOf</span><span class="o">)</span> <span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="nc">Collectors</span><span class="o">.</span><span class="na">joining</span><span class="o">(</span><span class="n">separator</span><span class="o">));</span> <span class="o">}</span></code></pre></figure> <p>Then, let’s use our <em>join</em> method with a separator of <strong>comma</strong> and a limit parameter of <strong>3</strong>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">String</span><span class="o">[]</span> <span class="n">array</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">String</span><span class="o">[]</span> <span class="o">{</span> <span class="s">"apple"</span><span class="o">,</span> <span class="s">"banana"</span><span class="o">,</span> <span class="s">"orange"</span><span class="o">,</span> <span class="s">"avocado"</span><span class="o">,</span> <span class="s">"mango"</span> <span class="o">};</span> <span class="nc">String</span> <span class="n">joined</span> <span class="o">=</span> <span class="nc">UtilsForCollections</span><span class="o">.</span><span class="na">join</span><span class="o">(</span><span class="n">array</span><span class="o">,</span> <span class="s">", "</span><span class="o">,</span> <span class="mi">3</span><span class="o">);</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">joined</span><span class="o">);</span></code></pre></figure> <p>Last, we will see the output, maximum of <strong>3</strong> elements joined:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">apple</span><span class="o">,</span> <span class="n">banana</span><span class="o">,</span> <span class="n">orange</span><span class="o">,</span> <span class="o">...</span></code></pre></figure> <h3 id="finally">Finally</h3> <p>In this tutorial, <strong>we explained how to implement a simple utility class for collections by the help of Java 8 Stream API</strong>.</p> <p>There are many possible methods to implement which are likely to come in handy when we are dealing with collections.</p> <p>So, what do you think about any other useful methods to include in our utility class? Just feel free to comment below!</p> <p>All the code samples given in this tutorial are available <a href="https://github.com/yavuztas/java-utility-collections">over on GitHub</a>.</p> Sat, 10 Aug 2019 18:00:00 +0000 https://yavuztas.dev/java/collections/streams/2019/08/10/java8-utility-class.html https://yavuztas.dev/java/collections/streams/2019/08/10/java8-utility-class.html regular java collections streams Containers, Inversion of Control and Dependency Injection <h4 id="overview">Overview</h4> <p>This is the <strong>second</strong> article of the series <a href="https://github.com/yavuztas/java-spring-fundamentals" target="blank">Spring Framework Fundamentals</a>.</p> <p>In this article, we will explain <strong>Containers</strong>, what <strong>Inversion of Control</strong> is and how it is implemented by <strong>Dependency Injection</strong> with given examples in a simple way.</p> <h3 id="what-is-containers">What is Containers?</h3> <p>Containers in computer science, are special structures that contain child objects as well as are responsible for managing their life-cycle. Although there may be different types of containers classified by how they <strong>access</strong>, <strong>store</strong> and <strong>traverse</strong> the objects inside, the most common behavior is, they <strong>create</strong>, <strong>alter</strong> and <strong>remove</strong> these child objects on purpose.</p> <p>On the wild, this purpose is mostly to be a framework for solving specific business problems or at least providing a way to solve them with ease.</p> <p>The <em>ApplicationContext</em> types from <strong>Spring Framework</strong> is a good example for a container class:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="nc">GenericWebApplicationContext</span> <span class="n">applicationContext</span><span class="o">;</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setApplicationContext</span><span class="o">(</span><span class="nc">GenericWebApplicationContext</span> <span class="n">webApplicationContext</span><span class="o">){</span> <span class="k">this</span><span class="o">.</span><span class="na">applicationContext</span> <span class="o">=</span> <span class="n">webApplicationContext</span><span class="o">;</span> <span class="c1">// register a bean to context</span> <span class="k">this</span><span class="o">.</span><span class="na">applicationContext</span><span class="o">.</span><span class="na">registerBean</span><span class="o">(</span><span class="nc">SomeComponent</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="o">()</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nc">SomeComponent</span><span class="o">());</span> <span class="c1">// and get an instance of that bean</span> <span class="nc">SomeComponent</span> <span class="n">component</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">applicationContext</span><span class="o">.</span><span class="na">getBean</span><span class="o">(</span><span class="nc">SomeComponent</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="o">}</span></code></pre></figure> <h3 id="what-is-inversion-of-control">What is Inversion of Control?</h3> <p>There is a well-known term as <strong>cohesion</strong> in computer science, which defines the relations of objects and how they can act together in a container class.</p> <p>Most of the time it is mentioned by <strong>high cohesion</strong>. This means acting well of objects together with great solidarity while keeping complexity low and maintainable.</p> <p>Besides, while we keep these objects cohesive, we also need to keep them <strong>loosely coupled</strong> because every object should independently operate their own single responsibility.</p> <p>Hence, this provides some critical benefits such as; <strong>maintainability</strong>, <strong>reusability</strong> and <strong>testability</strong>.</p> <p>When it comes to <strong>Inversion of Control</strong>, indeed better to call it as a <em>principle</em>, a way of implementing highly cohesive and loosely coupled objects. In OOP, it literally means to convert the flow of controlling a child object by delegating its creation logic to another class.</p> <p>Thus, the parent object does not need to worry about how its dependent objects should be initialized and the coupling becomes loose.</p> <p>There are many design patterns in order to implement the IoC principle, some of these patterns are <em>Service Locator</em>, <em>Factory</em>, <em>Abstract Factory</em>, <em>Template Method</em>, <em>Strategy</em>, <em>Dependency Injection</em>.</p> <p>Let’s imagine we have a simple <em>UserService</em> as a container:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserService</span> <span class="o">{</span> <span class="kd">private</span> <span class="nc">UserDao</span> <span class="n">userDao</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">UserDao</span><span class="o">();</span> <span class="o">}</span></code></pre></figure> <p>Then, change the code like below by using <em>Factory</em> pattern:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">DaoFactory</span> <span class="o">{</span> <span class="kd">public</span> <span class="kd">static</span> <span class="nc">UserDao</span> <span class="nf">createUserDao</span><span class="o">(){</span> <span class="k">return</span> <span class="k">new</span> <span class="nf">UserDao</span><span class="o">();</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserService</span> <span class="o">{</span> <span class="kd">private</span> <span class="nc">UserDao</span> <span class="n">userDao</span> <span class="o">=</span> <span class="nc">DaoFactory</span><span class="o">.</span><span class="na">createUserDao</span><span class="o">();</span> <span class="o">}</span></code></pre></figure> <p>So, we have implemented a basic IoC and made the dependency between <em>UserService</em> and <em>UserDao</em> less strict which means <strong>loose coupling</strong>.</p> <h3 id="what-is-dependency-injection">What is Dependency Injection?</h3> <p><strong>Dependency Injection</strong> is a popular design pattern to implement IoC. It is a mechanism that scans object hierarchy, resolves dependencies and assigns the instances properly to dependent objects.</p> <p>For example in <strong>Spring Framework</strong>, this is clearly provided by the well-known annotation <em>@Autowired</em>. Spring’s <em>ApplicationContext</em> makes a component scan on startup and handles the injection of dependent instances internally among its managed objects.</p> <p>Let’s show a simple DI over a spring bean defined as <em>UserService</em>:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Service</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserService</span> <span class="kd">implements</span> <span class="nc">IUserService</span> <span class="o">{</span> <span class="nd">@Autowired</span> <span class="kd">private</span> <span class="nc">IUserDao</span> <span class="n">userDao</span><span class="o">;</span> <span class="o">}</span></code></pre></figure> <p>Note that we need to depend on abstract types in order to make <em>loosely coupled</em> connections. This is also an obvious rule of <em>Dependency Inversion Principle</em> which we explained in our <a href="https://yavuztas.dev/java/oop/2019/06/22/object-oriented-programming-and-solid-principles.html">previous article</a>.</p> <p>Consequently, we can say that DIP is a well-fit design to implement a practicle <em>IoC Container</em>. This is why we use an interface called <em>IUserDao</em> instead of a concrete <em>UserDao</em> type.</p> <h4 id="conclusion">Conclusion</h4> <p>After we mentioned about <em>containers, inversion of control and dependency injection</em>, in our <a href="https://yavuztas.dev/java/spring/2019/08/26/application-context-in-spring.html">next article</a>, we will continue with the <em>ApplicationContext</em> and explain the basics of <em>Spring Framework</em>.</p> Sat, 27 Jul 2019 14:45:00 +0000 https://yavuztas.dev/java/oop/2019/07/27/continers-inversion-of-control-and-dependency-injection.html https://yavuztas.dev/java/oop/2019/07/27/continers-inversion-of-control-and-dependency-injection.html regular java oop Java Algorithm Questions <p>Today, I would like to share one of my repositories which is about some interesting <b>java algorithm questions</b> and my solutions to them.</p> <p>These questions are;</p> <ol> <li>Path</li> <li>Folders</li> <li>Sorted Search</li> <li>Palindrome</li> <li>Train Composition</li> <li>Circular Primes</li> <li>Truncatable Primes</li> </ol> <p>You can check the questions and solutions from the repository <a href="https://github.com/yavuztas/java-quiz-common">over on Github</a>.</p> <p>Feel free to comment if you have something to share. Cheers!</p> Tue, 16 Jul 2019 18:04:00 +0000 https://yavuztas.dev/java/algorithm/2019/07/16/java-quiz-questions.html https://yavuztas.dev/java/algorithm/2019/07/16/java-quiz-questions.html regular java algorithm Object Oriented Programming and SOLID Principles <h4 id="overview">Overview</h4> <p>This article is the <strong>first</strong> one of the series <a href="https://github.com/yavuztas/java-spring-fundamentals" target="blank">Spring Framework Fundamentals</a>.</p> <p>In this very first article, we will explain <strong>Object Oriented Programming</strong> and some basic principles both with definitions and code samples.</p> <h4 id="object-oriented-programming">Object Oriented Programming</h4> <p>One of the popular programming paradigms is called <strong>Object Oriented Programming</strong>, generally abbreviated as <strong>OOP</strong>, suggests that <strong>objects</strong> should be used in computer programs.</p> <p>Objects are special structures in programming contain <strong>data</strong> in forms of their properties, also named as attributes.</p> <p>Besides, they contain procedures that are responsible for altering this data which are mostly called as <strong>functions.</strong></p> <p>Hopefully, <strong>Java</strong> is a clean implementation of the object oriented programming and contains many high-level structures for developers which are formed by objects. Thus we do not need to worry about most of the low-level operations.</p> <p>However, there are further principles to learn to apply OOP correctly. These are widely known as solid principles in the programming world. When we say solid, this is because they literally form the <strong>SOLID</strong>. It is a funny story about that our former computer scientists culminated with an acronym for five OOP design principles intended to make software designs better and understandable.</p> <h4 id="what-are-these-solid-principles">What are these SOLID principles?</h4> <p>We have five principles each of them stands for each letter <strong>S-O-L-I-D</strong>. They are <em><a href="#single-responsibility-principle">Single Responsibility Principle</a>, <a href="#open-closed-principle">Open Closed Principle</a>, <a href="#liskov-substitution-principle">Liskov Substitution Principle</a>, <a href="#interface-segregation-principle">Interface Segregation Principle</a> and <a href="#dependency-inversion-principle">Dependency Inversion Principle</a>.</em></p> <h4 id="single-responsibility-principle">Single Responsibility Principle</h4> <p>Single Responsibility Principle in software programming suggests that an object should only have single responsibility. We usually refer any <strong>module</strong>, <strong>class</strong> or <strong>function</strong> here. In this way, one object can only modify one part of the software’s specifications.</p> <p>Objects trying to handle more than one responsibility will eventually ensue fragility and become impossible to maintain. Thus, it is highly possible, the violation of this principle causes us the famous <a href="https://en.wikipedia.org/wiki/God_object" target="blank">God Object</a> anti-pattern in time.</p> <p>An example to indicate a violation of the single responsibility principle:</p> <blockquote class="filename"> <p>LoginManager.java</p> </blockquote> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">if</span><span class="o">(</span><span class="nc">LoginType</span><span class="o">.</span><span class="na">LOCAL_DB</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">type</span><span class="o">)){</span> <span class="c1">// authenticating user from local db</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span><span class="o">(</span><span class="nc">LoginType</span><span class="o">.</span><span class="na">REMOTE_DB</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">type</span><span class="o">)){</span> <span class="c1">// authenticating user from remote db</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span><span class="o">(</span><span class="nc">LoginType</span><span class="o">.</span><span class="na">LDAP</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">type</span><span class="o">)){</span> <span class="c1">// authenticating user from ldap</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span><span class="o">(</span><span class="nc">LoginType</span><span class="o">.</span><span class="na">SOCIAL</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">type</span><span class="o">)){</span> <span class="c1">// authenticating user from social network accounts</span> <span class="o">}</span> <span class="c1">// and this conditional cases can go on...</span></code></pre></figure> <p>So this code seems to start smelling like becoming a <strong>god object</strong>. Although it looks like a semi-god for now, it definitely intends to become bigger in time unless we do not stop it by <strong>refactoring</strong>:</p> <blockquote class="filename"> <p>LoginManager.java</p> </blockquote> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="nf">LoginManager</span><span class="o">()</span> <span class="o">{</span> <span class="c1">// registering our manager implementations</span> <span class="n">loginManagers</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">LocalDBLoginManager</span><span class="o">());</span> <span class="n">loginManagers</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">RemoteDBLoginManager</span><span class="o">());</span> <span class="n">loginManagers</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">LdapLoginManager</span><span class="o">());</span> <span class="n">loginManagers</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">SocialLoginManager</span><span class="o">());</span> <span class="o">}</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">authenticate</span><span class="o">(</span><span class="nc">User</span> <span class="n">user</span><span class="o">,</span> <span class="nc">LoginType</span> <span class="n">type</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// getManager method returns the right implementation</span> <span class="c1">// according to login type we need</span> <span class="nc">ILoginManager</span> <span class="n">loginManager</span> <span class="o">=</span> <span class="n">getManager</span><span class="o">(</span><span class="n">type</span><span class="o">);</span> <span class="n">loginManager</span><span class="o">.</span><span class="na">authenticate</span><span class="o">(</span><span class="n">user</span><span class="o">);</span> <span class="o">}</span></code></pre></figure> <p>You can check the source code for this sample over <a href="https://github.com/yavuztas/java-solid-principles/blob/master/src/main/java/dev/yavuztas/samples/solid/srp/LoginManager.java" target="blank">here</a>.</p> <p>Besides, you can read <a href="https://en.wikipedia.org/wiki/Single_responsibility_principle" target="blank">single responsibility principle</a> over on Wikipedia for further details.</p> <h4 id="open-closed-principle">Open Closed Principle</h4> <p>Open Closed Principle in software programming means that an ideal software application should be open for extensions but closed for modifications. Doing <strong>modification</strong> here is thought for changing the existing codes of pre-made modules, classes, etc.</p> <p>On the other hand, what is mentioned when we say <strong>extension</strong> is; adding new classes, modules or even functions without touching the rest of the codebase.</p> <p>Some implications of modification:</p> <ul> <li>Increases <strong>fragility</strong>, decreases maintainability.</li> <li>Causes <strong>strictly tight modules</strong> and classes.</li> <li><strong>Hard to test</strong>, leads to unexpected bugs.</li> </ul> <p>A clear example to show a piece of code which will probably need modifications later:</p> <blockquote class="filename"> <p>ModificationManager.java</p> </blockquote> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">if</span><span class="o">(</span><span class="nc">ModificationType</span><span class="o">.</span><span class="na">LESS</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">type</span><span class="o">)){</span> <span class="c1">// less modification :)</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span><span class="o">(</span><span class="nc">ModificationType</span><span class="o">.</span><span class="na">MEDIUM</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">type</span><span class="o">)){</span> <span class="c1">// medium modification :(</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span><span class="o">(</span><span class="nc">ModificationType</span><span class="o">.</span><span class="na">QUITE</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">type</span><span class="o">)){</span> <span class="c1">// quite a lot modification :O</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span><span class="o">(</span><span class="nc">ModificationType</span><span class="o">.</span><span class="na">ENORMOUS</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">type</span><span class="o">)){</span> <span class="c1">// vast modification &gt;:O</span> <span class="o">}</span> <span class="c1">// and this conditional cases can go on...</span></code></pre></figure> <p>One proper solution to this problem is <strong>Chain of Responsibility</strong> pattern which is also a good example of design by extensions, can be achieved like the code below:</p> <blockquote class="filename"> <p>ModificationManager.java</p> </blockquote> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="nf">ModificationManager</span><span class="o">()</span> <span class="o">{</span> <span class="c1">// new modifier implementations can be easily added</span> <span class="c1">// without touching the rest of the code</span> <span class="n">modifiers</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">LessModifier</span><span class="o">());</span> <span class="n">modifiers</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">MediumModifier</span><span class="o">());</span> <span class="n">modifiers</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">QuiteModifier</span><span class="o">());</span> <span class="n">modifiers</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">EnormousModifier</span><span class="o">());</span> <span class="o">}</span> <span class="c1">// main part of the code that handles the logic</span> <span class="c1">// is not affected by adding or removing different type of modifiers</span> <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">modifySystem</span><span class="o">(</span><span class="nc">ModificationType</span> <span class="n">type</span><span class="o">)</span> <span class="o">{</span> <span class="k">for</span> <span class="o">(</span><span class="nc">IModifier</span> <span class="n">modifier</span> <span class="o">:</span> <span class="n">modifiers</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// each modifier instance knows that they can modify it</span> <span class="c1">// or not and returns the result as boolean</span> <span class="k">if</span> <span class="o">(</span><span class="n">modifier</span><span class="o">.</span><span class="na">modify</span><span class="o">(</span><span class="n">type</span><span class="o">))</span> <span class="o">{</span> <span class="k">return</span> <span class="kc">true</span><span class="o">;</span> <span class="o">}</span> <span class="o">}</span> <span class="c1">// if we are here then it seems no modification is done</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span> <span class="o">}</span></code></pre></figure> <p>You can check the source code for this sample over <a href="https://github.com/yavuztas/java-solid-principles/blob/master/src/main/java/dev/yavuztas/samples/solid/ocp/ModificationManager.java" target="blank">here</a>.</p> <h4 id="how-the-ocp-can-be-used-in-java">How the OCP can be used in Java?</h4> <p>One of the best practices is <strong>programming to interface</strong> when it comes to applying OCP into java. Programming to interface means to prefer using interfaces instead of concrete types unless you specifically need to.</p> <p>Interfaces are the contracts to expose the behavior type of our program to the outer world. With the help of well-defined interfaces, you always have a chance to create new implementations and easily extend your project without affecting the world outside. This technically means adding an extension.</p> <p>Hence, we can say that interfaces really play nice with the OCP.</p> <p>A simple example to show an advantage of <strong>using interfaces over concrete types:</strong></p> <blockquote class="filename"> <p>CoffeeMachine.java</p> </blockquote> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Coffee</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">taste</span><span class="o">();</span> <span class="o">}</span> <span class="nc">Coffee</span> <span class="n">coffee</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FilterCoffee</span><span class="o">();</span> <span class="c1">// you taste filter coffee!</span> <span class="n">coffee</span><span class="o">.</span><span class="na">taste</span><span class="o">();</span> <span class="c1">// After some time we discover a new taste and add our new coffee formula!</span> <span class="nc">Coffee</span> <span class="n">coffee</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">EspressoCoffee</span><span class="o">();</span> <span class="c1">// now you taste espresso, we do not need to modify the code below!</span> <span class="n">coffee</span><span class="o">.</span><span class="na">taste</span><span class="o">();</span></code></pre></figure> <p>Besides, you can read <a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">open closed principle</a> over on Wikipedia for further details.</p> <h4 id="liskov-substitution-principle">Liskov Substitution Principle</h4> <p>Liskov Substitution Principle suggests that objects in a software program should be replaceable with the instances of their subtypes without need to change properties of theirs.</p> <p>Another use case of interfaces transpires here, since we need a behavioral similarity between subtypes, also called as <strong>strong behavioral subtyping</strong>. Different behaviors can output different results so we need to group subtypes with similar behavior by using interfaces not to break our program’s communication with the outside.</p> <p>An example to demonstrate this problem:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Fish</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">swim</span><span class="o">(){</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"I'm swimming"</span><span class="o">)</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">DeadFish</span> <span class="kd">extends</span> <span class="nc">Fish</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">swim</span><span class="o">(){</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Cannot swim because I'm dead!"</span><span class="o">)</span> <span class="o">}</span> <span class="o">}</span> <span class="c1">// Let's say that we need a fishing pool which every Fish instance should swim.</span> <span class="c1">// However as you can see some instances will not be able to swim because they are dead.</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Fish</span><span class="o">&gt;</span> <span class="n">pool</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;();</span> <span class="n">pool</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">Fish</span><span class="o">());</span> <span class="n">pool</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">Fish</span><span class="o">());</span> <span class="n">pool</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">DeadFish</span><span class="o">());</span> <span class="k">for</span><span class="o">(</span><span class="nc">Fish</span> <span class="nl">fish:</span><span class="n">pool</span><span class="o">){</span> <span class="n">fish</span><span class="o">.</span><span class="na">swim</span><span class="o">();</span> <span class="o">}</span></code></pre></figure> <p>An elegant solution comes with the help of interfaces to discriminate subtypes according to their behaviors:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Alive</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">swim</span><span class="o">();</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Dead</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">sink</span><span class="o">();</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">AliveFish</span> <span class="kd">extends</span> <span class="nc">Fish</span> <span class="kd">implements</span> <span class="nc">Alive</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">swim</span><span class="o">()</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"I'm swimming because I'm alive :)"</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">DeadFish</span> <span class="kd">extends</span> <span class="nc">Fish</span> <span class="kd">implements</span> <span class="nc">Dead</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">swim</span><span class="o">()</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Cannot swim because I'm dead!"</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">sink</span><span class="o">()</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"I'm sinking :("</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> <span class="c1">// So we need only alive fish for our fishing pool.</span> <span class="c1">// Now we are sure that every Fish instance in our pool can swim!</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Alive</span><span class="o">&gt;</span> <span class="n">pool</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;();</span> <span class="n">pool</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">AliveFish</span><span class="o">());</span> <span class="n">pool</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">AliveFish</span><span class="o">());</span> <span class="n">pool</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">AliveFish</span><span class="o">());</span> <span class="c1">// compilation error prevents us to add DeadFish instances by mistake!</span> <span class="c1">// pool.add(new DeadFish());</span> <span class="k">for</span><span class="o">(</span><span class="nc">Alive</span> <span class="nl">fish:</span><span class="n">pool</span><span class="o">){</span> <span class="n">fish</span><span class="o">.</span><span class="na">swim</span><span class="o">();</span> <span class="o">}</span></code></pre></figure> <p>You can check the source code for this sample over <a href="https://github.com/yavuztas/java-solid-principles/blob/master/src/main/java/dev/yavuztas/samples/solid/lsp/FishingPool.java" target="blank">here</a>.</p> <p>Besides, you can read <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle" target="blank">liskov substitution principle</a> over on Wikipedia for further details.</p> <h4 id="interface-segregation-principle">Interface Segregation Principle</h4> <p>Interface Segregation Principle in software simply tells us that instead of one general-purpose interface, it is better to use many client-specific ones. One obvious problem we can encounter when we violate this principle, is the boilerplate invasion of meaningless, empty methods.</p> <p>Let us show this problem with an example:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Animal</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">swim</span><span class="o">();</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">fly</span><span class="o">();</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">();</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">SwimmingAnimal</span> <span class="kd">implements</span> <span class="nc">Animal</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">swim</span><span class="o">(){</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Oh it's swimming, I know how to swim :)"</span><span class="o">);</span> <span class="o">}</span> <span class="c1">// Ideally we do not need to implement the methods below</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">fly</span><span class="o">(){</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"What am i going to do?"</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">(){</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"What am i going to do?"</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>And the solution would be splitting our general interface into more specific ones:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Animal</span> <span class="o">{</span> <span class="c1">// let this be just a marker interface</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">interface</span> <span class="nc">CanSwim</span> <span class="kd">extends</span> <span class="nc">Animal</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">swim</span><span class="o">();</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">interface</span> <span class="nc">CanFly</span> <span class="kd">extends</span> <span class="nc">Animal</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">fly</span><span class="o">();</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">interface</span> <span class="nc">CanRun</span> <span class="kd">extends</span> <span class="nc">Animal</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">();</span> <span class="o">}</span> <span class="c1">// no need to implement unnecessary methods</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">SwimmingAnimal</span> <span class="kd">implements</span> <span class="nc">CanSwim</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">swim</span><span class="o">(){</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Oh it's swimming, I know how to swim :)"</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>You can check the source code for this sample over <a href="https://github.com/yavuztas/java-solid-principles/blob/master/src/main/java/dev/yavuztas/samples/solid/isp/AnimalFarm.java" target="blank">here</a>.</p> <p>Besides, you can read <a href="https://en.wikipedia.org/wiki/Interface_segregation_principle" target="blank">interface segregation principle</a> over on Wikipedia for further details.</p> <h4 id="dependency-inversion-principle">Dependency Inversion Principle</h4> <p>Dependency Inversion Principle states that in a software program high-level objects should not depend on low-level objects, on the contrary, both should depend on abstractions.</p> <p>Similarly, concrete classes should depend on abstractions, but abstract ones should not. After these explanations, let’s be a little bit more explanatory.</p> <p>An example of a DIP violation:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">OperatingSystem</span> <span class="o">{</span> <span class="kd">private</span> <span class="nc">HttpService</span> <span class="n">httpService</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">HttpService</span><span class="o">();</span> <span class="kd">private</span> <span class="nc">SmtpService</span> <span class="n">smtpService</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SmtpService</span><span class="o">();</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">runOnStartup</span><span class="o">()</span> <span class="o">{</span> <span class="n">httpService</span><span class="o">.</span><span class="na">startHttpd</span><span class="o">();</span> <span class="n">smtpService</span><span class="o">.</span><span class="na">startSmtpd</span><span class="o">();</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>Instead of depending on concrete classes we should definitely make an abstraction by the help of interfaces and refactor our tiny operating system to accept only abstract services in order to initiate on the os startup.</p> <p>See the code below:</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">HttpService</span> <span class="kd">implements</span> <span class="nc">IService</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">start</span><span class="o">(){</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Starting httpd service..."</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">SmtpService</span> <span class="kd">implements</span> <span class="nc">IService</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">start</span><span class="o">(){</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Starting smtpd service..."</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">OperatingSystem</span> <span class="o">{</span> <span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">IService</span><span class="o">&gt;</span> <span class="n">services</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;();</span> <span class="kd">public</span> <span class="nf">OperatingSystem</span><span class="o">()</span> <span class="o">{</span> <span class="n">register</span><span class="o">(</span><span class="k">new</span> <span class="nc">HttpService</span><span class="o">());</span> <span class="n">register</span><span class="o">(</span><span class="k">new</span> <span class="nc">SmtpService</span><span class="o">());</span> <span class="o">}</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">register</span><span class="o">(</span><span class="nc">IService</span> <span class="n">service</span><span class="o">){</span> <span class="k">this</span><span class="o">.</span><span class="na">services</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">service</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">runOnStartup</span><span class="o">()</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">services</span><span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">s</span> <span class="o">-&gt;</span> <span class="n">s</span><span class="o">.</span><span class="na">start</span><span class="o">());</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> <p>You can check the source code for this sample over <a href="https://github.com/yavuztas/java-solid-principles/blob/master/src/main/java/dev/yavuztas/samples/solid/dip/OperatingSystem.java" target="blank">here</a>.</p> <p>Besides, you can read <a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle" target="blank">dependency inversion principle</a> over on Wikipedia for further details.</p> <h4 id="conclusion">Conclusion</h4> <p>After we explained OOP and the solid principles shortly we will go on <strong>Containers, Inversion of Control and Dependency Injection</strong> and give some examples about how they are applied in our <a href="https://yavuztas.dev/java/oop/2019/07/27/continers-inversion-of-control-and-dependency-injection.html">next article</a>.</p> Sat, 22 Jun 2019 16:33:00 +0000 https://yavuztas.dev/java/oop/2019/06/22/object-oriented-programming-and-solid-principles.html https://yavuztas.dev/java/oop/2019/06/22/object-oriented-programming-and-solid-principles.html java oop Spring Framework Fundamentals <p>I have created an educational repository that aims to provide fundamental information and code samples with <strong>Java</strong>. My project primarily focuses on <strong>Spring Framework</strong> and attempts to prepare such a repository not only to refresh potential knowledge and practice but also to contribute, for developing the open-source community. So feel free to drop comments about your opinion and any contributions are welcome!</p> <p>Please note that this guide does not like regular how-to guides explaining every detail from scratch. My goal is to touch every important topic about the core of the Spring Framework instead of writing about specific topics in detail. It is a collection of simple answers to the most common questions about the framework. Thus, it might not be for totally beginners or who do not have any experience with Spring Framework before.</p> <p>You can check the repository <a href="https://github.com/yavuztas/java-spring-fundamentals">over on Github</a></p> <h3 id="before-start">Before Start</h3> <p>First of all, before we dive into Spring, we should get familiar with some basic programming principles which are highly accepted in <strong>Java</strong> world and moreover strictly followed in <strong>Spring Framework.</strong></p> <p>In this way, I believe this guide will be much more effective and easily understandable.</p> <p>So, I will start with the topic <strong>Object Orient Programming and SOLID Principles</strong> as <a href="https://yavuztas.dev/java/oop/2019/06/22/object-oriented-programming-and-solid-principles.html">my first article</a>.</p> Sat, 15 Jun 2019 14:52:00 +0000 https://yavuztas.dev/java/spring/2019/06/15/spring-fundamentals.html https://yavuztas.dev/java/spring/2019/06/15/spring-fundamentals.html regular java spring Welcome to My Blog! <p>A momentous occasion for me, so many years passed until I launched my own blog. Under the burden of my daily work, I thought I couldn’t share my experience because I was a fairly busy guy. Man, I was wrong!</p> <p>Developers — especially the lazy ones like me — always tend to cop out quickly when it comes to writing, simply anything than code. Even though the output doesn’t have to be perfect, it feels way harder than coding most of the time.</p> <p>But believe me, the trick is a bit of time management and self-discipline, nothing more. We, developers, owe so many things to the public community. And we, developers, have so much to share.</p> <p>From now on, I’m writing.</p> <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyBlogApplicationStarter</span> <span class="o">{</span> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span> <span class="n">args</span><span class="o">[]){</span> <span class="nc">MyBlog</span> <span class="n">myBlog</span> <span class="o">=</span> <span class="nc">MyBlogFactory</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">"https://yavuztas.dev"</span><span class="o">);</span> <span class="n">myBlog</span><span class="o">.</span><span class="na">start</span><span class="o">();</span> <span class="o">}</span> <span class="o">}</span></code></pre></figure> Thu, 13 Jun 2019 13:00:00 +0000 https://yavuztas.dev/general/2019/06/13/welcome-to-my-blog.html https://yavuztas.dev/general/2019/06/13/welcome-to-my-blog.html featured general