<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[BLOG.OUSSAMA.GURU]]></title><description><![CDATA[Programming, design, technology, thoughts, stories and ideas]]></description><link>https://blog.oussama.guru/</link><image><url>https://blog.oussama.guru/favicon.png</url><title>BLOG.OUSSAMA.GURU</title><link>https://blog.oussama.guru/</link></image><generator>Ghost 3.31</generator><lastBuildDate>Sat, 25 Apr 2026 18:08:18 GMT</lastBuildDate><atom:link href="https://blog.oussama.guru/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Reading an HTTP Response Body as a String in Java]]></title><description><![CDATA[How to use the new HttpClient in JDK, the old HttpURLConnection and Apache HttpClient for reading an HTTP response body as a string in Java.]]></description><link>https://blog.oussama.guru/reading-an-http-response-body-as-a-string-in-java/</link><guid isPermaLink="false">5f73486617c27900015ef6ea</guid><category><![CDATA[Java]]></category><dc:creator><![CDATA[Oussama Ben Mahmoud]]></dc:creator><pubDate>Wed, 18 Mar 2020 15:45:00 GMT</pubDate><content:encoded><![CDATA[<h2 id="1-introduction">1. Introduction</h2><p>In this tutorial, we'll explore several libraries for reading an HTTP response body as a string in Java. Since the first versions, Java provided the <a href="https://www.baeldung.com/java-http-request"><em>HttpURLConnection</em></a> API. This includes only basic features and is known for not being very user-friendly.</p><p>With the release of JDK 11, Java introduced the new and improved <em><a href="https://www.baeldung.com/java-9-http-client">HttpClient</a> </em>API to handle HTTP communication. We'll cover these libraries, and we'll check some alternatives such as the <a href="https://www.baeldung.com/httpclient-guide">Apache HttpClient</a> and the <a href="https://www.baeldung.com/rest-template">Spring Rest Template</a>.</p><h2 id="2-httpclient">2. <em>HttpClient</em></h2><p>As we mentioned before, <a href="https://www.baeldung.com/java-9-http-client"><em>HttpClient</em></a> was added to Java 11. It allows us to access resources over the network. But, unlike <em>HttpURLConnection</em>, <strong><em>HttpClient</em> supports HTTP/1.1 and HTTP/2</strong>. Moreover, it <strong>provides both synchronous and asynchronous request types</strong>.</p><p><em>HttpClient</em> offers a modern API with a lot of flexibility and powerful features. Mainly, this API consists of three core classes: <em>HttpClient</em>, <em>HttpRequest</em>, and <em>HttpResponse</em>.</p><p><em>HttpResponse</em> describes the result of an <em>HttpRequest</em> call. <strong><em>HttpResponse</em> isn't created directly and is made available when the body has been fully received.</strong></p><p>To read a response body as a <em>String,</em> we'll first need to create simple client and request objects:</p><pre><code class="language-java">HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(DUMMY_URL))
    .build();</code></pre><p>Then, we simply use <em>BodyHandlers</em> and call the method <em>ofString()</em> to return the response:</p><pre><code class="language-java">HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());</code></pre><h2 id="3-httpurlconnection">3. <em>HttpURLConnection</em></h2><p><a href="https://www.baeldung.com/java-http-request"><em>HttpURLConnection</em></a> is a lightweight HTTP client used to access resources via the HTTP or HTTPS protocol and allows us to create an <em>InputStream</em>. Once we obtain the <em>InputStream,</em> we can read it like a normal local file.</p><p>In Java, the main classes we can use to access the Internet are the <em>java.net.URL</em> class and the <em>java.net.HttpURLConnection</em> class. First, we'll use the <em>URL</em> class to point to a web resource. Then, we can access it by using the <em>HttpURLConnection</em> class.</p><p>To get the response body from a <em>URL</em> as a <em>String</em>, we should first <strong>create an <em>HttpURLConnection</em></strong> using our <em>URL</em>:</p><pre><code class="language-java">HttpURLConnection connection = (HttpURLConnection) new URL(DUMMY_URL).openConnection();</code></pre><p>The <em>new URL(DUMMY_URL).openConnection()</em> returns a <em>HttpURLConnection</em>. This object allows us to add headers or checking the response code.</p><p>Next, let's <strong>get the <em>InputStream</em> from the <em>connection</em></strong> object:</p><pre><code class="language-java">InputStream inputStream = connection.getInputStream();</code></pre><p>Finally, we need to <strong><a href="https://www.baeldung.com/convert-input-stream-to-string">convert the <em>InputStream</em> to a <em>String</em></a></strong>.</p><h2 id="4-apache-httpclient">4. Apache <em>HttpClient</em></h2><p>In this section, we'll see how to use the <a href="https://www.baeldung.com/httpclient-guide">Apache <em>HttpClient</em></a> for reading an HTTP response body as a string.</p><p>To use this library, we'll need to add its dependency to our Maven project:</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.apache.httpcomponents&lt;/groupId&gt;
    &lt;artifactId&gt;httpclient&lt;/artifactId&gt;
    &lt;version&gt;4.5.12&lt;/version&gt;
