<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Solutions &#8211; CodePills.com</title>
	<atom:link href="https://codepills.com/category/solutions/feed/" rel="self" type="application/rss+xml" />
	<link>https://codepills.com</link>
	<description>Helping you make a better code</description>
	<lastBuildDate>Sat, 30 Mar 2024 14:05:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Simple algorithm for casting strings to double</title>
		<link>https://codepills.com/simple-algorithm-for-casting-strings-to-double/</link>
					<comments>https://codepills.com/simple-algorithm-for-casting-strings-to-double/#respond</comments>
		
		<dc:creator><![CDATA[Andrej Buday]]></dc:creator>
		<pubDate>Mon, 05 Feb 2024 14:30:33 +0000</pubDate>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[separators]]></category>
		<guid isPermaLink="false">https://codepills.com/?p=1356</guid>

					<description><![CDATA[The article describes a method for converting incorrectly formatted numeric strings in CSV files into doubles by replacing commas with dots and handling various input errors, complemented by a Java util class implementation and tests. <a href="https://codepills.com/simple-algorithm-for-casting-strings-to-double/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>This article describes a method for converting incorrectly formatted numeric strings in CSV files into doubles by replacing commas with dots and handling various input errors, complemented by a Java util class implementation and tests.</p>
<p><span id="more-1356"></span></p>
<h2>Introduction</h2>
<p>Recently, I was solving a straightforward issue. The technical documentation about the input format was straightforward. A particular column in the CSV document represented numbers in double format. However, users were allowed to interact with CSV files and make manual edits. This lead to a situation where the user or the processing program changes the number to a standardized format or even to an incorrect one. In most cases, users change the dot to a comma.</p>
<p>Thus, if possible, I needed to devise a simple way to fix the incorrect input and cast the string to double.</p>
<h2>Implementation</h2>
<p>I have created a simple util class with a single static method to fix the incorrect string format.</p>
<p>The method implementation catches and solves the following cases:</p>
<ul>
<li>The method throws an exception if the input string is null or empty.</li>
<li>The method throws an exception if the input string contains more than one separator or a mix of different separators.</li>
<li>The method throws an exception if the input string is not a number.</li>
<li>Otherwise, the process replaces the comma with a dot and parses the string to double.</li>
</ul>
<p>Casting can still fail and throw <code>NumberFormatException</code> if the input string is not a number. <em>parseStringToDouble()</em> method will not handle the failure, and it will be up to the caller to catch the exception and manage it. Feel free to adjust the method according to your needs.</p>
<p>Here is a simple algorithm for how to cast string to double:</p>
<pre><code class="language-java">public static class StringUtil {
  
  private static final String DOT = ".";
  private static final String COMMA = ",";
  private static final String EMPTY = "";
  
  /**
   * Parses a string to a double.
   *
   * @param numberStr
   * @return the parsed double
   * @throws IllegalArgumentException if the input string is null or empty, or if the number is ambiguous
   */
  public static Double parseStringToDouble(final String numberStr) {
      if (numberStr == null || numberStr.isEmpty()) {
          throw new IllegalArgumentException("Input string is null or empty");
      }

      val numberStrWithReplacedCommas = numberStr.replace(COMMA, DOT);

      int dotCount = numberStr.length() - numberStr.replace(DOT, EMPTY).length();
      int commaCount = numberStr.length() - numberStrWithReplacedCommas.length();

      if (dotCount + commaCount > 1) {
          throw new IllegalArgumentException("There is more than one separator, or a mix of them, the number is ambiguous");
      }

      return Double.parseDouble(numberStrWithReplacedCommas);
  }

}</code></pre>
<p>Feel free to use this simple algorithm in your projects and extend it according to your will. You may not need to throw an exception if the input string is null or empty or if the number is ambiguous. You may want to catch <code>NumberFormatException</code> from <i>parseDouble</i> method and return 0.0 in such case. You could return empty Optional. It is up to you.</p>
<h2>Tests</h2>
<p>I also wrote a few tests to verify that the algorithm works correctly. Please check it and adjust it according to your will. Here are the tests:</p>
<pre><code class="language-java">import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import lombok.val;

class StringUtilTest {

    @Test
    public void testParseValidStringWithDot() {
        val result = StringUtil.parseStringToDouble("123.45");
        Assertions.assertEquals(123.45, result, 0.000);
    }

    @Test
    public void testParseValidStringWithComma() {
        val result = StringUtil.parseStringToDouble("123,45");
        Assertions.assertEquals(123.45, result, 0.000);
    }

    @Test
    public void testParseStringWithMultipleSeparatorsShouldThrowException() {
        Assertions.assertThrows(IllegalArgumentException.class,
            () -> StringUtil.parseStringToDouble("123,45.67"));
    }

    @Test
    public void testParseStringWithInvalidCharactersShouldThrowException() {
        Assertions.assertThrows(IllegalArgumentException.class,
            () -> StringUtil.parseStringToDouble("123..45"));
    }

    @Test
    public void testParseStringWithOtherInvalidCharactersShouldThrowException() {
        Assertions.assertThrows(IllegalArgumentException.class,
            () -> StringUtil.parseStringToDouble("123,,45"));
    }

    @Test
    public void testParseNonNumericStringShouldThrowException() {
        Assertions.assertThrows(NumberFormatException.class,
            () -> StringUtil.parseStringToDouble("not a number"));
    }

    @Test
    public void testParseEmptyStringShouldThrowException() {
        Assertions.assertThrows(IllegalArgumentException.class,
            () -> StringUtil.parseStringToDouble(""));
    }

    @Test
    public void testParseNullShouldThrowException() {
        Assertions.assertThrows(IllegalArgumentException.class,
            () -> StringUtil.parseStringToDouble(null));
    }

}</code></pre>
<h2>Conclusion</h2>
<p>In simple algorithms, we have seen how to handle multiple cases of incorrect string input and how to cast string to double.</p>
<p>But in the end, it is up to you how to handle the cases when the input string is null or empty or if the number is ambiguous. You can throw a custom exception, return 0.0, empty Optional, or do something else.</p>
<p>Did you find an algorithm for casting strings to double easily? Do you have your trick or know another way <u>how to change arbitrary string to double</u>? Let us know in the comments below the article. We would like to hear your ideas and stories.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codepills.com/simple-algorithm-for-casting-strings-to-double/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to make multipart requests with file and object through autogenerated code defined in OpenAPI</title>
		<link>https://codepills.com/how-to-make-multipart-requests-with-file-and-object-through-autogenerated-code-defined-in-openapi/</link>
					<comments>https://codepills.com/how-to-make-multipart-requests-with-file-and-object-through-autogenerated-code-defined-in-openapi/#respond</comments>
		
		<dc:creator><![CDATA[Andrej Buday]]></dc:creator>
		<pubDate>Sat, 03 Feb 2024 18:08:37 +0000</pubDate>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Converter]]></category>
		<category><![CDATA[Deserialization]]></category>
		<category><![CDATA[Endpoint Creation]]></category>
		<category><![CDATA[File Upload]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Multipart Form Data]]></category>
		<category><![CDATA[MultipartFile]]></category>
		<category><![CDATA[Object Validation]]></category>
		<category><![CDATA[ObjectMapper]]></category>
		<category><![CDATA[OpenAPI]]></category>
		<category><![CDATA[Postman]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[Validator]]></category>
		<guid isPermaLink="false">https://codepills.com/?p=1364</guid>

					<description><![CDATA[This article explains how to create a Spring Boot endpoint using OpenAPI to receive objects and, optionally, files through multipart form data, focusing on deserialization and validation of incoming objects. <a href="https://codepills.com/how-to-make-multipart-requests-with-file-and-object-through-autogenerated-code-defined-in-openapi/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>This article explains creating a Spring Boot endpoint using OpenAPI to receive objects and, optionally, files through multipart form data, focusing on deserialization and validation of incoming objects.</p>
<p><span id="more-1364"></span></p>
<h2>Introduction</h2>
<p>In this article we will continue and spin from the <a href="https://codepills.com/how-to-make-multipart-requests-with-files-through-autogenerated-code-defined-in-openapi/" title="How to make multipart requests with files through autogenerated code defined in OpenAPI" target="_blank" rel="nofollow noopener">previous article</a> about generating OpenAPI with Spring Boot for multipart endpoint and uploading files through it. We strongly recommend reading the last article if you want to import more than one file. But in this article, we will focus only on the optional import of a single file.</p>
<p>But instead of multiple files, we will try to upload only one file and one serialized object, for example, the information about the new user.</p>
<p>We will also show how to handle the deserialization of the incoming object from the string at the Spring Boot backend and how to control proper deconstruction if some fields are optional or not mandatory.</p>
<h2>OpenAPI User import definition YAML</h2>
<p>So we start where we end the last time. Let&#8217;s generate the Spring Boot endpoint through the OpenAPI schema, which will be able to receive objects and, optionally, a file through multipart form data.</p>
<pre><code class="language-yaml">openapi: 3.0.2
info:
  title: User management module
  description: User management
  version: '0.1'
  contact:
  email: optional@email.com
servers:
  - url: https://localhost:8080/api/user-management

paths:
  /users/import:
    post:
      summary: Create new Users with optional attachment
      tags:
        - users
      operationId: createUserWithOptionalFile
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                createUser:
                  description: Wrapper containing information for new user creation
                  type: object
                  properties:
                    username:
                      description: Users username
                      type: string
                    age:
                      description: Users password
                      type: number
                    creationTimestamp:
                      description: Time when the user will be defined as created in the system
                      type: string
                      format: date-time
                      example: "2024-02-29T12:30:00.000Z"
                    email:
                      description: Email of the user
                      type: string
                    addressId:
                      description: ID of the users address
                      type: string
                    accessRights:
                      description: List of access rights for the user
                      type: array
                      items:
                        type: object
                        properties:
                          accessRightId:
                            description: ID of the access right
                            type: string
                          note:
                            description: Note for the access right
                            type: string
                  required:
                    - username
                    - email
                    - accessRights
                optionalFile:
                  description: Optional file attachment
                  type: string
                  format: binary
              required:
              - createUser
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateUserResponse'
        '400':
          description: Bad Request</code></pre>
<p>As you can see, we have defined the endpoint /users/import, which will be able to receive the object createUser and optionally also a single file. The createUser object is defined in the schema and is required, while the file is optional. CreateUser object also has various definitions of fields, although unimportant and displayed only for current examples.</p>
<p>You can refer to the object schema to make the YAML file more readable and concise. The object&#8217;s schema can be defined in self-standing section dedicated to components.</p>
<pre><code class="language-yaml">openapi: 3.0.2
info:
  title: User management module
  description: User management
  version: '0.1'
  contact:
  email: optional@email.com
servers:
  - url: https://localhost:8080/api/user-management

paths:
  /users/import:
    post:
      summary: Create new Users with optional attachment
      tags:
        - users
      operationId: createUserWithOptionalFile
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                createUser:
                  $ref: '#/components/schemas/CreateUser'
                optionalFile:
                  description: Optional file attachment
                  type: string
                  format: binary
              required:
              - createUser
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateUserResponse'
        '400':
          description: Bad Request

components:
  schemas:
    CreateUser:
      description: Wrapper containing information for new user creation
      type: object
      properties:
        username:
          description: Users username
          type: string
        age:
          description: Users password
          type: number
        creationTimestamp:
          description: Time when the user will be defined as created in the system
          type: string
          format: date-time
          example: "2024-02-29T12:30:00.000Z"
        email:
          description: Email of the user
          type: string
        addressId:
          description: ID of the users address
          type: string
        accessRights:
          description: List of access rights for the user
          type: array
          items:
            type: object
            properties:
              accessRightId:
                description: ID of the access right
                type: string
              note:
                description: Note for the access right
                type: string
      required:
        - username
        - email
        - accessRights</code></pre>
<h2>Enforcing and casting mandatory properties of multipart request</h2>
<p>Multipart file can accept only the <i>String</i>s or <i>File</i>s (better visible in <a href="#testing_with_postman">testing with Postman</a> section). So any string input &#8211; Java&#8217;s serialized object, or JSON, is at the end nothing more than just a string of bytes.</p>
<p>The problem will arise during the deserialization of autogenerated code. It does not matter if you declare the object cast as required. With proper mapping, the input will be taken as a String and not as the type you want to use from the method signature.</p>
<p>Mapper and validator factory beans can solve the issue and handle the input.</p>
<p>First, register one new bean for object Validation. Optionally, you can register the ObjectMapper with JavaTimeModule to handle the date-time format, as we will use the date-time string in ISO format (&#8220;YYYY-MM-DDTHH:MM:SS.mmmZ&#8221;). The Validator is created through LocalValidatorFactoryBean.</p>
<pre><code class="language-java">import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import jakarta.validation.Validator;
import lombok.val;

@Configuration
public class AppConfig {

  //@Bean
  //public ObjectMapper objectMapper() {
  //  val objectMapper = new ObjectMapper();
  //  objectMapper.registerModule(new JavaTimeModule());
  //  return objectMapper;
  //}

  @Bean
  public Validator validator() {
    return new LocalValidatorFactoryBean();
  }

}</code></pre>
<p>The code was written for Java 21 dependencies with Lombok.</p>
<p>To enforce the proper conversion, you must create a new Spring component to convert the incoming string to the object. The component will be able to handle the deserialization and validation of the object.</p>
<pre><code class="language-java">import java.util.Set;

import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validator;
import lombok.val;

@Component
public class StringToCreateUserDtoConverter implements Converter&lt;String, CreateUserDto> {

  private final Validator validator;
  private final ObjectMapper objectMapper;

  public StringToCreateUserDtoConverter(final Validator validator, final ObjectMapper objectMapper) {
    this.validator = validator;
    this.objectMapper = objectMapper;
  }

  @Override
  public CreateUserDto convert(final String source) {
    CreateUserDto createUserDto;
    try {
        createUserDto = objectMapper.readValue(source, CreateUserDto.class);
    } catch (JsonProcessingException e) {
        throw new CreateUserDeserializationException("Input mapping and processing error: " + e.getMessage());
    }
    val violations = validator.validate(createUserDto);
    if (!violations.isEmpty()) {
        throw new ConstraintViolationException(violations);
    }
    return createUserDto;
  }

}</code></pre>
<p>Just for the record, I will also add here the custom exception you can throw and catch in the custom exception handler:</p>
<pre><code class="language-java">import java.io.Serial;

import lombok.Getter;

@Getter
public class CreateUserDeserializationException extends RuntimeException {

  @Serial
  private static final long serialVersionUID = 1659771269447893294L;

  public CreateUserDeserializationException(String msg) {
    super(msg);
  }

}</code></pre>
<h2>Unit tests</h2>
<p>I recommend writing the unit tests for the converter. It is a good practice to test the conversion and validation of the object. As we rely heavily upon Spring magic, a lot can unintentionally influence the component&#8217;s behaviour without us discovering it.</p>
<p>The code below is just an example of the unit tests with the usage of <i>SpringBootTest</i> and <i>LocalTestcontainers</i> which ties to get close to real-world use scenarios. We highly recommend to accommodate tests to your environment and needs.</p>
<pre><code class="language-java">
import org.testcontainers.containers.PostgreSQLContainer;

public class LocalTestcontainers {

    public static void startPostgres(){
        PostgreSQLContainer<?> postgre = new PostgreSQLContainer<>("postgres:16.0")
            .withDatabaseName("INSERT_DATABASE_NAME")
            .withUsername("INSERT_DATABASE_USERNAME")
            .withPassword("INSERT_DATABASE_PASSWORD");
        postgre.start();

        System.setProperty("spring.datasource.url", postgre.getJdbcUrl());
        System.setProperty("spring.datasource.username", postgre.getUsername());
        System.setProperty("spring.datasource.password", postgre.getPassword());
    }

}</code></pre>
<pre><code class="language-java">import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.testcontainers.junit.jupiter.Testcontainers;

import com.codepills.usermanagementmodule.api.exception.CreateUserDeserializationException;
import com.codepills.usermanagementmodule.utils.LocalTestcontainers;

import jakarta.validation.ConstraintViolationException;
import lombok.val;

@SpringBootTest
@Testcontainers
class StringToCreateUserDtoConverterTest {

    static {
        LocalTestcontainers.startPostgres();
    }

    @Autowired
    private StringToCreateUserDtoConverter stringToCreateUserDtoConverter;

    @Test
    void testConvertValidInputString() {
        // Arrange
        val username = "JohnDoe";
        val age = 25;
        val formatter = DateTimeFormatter.ISO_INSTANT;
        val now4CreationTime = Instant.now();
        val email = "john.doe@noemail.com";
        val addressId = UUID.randomUUID();
        val accessRightId1 = UUID.randomUUID();
        val accessRightId2 = UUID.randomUUID();

        val stringBuilder = new StringBuilder();
        stringBuilder.append("{");
        stringBuilder.append("\"username\" : \"").append(username).append("\",");
        stringBuilder.append("\"age\" : ").append(age).append(",");
        stringBuilder.append("\"creationTimestamp\" : \"").append(formatter.format(now4CreationTime)).append("\",");
        stringBuilder.append("\"email\" : \"").append(email).append("\",");
        stringBuilder.append("\"addressId\" : \"").append(addressId).append("\",");
        stringBuilder.append("\"accessRights\" : [");
        stringBuilder.append("{");
        stringBuilder.append("\"accessRightId\" : \"").append(accessRightId1).append("\",");
        stringBuilder.append("}, {");
        stringBuilder.append("\"accessRightId\" : \"").append(accessRightId2).append("\"");
        stringBuilder.append("}]}");
        val validInput = stringBuilder.toString();

        // Act
        val createUserDto = stringToCreatUserDtoConverter.convert(validInput);

        // Assert
        assertNotNull(createUserDto);
        assertEquals(username, createUserDto.getUsername());
        assertEquals(age, createUserDto.getAge());
        assertEquals(now4CreationTime, createUserDto.getCreationTimestamp());
        assertEquals(email, createUserDto.getEmail());
        assertEquals(addressId.toString(), createUserDto.getAddressId());
        assertEquals(2, createUserDto.getAccessRights().size());
        assertEquals(accessRightId1.toString(), createUserDto.getAccessRights().get(0).getAccessRightId());
        assertEquals(accessRightId2.toString(), createUserDto.getAccessRights().get(1).getAccessRightId());
    }

    @Test
    void testConvertInvalidInputString() {
        // Arrange
        val invalidInput = "invalid input string";
        // Act & Assert
        try {
            stringToCreateUserDtoConverter.convert(invalidInput);
        } catch (CreateUserDeserializationException ex) {
            assertEquals("Input mapping and processing error: Unrecognized token 'invalid': was expecting (JSON String, Number, Array, "
                             + "Object or token 'null', 'true' or 'false')\n at [Source: (String)\"invalid input string\"; line: 1, "
                             + "column: 8]", ex.getMessage());
        }
    }

    @Test
    void testConvertInputWithValidationErrors() {
        // Arrange
        val username = "JohnDoe";
        val age = 25;
        val formatter = DateTimeFormatter.ISO_INSTANT;
        val now4CreationTime = Instant.now();
        val email = "john.doe@noemail.com";
        val addressId = UUID.randomUUID();
        val accessRightId1 = UUID.randomUUID();
        val accessRightId2 = UUID.randomUUID();

        val stringBuilder = new StringBuilder();
        stringBuilder.append("{");
        stringBuilder.append("\"username\" : \"").append(username).append("\",");
        stringBuilder.append("\"age\" : ").append(age).append(",");
        stringBuilder.append("\"creationTimestamp\" : \"").append(formatter.format(now4CreationTime)).append("\",");
        stringBuilder.append("\"email\" : \"").append(email).append("\",");
        // Missing addressId
        stringBuilder.append("\"addressId\" : null,");
        stringBuilder.append("\"accessRights\" : [");
        stringBuilder.append("{");
        stringBuilder.append("\"accessRightId\" : \"").append(accessRightId1).append("\",");
        stringBuilder.append("}, {");
        stringBuilder.append("\"accessRightId\" : \"").append(accessRightId2).append("\"");
        stringBuilder.append("}]}");
        val validInput = stringBuilder.toString();

        // Act & Assert
        try {
            stringToCreateUserDtoConverter.convert(inputWithValidationErrors);
        } catch (ConstraintViolationException ex) {
            assertEquals(1, ex.getConstraintViolations().size());
        }
    }

}</code></pre>
<h2>User Management Controller</h2>
<p>Now, all we need to do is create a controller to implement the OpenAPI schema.</p>
<p>Here is an example of the controller:</p>
<pre><code class="language-java">@Logger
@RestController
@RequiredArgsConstructor
public class UserManagementController implements UserManagementApi {

  @Override
  public ResponseEntity&lt;Void&gt&gt; createUserWithOptionalFile(
        @RequestPart(name = "createUser") final CreateUserDto createUserDto,
        @RequestPart(name = "optionalFile", required = false) MultipartFile optionalFile
     ) {
    if (optionalFile == null || optionalFile.isEmpty()) {
        log.info("No optionalFile uploaded.");
    } else {
        log.info("PDF optionalFile {} uploaded but not saved.", optionalFile.getOriginalFilename());
    }

    // You can work with createUserDto here

    return ResponseEntity.ok().build();
  }

}</code></pre>
<p>I will leave the implementation of <em>createUserWithOptionalFile()</em> method up to you as it is not the main focus of this article.</p>
<p>Again, notice the <i>optionalFile</i> and <i>createUser</i> keywords in the method arguments. It is the same as the keyword as defined in the OpenAPI schema.</p>
<h2 id="testing_with_postman">Testing with Postman</h2>
<p>Nothing blocks our development anymore, and we can start testing the endpoint with Postman. The endpoint will be able to receive the serialized object in the form of string and also the file. However, attaching the file to the request is, of course, optional.</p>
<p>As it might need to be stressed more, the most important thing is using the exact keywords defined in the OpenAPI schema. In our case, for importing object, it will be <i>createUser</i> and for optional file, it will be <i>optionalFile</i>.</p>
<p>Let&#8217;s run the SpringBoot app at localhost.</p>
<p>Backend should be running at localhost. And if added the necessary logic for file processing into the controller, we should be able to upload serialized objects in JSON format and optional file through the <em>/users/import</em> endpoint.</p>
<p>When using Postman, you also need to define the type of multipart key. It is either the <em>String</em> or <em>File</em>. For files, use <em>File</em>, and for the object, use <em>String</em>. Do not forget that in the <a href="https://codepills.com/how-to-make-multipart-requests-with-files-through-autogenerated-code-defined-in-openapi/" title="How to make multipart requests with files through autogenerated code defined in OpenAPI" target="_blank" rel="nofollow noopener">previous article</a> we discuss the implementation of sending multiple files through multipart request.</p>
<p>All you need to do is to define your endpoint <code>POST</code> request in Postman. Select <code>POST</code> request, add the URL, and in the body tab, select form-data and add the keywords <em>createUser</em> set as <em>String</em> and <em>optionalFile</em> as <em>File</em> .</p>
<p><img fetchpriority="high" decoding="async" src="https://codepills.com/wp-content/uploads/2024/02/postman_multipart_request_with_multiple_objects_and_files.png" alt="Postman multipart request with multiple objects and files" width="665" height="316" class="size-full wp-image-1373" srcset="https://codepills.com/wp-content/uploads/2024/02/postman_multipart_request_with_multiple_objects_and_files.png 665w, https://codepills.com/wp-content/uploads/2024/02/postman_multipart_request_with_multiple_objects_and_files-300x143.png 300w" sizes="(max-width: 665px) 100vw, 665px" /></p>
<p>The most important part is to really define serialized object as <em>String</em> and not <em>File</em>.</p>
<p>Here is an example of <em>createUser</em> as <em>String</em>:</p>
<pre><code class="language-text">{
	"username" : "johndoe",
	"age" : "25",
	"creationTimestamp" : "2024-02-29T12:30:00.000Z",
	"email" : "john.doe@noemail.com",
	"addressId" : "f8935f28-8d7b-40a4-96d7-a3288976617e",
	"accessRights" : [
		{
      "accessRightId" : "712d5a0a-11b5-4a44-9e92-6e67d16be2aa"
    }
	]
}</code></pre>
<h2>Conclusion</h2>
<p>This article has shown how to create a Spring Boot endpoint to receive objects and, optionally, file through multipart form data. We have also demonstrated how to handle the deserialization of the incoming object from the string at the Spring Boot backend and how to control proper deconstruction if some fields are optional or not mandatory.</p>
<p>Is it applicable to auto-generating infrastructure code through OpenAPI with Spring Boot for multipart endpoint and uploading files? Let us know in the comments below. Do you have your trick or see another way <u>how to enforce and deserialize multipart object</u>? Let us know in the comments below the article. We would like to hear your ideas and stories.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codepills.com/how-to-make-multipart-requests-with-file-and-object-through-autogenerated-code-defined-in-openapi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to make multipart requests with files through autogenerated code defined in OpenAPI</title>
		<link>https://codepills.com/how-to-make-multipart-requests-with-files-through-autogenerated-code-defined-in-openapi/</link>
					<comments>https://codepills.com/how-to-make-multipart-requests-with-files-through-autogenerated-code-defined-in-openapi/#respond</comments>
		
		<dc:creator><![CDATA[Andrej Buday]]></dc:creator>
		<pubDate>Thu, 01 Feb 2024 15:55:58 +0000</pubDate>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Auto-generated Code]]></category>
		<category><![CDATA[Maven Plugin]]></category>
		<category><![CDATA[Multipart File Uploads]]></category>
		<category><![CDATA[OpenAPI Schema]]></category>
		<category><![CDATA[Postman Testing]]></category>
		<category><![CDATA[REST Endpoint]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<guid isPermaLink="false">https://codepills.com/?p=1360</guid>

					<description><![CDATA[This article provides a clear tutorial on generating infrastructure code defined in OpenAPI schema for your custom Spring Boot application and handling multipart file uploads through an autogenerated REST endpoint. <a href="https://codepills.com/how-to-make-multipart-requests-with-files-through-autogenerated-code-defined-in-openapi/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>This article provides a clear tutorial on generating code infrastructure defined OpenAPI schema for your custom Spring Boot application and handling multipart file uploads through an autogenerated REST endpoint.</p>
<p><span id="more-1360"></span></p>
<h2>Introduction</h2>
<p>Let&#8217;s imagine we want to build some simple user management app separated frontend with which we will communicate through REST.</p>
<p>Also, let&#8217;s add some limitations and requirements for our user management project. We will need to use the OpenAPI schema to generate the code infrastructure, as it can help us speed up interface development between the frontend and backend. We will focus on the implementation of code infrastructure on the backend side.</p>
<p>We generally want to receive and process multiple user files through multipart form data in Spring Boot.</p>
<h2>Maven OpenAPI plugin</h2>
<p>First, we must define a plugin in the pom.xml file to generate the code infrastructure from the OpenAPI schema.</p>
<p>Here is an example of the <em>pom.xml</em> file with the plugin definition:</p>
<pre><code class="language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

  &lt;parent&gt;
    &lt;groupId&gt;com.codepills.openapi&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-parent&lt;/artifactId&gt;
    &lt;version&gt;1.1.0&lt;/version&gt;
  &lt;/parent&gt;

  &lt;groupId&gt;com.codepills.openapi&lt;/groupId&gt;
  &lt;artifactId&gt;user-management-module&lt;/artifactId&gt;
  &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;
  &lt;name&gt;user-management-module&lt;/name&gt;
  &lt;description&gt;User management module&lt;/description&gt;

  &lt;properties&gt;
    &lt;java.version&gt;21&lt;/java.version&gt;
    &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
    &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
    &lt;version.swagger.codegen&gt;3.0.50&lt;/version.swagger.codegen&gt;
    &lt;open.api.file&gt;${project.basedir}/src/main/api-specification/OpenApi-UserManagement.yaml&lt;/open.api.file&gt;
    &lt;open.api.base&gt;com.codepills.openapi.usermanagementmodule&lt;/open.api.base&gt;
    &lt;generated-sources-path&gt;${project.build.directory}/generated-sources&lt;/generated-sources-path&gt;
    &lt;generated-sources-java-path&gt;main/java&lt;/generated-sources-java-path&gt;
  &lt;/properties&gt;

  &lt;dependencies&gt;...&lt;/dependencies&gt;

  &lt;build&gt;
    &lt;finalName&gt;${project.name}&lt;/finalName&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;io.swagger.codegen.v3&lt;/groupId&gt;
        &lt;artifactId&gt;swagger-codegen-maven-plugin&lt;/artifactId&gt;
        &lt;version&gt;${version.swagger.codegen}&lt;/version&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;id&gt;generate-the-stuff&lt;/id&gt;
            &lt;phase&gt;generate-sources&lt;/phase&gt;
            &lt;goals&gt;
              &lt;goal&gt;generate&lt;/goal&gt;
            &lt;/goals&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
        &lt;configuration&gt;
          &lt;inputSpec&gt;${open.api.file}&lt;/inputSpec&gt;
          &lt;language&gt;spring&lt;/language&gt;
          &lt;modelNameSuffix&gt;Dto&lt;/modelNameSuffix&gt;
          &lt;configOptions&gt;
            &lt;sourceFolder&gt;${generated-sources-java-path}&lt;/sourceFolder&gt;
            &lt;basePackage&gt;${open.api.base}&lt;/basePackage&gt;
            &lt;modelPackage&gt;${open.api.base}.api.model&lt;/modelPackage&gt;
            &lt;apiPackage&gt;${open.api.base}.api&lt;/apiPackage&gt;
            &lt;interfaceOnly&gt;true&lt;/interfaceOnly&gt;
            &lt;useBeanValidation&gt;true&lt;/useBeanValidation&gt;
            &lt;library&gt;spring-boot3&lt;/library&gt;
            &lt;dateLibrary&gt;custom&lt;/dateLibrary&gt;
            &lt;jakarta&gt;true&lt;/jakarta&gt;
          &lt;/configOptions&gt;
          &lt;typeMappings&gt;
            &lt;typeMapping&gt;DateTime=Instant&lt;/typeMapping&gt;
            &lt;typeMapping&gt;multipartFile=org.springframework.web.multipart.MultipartFile&lt;/typeMapping&gt;
          &lt;/typeMappings&gt;
          &lt;importMappings&gt;
            &lt;importMapping&gt;Instant=java.time.Instant&lt;/importMapping&gt;
          &lt;/importMappings&gt;
          &lt;output&gt;${generated-sources-path}&lt;/output&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;

  &lt;repositories&gt;...&lt;/repositories&gt;

&lt;/project&gt;</code></pre>
<p>As you can see, we have defined the SpringBoot module, and in it, the OpenAPI file is located at <i>/src/main/API-specification/OpenApi-UserManagement.yaml</i>. The <em>OpenApi-UserManagement.yaml</em> file will also be responsible for defining generated code infrastructure.</p>
<h2>OpenAPI User management definition YAML</h2>
<p>Let&#8217;s create the <em>OpenApi-UserManagement.yaml</em> file at <i>/src/main/api-specification/</i> relative to the location of <i>pom.xml</i></p>
<pre><code class="language-yaml">openapi: 3.0.2
info:
  title: User management module
  description: User management
  version: '0.1'
  contact:
  email: optional@email.com
servers:
  - url: https://localhost:8080/api/user-management

paths:
  /users/import:
    post:
      summary: Import User files
      tags:
        - UserManagement
      operationId: importFiles
      requestBody:
        content:
          multipart/form-data:
            schema:
              properties:
                userFiles:
                  type: array
                  items:
                    type: multipartFile
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: array
                  items:
                    type: string
        '400':
          description: Bad Request</code></pre>
<p>As you can see, we have defined a simple endpoint for importing user files. The endpoint is defined as a <code>POST</code> request with a summary, tags, operationId, requestBody and responses.</p>
<p>It is essential to define the keywords for user files well. I picked up the <i>userFiles</i>, but you can use whatever you like. For example &#8211; simply <i>files</i>. The keyword will be used for the protocol to tie the files during transmission.</p>
<h2>User Management Controller</h2>
<p>Now, all we need to do is create a controller to implement the OpenAPI schema. User management schema name will be generated based on the tags in the OpenAPI schema.</p>
<p>Here is an example of the controller:</p>
<pre><code class="language-java">@RestController
@RequiredArgsConstructor
public class UserManagementController implements UserManagementApi {

  @Override
  public ResponseEntity&lt;Map&lt;&lt;tring, List<String&gt;&gt;&gt; importFiles(@RequestPart("userFiles") List&lt;MultipartFile> userFiles) {
    // ... your logic here ...
  }

}</code></pre>
<p>I will leave the implementation up to you as it is not the main focus of this article.</p>
<p>Again, notice the <i>userFiles</i> keyword in the method argument. It is the same as the keyword as defined in the OpenAPI schema.</p>
<h2>Testing with Postman</h2>
<p>Let&#8217;s run the app; the last thing will be testing the endpoint with Postman.</p>
<p>As it might not be stressed enough so far, the most important thing is to use the same keyword as defined in the OpenAPI schema. In our case, it is <i>userFiles</i>.</p>
<p><img decoding="async" src="https://codepills.com/wp-content/uploads/2024/02/postman_multipart_request_with_multiple_files.png" alt="Postman - Multipart request with multiple files" width="665" height="319" class="size-full wp-image-1361" srcset="https://codepills.com/wp-content/uploads/2024/02/postman_multipart_request_with_multiple_files.png 665w, https://codepills.com/wp-content/uploads/2024/02/postman_multipart_request_with_multiple_files-300x144.png 300w" sizes="(max-width: 665px) 100vw, 665px" /></p>
<p>And now, if the backend is running at localhost, and we added the necessary logic for file processing into the controller, we should be able to upload multiple files through the endpoint.</p>
<p>When using Postman, you also need to define the type of multipart key. It is either the <em>String</em> or <em>File</em>. For files, use <em>File</em>, and for the object, use <em>String</em>. The following article will discuss the <a href="https://codepills.com/how-to-make-multipart-requests-with-file-and-object-through-autogenerated-code-defined-in-openapi/" title="How to make multipart requests with file and object through autogenerated code defined in OpenAPI" target="_blank" rel="nofollow noopener">implementation and use of mixed input</a>.</p>
<p>Otherwise, all you need to do is to define your endpoint <code>POST</code> request as everything else. Select <code>POST</code> request, add the URL, and in the body tab, select form-data and add the keyword and the file.</p>
<p>Add multiple files with the same key &#8220;userFiles&#8221; and send the request.</p>
<h2>Conclusion</h2>
<p>This article has shown how to implement autogenerate of code from OpenAPI schema, how to define the schema for multiple file uploads and how to implement the endpoint at the Spring Boot backend. All you need to do is run your application and use the same keyword defined in the OpenAPI schema for the file upload.</p>
<p>Did you find autogenerate OpenAPI implementation and sending files through multipart requests easy? Do you have your trick or know another way <u> to send effectively multipart requests with files</u>? Let us know in the comments below the article. We would like to hear your ideas and stories.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codepills.com/how-to-make-multipart-requests-with-files-through-autogenerated-code-defined-in-openapi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Create PostgreSQL database for integration testing with Docker</title>
		<link>https://codepills.com/create-postgresql-database-for-integration-testing-with-docker/</link>
					<comments>https://codepills.com/create-postgresql-database-for-integration-testing-with-docker/#respond</comments>
		
		<dc:creator><![CDATA[Andrej Buday]]></dc:creator>
		<pubDate>Mon, 01 Nov 2021 17:33:29 +0000</pubDate>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Dockerfile]]></category>
		<category><![CDATA[integration tests]]></category>
		<category><![CDATA[IntelliJ]]></category>
		<category><![CDATA[postgresql]]></category>
		<guid isPermaLink="false">https://codepills.com/?p=1264</guid>

					<description><![CDATA[In this article, we will explore the idea of creating a PostgreSQL database Dockerfile. We can, for example, use it for creating integration tests in a separate CI/CD workflow. <a href="https://codepills.com/create-postgresql-database-for-integration-testing-with-docker/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>In this article, we will explore the idea of creating a PostgreSQL database Dockerfile. We can, for example, use it for creating integration tests in a separate CI/CD workflow.</p>
<p><span id="more-1264"></span></p>
<h2>Introduction</h2>
<p>Let&#8217;s have an idea to create a separate database for integration testing. Creating a separate database will require creating a Docker file with a PostgreSQL database. We can consequently make and run dedicated integration CI/CD workflow for the integration tests. This CI/CD workflow will take our Docker PostgreSQL database and run the database with which integration tests will be working.</p>
<h2>Creating Dockerfile</h2>
<p>We will need to write three files for creating a database testing environment. Technically, we need to write only one file &#8211; <code>Dockerfile</code>. But two other files, database init scripts, will be used to prepare our containerized database for integration tests.</p>
<p>First we need to write PostgreSQL <code>Dockerfile</code>:</p>
<pre><code class="language-yaml">FROM postgres:latest
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD admin
ENV POSTGRES_DB postgres
COPY ./sql/db_user_creation.sql /docker-entrypoint-initdb.d/
COPY ./sql/init_tables.sql /docker-entrypoint-initdb.d/</code></pre>
<p>Let&#8217;s take latest image of PostgreSQL database from posgres Docker vendor. We set up PostgreSQL&#8217;s image environment properties <code>POSTGRES_USER</code>, <code>POSTGRES_PASSWORD</code> and <code>POSTGRES_DB</code> by default values and copy our database init scripts to Docker image entry folder.</p>
<p>The official postgres docker image will run <code>.sql</code> scripts found in the <i>/docker-entrypoint-initdb.d/</i> folder. I highly encourage you to check <a href="https://hub.docker.com/_/postgres" title="Docker Hub Postgres official page" target="_blank" rel="nofollow noopener">official documentation</a> in case in future postgres releases might change this.</p>
<h3>Best practice</h3>
<p>I will go here a little bit sideways. There is a good practice to add on custom-defined <code>Dockerfile</code> last Docker commands from a source image.</p>
<pre><code class="language-yaml">ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]</code></pre>
<p>The last three lines of our <code>Dockerfile</code> are copied from the Postgres image and considered a best practice. However, you can omit them. But in case you want to extend this <code>Dockerfile</code> further, please realize that first, you are running all commands in the Postgres source image. And only then you are running your custom Docker commands. Placing the last command from PostgreSQL&#8217;s image will secure consistent API.</p>
<p>Therefore, the Whole <code>Dockerfile</code> should look like this:</p>
<pre><code class="language-yaml">FROM postgres:latest
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD admin
ENV POSTGRES_DB postgres
COPY ./sql/db_user_creation.sql /docker-entrypoint-initdb.d/
COPY ./sql/init_tables.sql /docker-entrypoint-initdb.d/
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]</code></pre>
<p>The environment variables will instruct the container to create a <i>postgres</i> schema with <i>postgres</i> user (having <i>admin</i> password) on its first run. Any <code>.sql</code> files found in the <i>/docker-entrypoint-initdb.d/</i> of the PostgreSQL container will be executed. If you want to execute <code>.sh</code> scripts, you can also place them in the <i>/docker-entrypoint-initdb.d/</i> folder.</p>
<h2>Custom init scripts</h2>
<p>As you have noticed in <code>Dockerfile</code> description, we have created two other files which we copied to PostgreSQL image. First file is <code>db_user_creation.sql</code>:</p>
<pre><code class="language-sql">CREATE USER mycustomsuperadmin WITH PASSWORD 'changethispassword';
GRANT ALL PRIVILEGES ON DATABASE postgres TO mycustomsuperadmin;</code></pre>
<p>In this file, we could, for example, add a command for creating another database. However, only for demonstration purpose, we will create <i>mycustomsuperadmin</i> user with all the privileges for <i>postgres</i> database. Creating a new user is not mandatory.</p>
<p>The second file we need to create is the initialization of our database with tables and content. This file is also just for demonstration purposes, and you can come with your ideas and needs for what you need to put into the database. Here is example of some database tables we will pad into <i>postgres</i> database.</p>
<pre><code class="language-sql">CREATE TABLE "public".items (
    "id"           integer NOT NULL GENERATED ALWAYS AS IDENTITY (start 1),
    name           varchar(50) NOT NULL,
    price          double precision NOT NULL,
    release        timestamptz(3) NOT NULL,
    CONSTRAINT     PK_Customer PRIMARY KEY ("id", "name", "price", "release")
);

CREATE TABLE "public".users (
    "id"           integer NOT NULL GENERATED ALWAYS AS IDENTITY (start 1),
    name           varchar(50) NOT NULL,
    salary         double precision
    timestamp      timestamptz(3) NOT NULL,
    CONSTRAINT     PK_Customer PRIMARY KEY ("id", "name", "salary", "timestamp")
);</code></pre>
<p>Again, the following code is just for demonstration purposes, and naturally, you can place your own init scripts here.</p>
<p><b>Note</b> : Default syntax for creating database in PostgreSQL is &#8220;database_name&#8221;.&#8221;scheme_name&#8221;.&#8221;table_name&#8221;.</p>
<h2>Build Dockerfile</h2>
<p>Now, when we have all the files, we need to run the Docker build command. So, go to the folder where you placed PostgreSQL <code>Dockerfile</code> and run Docker build command like this:</p>
<h3>IntelliJ configuration</h3>
<p>You can easily build and run your Docker image from IntelliJ. Check the image of configuration for setting up the file:</p>
<p><img decoding="async" src="https://codepills.com/wp-content/uploads/2021/11/intellij_postgresql_docker_build_runner_settings.png" alt="IntelliJ PostgreSQL Docker build runner settings" width="635" height="522" class="alignnone size-full wp-image-1265" srcset="https://codepills.com/wp-content/uploads/2021/11/intellij_postgresql_docker_build_runner_settings.png 635w, https://codepills.com/wp-content/uploads/2021/11/intellij_postgresql_docker_build_runner_settings-300x247.png 300w" sizes="(max-width: 635px) 100vw, 635px" /></p>
<pre><code class="language-yaml">Docker build .</code></pre>
<p>Hitting the following setup in IntelliJ will build your <code>Dockerfile</code> and place it in your local Docker repository.</p>
<h2>Alternative with docker-compose</h2>
<p>There is alternative way how to build and run PostgreSQL locally. It is without creating Docker image and instead just run <code>docker-compose</code>. Here is a code for <code>docker-compose.yaml</code> file:</p>
<pre><code class="language-yml">version: '3.7'
services:
    postgres:
        image: postgres:latest
        restart: always
        environment:
            POSTGRES_USER: postgres
            POSTGRES_PASSWORD: admin
            POSTGRES_DB: postgres
        logging:
            options:
                max-size: 10m
                max-file: "3"
        ports:
            - '5432:5432'
        volumes:
            - ./postgres-data:/var/lib/postgresql/data
            # copy the sql script to create tables
            - .sql/init_tables.sql:/docker-entrypoint-initdb.d/init_tables.sql
            # copy the sql script to create user
            - .sql/db_user_creation.sql:/docker-entrypoint-initdb.d/db_user_creation.sql</code></pre>
<p>Running <code>docker-compose up -d</code> will run docker-compose script in your repository. To turn off the service, execute command <code>docker-compose down</code>.</p>
<p><b>Node</b>: So if you placed your Dockerfile in <i>project-root/src/test/resources</i> and you are in your command prompt on this sys-path, running docker-compose might first run docker-compose in your <i>project-root/</i> folder.</p>
<h2>Conclusion</h2>
<p>This article has shown us how to create a PostgreSQL database Dockerfile. However, we can develop this idea further and, for example, make it for integration tests in a separate CI/CD workflow.</p>
<p>Did you find creating <code>Dockerfile</code> easy? Do you have your trick or know another way <u>how to create Dockerfile</u>? Let us know in the comments below the article. We would like to hear your ideas and stories.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codepills.com/create-postgresql-database-for-integration-testing-with-docker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Compare all elements in an array against each other in Java</title>
		<link>https://codepills.com/compare-all-elements-in-an-array-against-each-other-in-java/</link>
					<comments>https://codepills.com/compare-all-elements-in-an-array-against-each-other-in-java/#respond</comments>
		
		<dc:creator><![CDATA[Andrej Buday]]></dc:creator>
		<pubDate>Sun, 08 Nov 2020 10:08:03 +0000</pubDate>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[array element comparison]]></category>
		<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">https://codepills.com/?p=1075</guid>

					<description><![CDATA[One of the most common requests when processing an array is to compare each element against all other elements in the array. An abstract solution to this request is demonstrated in this article in Java <a href="https://codepills.com/compare-all-elements-in-an-array-against-each-other-in-java/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>One of the most common requests when processing an array is to compare each element in an array against every other element. You can imagine it as you want to take the 1st array element and compare it with every other element, then take the 2nd array element and compare it with every other element and so on and on.</p>
<p><span id="more-1075"></span></p>
<p>We will write the following code examples in Java. As input example, let&#8217;s have a simple Java array <code>array</code> with 5 integer elements as method input for our <code>arrayComparison(final int[] arr)</code>. Here is the Java code:</p>
<pre><code class="language-java">final int[] array = new int[]{1, 2, 3, 4, 5};
public void arrayComparison(final int[] arr);</code></pre>
<p>So let&#8217;s write a simple solution for all element comparison. There is no other way than just loop trough array and take each element individually and compare it with the rest of an array. Here is the code which does exactly that:</p>
<pre><code class="language-java">for (int i = 0; i < arr.length; i++) {
    for (int j = 0; j < arr.length; j++) {
        // Comparison code
        System.out.println(arr[i] + " " + arr[j]);
    }
}</code></pre>
<p>And this is the Java code outcome:</p>
<pre><code class="language-bash">1 - 1   2 - 1   3 - 1   4 - 1   5 - 1
1 - 2   2 - 2   3 - 2   4 - 2   5 - 2
1 - 3   2 - 3   3 - 3   4 - 3   5 - 3
1 - 4   2 - 4   3 - 4   4 - 4   5 - 4
1 - 5   2 - 5   3 - 5   4 - 5   5 - 5</code></pre>
<p>From the output, we see that we compare every element with every other element in the array.</p>
<p>Is it the most effective solution we can come with? Definitely no! Looping through elements <code>2 - 3</code> is the same as looping through <code>3 - 2</code>, isn't it?</p>
<p>We can slightly optimize this solution by making a check on every iteration and omitting self-comparing elements. Here is the improved code:</p>
<pre><code class="language-java">for (int i = 0; i < arr.length; i++) {
    for (int j = i; j < arr.length; j++) {
        // Comparison code
        System.out.println(arr[i] + " " + arr[j]);
    }
}</code></pre>
<p>And this is overall Java code output:</p>
<pre><code class="language-bash">1 - 1
1 - 2   2 - 2
1 - 3   2 - 3   3 - 3
1 - 4   2 - 4   3 - 4   4 - 4
1 - 5   2 - 5   3 - 5   4 - 5   5 - 5</code></pre>
<p>In this solution, we see that we do not need to compare the same elements, for example, <code>1 - 1</code> etc.</p>
<p>We can push optimization again little bit further and by making a check on every iteration omit self-reflecting elements. Here is more optimized code:</p>
<pre><code class="language-java">for (int i = 0; i < arr.length; i++) {
    for (int j = i; j < arr.length; j++) {
        if(arr[i] != arr[j]) {
            // Comparison code
            System.out.println(arr[i] + " " + arr[j]);
        }
    }
}</code></pre>
<p>And this is overall Java code output:</p>
<pre><code class="language-bash">
1 - 2
1 - 3   2 - 3
1 - 4   2 - 4   3 - 4
1 - 5   2 - 5   3 - 5   4 - 5</code></pre>
<p>This way, we get precisely the comparison pairs we were looking for.</p>
<p>However, there is still a way how to optimize this solution. First, we still loop through the identical elements; but we omit them with the  <code>if</code> check.</p>
<p>Is there a way how to rewrite and optimize this solution? Yes, it is!</p>
<p>We can improve the existing solution with the start of comparison from the point of element one after the current point on the second level iteration.</p>
<p>Here is the solution:</p>
<pre><code class="language-java">for (int i = 0; i < arr.length; i++) {
    for (int j = i +  1; j < arr.length; j++) {
        // Comparison code
        System.out.println(arr[i] + " " + arr[j]);
    }
}</code></pre>
<p>And this is overall Java code output:</p>
<pre><code class="language-bash">
1 - 2
1 - 3   2 - 3
1 - 4   2 - 4   3 - 4
1 - 5   2 - 5   3 - 5   4 - 5</code></pre>
<p><b>Note:</b> Real trick of this solution is on its last iteration. When we finish <code>3 - 4</code> we jump to <code>4</code> element. However inner loop is <code>5 = arr.length</code> therefore is not valid, loop terminates and and no print is pushed to System output.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codepills.com/compare-all-elements-in-an-array-against-each-other-in-java/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How do you kill the port on Windows?</title>
		<link>https://codepills.com/how-do-you-kill-the-port-on-windows/</link>
					<comments>https://codepills.com/how-do-you-kill-the-port-on-windows/#respond</comments>
		
		<dc:creator><![CDATA[Andrej Buday]]></dc:creator>
		<pubDate>Sat, 01 Jun 2019 08:00:28 +0000</pubDate>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[windows]]></category>
		<guid isPermaLink="false">http://codekopf.com/?p=799</guid>

					<description><![CDATA[This tutorial shows how to kill the port in the Windows operating system. <a href="https://codepills.com/how-do-you-kill-the-port-on-windows/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>How do you set a port free that is assigned to a particular process or application? This tutorial shows how to kill the port in the Windows operating system.</p>
<p><span id="more-799"></span></p>
<p><strong>Issue</strong></p>
<p>I got into trouble with my Spring Boot application on my development machine. The application port occupancy prevented my local Spring development environment from running. By default, Spring uses port 8443. So, I needed to make the port free to run my application without needing to rewrite the port number in the application config file.</p>
<p><strong>Solution</strong></p>
<p>Here is a simple solution on how to set the occupied port free on Windows OS:</p>
<p><strong>Step 1</strong></p>
<p>You must run the Windows Command Line as an Administrator or Git Bash. Then, run the command below with the port number in the port number placeholder.</p>
<pre><code class="language-bash">netstat -ano | findstr :MY_PORT_NUMBER</code></pre>
<p>The number on the right side (PID &#8211; process identifier) is the number of processes currently using the port.</p>
<p><strong>Step 2</strong></p>
<p>For this, you can use only the Windows Command Line. First, you need to kill the process using the port so the port can be set free. Type the following command with process PID to the command line:</p>
<pre><code class="language-bash">taskkill /PID YOUR_PID_NUMBER /F</code></pre>
<p>Prefix /F, in this case, means forcefully terminates the process.</p>
<p>If everything went smoothly, you should get the following message:</p>
<blockquote><p>SUCCESS: The process with PID YOUR_PID_NUMBER has been terminated.</p></blockquote>
<p>In the end, rerun the first command to check whether the process is on or not. If you get an empty line, the process successfully ends, and the required port is free.</p>
<h2>Conclusion</h2>
<p>This article shows how to kill the Windows operating system port quickly.</p>
<p>Did you find releasing ports easy? Do you have your trick, or do you know another way <u>how to kill specific port on the Windows operating system</u>? Let us know in the comments below. We would like to hear your ideas and stories.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codepills.com/how-do-you-kill-the-port-on-windows/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to sync up new Git repository on GitHub or GitLab</title>
		<link>https://codepills.com/how-to-sync-up-new-git-repository-on-github-or-gitlab/</link>
					<comments>https://codepills.com/how-to-sync-up-new-git-repository-on-github-or-gitlab/#respond</comments>
		
		<dc:creator><![CDATA[Andrej Buday]]></dc:creator>
		<pubDate>Sat, 17 Jun 2017 18:56:55 +0000</pubDate>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[GitLab]]></category>
		<guid isPermaLink="false">http://codekopf.com/?p=879</guid>

					<description><![CDATA[From time to time you necessary to set up new Git repository. This article is about a list of commands which are helpful for creating a new repository and syncing it with GitHub or GitLab. This article focuses only on users &#8230; <a href="https://codepills.com/how-to-sync-up-new-git-repository-on-github-or-gitlab/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>From time to time you necessary to set up new Git repository. This article is about a list of commands which are helpful for creating a new repository and syncing it with GitHub or GitLab.</p>
<p><span id="more-879"></span></p>
<p>This article focuses only on users with Mac or Linux. For creating new repository or pairing existing with GitHub account or custom GitLab on Windows, please visit official tutorial at <a href="https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/">GitHub website</a>.</p>
<p>&nbsp;</p>
<h5>Setting global git config credentials</h5>
<p>First of all, we need to be sure that we have set global config information. This is one-time configuration.</p>
<pre class="">git config --global user.name "Your Name"
git config --global user.email "your.name@email.com"
</pre>
<h5>Creating the new repository and pushing new it to GitHub or GitLab</h5>
<p>This is the short list of terminal commands for creating a new local repository and syncing the changes with GitHub or GitLab repository.</p>
<pre class="">cd folder
# Change to desired directory 
git init
# Initiate local Git repository
git remote add origin git@github.com:UserName/project.git || git@gitlab.domain.com:UserName/project.git
# Sets the new origin repository
git remote -v
# Verifies the new remote URL
git add .
# Adds all files in the local repository to stage for commit. To unstage a file, use 'git reset HEAD YOUR-FILE'.
git commit -m "init commit"
# First local commit with message. It commits the tracked changes and prepares them to be pushed to a remote repository. 
# To remove this commit and modify the file, use 'git reset --soft HEAD~1'; and commit and add the file again.
git push -u origin master
# Pushes the changes in your local repository up to the remote repository you specified as the origin</pre>
<p>Repository SSH link can be found at GitHub or GitLab project landing page or quick setup page.</p>
<h5>Copy/Clone existing GitHub or GitLab repository to local folder</h5>
<p>This is the short list of terminal commands for cloning existing GitHub or GitLab repository to local repository.</p>
<pre class="">cd folder
# Change to desired directort
git clone git@github.com:UserName/project.git || git@gitlab.domain.com:UserName/project.git
# Clone/Copy all files</pre>
<p>Cloning the repository does not make automatically git repository. For that, we need to repeat the step (above) of initializing local Git repository and setting the origin repository on GitHub or GitLab.</p>
<h5>Security reminder</h5>
<p>Never g<code>it add</code>, <code>commit<span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;">, </span></code><code>push</code> sensitive information (like passwords, keys, configs, credit card numbers PINs and numbers, etc.) to your remote repository.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codepills.com/how-to-sync-up-new-git-repository-on-github-or-gitlab/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to compute distance between 2 GPS points?</title>
		<link>https://codepills.com/compute-distance-2-gps-points/</link>
					<comments>https://codepills.com/compute-distance-2-gps-points/#respond</comments>
		
		<dc:creator><![CDATA[Andrej Buday]]></dc:creator>
		<pubDate>Thu, 15 Dec 2016 18:05:03 +0000</pubDate>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[code snippet]]></category>
		<category><![CDATA[direct distance]]></category>
		<category><![CDATA[distance between airports]]></category>
		<category><![CDATA[Earth's surface]]></category>
		<category><![CDATA[geographical calculations]]></category>
		<category><![CDATA[Great Circle distance]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://codekopf.com/?p=750</guid>

					<description><![CDATA[This is an algorithm for measuring distance between 2 GPS points.  <a href="https://codepills.com/compute-distance-2-gps-points/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>When working on projects involving geographical calculations, such as determining the direct distance between two airports on a global scale, developers often seek efficient methods to compute such distances accurately. One common approach involves utilizing algorithms derived from the Great Circle distance method, which considers the curvature of the Earth&#8217;s surface.</p>
<p><span id="more-750"></span></p>
<p>In this article, we explore a PHP implementation of this method and propose two simplifications to enhance its efficiency and readability.</p>
<h2>Introduction</h2>
<p>In one of my projects, I was looking for a simple way to compute the direct distance between 2 arbitrary airports in the world.</p>
<p>I was looking for a way to measure the distance between 2 GPS points. Naturally, there are several ways to compute such distances.</p>
<p>After research, I found that many people use algorithms derived from the Great circle distance method [<a href="https://en.wikipedia.org/wiki/Great-circle_distance" title="Great-circle distance" target="_blank" rel="nofollow noopener">wiki</a>].</p>
<p><!--more--></p>
<p>Here is a PHP code:</p>
<pre><code class="language-php">/**
 * Great Circle distance algorithm
 *
 * Notes:
 * - South and West locations are negative, North and East are positive.
 * - Automatically transfer degrees to radians
 * - https://en.wikipedia.org/wiki/Great-circle_distance
 *
 * @param lat1 - latitude of the first point on the sphere
 * @param lon1 - longitude of the first point on the sphere
 * @param lat2 - latitude of the second point on the sphere
 * @param lon2 - longitude of the second point on the sphere
 * @param unit - units for output (miles, kilometers, nautical miles)
 * @return - distance in desired distance units
 *
 */
function GreatCircleDistance($lat1, $lon1, $lat2, $lon2, $unit) {
    $theta = $lon1 - $lon2;
    $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
    $dist = acos($dist);
    $dist = rad2deg($dist);
    $miles = $dist * 60 * 1.1515;
    $unit = strtoupper($unit);

    switch ($unit) {
        case 'MI':
            return $miles;
            break;
        case 'KM':
            return ($miles * 1.609344);
            break;
        case 'NM':
            return ($miles * 0.8684);
            break;
    }
}</code></pre>
<p>There are two simple corrections to simplify this algorithm.</p>
<p>First by padding all the sub-results into one big equation.</p>
<p>Second, by ensuring the input units will always be the same (using numbers instead of Strings), the <code>strtoupper()</code> function can be removed.</p>
<h2>Conclusion</h2>
<p>In conclusion, by streamlining the implementation of the Great Circle distance algorithm in PHP, developers can achieve enhanced efficiency and readability in their geographical computations. These simplifications make the code more concise and ensure consistent input handling, contributing to a smoother development process.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codepills.com/compute-distance-2-gps-points/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Fixing SimplePie &#8220;./cache is not writeable.&#8221; error</title>
		<link>https://codepills.com/fixing-simplepie-cache-is-not-writeable-error/</link>
					<comments>https://codepills.com/fixing-simplepie-cache-is-not-writeable-error/#respond</comments>
		
		<dc:creator><![CDATA[Andrej Buday]]></dc:creator>
		<pubDate>Sun, 20 Mar 2016 20:21:18 +0000</pubDate>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://codekopf.com/?p=408</guid>

					<description><![CDATA[Switching from EasyPHP to XAMPP as development environment and Windows to OSX I have encounter error regarding cache file in my app based on SimplePie library. Error looked like this: Warning: simplePie/cache is not writeable. Make sure you&#8217;ve set the correct relative or &#8230; <a href="https://codepills.com/fixing-simplepie-cache-is-not-writeable-error/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Switching from EasyPHP to XAMPP as development environment and Windows to OSX I have encounter error regarding cache file in my app based on SimplePie library.</p>
<p><span id="more-408"></span><br />
Error looked like this:</p>
<blockquote><p>Warning: simplePie/cache is not writeable. Make sure you&#8217;ve set the correct relative or absolute path, and that the location is server-writable. in /Applications/XAMPP/xamppfiles/htdocs/xxxxxxxxx/simplePie/library/SimplePie.php on line 1369</p></blockquote>
<p>I browsed internet and first counter measure is to define absolute path to SimplePie cache folder from this:</p>
<pre class="lang:php decode:true">$feed-&gt;set_cache_location('simplePie/cache');</pre>
<p>to this:</p>
<pre class="lang:php decode:true">$feed-&gt;set_cache_location($_SERVER['DOCUMENT_ROOT'] . '/xxxxxxxxx/simplePie/cache/');</pre>
<p>or any other possible way to define absolute path in file.</p>
<p>Second counter measure is to set proper permission on folder where cache is made. I used Double Commander in OSX.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codepills.com/fixing-simplepie-cache-is-not-writeable-error/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