&lt;/dependency&gt;</code></pre><p>We can <strong>retrieve and send data via the <em>CloseableHttpClient</em> class</strong>. To create an instance of it with default configuration we can use the <em>HttpClients.createDefault()</em>.</p><p><em>CloseableHttpClient</em> provides an <em>execute</em> method to send and receive data. This method uses a parameter of type <em>HttpUriRequest</em>, which has many subclasses including <em>HttpGet</em> and <em>HttpPost</em>.</p><p>Let's first <strong>create an <em>HttpGet</em> object</strong>:</p><pre><code class="language-java">HttpGet request = new HttpGet(DUMMY_URL);</code></pre><p>Second, let's <strong>create the client</strong>:</p><pre><code class="language-java">CloseableHttpClient client = HttpClients.createDefault();</code></pre><p>Third, we <strong>retrieve the response object</strong> from the result of the <em>execute</em> method:</p><pre><code class="language-java">CloseableHttpResponse response = client.execute(request);</code></pre><p>Finally, we return the response body by <strong>converting the response entity to a <em>String</em></strong>:</p><pre><code class="language-java">HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);</code></pre><h2 id="5-spring-resttemplate">5. Spring <em>RestTemplate</em></h2><p>In this section, we'll see how to use <a href="https://www.baeldung.com/rest-template">Spring <em>RestTemplate</em></a> for reading an HTTP response body as a string.</p><p>The <em>RestTemplate</em> class is an essential tool provided by Spring that offers <strong>a simple template for making client-side HTTP operations</strong> over underlying HTTP client libraries such as the JDK <em>HttpURLConnection</em>, Apache <em>HttpClient</em>, and others.</p><p><em>RestTemplate</em> provides <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html">some useful methods</a> for creating HTTP requests and handling responses.</p><p>We can use this library by first adding some dependencies to our Maven project:</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
    &lt;version&gt;${spring-boot.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
    &lt;version&gt;${spring-boot.version}&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;</code></pre><p>To make a web request and return the response body as a string, let's first <strong>create an instance of <em>RestTemplate</em></strong>:</p><pre><code class="language-java">RestTemplate restTemplate = new RestTemplate();</code></pre><p>Second, we <strong>get the response object by calling the method <em>getForObject()</em>, passing in the URL and desired response type</strong> — we'll use <em>String.class</em> in our example:</p><pre><code class="language-java">String response = restTemplate.getForObject(DUMMY_URL, String.class);</code></pre><h2 id="6-conclusion">6. Conclusion</h2><p>In this article, we’ve seen how to use several libraries for reading an HTTP response body as a <em>String</em>.</p><p>As usual, the complete code is available <a href="https://github.com/eugenp/tutorials/tree/master/httpclient-2">over on GitHub</a>.</p>]]></content:encoded></item><item><title><![CDATA[Java Files Open Options]]></title><description><![CDATA[An overview of StandardOpenOptions, covering the available options to open files in java, and what each of them means with examples.]]></description><link>https://blog.oussama.guru/java-files-open-options/</link><guid isPermaLink="false">5f6cdab617c27900015ef6af</guid><category><![CDATA[Java]]></category><dc:creator><![CDATA[Oussama Ben Mahmoud]]></dc:creator><pubDate>Tue, 11 Feb 2020 18:46:00 GMT</pubDate><media:content url="https://blog.oussama.guru/content/images/2020/09/How-to-format-a-book.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="overview">Overview</h2><img src="https://blog.oussama.guru/content/images/2020/09/How-to-format-a-book.jpg" alt="Java Files Open Options"><p>In this tutorial, we're going to focus on the standard open options available for files in Java.</p><p>We'll explore the <em>StandardOpenOption</em> enum that implements the <em>OpenOption</em> interface and that defines these standard open options.</p><h2 id="the-openoption-parameter">The <em>OpenOption</em> Parameter</h2><p>In Java, we can work with files using the NIO2 API, which contains several utility methods. Some of these methods use an optional <em>OpenOption</em> parameter that configures how to open or create a file. In addition, this parameter will have a default value if not set, which can be different for each of these methods.</p><p>The <em>StandardOpenOption</em> enum type defines the standard options and implements the <em>OpenOption</em> interface.</p><p><strong>Here's the list of supported options we can use with the <em>StandardOpenOptions</em> enum:</strong></p><ul><li><em>WRITE</em>: opens the file for write access</li><li><em>APPEND</em>: appends some data to the file</li><li><em>TRUNCATE_EXISTING</em>: truncates the file</li><li><em>CREATE_NEW</em>: creates a new file and throws an exception if the file already exists</li><li><em>CREATE</em>: opens the file if it exists or creates a new file if it does not</li><li><em>DELETE_ON_CLOSE</em>: deletes the file after closing the stream</li><li><em>SPARSE</em>: the newly created file will be sparse</li><li><em>SYNC</em>: preserves the content and the metadata of the file synchronized</li><li><em>DSYNC</em>: preserves only the content of the file synchronized</li></ul><p><strong>In the next sections, we'll see examples of how to use each of these options.</strong></p><p>To avoid any confusion on the file path, let's get a handle on the home directory of the user, which will be valid across all operating systems:</p><pre><code class="language-java">private static String HOME = System.getProperty("user.home");</code></pre><h2 id="opening-a-file-for-reading-and-writing">Opening a File for Reading and Writing</h2><p>First, if we want <strong>to create a new file if it does not exist we can use the option <em>CREATE</em></strong>:</p><pre><code class="language-java">@Test
public void givenExistingPath_whenCreateNewFile_thenCorrect() throws IOException {
    assertFalse(Files.exists(Paths.get(HOME, "newfile.txt")));
    Files.write(path, DUMMY_TEXT.getBytes(), StandardOpenOption.CREATE);
    assertTrue(Files.exists(path));
}</code></pre><p>We can also use the option <strong><em>CREATE_NEW, </em>which will create a new file if it does not exist.</strong> <strong>However, it will throw an exception if the file already exists.</strong></p><p>Secondly, if we want <strong>to open the file for reading we can use the <em>newInputStream(Path, OpenOption.</em></strong>..) method. This method opens the file for reading and returns an input stream:</p><pre><code class="language-java">@Test
public void givenExistingPath_whenReadExistingFile_thenCorrect() throws IOException {
    Path path = Paths.get(HOME, DUMMY_FILE_NAME);

    try (InputStream in = Files.newInputStream(path); BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
        String line;
        while ((line = reader.readLine()) != null) {
            assertThat(line, CoreMatchers.containsString(DUMMY_TEXT));
        }
    }
}
</code></pre><p>Notice how <strong>we didn't use the option <em>READ</em> because it's used by default by the method <em>newInputStream</em></strong>.</p><p>Third, <strong>we can create a file, append to a file, or write to a file by using the <em>newOutputStream(Path, OpenOption.</em></strong>..) method. This method opens or creates a file for writing and returns an <em>OutputStream</em>.</p><p>The API will create a new file if we don't specify the open options, and the file does not exist. However, if the file exists, it will be truncated. This option is similar to calling the method with the <em>CREATE</em> and <em>TRUNCATE_EXISTING</em> options.</p><p>Let's open an existing file and append some data:</p><pre><code class="language-java">@Test
public void givenExistingPath_whenWriteToExistingFile_thenCorrect() throws IOException {
    Path path = Paths.get(HOME, DUMMY_FILE_NAME);

    try (OutputStream out = Files.newOutputStream(path, StandardOpenOption.APPEND, StandardOpenOption.WRITE)) {
        out.write(ANOTHER_DUMMY_TEXT.getBytes());
    }
}</code></pre><h2 id="creating-a-sparse-file">Creating a <em>SPARSE</em> File</h2><p>We can tell the file system that the newly created file should be sparse (files containing empty spaces that will not be written to disk).</p><p>For this, we should use the option <em>SPARSE</em> with the <em>CREATE_NEW</em> option. However, <strong>this option will be ignored if the file system does not support sparse files</strong>.</p><p>Let's create a sparse file:</p><pre><code class="language-java">@Test
public void givenExistingPath_whenCreateSparseFile_thenCorrect() throws IOException {
    Path path = Paths.get(HOME, "sparse.txt");
    Files.write(path, DUMMY_TEXT.getBytes(), StandardOpenOption.CREATE_NEW, StandardOpenOption.SPARSE);
}</code></pre><h2 id="keeping-the-file-synchronized">Keeping the File Synchronized</h2><p>The <em>StandardOpenOptions</em> enum has <em>SYNC</em> and <em>DSYNC</em> options. These options require that data is written to the file synchronously in the storage. In other words, <strong>these will guarantee that the data is not lost in the event of a system crash</strong>.</p><p>Let's append some data to our file and use the option <em>SYNC</em>:</p><pre><code class="language-java">@Test
public void givenExistingPath_whenWriteAndSync_thenCorrect() throws IOException {
    Path path = Paths.get(HOME, DUMMY_FILE_NAME);
    Files.write(path, ANOTHER_DUMMY_TEXT.getBytes(), StandardOpenOption.APPEND, StandardOpenOption.WRITE, StandardOpenOption.SYNC);
}</code></pre><p>The difference between <em>SYNC</em> and <em>DSYNC</em> is that <strong><em>SYNC</em></strong> <strong>stores the content and the metadata of the file synchronously</strong> in the storage, while <strong><em>DSYNC</em> stores only the contents of the file synchronously</strong> in the storage.</p><h2 id="deleting-the-file-after-closing-the-stream">Deleting the File After Closing the Stream</h2><p>The <em>StandardOpenOptions</em> enum also offers a useful option that gives us the ability to destroy the file after closing the stream. <strong>This useful if we want to create a temporary file.</strong></p><p>Let's append some data to our file, and <strong>use the option <em>DELETE_ON_CLOSE</em></strong>:</p><pre><code class="language-java">@Test
public void givenExistingPath_whenDeleteOnClose_thenCorrect() throws IOException {
    Path path = Paths.get(HOME, EXISTING_FILE_NAME);
    assertTrue(Files.exists(path)); // file was already created and exists

    try (OutputStream out = Files.newOutputStream(path, StandardOpenOption.APPEND, 
      StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE)) {
        out.write(ANOTHER_DUMMY_TEXT.getBytes());
    }

    assertFalse(Files.exists(path)); // file is deleted
}</code></pre><h2 id="conclusion">Conclusion</h2><p>In this tutorial, we covered the available options to open files in Java using the new file system API (NIO2) that was shipped as a part of Java 7.</p><p>As usual, the source code with all the examples in the tutorial can be found <a href="https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-io-3">over on Github</a>.</p>]]></content:encoded></item><item><title><![CDATA[A Quick And Practical Example Of Hexagonal Architecture In Java]]></title><description><![CDATA[Hexagonal architecture (a.k.a. Ports and Adapters Architecture) is a design pattern that isolates the core domain logic from all other application components.]]></description><link>https://blog.oussama.guru/a-quick-and-practical-example-of-hexagonal-architecture-in-java/</link><guid isPermaLink="false">5f67870af9ca3a0001b9d6a3</guid><category><![CDATA[Java]]></category><category><![CDATA[Design Patterns]]></category><dc:creator><![CDATA[Oussama Ben Mahmoud]]></dc:creator><pubDate>Wed, 01 Jan 2020 16:47:00 GMT</pubDate><content:encoded><![CDATA[<h2 id="overview">Overview</h2><p>In this tutorial, we'll implement a simple Java application applying <strong>hexagonal architecture</strong>.</p><h2 id="hexagonal-architecture">Hexagonal Architecture</h2><p>Hexagonal architecture (a.k.a. <strong>Ports and Adapters Architecture</strong>) is a design pattern that <strong>isolates the core domain logic from all other application components</strong>.</p><p>As a result, the <strong>business core</strong> will communicate with other parts of the application through <strong>ports</strong> and <strong>adapters</strong>. This way, we can change the underlying technologies without having to change the <strong>application core.</strong></p><p>Let's move on to the actual implementation of this architecture.</p><h2 id="implementation-using-java">Implementation Using Java</h2><p>We're going to build a small <em>PhoneBook</em> application with an <em>add </em>operation to show how to organize code around <strong>ports</strong> and <strong>adapters</strong>.</p><p>We can divide our application into three layers; <strong>domain (internal component)</strong>, <strong>application (external component)</strong>, and <strong>infrastructure (external component)</strong>.</p><h2 id="domain-layer">Domain Layer</h2><p>The <strong>domain layer</strong> defines the inside of the application and <strong>provides ports to communicate with the application's use cases</strong>.</p><p>Firstly, we should create a <em>PhoneBook</em> class:</p><pre><code class="language-java">public class PhoneBook {

    private Long id;
    private List numbers;

    public PhoneBook(Long id, List numbers) {
        this.id = id;
        this.numbers = numbers;
    }

    public void addNumber(String number) {
        numbers.add(number);
    }

    // standard setters and getters
}</code></pre><p>Anything related to our <strong>business logic</strong> will go through this class. Additionally, <em>PhoneBook</em> is responsible for adding a phone number.</p><p>Secondly, we should define the <strong>incoming ports</strong>. These are <strong>used by external components to interact with our application</strong>.</p><p>Let's create a port for the <em>add</em> use case:</p><pre><code class="language-java">public interface AddPhoneNumberPort {
    void add(Long id, String number);
}</code></pre><p>Thirdly, we should define our <strong>outgoing ports</strong>. These are<strong> used by the domain to interact with the storage</strong>.</p><p>In this example, we can define two ports: the first one for <em>Load</em> and the second one for <em>Save</em>.</p><pre><code class="language-java">public interface LoadPhoneBookPort {
    Optional load(Long id);
}</code></pre><pre><code class="language-java">public interface SavePhoneBookPort {
    void save(PhoneBook phoneBook);
}</code></pre><p>Lastly, we should implement the <em>PhoneBookAddService</em> to tie all the pieces together.</p><p>Notice how the service <strong>implements the incoming port</strong> in which it <strong>uses the outgoing ports</strong>.</p><pre><code class="language-java">public class PhoneBookAddService implements AddPhoneNumberPort {

    private LoadPhoneBookPort loadPhoneBookPort;
    private SavePhoneBookPort savePhoneBookPort;

    // constructor

    @Override
    public void add(Long id, String number) {
        PhoneBook phoneBook = loadPhoneBookPort.load(id).orElse(new PhoneBook(id, new ArrayList&lt;&gt;()));

        phoneBook.addNumber(number);

        savePhoneBookPort.save(phoneBook);
    }
}</code></pre><p>On the <em>add</em> method, it uses the <em>LoadPhoneBookPort</em> port to fetch the <em>PhoneBook</em> from the storage. Then, it performs the changes in the <strong>domain model</strong>. And finally, it saves those changes through the <em>SavePhoneBookPort</em> port.</p><h2 id="infrastructure-layer">Infrastructure Layer</h2><p>In this section, we need to provide implementations for the defined ports to <strong>help retrieve and save the data</strong>. We call these <strong>adapters</strong>.</p><p>Firstly, we should define a <strong>repository</strong> class that will be used later by the adapters:</p><pre><code class="language-java">public class PhoneBookRepository {

    List phoneBooks = new ArrayList&lt;&gt;();

    public void save(PhoneBook phoneBook) {
        phoneBooks.add(phoneBook);
    }

    public Optional load(Long id) {
        return phoneBooks.stream().filter(phoneBook -&gt; phoneBook.getId().equals(id)).findFirst();
    }
}</code></pre><p>Secondly, we should implement the <strong>adapters</strong> and use the <strong>repository</strong>.</p><p>Briefly, they load and save <em>PhoneBook</em> by calling the load and save methods of the <strong>repository</strong> class.</p><pre><code class="language-java">public class LoadPhoneBookAdapter implements LoadPhoneBookPort {

    private PhoneBookRepository phoneBookRepository;

    // constructor

    @Override
    public Optional load(Long id) {
        return phoneBookRepository.load(id);
    }
}</code></pre><pre><code class="language-java">public class SavePhoneBookAdapter implements SavePhoneBookPort {

    private PhoneBookRepository phoneBookRepository;

    // constructor

    @Override
    public void save(PhoneBook phoneBook) {
        phoneBookRepository.save(phoneBook);
    }
}</code></pre><h2 id="application-layer">Application Layer</h2><p>In this section, we'll implement the application layer. We'll <strong>use the adapters for the outside entities to interact with the domain</strong>.</p><p>Therefore, let's create a <em>PhoneBookApplication:</em></p><pre><code class="language-java">public class PhoneBookApplication {
    private AddPhoneNumberPort addPhoneNumberService;

    private PhoneBookRepository phoneBookRepository;

    private SavePhoneBookPort savePhoneBookAdapter;
    private LoadPhoneBookPort loadPhoneBookAdapter;

    public static void main(String[] args) {
        new PhoneBookApplication().init();
    }

    public void init() {
        phoneBookRepository = new PhoneBookRepository();

        savePhoneBookAdapter = new SavePhoneBookAdapter(phoneBookRepository);
        loadPhoneBookAdapter = new LoadPhoneBookAdapter(phoneBookRepository);

        addPhoneNumberService = new PhoneBookAddService(loadPhoneBookAdapter, savePhoneBookAdapter);
        addPhoneNumberService.add(100L, "064502131");
    }
}</code></pre><h2 id="conclusion">Conclusion</h2><p>In this article, we've learned how to implement the <strong>hexagonal architecture</strong> in Java.</p><p>As always, the code for these examples is available <a href="https://github.com/oussama-guru/java-hexagonal-architecture">over on GitHub</a>.</p>]]></content:encoded></item></channel></rss>