[{"content":"Status: actively in progress — the core ledger and recurring payments flow are working end to end; UI polish and additional reporting are ongoing.\nThe problem #Spreadsheets are fine for tracking expenses until you need recurring payments, partial confirmations, or an accurate running balance that accounts for money that will leave your account but hasn\u0026rsquo;t yet. GP Expenses is a personal finance tracker built to solve that properly: a single source of truth for what you have, what\u0026rsquo;s pending, and what\u0026rsquo;s projected.\nArchitecture #A monorepo with two independent packages:\nBackend (gpexpenses/) — Spring Boot 3.4, Java 21, Spring Data JDBC (no JPA/Hibernate), JWT authentication. REST API only, no server-rendered UI. Frontend (frontend-web/) — SvelteKit 2, Svelte 5 (runes), Tailwind CSS 4, DaisyUI. A fully client-side SPA (SSR disabled) that proxies to the backend API. Database — H2 file-based for local development, PostgreSQL in production. Key design decisions # Unified transactions ledger. Expenses and income share a single table, distinguished by a type field, instead of separate models. This simplifies the statement/balance logic considerably and avoids duplicating queries across two parallel domains. Three-state transaction lifecycle. Every transaction is PENDING, CONFIRMED, or CANCELLED. Manual entries start CONFIRMED; payments generated from a recurring template start PENDING so an outdated template amount never silently affects the balance. Cancelling is a soft delete — the row stays for auditing and is excluded from all balance calculations. Two balances, not one. The account statement reports a confirmedBalance (what you actually have) and a projectedBalance (including pending payments and unpaid recurring templates), so the app can answer both \u0026ldquo;what do I have\u0026rdquo; and \u0026ldquo;what will I have\u0026rdquo; without extra client-side logic. Spring Data JDBC over JPA. Deliberately avoided Hibernate\u0026rsquo;s implicit behavior (lazy loading, dirty checking) in favor of explicit, predictable queries — a better fit for a domain this size. Stack #Java 21 · Spring Boot 3.4 · Spring Data JDBC · JWT · SvelteKit 2 · Svelte 5 · Tailwind CSS 4 · DaisyUI · PostgreSQL (prod) / H2 (dev)\nLinks # Source on GitHub ","date":"Oct 16, 2026","permalink":"https://gustavopeiretti.com/projects/expenses-project/","section":"Projects","summary":"A personal expense and income tracker with a unified transaction ledger, recurring payments, and a pending/confirmed/cancelled workflow — built to replace spreadsheets with something that actually models how money moves.","title":"GP Expenses — Personal Finance Tracker"},{"content":"Senior Backend Developer specializing in Java, Spring Boot, and microservices architecture. I care about clean architecture and solid coding practices — this site showcases my projects, technical decisions, and what I\u0026rsquo;m currently exploring.\nBrowse my projects or recent posts below.\n","date":null,"permalink":"https://gustavopeiretti.com/","section":"Gustavo Peiretti","summary":"","title":"Gustavo Peiretti"},{"content":"Status: actively in progress — core study flow (SM-2 scheduling, card review) is working; deck/LLM-assisted content generation is evolving.\nThe problem #Most flashcard apps either get the spaced-repetition math right or make card creation pleasant — rarely both. LexiStack is a from-scratch implementation of the SM-2 algorithm paired with an LLM-assisted workflow for suggesting cards and generating deck content, aimed at making both the science and the day-to-day use frictionless.\nArchitecture #Two independent packages, each with its own Git history:\nBackend (lexistack/) — Java 21, Spring Boot, Maven, file-based H2 database, Spring AI for LLM integration. Frontend (lexistack-web/) — SvelteKit 2, Svelte 5 (runes), TypeScript, Tailwind CSS 4. Key design decisions # SM-2 behind a strategy interface. The spaced-repetition algorithm is implemented as SrsAlgorithmStrategy → Sm2StrategyImpl, keeping the scheduling logic swappable without touching the rest of the review flow. Review grades map to the classic Again/Hard/Good/Easy scale, with a minimum ease factor floor to prevent runaway scheduling intervals. LLM as an assistant, not a dependency. Spring AI integrates an LLM to suggest cards and generate deck content, but the core review loop works entirely independently of it — the app degrades gracefully without the AI provider. 1:1 Card/CardProgress split. Scheduling state (CardProgress) is modeled separately from card content (Card), inserted first and referenced by id — keeping SRS bookkeeping decoupled from the editorial content of a card. Strict typing end to end. TypeScript strict mode on the frontend and Lombok-reduced boilerplate on the backend, prioritizing explicitness over convenience shortcuts. Stack #Java 21 · Spring Boot · Spring AI · SvelteKit 2 · Svelte 5 · TypeScript · Tailwind CSS 4 · H2\nLinks # Source on GitHub ","date":"Oct 16, 2026","permalink":"https://gustavopeiretti.com/projects/lexistack/","section":"Projects","summary":"A flashcard app for learning vocabulary and concepts, scheduled with the SM-2 spaced-repetition algorithm, with an LLM assist for generating deck content.","title":"LexiStack — Spaced-Repetition Flashcards"},{"content":"A selection of personal projects I design, build, and maintain end to end — backend, frontend, and everything in between. They\u0026rsquo;re how I keep experimenting with new tools and patterns outside the constraints of any single employer. Most are actively evolving, so expect in-progress notes alongside the finished parts.\n","date":null,"permalink":"https://gustavopeiretti.com/projects/","section":"Projects","summary":"","title":"Projects"},{"content":"Status: actively in progress — the REST API, JWT auth, and core task workflow are working; the web UI and AI assistant page are evolving.\nThe problem #Task lists are easy to create and hard to actually work through. TaskTime pairs lightweight task capture (priority, pomodoro estimate) with a Pomodoro timer and a daily focus list, so planning and execution live in the same tool instead of a task list and a separate timer app.\nArchitecture #The project is built around a REST API and a single web frontend:\nBackend (tasktime/) — Java 21, Spring Boot, JWT authentication, H2 database, some server-rendered views via Thymeleaf alongside the REST API. Frontend (frontend-web/) — SvelteKit 2, Vite, adapter-static, including an AI assistant page for natural-language task interaction. Key design decisions # Pomodoro-first task model. Tasks carry a pomodoro estimate and priority as first-class fields, not bolted-on metadata — the data model reflects the Pomodoro workflow directly instead of treating it as a UI convention. Shared enums across components. ActivityStatus, Priority, and Recurrence values are kept in sync across backend and frontend by convention, highlighting a real tradeoff of a multi-component architecture without a shared schema package. Stack #Java 21 · Spring Boot · JWT · H2 · SvelteKit 2 · Vite\nLinks # Source on GitHub ","date":"Oct 16, 2026","permalink":"https://gustavopeiretti.com/projects/tasktime/","section":"Projects","summary":"A task management app with a Pomodoro-based workflow: quick task capture, priority and pomodoro estimates, and a daily focus list.","title":"TaskTime — Pomodoro Task Manager"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/categories/","section":"Categories","summary":"","title":"Categories"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/post/","section":"Posts","summary":"","title":"Posts"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/spring-boot/","section":"Tags","summary":"","title":"Spring Boot"},{"content":"Here we are going to understand how to manage errors in Spring Boot Rest applications.\nTo manage errors, Spring provides a special component name like controller advice.\nThis special component allows us to handle exceptions coming through controllers and form the global application and, looks like this:\nYou have to annotate your error handler class with @ControllerAdvice\n@ControllerAdvice public class ApiExceptionHandler { // manage errors } How to handle errors with a Controller Advice Component #Into our component @ControllerAdvice, we have to create a method with this annotation @ExceptionHandler to indicate which exception this method should manage.\nHere, in the following example, we are catching all error types Exception and returning a ResponseEntity with legible information to the client.\nA ResponseEntity is an extension class of HttpEntity and represents an HTTP response allowing to include status code, headers, and body.\n@ControllerAdvice public class ApiExceptionHandler { // Generic exception handler @ExceptionHandler(Exception.class) public ResponseEntity\u0026lt;String\u0026gt; handleAllExceptions(Exception ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(\u0026#34;An error occurred - \u0026#34; + ex.getMessage()); } } In this controller, we have a Rest API with an intentional error for understanding purposes:\n@RestController public class DemoController { @GetMapping(\u0026#34;/demo-error\u0026#34;) public String demo() { //Calling service that produces an error throw new RuntimeException(\u0026#34;Generic Runtime error\u0026#34;); } } The result of this error will be like that.\nNotice, the body message and the status code.\nHandle specific exceptions #To manage specific errors you can use @ExceptionHandler also, but you have to indicate your custom error instead of a generic error.\n@RestController public class DemoController { @GetMapping(\u0026#34;/demo-error\u0026#34;) public String demo() { //Calling service that produces an error throw new RuntimeException(\u0026#34;Generic Runtime error\u0026#34;); } @GetMapping(\u0026#34;/demo-custom-error\u0026#34;) public String demoCustomError() { //Calling service that produces a custom error throw new CustomException(\u0026#34;Custom service error\u0026#34;); } } This is the custom expectation that we created.\npublic class CustomException extends RuntimeException { public CustomException(String message) { super(message); } } Running /demo-custom-error\nNotice we can combine errors in the same method to handle similar errors.\n@ExceptionHandler(value = {CustomException2.class, CustomException3.class}) public ResponseEntity\u0026lt;String\u0026gt; handleSeveralException(Exception ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(\u0026#34;A custom error occurred - \u0026#34; + ex.getMessage()); } Of course, the error status, messages and other values that we return must be consistent with the error\nException Handler with Response Status annotation #In the previous examples we sent the status code into ResponseEntity but, you can use the @ResponseStatus annotation.\n@ResponseStatus(HttpStatus.CONFLICT) // 409 @ExceptionHandler(DataIntegrityViolationException.class) public HttpEntity\u0026lt;String\u0026gt; handleSeveralExceptionWithResponseStatus(DataIntegrityViolationException ex) { return new HttpEntity\u0026lt;\u0026gt;(\u0026#34;A error with ResponseStatus annotation\u0026#34;); } A new url controller to review this example:\n@GetMapping(\u0026#34;/demo-custom-error-status\u0026#34;) public String demoCustomErrorStatus() { //Calling exception that produces a custom error with ResponseStatus annotation throw new DataIntegrityViolationException(\u0026#34;DataIntegrityViolationException exception error with ResponseStatus annotation\u0026#34;); } Extending from Response Entity Exception Handler #To address the most frequent errors that Spring raises, you can extend your advice component from the ResponseEntityExceptionHandler.class.\nThis ResponseEntityExceptionHandler class handles all the internal Spring exceptions and it is recommended to use it to return formatted errors.\nCheck the source code for this class and notice that it handles all of Spring’s internal exception classes\nThis is our control advice extending from ResponseEntityExceptionHandler\n@ControllerAdvice public class ApiExceptionHandler extends ResponseEntityExceptionHandler { // Generic exception handler @ExceptionHandler(Exception.class) public ResponseEntity\u0026lt;String\u0026gt; handleAllExceptions(Exception ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(\u0026#34;An error occurred - \u0026#34; + ex.getMessage()); } // Custom exception handler @ExceptionHandler(CustomException.class) public ResponseEntity\u0026lt;String\u0026gt; handleCustomException(CustomException ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(\u0026#34;A custom error occurred - \u0026#34; + ex.getMessage()); } @ExceptionHandler(value = {CustomException2.class, CustomException3.class}) public ResponseEntity\u0026lt;String\u0026gt; handleSeveralException(CustomException ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(\u0026#34;A custom error occurred - \u0026#34; + ex.getMessage()); } } Testing these examples #This test checks all of our examples.\n@SpringBootTest @AutoConfigureMockMvc class DemoControllerTest { private final MockMvc mockMvc; DemoControllerTest(@Autowired MockMvc mockMvc) { this.mockMvc = mockMvc; } @Test void demo() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.get(\u0026#34;/demo-error\u0026#34;)) .andDo(print()) .andExpect(status().is5xxServerError()) .andExpect(content().string(containsString(\u0026#34;An error occurred - Generic Runtime error\u0026#34;))); } @Test void demoCustomError() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.get(\u0026#34;/demo-custom-error\u0026#34;)) .andDo(print()) .andExpect(status().is5xxServerError()) .andExpect(content().string(containsString(\u0026#34;A custom error occurred - Custom exception error\u0026#34;))); } @Test void demoCustomErrorStatus() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.get(\u0026#34;/demo-custom-error-status\u0026#34;)) .andDo(print()) .andExpect(status().isConflict()) // status 409 .andExpect(content().string(containsString(\u0026#34;A error with ResponseStatus annotation\u0026#34;))); } } If you don\u0026rsquo;t know how to test @RestController, see this post about it.\nConclusion #You can use @ControllerAdvice and @ExceptionHandler to handle exceptions in your Spring Boot applications to send a proper response to the client with enough information about the reason for the error.\nIt is convenient to extend your control advice from ResponseEntityExceptionHandler to handle the Spring exception.\nRemember, the message and especially the HTTP status should be valid and must agree with the code convention. Check this good guide about HTTP codes\n","date":"Feb 2, 2024","permalink":"https://gustavopeiretti.com/spring-boot-rest-error-handling-controller-advice/","section":"Posts","summary":"\u003cp\u003eHere we are going to understand how to manage errors in Spring Boot Rest applications.\u003c/p\u003e","title":"Spring Boot Rest Error Handling with Controller Advice"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/categories/spring-framework/","section":"Categories","summary":"","title":"Spring Framework"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/","section":"Tags","summary":"","title":"Tags"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/categories/software-design/","section":"Categories","summary":"","title":"Software Design"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/solid/","section":"Tags","summary":"","title":"SOLID"},{"content":"What is SOLID in software development: #The SOLID principles are a valuable set of guidelines for developing high-quality software.\nDevelopers can create software that is easier to understand, maintain, and extend by adhering to these principles.\nSOLID aims to achieve high cohesion and low association in our programs.\nLet’s look at examples of what each principle is about and how to use it.\nS — Single responsibility principle O — Open/closed principle L — Liskov substitution principle I — Interface segregation principle D — Dependency inversion principle Single responsibility principle #This principle refers to the unique responsibility that each program should have with a specific and limited task. Read more\nOpen/closed principle #The open/closed principle says that every class, module, method, etc. should be open for an extension but must be closed for modification. Read more\nLiskov substitution principle #The Liskov substitution principle says If we have a class A and a class B that inherits from A, we can use an object of B where an object of A is expected and the program will still work properly. Read more\nInterface segregation principle #This principle about \u0026ldquo;segregated interfaces\u0026rdquo; says that any client should not be required to depend on methods they do not use. Read more\nDependency inversion principle #This principle about the inversion of dependencies allows us to decouple different modules of software. Read more\n","date":"Dec 21, 2023","permalink":"https://gustavopeiretti.com/solid-principles-with-examples/","section":"Posts","summary":"","title":"SOLID principles with examples"},{"content":"This principle about the inversion of dependencies allows us to decouple different modules of software.\nIn other words, our software should not depend, for example, on how frameworks are implemented for database access or server connections.\nFor this purpose, we should use interfaces without the need to know what exactly happens behind the implementation of such interfaces.\nWe want the following:\nThe classes in our code do not depend directly on low-level classes. Use abstractions through interfaces and only rely on these abstractions. Poorly implemented code where we do NOT use this dependency inversion principle #We have this Cash class that receives a Product.\nThen, within the class Cash the database class is created to persist the product.\nNote that we are directly using the Database with its implementation.\nWe are using low-level classes in our code MySqlDatabase. If later we want to migrate to another database, we should modify our code as well.\nclass Cash { public void pay(Product product) { MySqlDatabase persistence = new MySqlDatabase(); persistence.save(product); } } \u0026hellip;\nclass MySqlDatabase { void save(Product product) { // save into MySqlDatabase... } } In this example, the Cash class depends on the concrete implementation of the MySqlDatabase class. This breaks the Dependency Inversion Principle.\nRunning this code\npublic class Demo { public static void main(String[] args) { Cash cash = new Cash(); cash.pay(new Product()); } } How to implement the Dependency inversion principle #The first thing we have to do is stop depending on the particular class MySqlDatabase, so we are going to create an interface that decouples it from persistence.\nWe do not need to know in this part of our code how or where the product is stored.\nTo refactor the code and apply DIP, we need to introduce an abstraction. We\u0026rsquo;ll create an interface called Persistence that abstracts the save method.\nWe create our interface for persistence:\ninterface Persistence { void save(Product product); } We implement the interface in our class MySqlDatabase\nclass MySqlDatabase implements Persistence { public void save(Product product) { System.out.println(\u0026#34;Save product \u0026#34; + product); // save into MySqlDatabase... } } Our Cash class will now receive the Persistence interface in the constructor.\nThe class no longer needs to know who or how the persistence is implemented.\nThe Cash class uses the interface and is unaware of its implementation.\nWe are going to modify the Cash class to depend on the abstraction (Persistence) instead of the concrete implementation (MySqlDatabase):\nclass Cash { Persistence persistence; public Cash(Persistence persistence) { this.persistence = persistence; } public void pay(Product product) { persistence.save(product); } } Now, the Cash class is no longer coupled to the specific implementation of the MySqlDatabase class; it only depends on the Persistence interface.\nRunning this code\npublic class Demo { public static void main(String[] args) { // the Cash class is no longer coupled to the specific implementation // of the MySqlDatabase class Persistence persistence = new MySqlDatabase(); Cash cash = new Cash(persistence); cash.pay(new Product()); } } Conclusion #Software designers can use the Dependency Inversion Principle to create more flexible, testable, and reusable systems, making it easier to adapt to changing requirements and maintain software quality over time.\nWe have several advantages:\nFlexibility and modularity: By depending on abstractions rather than concrete implementations, DIP allows for easier modification and substitution of components without affecting the rest of the system Testability: DIP promotes effective testing by allowing dependencies to be easily mocked or stubbed. Code reusability: DIP enhances code reusability by decoupling high-level modules from low-level modules. You can review these examples at GitHub\n","date":"Dec 20, 2023","permalink":"https://gustavopeiretti.com/solid-dependency-inversion-principle/","section":"Posts","summary":"","title":"SOLID Dependency inversion principle"},{"content":"This principle about Interface segregation principle (ISP) says that any client should not be required to depend on methods they do not use.\nThis principle is quite easy to understand. If you usually use interfaces, then it’s very likely that you’re applying this principle.\nAny client should not be required to depend on methods they do not use. What does this mean?\nIn an existing interface, we should not add new methods that require implementing additional functionality.\nInstead of adding methods to an existing interface, it is better to create another interface. In this way, the new interface is implemented only if the new method is required.\nThe following is an example of incorrect interface use that violates this principle.\nPoorly implemented code where we DO NOT use this principle of interface segregation #See the code below for examples where we break this principle.\nInterface Vehicle\n// Interface segregation violation interface Vehicle { void start(); void accelerate(); void brake(); void fly(); } Class Car implements Vehicle\nclass Car implements Vehicle { // Implementation of methods specific to Cars public void start() { // Start the car } public void accelerate() { // Accelerate the car } public void brake() { // Brake the car } // Flying is not relevant to Cars, but still implemented due to the interface contract. public void fly() { // Fly the car? Doesn\u0026#39;t make sense! throw new UnsupportedOperationException(\u0026#34;I can\u0026#39;t fly :(\u0026#34;); } } Airplane implements Vehicle\nclass Airplane implements Vehicle { // Implementation of methods specific to Airplanes public void start() { // Start the airplane } public void accelerate() { // Accelerate the airplane } public void brake() { // Brake the airplane } public void fly() { // Fly the airplane } } In the above example, Vehicle interface violates the Interface Segregation Principle.\nThe fly() method does not make sense for the Car class, but it is still required to implement it because it is part of the Vehicle interface.\nThis leads to unnecessary coupling and forces clients of Car to depend on a method that is not relevant to them.\nRunning the previous code:\npublic class Demo { public static void main(String[] args) { Vehicle car = new Car(); car.start(); car.accelerate(); car.fly(); // car can\u0026#39;t fly Vehicle airplane = new Airplane(); airplane.start(); airplane.accelerate(); airplane.fly(); // ok } } How to implement the Interface segregation principle #To adhere to the Interface Segregation Principle, we can split the Vehicle interface into smaller, more specialized interfaces.\nIn this way, we do NOT force any class to implement the method that it will not use.\ninterface Drivable\ninterface Drivable { void start(); void accelerate(); void brake(); } interface Flyable\ninterface Flyable { void fly(); } Car implements Drivable\nclass Car implements Drivable { // Implementation of methods specific to Cars public void start() { // Start the car } public void accelerate() { // Accelerate the car } public void brake() { // Brake the car } } Airplane implements Drivable, Flyable\nclass Airplane implements Drivable, Flyable { // Implementation of methods specific to Airplanes public void start() { // Start the airplane } public void accelerate() { // Accelerate the airplane }h public void brake() { // Brake the airplane } public void fly() { // Fly the airplane } } In the updated example, we have separated the responsibilities by creating Drivable and Flyable interfaces.\nNow, the clients can depend on only the interfaces they require. The Car class only implements the Drivable interface, and the Airplane class implements both, the Drivable and Flyable interfaces.\nRunning our new fixed code:\npublic class Demo { public static void main(String[] args) { Car car = new Car(); car.start(); car.accelerate(); Airplane airplane = new Airplane(); airplane.start(); airplane.accelerate(); airplane.fly(); } } Conclusion #ISP has the following advantages:\nReduces coupling: The system is more decoupled and simpler to manage when clients are only attached to the interfaces they require. Boosts flexibility: It is simpler to introduce new features or modify current ones without disrupting the system when interfaces are more specific and smaller. Enhances code reuse: It is simpler to reuse code across many system components when interfaces are more concise and specialized. By adhering to the Interface Segregation Principle, we achieve better cohesion, loose coupling, and improved maintainability in our code.\nYou can review these examples at GitHub\n","date":"Dec 20, 2023","permalink":"https://gustavopeiretti.com/solid-interface-segregation-principle/","section":"Posts","summary":"\u003cp\u003eThis principle about Interface segregation principle (ISP) says that any client should not be required to depend on methods they do not use.\u003c/p\u003e","title":"SOLID Interface segregation principle"},{"content":"The Liskov substitution principle (LSP) is an object-oriented design principle that states that a subclass must be interchangeable with its superclass without changing the program\u0026rsquo;s behavior.\nThat is, if we have a class A and a class B that inherits from A, we can use an object of B where an object of A is expected and the program will still work properly.\nHere is an example where we don\u0026rsquo;t use this principle, that is to say, a bad code implementation. Next, we are going to fix this code to follow this principle.\nPoorly implemented code where we DO NOT use this Liskov substitution principle #Let us use the example with the class Vehicle to demonstrate a misuse of this principle.\nWe have here our Vehicle class and three subclasses. In the Vehicle class we have added all the methods that a vehicle needs.\nclass Vehicle { private String name; public Vehicle(String name) { this.name = name; } public void startMotor() { System.out.println(\u0026#34;starting motor\u0026#34;); } public void accelerate() { System.out.println(\u0026#34;accelerate\u0026#34;); } public void stop() { System.out.println(\u0026#34;stop\u0026#34;); } public String getName() { return name; } } Now some types of vehicles, like CombustionVehicle, ElectricVehicle.\nclass CombustionVehicle extends Vehicle { public CombustionVehicle(String name) { super(name); } } class ElectricVehicle extends Vehicle { public ElectricVehicle(String name) { super(name); } } Until here, everything looks good, but\u0026hellip;\nNow we want to add another type of vehicle, a Bicycle (without motor).\nBut how you can notice, a Bicycle should not have a startMotor method. So, in this class we are going to throw an exception.\nWith this class design, we are breaking the substitution principle because we are interrupting the correct behavior of the code.\nRemember:\nObjects of a derived class should be able to replace objects of the base class without breaking the program.\nclass Bicycle extends Vehicle { public Bicycle(String name) { super(name); } @Override public void startMotor() { throw new UnsupportedOperationException(\u0026#34;Invalid for Bicycle\u0026#34;); } } Call bicycle.startMotor() will throw an error and break the program.\nThis does not satisfy the principle because if we run it, this method will break the program.\npublic class Demo { public static void main(String[] args) { CombustionVehicle vehicle = new CombustionVehicle(\u0026#34;Suv Nissan\u0026#34;); vehicle.startMotor(); vehicle.accelerate(); vehicle.stop(); ElectricVehicle electricVehicle = new ElectricVehicle(\u0026#34;Tesla\u0026#34;); electricVehicle.startMotor(); electricVehicle.accelerate(); electricVehicle.stop(); // LSP violation // Subtypes must be substitutable for their base types. Bicycle bicycle = new Bicycle(\u0026#34;BMX Bike\u0026#34;); bicycle.startMotor(); // This will throw an error. (The subtype is not substitutable by its base class) bicycle.accelerate(); bicycle.stop(); } } How to implement the Liskov substitution principle. #We will arrange this so that the designs of our previous classes comply with this principle.\nLet’s fix the class Vehicle. We are going to remove the method startMotor because not all vehicles have a motor.\nWe are going to define a new class MotorVehicle for all motor vehicles and redefine the inheritance.\nclass Vehicle { private String name; public Vehicle(String name) { this.name = name; } public void accelerate() { System.out.println(\u0026#34;accelerate\u0026#34;); } public void stop() { System.out.println(\u0026#34;stop\u0026#34;); } public String getName() { return name; } } Now the Bicycle class looks like this. This class no longer needs to implement the method startMotor. We are not force to throw an error.\nclass Bicycle extends Vehicle { public Bicycle(String name) { super(name); } } Then the parent class for all vehicles with motors. This class is a subtype of vehicle, so also extends from Vehicle class.\nclass MotorVehicle extends Vehicle { public MotorVehicle(String name) { super(name); } public void startMotor() { // start the motor } } Now, all subtypes of MotorVehicle class:\nclass CombustionVehicle extends MotorVehicle { public CombustionVehicle(String name) { super(name); } } class ElectricVehicle extends MotorVehicle { public ElectricVehicle(String name) { super(name); } } Running the program, we can check that it does not break.\nclass Demo { public static void main(String[] args) { CombustionVehicle vehicle = new CombustionVehicle(\u0026#34;Suv Nissan\u0026#34;); vehicle.startMotor(); vehicle.accelerate(); vehicle.stop(); ElectricVehicle electricVehicle = new ElectricVehicle(\u0026#34;Tesla\u0026#34;); electricVehicle.startMotor(); electricVehicle.accelerate(); electricVehicle.stop(); // LSP now is satisfied // Subtypes must be substitutable for their base types. Bicycle bicycle = new Bicycle(\u0026#34;BMX Bike\u0026#34;); bicycle.accelerate(); bicycle.stop(); } } Covariance #We should ensure that the method return type overwritten in the subclass is a subtype of the same return type declared in the superclass. This is called Covariance, and it is another rule that we should follow for this Liskov principle.\nWe are lucky that Java forces this, since it is not possible to return a different type to the one defined in the upper class.\npublic abstract class Foo { public abstract Number calculateSomething(); } public class FooSub extends Foo { // This does not follow the covariance rule, // we should return a number or subtype of number // Java does not allow this public String calculateSomething() { // error this does not compile return \u0026#34;hi\u0026#34;; } // Correct. Integer is a subtype of Number public Integer calculateSomething() { return 123; } } Conclusion #The Liskov Substitution Principle (LSP) promotes modularity and extensibility by allowing the addition of new subclasses without breaking the existing code.\nLSP also improves code reusability by allowing superclass behaviors to be inherited and specialized in subclasses.\nFurthermore, LSP facilitates polymorphism by allowing different types of objects to be treated interchangeably.\nOverall, LSP results in more modular, reusable, and flexible code, making it easier to enhance and maintain software systems.\nYou can review these examples at GitHub\n","date":"Dec 20, 2023","permalink":"https://gustavopeiretti.com/solid-liskov-substitution-principle/","section":"Posts","summary":"\u003cp\u003eThe Liskov substitution principle (LSP) is an object-oriented design principle that states that a subclass\nmust be interchangeable with its superclass without changing the program\u0026rsquo;s behavior.\u003c/p\u003e","title":"SOLID Liskov substitution principle"},{"content":"The open/closed principle (OCP) says that every class, module, method, etc. should be open for an extension but must be closed for modification.\nThis means that new functionality should be added by extending existing classes rather than modifying them.\nThis principle is important because it aids in the maintenance and extensibility of code.\nIt can be difficult to track and manage changes when existing classes are modified to add new functionality, and it can also result in the introduction of new bugs.\nWith this principle, new functionality can be added to existing classes without modifying existing code, making code more maintainable and less prone to bugs.\nWhat we want is to prevent our code from being unintentionally modified causing errors or unexpected functionality.\nThis definition \u0026ldquo;open for an extension but closed for modification\u0026rdquo; can be somewhat confusing.\nLet’s look at an example to apply it.\nPoorly implemented code where we do NOT use this open/closed principle #Note this class with the basic functionality for a vehicle.\nclass Car { void accelerate() { // accelerate car } void stop() { // stop car } } Now if we would also like to add functionality for a race vehicle, we might be tempted to do it in the same class.\nA race vehicle needs this extra functionality injectExtraGas\nclass Car { void accelerate(boolean isCarRace) { if (isCarRace) { injectExtraGas(); } // accelerate car } void stop() { // stop car } private void injectExtraGas() { // only for Race Car } } This class can be used to accelerate a common Car and to accelerate a race car, but it cannot be used for another type of card like an electric car.\nTo add support for other cars, we would need to modify the accelerate() method to handle each type of car, creating a very confuse method.\nRunning the code is more noticeable that this code does not look good. What if we need several types of cars?\npublic class Demo { public static void main(String[] args) { Car carCoupe = new Car(); carCoupe.accelerate(false); carCoupe.stop(); Car raceCar = new Car(); raceCar.accelerate(true); raceCar.stop(); } } How to implement the open/closed principle #But instead of doing this, to comply with the open/closed principle (OCP), we can extend our class by creating another class type derived from the principal.\nNow we create our class RaceCar which is going to extend from ICar and add the new functionality.\nThe following code example shows a class that implements the OCP.\nThis code uses an interface to define the ICar class. This interface has two methods, accelerate() and stop(), which all concrete car classes must implement.\ninterface ICar { void accelerate(); void stop(); } Car implements ICar\nclass Car implements ICar { public void accelerate() { System.out.println(\u0026#34;accelerate car\u0026#34;); } public void stop() { System.out.println(\u0026#34;stop car\u0026#34;); } } RaceCar implements ICar but also adds the particular method it needs injectExtraGas without affecting other classes.\npublic class RaceCar implements ICar { public void accelerate() { System.out.println(\u0026#34;accelerate race car\u0026#34;); injectExtraGas(); } public void stop() { System.out.println(\u0026#34;stop race car\u0026#34;); } private void injectExtraGas() { System.out.println(\u0026#34;inject extra gas race car\u0026#34;); } } How you can notice, OCP is the principle of polymorphism.\nRunning our fixed code, looks better:\npublic class Demo { public static void main(String[] args) { ICar carCoupe = new Car(); carCoupe.accelerate(); carCoupe.stop(); ICar raceCar = new RaceCar(); raceCar.accelerate(); raceCar.stop(); } } Conclusion #Following \u0026ldquo;OCP\u0026rdquo; we achieve these advantages\nMaintainability: easier to understand and modify, making it more maintainable. Extensibility: new functionality can be added without modifying existing code, making it more extensible. Reusability: more reusable because it can be used in multiple contexts without being modified. Applying these principles makes your code reusable, maintainable, and scalable. Also, helps to make it easier to test.\nYou can review these examples at GitHub\n","date":"Dec 20, 2023","permalink":"https://gustavopeiretti.com/solid-open-close-principle/","section":"Posts","summary":"\u003cp\u003eThe open/closed principle (OCP) says that every class, module, method, etc. should be open for an extension but must be closed for modification.\u003c/p\u003e","title":"SOLID Open/closed principle"},{"content":"This principle refers to the unique responsibility that each program should have with a specific and limited task.\nThe single responsibility principle (SRP) is a software design principle that states that each class should only change for one reason. This means that a class should only have one responsibility and that all of its methods should be related to that responsibility.\nIt is then intended that our program should do something determined and concrete.\nSome of the benefits of this single liability principle:\nAbout to testing. It is simplified because a class has only one responsibility. Decreased coupling because lower functionality in a class will cause it to have fewer dependencies. The organization of classes and packages will be better and easier. Let’s see below an example that does not follow this principle, and then we will modify it so that you follow it.\nPoorly implemented code where we DO NOT use this single responsibility principle #This class UserLoginService has the responsibility to perform the login process, but also the responsibility of sending messages to the user.\n// Single responsibility principle violation class UserLoginService { private final DataBase db; UserLoginService(DataBase db) { this.db = db; } User login(String userName, String password) { User user = db.findUserByUserName(userName); if (user == null) { // do something throw new IllegalArgumentException(\u0026#34;Not found\u0026#34;); } // login process.. return user; } // email responsibility should not be part of Login responsibility void sendEmail(User user, String msg) { // sendEmail email to user } } We can observe better by running the program that this service has two different responsibilities and needs some change.\npublic class Demo { public static void main(String[] args) { UserLoginService userLoginService = new UserLoginService(new DataBase()); User user = userLoginService.login(\u0026#34;Bart\u0026#34;, \u0026#34;Simpson\u0026#34;); userLoginService.sendEmail(user, \u0026#34;Hi Bart\u0026#34;); } } This code violates the principle of single liability.\nIt\u0026rsquo;s doing two things for different purposes, so this class violates the SRP because it has two different responsibilities:\nLogin Send Emails If we need to change the way to send emails, we would also need to change the UserLoginService class that contains other functionality. As a result, the class becomes more difficult to maintain and less reusable.\nHow to implement the Single responsibility principle #We are going to fix the above code using this principle of single responsibility.\nEach class should have the same set of common features\nSo what should we do?\nIt would be convenient to separate the class in two classes. One for login and another one for messaging functionality.\nTo follow the SRP whe are going to move sendMail method to another class which is responsible only for sending messages.\nclass MessageSenderService { void sendEmail(User user, String msg) { // sendEmail email to user } } Refactor UserLoginService\nclass UserLoginService { private final DataBase db; UserLoginService(DataBase db) { this.db = db; } User login(String userName, String password) { User user = db.findUserByUserName(userName); if (user == null) { // do something throw new IllegalArgumentException(\u0026#34;Not found\u0026#34;); } // login process.. return user; } } Running our program:\npublic class Demo { public static void main(String[] args) { UserLoginService userLoginService = new UserLoginService(new DataBase()); User user = userLoginService.login(\u0026#34;Bart\u0026#34;, \u0026#34;Simpson\u0026#34;); MessageSenderService messageSenderService = new MessageSenderService(); messageSenderService.sendEmail(user, \u0026#34;Hi Bart\u0026#34;); } } Now, each class has a single responsibility. UserLoginService class represents the process to login the User, and MessageSenderService class handles email sending.\nThe UserLoginService and MessageSenderService classes are refactored to adhere to the SRP.\nThe UserLogin class now has a single responsibility to log in the User.\nSend emails to the User has been delegated to a separate class called MessageSenderService to achieve this principle SRP.\nConclusion #SRP makes our code easier to maintain and understand, as well as more reusable, less coupled, and testable.\nEvery class or component that uses SRP has a distinct and well-defined responsibility. As a result, changes associated with a particular responsibility can be isolated without affecting functionality that is not related, making the code easier to understand, modify, and maintain.\nIt also becomes simpler to reuse each component in different areas of the codebase or in future projects because it is task-specific.\nWriting unit tests for the code gets easier in terms of coverage.\nYou can review these examples at GitHub\n","date":"Dec 20, 2023","permalink":"https://gustavopeiretti.com/solid-single-responsibility-principle/","section":"Posts","summary":"\u003cp\u003eThis principle refers to the unique responsibility that each program should have with a specific and limited task.\u003c/p\u003e","title":"SOLID Single responsibility principle"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/design-patterns/","section":"Tags","summary":"","title":"Design Patterns"},{"content":"We identify something as a pattern when we solve a problem that occurs frequently using a common solution method.\nThis method of solution is possible to use every time the same problem occurs, turning this approach into a reusable design.\nThis helps save time by avoiding creating particular solutions for something that has been solved before.\nA design pattern is a known way to solve a recurring problem.\nThis design thus becomes a template that has already been evaluated countless times, so we can trust that they have been tested.\nHowever, we must remember that these templates are proposed to be used in our codes and some cases may require changes to adapt them, but the base of the template already summarizes much work.\nA good design allows maintenance without much difficulty because it is known and documented extensively. It facilitates any discussion and analysis that arises about the existing code and also improves the reading for new developers over the code.\nHow design patterns are classified # There are several types of patterns that can be very useful. Creational, structural, and behavioral. These are just some that I usually use and that I believe can not miss in our daily development routine.\nCreational design patterns. Solve problems in instance creation. # Singleton Factory Builder Proxy Structural design patterns. Solve problems related to class structure. # Decorator Facade Adapter Composite Behavioral design patterns. Solve problems related to the behavior of a class # Observer Strategy In conclusion: # Design pattern, helps to unify the code developed between different programmers. It helps to gain time applying known solutions to common problems. Helps to create a readable and maintainable code in the future. ","date":"Aug 20, 2023","permalink":"https://gustavopeiretti.com/design-patterns-you-should-know/","section":"Posts","summary":"","title":"Design patterns you should know"},{"content":"The Adapter design pattern works when you have different or incompatible interfaces, and you need the client to use both in the same way.\nThe Adapter design pattern says in its definition that it converts an interface or class into another interface that the client needs.\nWhat are the elements of the Adapter design pattern? #The Adapter pattern parts are\nTarget: the interface we use to create the adapter. Adapter: is the implementation of the target and will take care of the adaptation. Client: it is the one that interacts with and uses the adapter. Adaptee: it is the incompatible interface that we need to adapt with the adapter. How to create the Adapter design pattern with Java? #We mentioned earlier that the pattern had several parts. A client that interacts with the Adapter to get what it needs. The Target from which the Adapter will be implemented, who will be in charge of adapting the Adaptee response so that the Client understands it. The Adaptee that represents the class with an incompatible interface for the client\nLet’s take this to an example where a Client service needs information from a BankService service that returns the information in the BankData class.\nClient: the client service needs information from a bank account and needs it in the User class. Client: the client calls the adapter to get information from the User. Adapter: the adapter calls the service to return information. Adaptee: the service returns the BankUser, the Adaptee. Adapter: the adapter converts BankData to User and returns it to the client. Client: the client receives the info in User. The class User that the client can understand. Let\u0026rsquo;s see the classes:\nThe service that returns the BankData\npackage patterns.adapter; public class BankService { public BankData findByAccountNumber(int accountNumber) { if (accountNumber == 1) { return new BankData(accountNumber,\u0026#34;Nick\u0026#34;, 100d); } else if (accountNumber == 3) { return new BankData(accountNumber,\u0026#34;Susan\u0026#34;, 200d); } else { return null; } } } The BankData class with the info\npackage patterns.adapter; public class BankData { private int account; private String name; private double balance; public BankData(int account, String name, double balance) { this.account = account; this.name = name; this.balance = balance; } public String getName() { return name; } public int getAccount() { return account; } public double getBalance() { return balance; } } The User class required by the client\npackage patterns.adapter; public class User { private int id; private String name; private double totalAvailable; public User(int id, String name, double totalAvailable) { this.id = id; this.name = name; this.totalAvailable = totalAvailable; } public int getId() { return id; } public String getName() { return name; } public double getTotalAvailable() { return totalAvailable; } } The target (interface) from which we created the Adapter\npackage patterns.adapter; public interface UserAdapter { User getUser(int accountNumber); } The implementation of the adapter\npackage patterns.adapter; public class UserAdapterImpl implements UserAdapter { private BankService service = new BankService(); @Override public User getUser(int accountNumber) { BankData bankData = service.findByAccountNumber(accountNumber); User user = new User(bankData.getAccount(), bankData.getName(), bankData.getBalance()); return user; } } The client that needs information in the User class\npackage patterns.adapter; public class Client { public static void main(String[] args) { UserAdapterImpl adapter = new UserAdapterImpl(); adapter.getUser(1); } } Conclusion #We have seen that the Adapter pattern resolves incompatibilities between interfaces by adapting one interface to the other using an adapter. The adapter is responsible for the conversion between interfaces.\nThis is a widely used pattern, especially when we communicate with external apis and need to adapt its response to our interfaces.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/adapter-design-pattern/","section":"Posts","summary":"\u003cp\u003eThe Adapter design pattern works when you have different or incompatible interfaces, and you need the client to use both in the same way.\u003c/p\u003e\n\u003cp\u003eThe Adapter design pattern says in its definition that it converts an interface or class into another interface that the client needs.\u003c/p\u003e","title":"Adapter Design Pattern"},{"content":"The Builder design pattern allows you to create objects that are usually complex using another object that builds them step by step.\nThis Builder pattern is used in situations where an object must be built repeatedly or when this object has lots of attributes and associated objects, and where using constructors to create the object is not a convenient solution.\nThis is a very useful design pattern also in test execution (unit test, for example) where we must create the object with valid or default attributes.\nIt usually solves the problem of deciding which constructor to use. Often classes have many builders, and it is very difficult to maintain them. It is common to see multiple constructors with different combinations of parameters.\nWhat are the parts of the Builder design pattern? #We mentioned that the Builder design pattern proposes to create a complete object from a simpler one simplifying the creation of the object and helping us to obtain a consistent object.\nWe will then need a Builder object that will create the object based on parameters that we pass it step by step.\nUsually and it is good practice to create an interface with a method build that will return the object we want.\nWe have then in this pattern:\nThe implementation of the builder interface that implements the method build and contains the other methods that receive the parameters needed to build the final object.\nHow to create the Builder design pattern in Java #We said that the purpose of the Builder pattern is to simplify the creation of objects that we consider complex. Let’s look at an example to understand how it works.\nImagine a class that keeps the details of a bank account.\npackage patterns.builder; public class BankAccount { private long accountNumber; private String owner; private BankAccountType type; private double balance; private double interestRate; public BankAccount() { } public long getAccountNumber() { return accountNumber; } public void setAccountNumber(long accountNumber) { this.accountNumber = accountNumber; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } public BankAccountType getType() { return type; } public void setType(BankAccountType type) { this.type = type; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public double getInterestRate() { return interestRate; } public void setInterestRate(double interestRate) { this.interestRate = interestRate; } } The builder interface is very simple, you just need a build method. Using the interface is optional. You could skip if you want and create the build directly, but it’s good practice to use the interface.\npackage patterns.builder; public interface IBuilder { BankAccount build(); } Now you implement the interface and add the methods that will receive the parameters. In this example, all these methods that receive the parameters to create the object start with \u0026ldquo;with\u0026rdquo;. Each method returns the builder.\nThe builder method creates the object you need, using all parameters.\nIt is common to add any required field as an argument in the builder’s constructor leaving the remaining fields using the builder methods.\nIt is also common to see builders as internal static classes of the object you want to create.\npackage patterns.builder; public class BankAccountBuilder implements IBuilder { private long accountNumber; //This is important, so we will pass it to the constructor. private String owner; private BankAccountType type; private double balance; private double interestRate; public BankAccountBuilder(long accountNumber) { this.accountNumber = accountNumber; } public BankAccountBuilder withOwner(String owner){ this.owner = owner; return this; //By returning the builder each time, we can create a fluent interface. } public BankAccountBuilder withType(BankAccountType type){ this.type = type; return this; } public BankAccountBuilder withBalance(double balance){ this.balance = balance; return this; } public BankAccountBuilder withRate(double interestRate){ this.interestRate = interestRate; return this; } @Override public BankAccount build(){ BankAccount account = new BankAccount(); account.setAccountNumber(this.accountNumber); account.setOwner(this.owner); account.setType(this.type); account.setBalance(this.balance); account.setInterestRate(this.interestRate); return account; } } Now we try the builder pattern with this example. First, you create the builder new BankAccountBuilder(accountNumber) which by default needs the account number because we have considered it an indispensable value. Then we use the builder, and we send the parameters\u0026rsquo; one by one.\npackage patterns.builder; public class BuilderPatternExample { public static void main(String[] args) { BankAccountBuilder builder = new BankAccountBuilder(12345l); BankAccount bankAccount = builder.withBalance(1000.20) .withOwner(\u0026#34;Oaken\u0026#34;) .withRate(10.15) .withType(BankAccountType.PLATINUM) .build(); System.out.println(bankAccount); } } The output:\nBankAccount{accountNumber=12345, owner=\u0026#39;Oaken\u0026#39;, type=PLATINUM, balance=1000.2, interestRate=10.15} Some advantages and disadvantages of this pattern: #Code is easier to maintain when objects have a lot of attributes.\nDecrease errors when creating the object because the builder specifies step by step how to create them and what attributes you need. The biggest disadvantage is the need to maintain the duplication of attributes that must be in the target class and the builder.\nConclusion #When we work with complex objects or when complexity begins to grow, the Builder design pattern can separate this complexity by using another object to build the main object using a \u0026ldquo;step by step\u0026rdquo; to that end.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/build-design-pattern/","section":"Posts","summary":"\u003cp\u003eThe Builder design pattern allows you to create objects that are usually complex using another object\nthat builds them step by step.\u003c/p\u003e","title":"Builder Design Pattern"},{"content":"The Composite design pattern allows you to create objects from an interface by making them all similar and allowing them all to be treated in the same way.\nWhat are the parts of the composite design pattern? #Let’s look at the parts of this composite pattern:\nInterface Composite: is the abstract class or interface from which the classes are implemented. Leaf: is the object that was implemented from the component. Composition: component with children / leaves. Client: is the class that handles the composite through the Component interface. Think of this component as a tree structure in this way.\nNotice that a composition can be composed of other compositions or simply of a single child or leaf. All, both compositions and sheets can be treated in the same way through their interface.\nHow to create the composite design pattern in Java #A simple example of common use to better understand this pattern is the typical example of Employees and Subordinates with their different roles within.\nHere we have an example of a Composite Employee of which are created a Manager y Developer. One Manager handles several developers that depend on it.\nLet’s define our interface from which we will then implement other components.\npackage patterns.composite; import java.util.List; public interface Employee { String getName(); void add(Employee e); void remove(Employee e); List\u0026lt;Employee\u0026gt; getEmployees(); int calculatePoints(); } We now define the Manager component that implements the interface.\nA Manager is a composite that has a list of developers in charge.\nBoth classes, Manager and Developer implement the interface Employee.\npackage patterns.composite; import java.util.ArrayList; import java.util.List; public class Manager implements Employee { private List\u0026lt;Employee\u0026gt; employees = new ArrayList\u0026lt;\u0026gt;(); private String name; public Manager(String name) { this.name = name; } @Override public List\u0026lt;Employee\u0026gt; getEmployees() { return this.employees; } @Override public void add(Employee e) { if (e != null) { this.employees.add(e); } } @Override public void remove(Employee e) { if (e != null) { this.employees.remove(e); } } @Override public int calculatePoints() { if (this.employees.isEmpty()) { return 0; } return Math.round(this.employees.stream().mapToInt(e -\u0026gt; { System.out.println(e); return e.calculatePoints(); }).sum()); } @Override public String getName() { return this.name; } } Let’s define the Developer class that also implements the Employee interface.\nNote that a manager can be composed of other employees, in this case developers.\nA developer, we assume in this example, cannot have other employees in charge; so the methods to add items to the list have no functionality.\npackage patterns.composite; import java.util.List; import java.util.Random; public class Developer implements Employee { String name; public Developer(String name) { this.name = name; } @Override public String getName() { return this.name; } @Override public void add(Employee e) { // nothing to implement } @Override public void remove(Employee e) { // nothing to implement } @Override public List\u0026lt;Employee\u0026gt; getEmployees() { // nothing to implement return null; } @Override public int calculatePoints() { return new Random().nextInt(24); } @Override public String toString() { return \u0026#34;I am \u0026#34; + getName() + \u0026#34;, Developer\u0026#34;; } } Testing the composite with the client class. #We define the ClientComposite class that will make use of the Employee component.\npackage patterns.composite; public class ClientComposite { public static void main(String... args) { Employee m1 = new Manager(\u0026#34;Marc\u0026#34;); Employee d1 = new Developer(\u0026#34;Maria\u0026#34;); Employee d2 = new Developer(\u0026#34;Ema\u0026#34;); Employee d3 = new Developer(\u0026#34;Brian\u0026#34;); m1.add(d1); m1.add(d2); m1.add(d3); Employee m2 = new Manager(\u0026#34;Susan\u0026#34;); Employee d4 = new Developer(\u0026#34;James\u0026#34;); Employee d5 = new Developer(\u0026#34;Michael\u0026#34;); m2.add(d4); m2.add(d5); } } I am Maria, Developer I am Ema, Developer I am Brian, Developer 19 I am James, Developer I am Michael, Developer 20 Conclusion: #We saw that the composite pattern is useful to represent hierarchies and to unify the operations between objects and individual objects in order to treat them all in the same way simplifying their use.\nThe disadvantage of this composite pattern is that many times you must define general methods whose implementation will be empty in some cases, such the case of the developer class that we saw.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/composite-design-pattern/","section":"Posts","summary":"\u003cp\u003eThe Composite design pattern allows you to create objects from an interface by making them all similar and allowing them all to be treated in the same way.\u003c/p\u003e","title":"Composite Design Pattern"},{"content":"The Decorator pattern allows you to add new features to classes without modifying their structure.\nThe concept of this pattern is to dynamically add new behavior or functionality to the main class.\nThe official definition says that it \u0026ldquo;allows dynamic adjustment of objects to modify their existing responsibilities and behaviors.\u0026rdquo;\nWhat are the parts of the Decorator design pattern? #The decorator pattern consists mainly of an Interface from which the particular class is implemented and the decorators which will add more functionality to the particular class.\nComponent Interface: is the interface (can be an abstract class too) that defines the functionality and from which the specific class and decorators are inherited. Concrete Component: is the main implementation and whose class will receive decorators to add extra functionality dynamically. Decorator: It can be an abstract class or not that defines the Decorator inherited from the Component interface and from which all other decorators will be created. The decorator must keep the reference to the original object in order to invoke it and then add other features of the decorator. Each decorator has a relationship with the type HAS-A component (has a). Concrete Decorator: are the classes that extend or implement the Decorator with the bounded functionality. How to create the Decorator design pattern in Java #We said that the concept of the decorator pattern is to add functionalities to the main object dynamically. Thus avoiding the need to create subclasses to the main class to add functionality.\nThe advantage is that this way we do not affect all classes. Each class defines a specific functionality that is added and decorates to the main class without creating subclasses.\nThe first thing we need to look for is the common behavior that all objects have and that could be extracted to an interface. This interface will be the contract that all implementations, both the specific class and the decorators must fulfill.\nLet me show with an example.\nLet us think of a Watch to which functionalities are added and according to the added functionalities it becomes a sports watch or a Luxury watch.\nLet’s define the component that will be the Watch interface.\npackage patterns.decorator; public interface Watch { void createFunctionality(); } Now we create the particular BasicWatch class from the interface\npackage patterns.decorator; public class BasicWatch implements Watch { @Override public void createFunctionality() { System.out.println(\u0026#34; Basic Watch with: \u0026#34;); this.addTimer(); } private void addTimer() { System.out.print(\u0026#34; Timer\u0026#34;); } } We created the WatchDecorator decorator also from the interface.\npackage patterns.decorator; public abstract class WatchDecorator implements Watch { private final Watch watch; public WatchDecorator(Watch watch) { this.watch = watch; } @Override public void createFunctionality() { this.watch.createFunctionality(); } } We create the rest of decorators from the main decorator that will add the particular functionalities.\npackage patterns.decorator; public class SportWatchDecorator extends WatchDecorator { public SportWatchDecorator(Watch watch) { super(watch); } @Override public void createFunctionality(){ super.createFunctionality(); System.out.print(\u0026#34; and more features (Sport Watch): \u0026#34;); this.addPedometer(); this.addSleepMode(); } private void addPedometer() { System.out.print(\u0026#34; Pedometer\u0026#34;); } private void addSleepMode() { System.out.print(\u0026#34; SleepMode \u0026#34;); } } package patterns.decorator; public class LuxuryWatchDecorator extends WatchDecorator { public LuxuryWatchDecorator(Watch watch) { super(watch); } @Override public void createFunctionality() { super.createFunctionality(); System.out.print(\u0026#34; and more features (Luxury Watch): \u0026#34;); this.addFastCharge(); this.addImpermeability(); this.addNFC(); } private void addFastCharge() { System.out.print(\u0026#34; FastCharge \u0026#34;); } private void addImpermeability() { System.out.print(\u0026#34; Impermeability \u0026#34;); } private void addNFC() { System.out.print(\u0026#34; NFC \u0026#34;); } } Well, now let’s try our decorator pattern.\npackage patterns.decorator; public class ClientDecoratorPattern { public static void main(String... args) { Watch basicWatch = new BasicWatch(); basicWatch.createFunctionality(); System.out.println(\u0026#34;\\n---------\u0026#34;); Watch sportsWatch = new SportWatchDecorator(new BasicWatch()); sportsWatch.createFunctionality(); System.out.println(\u0026#34;\\n---------\u0026#34;); Watch sportsLuxuryWatch = new LuxuryWatchDecorator(new SportWatchDecorator(new BasicWatch())); sportsLuxuryWatch.createFunctionality(); } } What we did in the previous code:\nWe created our concrete and main BasicWatch object that does not have much functionality other than the timer. We create a SportWatchDecorator decorator object that adds more functionality to the main BasicWatch object We created a LuxuryWatchDecorator decorator object that adds more functionality to the SportWatch decorator that in turn adds functionality to the BasicWatch object. The output:\nBasic Watch with: Timer --------- Basic Watch with: Timer and more features (Sport Watch): Pedometer SleepMode --------- Basic Watch with: Timer and more features (Sport Watch): Pedometer SleepMode and more features (Luxury Watch): FastCharge Impermeability NFC Conclusion #We saw how to create a pattern decorator that allows us to add new functionality in cases where extending the main class is not a good option.\nThis functionality can be added statically or dynamically according to conditions and helps us to define the features in the decorator classes, so it is simpler to implement them.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/decorator-design-pattern/","section":"Posts","summary":"\u003cp\u003eThe Decorator pattern allows you to add new features to classes without modifying their structure.\u003c/p\u003e","title":"Decorator Design Pattern"},{"content":"The Facade design pattern simplifies the complexity of a system through a simpler interface.\nIt improves access to our system by allowing other systems or subsystems to use a common access point that reduces complexity, minimizing interactions and dependencies.\nThis design pattern is very useful because it also decouples systems.\nWhat are the parts of the Facade design pattern #We said that the design pattern Facade has a simple interface and accessible to other systems or subsystems.\nThis simplifies complexity for external service clients by exposing a clearer interface and unified access to these features, making them easier to use.\nWe have then in this pattern three parts:\nThe Client who accesses the facade. The Facade that accesses the other functionalities and unifies or simplifies them. The rest of functionalities / subsystems, which are \u0026ldquo;behind\u0026rdquo; the facade. How to create the Facade design pattern #We talked before that the objective of the Facade pattern is to simplify and unify functionalities.\nIn this way, the client does not have to understand the complexity on the other side of the facade.\nSee the following example of a Facade pattern.\nThink of a mobile phone that we must turn on and for this, it is necessary to execute several actions.\nLet’s define the different functionalities of this example.\npackage patterns.facade; public class Battery { public void on() { System.out.println(\u0026#34;Battery on\u0026#34;); } public void off() { System.out.println(\u0026#34;Battery off\u0026#34;); } } package patterns.facade; public class CPU { public void bootLoad() { System.out.println(\u0026#34;CPU boot loaded\u0026#34;); } public void shutDown() { System.out.println(\u0026#34;CPU shutdown\u0026#34;); } } From this interface, MobileService will implement Wifi and GPS services.\npackage patterns.facade; public interface MobileService { void start(); void close(); } package patterns.facade; public class GPSService implements MobileService { @Override public void start() { System.out.println(\u0026#34;GPS Service started\u0026#34;); } @Override public void close() { System.out.println(\u0026#34;GPS Service closed\u0026#34;); } } package patterns.facade; public class WifiSevice implements MobileService { @Override public void start() { System.out.println(\u0026#34;WIFI Service started\u0026#34;); } @Override public void close() { System.out.println(\u0026#34;WIFI Service started\u0026#34;); } } Our class represents Mobile.\nThe mobile has as attributes the battery, the cpu and the services.\npackage patterns.facade; import java.util.List; public class Mobile { private final Battery battery; private final CPU cpu; private final List\u0026lt;MobileService\u0026gt; mobileServices; public Mobile(Battery battery, CPU cpu, List\u0026lt;MobileService\u0026gt; mobileServices) { this.battery = battery; this.cpu = cpu; this.mobileServices = mobileServices; } public CPU getCpu() { return cpu; } public Battery getBattery() { return battery; } public List\u0026lt;MobileService\u0026gt; getMobileServices() { return mobileServices; } } Let’s define the facade that will simplify all mobile phone on and off operations.\nNote that the facade will expose two \u0026ldquo;ON\u0026rdquo;, \u0026ldquo;OFF\u0026rdquo; methods.\nAll the rest happens inside the facade, and the client does not need to understand the sequence of actions to turn on / off the phone.\npackage patterns.facade; import java.util.Arrays; import java.util.List; public class MobileFacade { public Mobile on() { Battery battery = new Battery(); battery.on(); CPU cpu = new CPU(); cpu.bootLoad(); MobileService gps = new GPSService(); gps.start(); MobileService wifi = new WifiSevice(); wifi.start(); List\u0026lt;MobileService\u0026gt; mobileServices = Arrays.asList(gps, wifi); Mobile mobile = new Mobile(battery, cpu, mobileServices); return mobile; } public void off(Mobile mobile) { for(MobileService service :mobile.getMobileServices()) { service.close(); } mobile.getCpu().shutDown(); mobile.getBattery().off(); } } We tested the Facade from our client.\npackage patterns.facade; public class ClientFacadePatternExample { public static void main(String[] args) { MobileFacade facade = new MobileFacade(); Mobile mobile = facade.on(); System.out.println(\u0026#34;---------------\u0026#34;); facade.off(mobile); } } Output:\n--------------- ON --------------- Battery on CPU boot loaded GPS Service started WIFI Service started --------------- OFF --------------- GPS Service closed WIFI Service started CPU shutdown Battery off Conclusion #As you saw with the example, this pattern is quite simple to implement and will help you to give your service clients easier access by unifying features.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/facade-design-pattern/","section":"Posts","summary":"\u003cp\u003eThe Facade design pattern simplifies the complexity of a system through a simpler interface.\u003c/p\u003e\n\u003cp\u003eIt improves access to our system by allowing other systems or subsystems to use a common access point that reduces complexity, minimizing interactions and dependencies.\u003c/p\u003e","title":"Facade Design Pattern"},{"content":"The Factory design pattern is mainly used when we have a class or interface with many subclasses or implementations, and according to some input, we need to return one of these specific subclasses.\nWhen should we use a Factory class? #Let’s think of an interface from which we then make several implementations. We can use the typical Shape example interface from which we implement several classes like Circle, Rectangle, Square.\npackage patterns.factory; public interface Shape { void draw(); } package patterns.factory; public class Circle implements Shape { @Override public void draw() { System.out.println(\u0026#34;I am a Circle\u0026#34;); } } package patterns.factory; public class Rectangle implements Shape { @Override public void draw() { System.out.println(\u0026#34;I am a Rectangle\u0026#34;); } } package patterns.factory; public class Square implements Shape { @Override public void draw() { System.out.println(\u0026#34;I am a Square\u0026#34;); } } In this case, we have several implementations and, depending on the type of Shape, we want to create the concrete implementation of the interface.\nThe usual way (without a factory) would be this way.\npackage patterns.factory; public class FactoryPatternExample { public static void main(String[] args) { FactoryPatternExample example = new FactoryPatternExample(); example.printShape(\u0026#34;CIRCLE\u0026#34;); } // Whithout factory public void printShape(String shapeType) { Shape shape; switch (shapeType) { case \u0026#34;CIRCLE\u0026#34;: shape = new Circle(); break; case \u0026#34;RECTANGLE\u0026#34;: shape = new Rectangle(); break; case \u0026#34;SQUARE\u0026#34;: shape = new Square(); break; default: throw new IllegalStateException(\u0026#34;Unexpected value: \u0026#34; + shapeType); } shape.draw(); } } How to create a Factory class #We see in the previous example that we could simplify the creation of the class by taking everything in the switch to another Factory class that takes care of it, leaving our code simpler and clearer.\nWe are going to create a ShapeFactory class to resolve this:\npackage patterns.factory; public class ShapeFactory { public static Shape getShape(String shapeType) { if (shapeType == null) { return null; } if (shapeType.equalsIgnoreCase(\u0026#34;CIRCLE\u0026#34;)) { return new Circle(); } else if (shapeType.equalsIgnoreCase(\u0026#34;RECTANGLE\u0026#34;)) { return new Rectangle(); } else if (shapeType.equalsIgnoreCase(\u0026#34;SQUARE\u0026#34;)) { return new Square(); } else { throw new IllegalStateException(\u0026#34;Unexpected value: \u0026#34; + shapeType); } } } Let’s see what our previous example looks like using our Factory.\nNote that it is much cleaner and clearer delegating the creation of the instances to the Factory.\nThe Factory will now be in charge of creating the particular instance, and our main class of example will make use of this factory forgetting the complexity to create it.\npackage patterns.factory; public class FactoryPatternExample { public static void main(String[] args) { FactoryPatternExample example = new FactoryPatternExample(); example.printShape(\u0026#34;CIRCLE\u0026#34;); } // Using Factory public void printShape(String shapeType) { Shape shape2 = ShapeFactory.getShape(shapeType); shape2.draw(); } } Obviously this is a basic example, in general, the Factory class can be more complex taking care of creating instances under business conditions or various inputs that make their use convenient.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/factory-design-pattern/","section":"Posts","summary":"\u003cp\u003eThe Factory design pattern is mainly used when we have a class or interface with many subclasses or implementations,\nand according to some input, we need to return one of these specific subclasses.\u003c/p\u003e","title":"Factory Design Pattern"},{"content":"The Observer’s design pattern is used primarily when we are interested in any change of status being notified to anyone who needs to know about that change.\nIn the observer design pattern, the object that looks at the state of another object is called \u0026ldquo;Observer\u0026rdquo; and the object that is \u0026ldquo;looking\u0026rdquo; those changes is called \u0026ldquo;Subject\u0026rdquo;.\nJava helps us by giving us tools to implement this pattern simply through the java.util.Observable class and the java.util.Observer interface.\nExtending from java.util.Observable we define our class, which is capable of being observed by others.\nImplementing the interface java.util.Observer we create our class to know if there are changes to the other Observable class.\nWhat are the elements of the Observer design pattern? #We said that this pattern consists mainly of two parts: an observable functionality and another that needs to observe the changes of the first.\nWe have in this pattern:\nSubject: is the Observable class that will notify others when their status changes. Observer: is the class that will receive the notification. The class that wants to know about the changes. How to create the Observer design pattern in Java #As we said previously, we need two parts. A class that allows to be observed and that will notify others that observe it.\nSuppose we have a Bank class that when modified must generate certain expenses.\nWe want any change of status in the Bank class to notify the classes calculating the expenses of this change.\nThe Observable class is created by extending from java.util.Observable. Java will do everything for us with this class taking care to change the status of this and notify observers.\nIn this BankAccount class extending from Observable, we have the addAmount* method that receives an amount and then marks its status as changed and notifies all \u0026ldquo;observers\u0026rdquo; about the change made.\npackage patterns.observer; import java.util.Observable; public class BankAccount extends Observable { private double balance; public void addAmount(Double amount) { this.balance += amount; setChanged(); notifyObservers(balance); } public Double getBalance() { return balance; } } Then we have our class that implements the Observer interface and will receive the notification in the interface method update\nThis method update receives a value that we know is a double that comes from the BankAccount (Observable) class that notifies it.\nThen with that value, you perform the corresponding calculations to calculate the expense.\npackage patterns.observer; import java.util.Observable; import java.util.Observer; public class BankExpense implements Observer { private String type; private Double totalCalculated = new Double(0D); private final Double rateCoefficient; public BankExpense(String type, Double rateCoefficient) { this.type = type; this.rateCoefficient = rateCoefficient; } @Override public void update(Observable o, Object value) { this.totalCalculated = ((Double) value) * rateCoefficient; } public Double getTotalCalculated() { return totalCalculated; } public String getType() { return type; } @Override public String toString() { return \u0026#34;BankExpense{\u0026#34; + \u0026#34;type=\u0026#39;\u0026#34; + type + \u0026#39;\\\u0026#39;\u0026#39; + \u0026#34;, rateCoefficient=\u0026#34; + rateCoefficient + \u0026#34;, totalCalculated=\u0026#34; + totalCalculated + \u0026#39;}\u0026#39;; } } We now try the Observer pattern #We created the Observable object, BankAccount.\nWe created all the Observer objects, BankExpense, that need to know about the changes.\nWe add the Observer object to the Observable using addObserver*.\nWe change the status of the BankAccount object.\nWe see the result. All BankExpense objects were notified of the change.\npackage patterns.observer; public class ObserverPatternExample { public static void main(String[] args) { // Observable class BankAccount bankAccount = new BankAccount(); // Observer class BankExpense bankExpense1 = new BankExpense(\u0026#34;commission\u0026#34;, 0.11d); BankExpense bankExpense2 = new BankExpense(\u0026#34;expense\u0026#34;, 0.22d); BankExpense bankExpense3 = new BankExpense(\u0026#34;compensation\u0026#34;, 0.33d); // Add Observer into Observable bankAccount.addObserver(bankExpense1); bankAccount.addObserver(bankExpense2); bankAccount.addObserver(bankExpense3); // Change Observable state bankAccount.addAmount(1000d); // Observer was notified System.out.println(bankExpense1.toString()); System.out.println(bankExpense2.toString()); System.out.println(bankExpense3.toString()); } } output\nBankExpense{type=\u0026#39;commission\u0026#39;, rateCoefficient=0.11, totalCalculated=110.0} BankExpense{type=\u0026#39;expense\u0026#39;, rateCoefficient=0.22, totalCalculated=220.0} BankExpense{type=\u0026#39;compensation\u0026#39;, rateCoefficient=0.33, totalCalculated=330.0} Some advantages and disadvantages of this pattern: #Using this pattern allows you to disengage the subjet (Observable) from all those observers (Observer).\nAllows you to add an unlimited number of Observers who want to know about the change.\nYou have to be careful with the implementation of Observers because it could complicate the performance if there are many or if it is poorly implemented.\nConclusion #We have seen the Observer pattern and how easy it is to implement it, helping us in cases where we want other objects to be notified whenever a change occurs.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/observer-design-pattern/","section":"Posts","summary":"\u003cp\u003eThe Observer’s design pattern is used primarily when we are interested in any change of status being notified to anyone who needs to know about that change.\u003c/p\u003e\n\u003cp\u003eIn the observer design pattern, the object that looks at the state of another object is called \u0026ldquo;Observer\u0026rdquo; and the object that is \u0026ldquo;looking\u0026rdquo; those changes is called \u0026ldquo;Subject\u0026rdquo;.\u003c/p\u003e","title":"Observer Design Pattern"},{"content":"The Proxy design pattern is simply an intermediary that is designed over a class to add some additional functionality, without modifying the original class.\nThe Proxy pattern tells us to build a new proxy class with the same interface as the original class. Then instead of using the original class, we used the proxy class on all clients that used the original class.\nThe proxy class adds the desired functionality and then delegates all the work to the original class. To create this pattern, we need to define an interface from which to extend the main class. We will then create our proxy class, which will also extend from the interface and have the main class as its attribute.\nWhat are the parts of the Proxy design pattern? #This pattern consists mainly of three parts:\nInterface: from which the main class will be created. Main class: implementing the interface. Proxy class: the class that will also extend from the interface and which will contain the main class as an attribute. How to create the Proxy design pattern in Java #To better understand this pattern, let’s look at an example. Suppose you have a class that performs processes for which you have to read a large file on disk. We want this class to lift the disk file only once, but we do not have access to modify the original class.\nWe will create from the interface our class. In addition to this same interface, we will implement the proxy. Instead of querying the actual class, the client will do so through the proxy.\nWe have our interface from which extends the original class.\npackage patterns.proxy; public interface BatchProcess { void process(); } The class that performs the process in the constructor reads the file from the disk.\nIn this class, we simulate in the method loadFromDisk the work of reading the file.\npackage patterns.proxy; public class BatchProcessImpl implements BatchProcess { private final String fileName; public BatchProcessImpl(String fileName) { this.fileName = fileName; loadFromDisk(fileName); } @Override public void process() { System.out.println(\u0026#34;Processing file \u0026#34; + fileName); } private void loadFromDisk(String fileName) { System.out.println(\u0026#34;Expensive and hard process...\u0026#34;); for (int i = 0; i \u0026lt; 10; i++) { System.out.println(\u0026#34;Loading \u0026#34; + fileName + \u0026#34; \u0026#34; + i * 10 + \u0026#34;%\u0026#34;); try { Thread.sleep(1000); } catch (InterruptedException e) { } } System.out.println(\u0026#34;Loaded \u0026#34; + fileName); } } We know that it is expensive to read in class BatchProcessImpl, and we would like it to be done only once.\nWe do not have access to modify the class BatchProcessImpl, so we decided to create a proxy class.\nThe proxy class implements the same interface BatchProcess and will have the class BatchProcessImpl\npackage patterns.proxy; public class ProxyBatchProcess implements BatchProcess { private BatchProcessImpl batchProcess; private String fileName; public ProxyBatchProcess(String fileName) { this.fileName = fileName; } @Override public void process() { if (batchProcess == null) { batchProcess = new BatchProcessImpl(fileName); } batchProcess.process(); } } We now try the Proxy design pattern # We created the ProxyBatchProcess object by sending a large file. We run for the first time and see in the output that the file is read. Then we run again, and this time we can check that the file is no longer read and only the process is performed on the file previously \u0026rsquo;that was read from the disk.' package patterns.proxy; public class ProxyPatternExample { public static void main(String[] args) { BatchProcess batchProcess = new ProxyBatchProcess(\u0026#34;big_file.txt\u0026#34;); //batchProcess will be loaded from disk System.out.println(\u0026#34;BatchProcess will be loaded from disk\u0026#34;); batchProcess.process(); System.out.println(\u0026#34;-----------------\u0026#34;); //batchProcess will not be loaded from disk System.out.println(\u0026#34;BatchProcess will not be loaded from disk\u0026#34;); batchProcess.process(); } } In the output, we see that the first execution \u0026rsquo;loads\u0026rsquo; the file and in the second the process is performed without re-loading it as we wanted.\nBatchProcess will be loaded from disk Expensive and hard process... Loading big_file.txt 0% Loading big_file.txt 10% Loading big_file.txt 20% Loading big_file.txt 30% Loading big_file.txt 40% Loading big_file.txt 50% Loading big_file.txt 60% Loading big_file.txt 70% Loading big_file.txt 80% Loading big_file.txt 90% Loaded big_file.txt Processing file big_file.txt ----------------- BatchProcess will not be loaded from disk Processing file big_file.txt Some advantages and disadvantages of this pattern: # We can modify functionality without affecting other functionalities that are using the original class directly. The code can become complicated if you need to introduce lots of new functionality. The actual response of the service may be unknown until it is actually invoked. Conclusion: #We\u0026rsquo;ve seen the Proxy pattern and how useful it can be to add functionality to a class without modifying it.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/proxy-design-pattern/","section":"Posts","summary":"\u003cp\u003eThe Proxy design pattern is simply an intermediary that is designed over a class to add some additional functionality, without modifying the original class.\u003c/p\u003e","title":"Proxy Design Pattern"},{"content":"This is one of the best-known patterns and is perhaps the first that comes to mind when you ask us about design patterns in Java.\nThe goal is to have only one instance of a class involved and ensure that this happens every time this instance is needed.\nThe Singleton design pattern has many ways of being implemented but we will see here the basis of its implementation consisting of:\nCreate a private constructor avoiding the possibility of using new Create a static variable in the class that will save the instance of that class. Create a public method that will always return the same instance of the class we have saved in the variable. What is a Singleton design pattern #Normally when we create an object in Java we use the keyword new.\nThis creates a new Object whenever required. However, there are times when we do not want to create a new object, on the contrary, we want to \u0026lsquo;share\u0026rsquo; the object.\nThe singleton design pattern ensures that only one object is created and that only one instance of the object exists for the class.\nEvery time we need the object we will get the same instance.\nHow to implement the Singleton pattern #There are several ways to implement the Singleton pattern. Let’s look at each.\nBasic Singleton Pattern Implementation #This is the basic form a Singleton class would have. We make the constructor private to avoid its creation with new, and we define a method that always returns the same instance.\npackage patterns; public class SingletonExample { private static SingletonExample instance = new SingletonExample(); private SingletonExample() { } static SingletonExample getInstance() { return instance; } } Singleton Lazy Implementation #If we see the previous implementation we can think that we are creating an instance always, instance = new SingletonExample(), even if it is not required. We can think of another implementation where the object is created when required.\nFor this, the variable remains null and we initialize it the first time the method getInstance() is invoked.\nTo prevent two threads from entering simultaneously the first time we synchronize the instance creation.\npackage patterns; public class SingletonExample2 { private static SingletonExample2 instance; private SingletonExample2() { } static SingletonExample2 getInstance() { if (instance == null) { synchronized (SingletonExample2.class) { if (instance == null) { instance = new SingletonExample2(); } } } return instance; } } In this article, you learn the two simplest ways to create a Singleton class.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/singleton-design-pattern/","section":"Posts","summary":"\u003cp\u003eThis is one of the best-known patterns and is perhaps the first that comes to mind when you ask us about design patterns in Java.\u003c/p\u003e\n\u003cp\u003eThe goal is to have only one instance of a class involved and ensure that this happens every time this instance is needed.\u003c/p\u003e","title":"Singleton Design Pattern"},{"content":"The Strategy design pattern helps to define different behaviors or functionalities that can be changed at runtime.\nIn the Strategy pattern, we create different classes that represent strategies and that we can use, according to some variation or input.\nWhat are the elements of the Strategy design pattern? #The Strategy pattern consists of a Strategy interface that defines the different specific classes with the strategy implemented and the context in which the strategy to use is established according to some condition, rule or input.\nThe components of the Strategy pattern are:\nInterface Strategy: is the interface that defines how the strategy contract will be shaped. Specific Classes Strategy: these are the classes that implement the interface and where the functionality is developed. Context: this decides what strategy will be used. How a Strategy design pattern is created #We talked before that the goal of the Strategy pattern is to divide functionalities into strategies.\nThis allows you to focus on a particular problem and solve it and, then decide what solution should be used for a particular case.\nWe need to think about what will be the common method or function for all the strategies that will go into the interface. From there, you realize the particular implementations.\nWith an example, it looks simpler. Let’s look at an example of the Strategy pattern with Java.\nWe are going to use a basic example to explain the Strategy pattern.\nSo suppose this business logic:\nWe have different commissions that are paid according to a sale amount.\nIf the sale amount is higher, a higher commission is paid.\nWe define the Strategy interface from which we will create specific strategies for each case.\npackage patterns.strategy; public interface CommissionStrategy { double applyCommission(double amount); } We think about the implementation of each Strategy.\nImplementation for a full commission payment.\npackage patterns.strategy; public class FullCommission implements CommissionStrategy { @Override public double applyCommission(double amount) { // do complicated formula of commissions. return amount * 0.50d; } } Implementation for a normal commission payment.\npackage patterns.strategy; public class NormalCommission implements CommissionStrategy { @Override public double applyCommission(double amount) { // do complicated formula of commissions. return amount * 0.30; } } Implementation for a regular commission payment.\npackage patterns.strategy; public class RegularCommision implements CommissionStrategy { @Override public double applyCommission(double amount) { // do complicated formula of commissions. return amount * 0.10; } } We create the context for strategies.\npackage patterns.strategy; public class Context { private CommissionStrategy commissionStrategy; public Context(CommissionStrategy commissionStrategy){ this.commissionStrategy = commissionStrategy; } public double executeStrategy(double amount){ return commissionStrategy.applyCommission(amount); } } We tested the strategy with different sales amounts.\npackage patterns.strategy; public class StrategyPatternExample { public static void main(String[] args) { CommissionStrategy commissionStrategy = getStrategy(1000d); Context context = new Context(commissionStrategy); System.out.println(\u0026#34;Commission for 1000d = \u0026#34; + context.executeStrategy(1000d)); commissionStrategy = getStrategy(500d); context = new Context(commissionStrategy); System.out.println(\u0026#34;Commission for 500d = \u0026#34; + context.executeStrategy(500d)); commissionStrategy = getStrategy(100d); context = new Context(commissionStrategy); System.out.println(\u0026#34;Commission for 100d = \u0026#34; + context.executeStrategy(100d)); } private static CommissionStrategy getStrategy(double amount) { CommissionStrategy strategy; if (amount \u0026gt;= 1000d) { strategy = new FullCommission(); } else if (amount \u0026gt;= 500d \u0026amp;\u0026amp; amount \u0026lt;= 999d) { strategy = new NormalCommission(); } else { strategy = new RegularCommision(); } return strategy; } } output\nCommission for 1000d = 500.0 Commission for 500d = 150.0 Commission for 100d = 10.0 What did we do in the previous code?\nAbove, we see that for a sale of 1000 our business rules decide to use FullCommission strategy.\nSimilarly, for sales of 500 and 100 Normal and Regular strategies are decided respectively.\nThe getStrategy method will decide the strategy to use based on the amount.\nThis strategy will then be established in context and used to calculate the resulting commission.\nWe decide the strategy to use, according to some input. We define strategy in context. We use context to determine the result. Conclusion #We saw how to create a Strategy pattern which helps us define different functionalities or algorithms on some common theme by solving and choosing the right one at runtime.\nYou can review this code GitHub\n","date":"Aug 19, 2023","permalink":"https://gustavopeiretti.com/strategy-design-pattern/","section":"Posts","summary":"\u003cp\u003eThe Strategy design pattern helps to define different behaviors or functionalities that can be changed at runtime.\u003c/p\u003e\n\u003cp\u003eIn the Strategy pattern, we create different classes that represent strategies and that we can use, according to some variation or input.\u003c/p\u003e","title":"Strategy Design Pattern"},{"content":"Here we will cover the fundamental commands for building and running a Spring Boot application using Maven Wrapper.\nFor this post, we suppose that we have a Spring Boot project\nMaven Wrapper #Maven Wrapper is a tool that helps to ensure consistent builds across different environments and eliminates the need for developers to install Maven on their local machines.\nWhy do we have to use Maven Wrapper:\nEasy to use: Maven is easy to use and comes with a simple and intuitive syntax for defining build processes. You can quickly build, test, and deploy your Java projects. Dependency management: Maven provides powerful dependency management capabilities, allowing you to manage dependencies easily. Standardization: Maven provides a standardized build process, making it easier to work with different Java projects. Maven follows a convention over the configuration approach, which means that you don\u0026rsquo;t need to specify a lot of details about your project as Maven already knows where to find the source files, where to put the compiled code, and how to package the project. Plugins: Maven provides a vast collection of plugins that allow performing a wide range of tasks. These plugins are easily configurable and can be used to run tests, generate documentation, build and deploy applications, and much more. Continuous Integration: Maven integrates well with Continuous Integration (CI) tools such as Jenkins, Bamboo, and TeamCity. This allows developers to automate the build, test, and deployment processes, ensuring the project is always in a releasable state. Community support: Maven has a large and active community of developers who contribute to the development of the tool, provide support, and create plugins. What is a Maven Plugin? #Plugins in Maven are used to perform a wide range of tasks, such as compiling code, generating documentation, running tests, deploying artifacts, and more. Maven plugins are typically executed during specific phases of the build process, and they are defined in the pom.xml file for a project.\nWhat is a Spring Boot Maven plugin? #The spring-boot-maven-plugin is used to build and package Spring Boot applications. It is included with the Spring Boot framework and provides several features to simplify the build process.\nSome of the key features of the spring-boot-maven-plugin include:\nPackaging: The plugin allows you to package your Spring Boot application into an executable JAR or WAR file. Re-packaging: The plugin can re-package an existing JAR or WAR file so that it can be executed as a Spring Boot application. Dependency management: The plugin can manage dependencies for your Spring Boot application, ensuring that all necessary libraries are included in the final package. Spring Boot configuration: The plugin can read and apply configuration properties from the Spring Boot configuration files (application.properties or application.yml) during the build process. Running your application: The plugin can start and stop your Spring Boot application during the build process, allowing you to run integration tests against a running instance of your application. To use the spring-boot-maven-plugin, you need to add it to the pom.xml file of your Spring Boot project and configure it to suit your needs. The plugin is typically used in the package phase of the Maven build lifecycle.\nHow to add the Spring Boot Maven plugin: #To add the Spring Boot plugin, simply add the following to your project\u0026rsquo;s pom.xml file:\n\u0026lt;build\u0026gt; \u0026lt;plugins\u0026gt; \u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;/plugin\u0026gt; \u0026lt;/plugins\u0026gt; \u0026lt;/build\u0026gt; Once you have added the Maven Wrapper plugin, you can generate the Maven wrapper script by running the following command from the root directory of your project:\n./mvnw clean install This will generate all of the maven files to run your application later and it will download the necessary dependencies for your project.\nMaven folders and files description #Here is a brief description of the folders and files in a Maven project:\nsrc/main/java: This is the directory where you put your Java source code files. By default, Maven expects Java source files to be located in this directory. src/main/resources: This is the directory where you put non-Java resources that your project needs at runtime. Examples of such resources include property files, XML files, and configuration files. src/test/java: This is the directory where you put your test code. By default, Maven expects test source files to be located in this directory. src/test/resources: This is the directory where you put resources that your test code needs at runtime. pom.xml: This is the Project Object Model (POM) file. It is an XML file that contains information about the project, such as its dependencies, build settings, and plugins. target: This is the directory where Maven puts the output of the build process. For example, when you run \u0026ldquo;mvn package\u0026rdquo;, the resulting JAR file will be located in the target directory. .m2: This is the default location of the local repository where Maven downloads dependencies. When you specify a dependency in your POM file, Maven will automatically download it and store it in the local repository. This .m2 folder is located into your “USER HOME”. .mvn: This is a directory that contains Maven configuration files and the wrapper jar file. These configuration files can be used to configure Maven settings and specify which JDK to use for building the project. mvnw and mvnw.cmd: These are wrapper scripts that allow you to run Maven without having to install it on your system. These are the most important folders and files you will encounter in a Maven project.\n├───.mvn │ └───wrapper ├───src │ ├───main │ │ ├───java │ │ └───resources │ └───test │ ├───java │ └───resources └───target Here is an example of a common Maven folder structure as seen from IntelliJ\nThe Maven pom.xml file #In Maven, the POM (Project Object Model) is represented by an XML file named \u0026ldquo;pom.xml\u0026rdquo;. It is the fundamental configuration file for a Maven-based project and contains information about the project, such as its dependencies, build settings, and plugins.\nThe pom.xml file is located in the root directory of the project and provides a complete and accurate description of the project to Maven.\nThe pom.xml file includes the following information:\nProject information such as name, description, and version. Dependencies required by the project, including their version numbers and scope. Build settings, such as the location of the source code and output files. Plugins to be used in the build process, including their configuration. Profiles, provide a way to specify different configurations for different environments. A common Spring Boot pom.xml maven file looks like that:\nHere is a short description of each part of Maven pom.xml file:\ngroupId: It is a unique identifier of the project’s group. It is generally in the form of a reversed domain name. artifactId: It is a unique identifier of the project’s artifact (jar, war, ear). It is generally in the form of a name that identifies the project. version: It is the version number of the project. dependencies: It specifies the dependencies that this project has on other projects or libraries. build: It specifies all the information related to building the project such as source directory, test source directory, output directory etc. plugins: It specifies all the plugins that are used in building the project. For Spring Boot web application use this dependency:\n\u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-test\u0026lt;/artifactId\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; Main commands for Spring Boot with Maven #Following are some of the most frequent Maven commands for work with Spring Boot:\nmvnw -help: Print all of the maven commands and options. mvnw clean: Cleans the project and removes all files generated by the previous build. mvnw compile: Compiles source code of the project. mvnw test: Run unit tests of the project. mvnw package: Packages the compiled code into a distributable format such as JAR or WAR files. mvnw install: Build and Installs the package into the local repository for use as a dependency in other projects. mvnw deploy: Copies the final package to the remote repository for sharing with other developers and projects. mvnw validate: validate the project and check if everything is correct. mvnw dependency:tree: show all of the dependencies in a tree ouput. Spring Boot Maven plugin command:\nmvnw spring-boot:run: This command starts your Spring Boot application in a local development environment. mvnw spring-boot:start: This command starts your Spring Boot application in the background as a daemon process. mvnw spring-boot:stop: This command stops a running instance of your Spring Boot application that was started with spring-boot:start. spring-boot:run with common arguments:\nmvnw spring-boot:run -Dspring-boot.run.arguments=\u0026quot;--server.port=8081\u0026quot;: This command starts your Spring Boot application with additional command line arguments, such as changing the default port number. These additional commands are optional. mvnw spring-boot:run -Dspring.profiles.active=dev: This command starts your Spring Boot application with a specific active Spring profile, such as dev. * (*) Check this page about Spring Boot profiles. Spring Boot Profiles\nCombining command:\nYou can combine commands to execute multiple tasks in one line. For example:\n.\\mvnw clean install Conclusion: #This document provides an initial guide to using Maven Wrapper with Spring Boot. It covers the benefits of using Maven Wrapper, the structure of a Maven project, the Maven pom.xml file, and the most frequent Maven commands for working with Spring Boot. It also explains the Spring Boot Maven plugin and its features, as well as providing examples of common Maven commands for running a Spring Boot application. Check this post about Spring Boot with Gradle wrapper\n","date":"Apr 11, 2023","permalink":"https://gustavopeiretti.com/spring-boot-with-maven-wrapper/","section":"Posts","summary":"\u003cp\u003eHere we will cover the fundamental commands for building and running a Spring Boot application using Maven Wrapper.\u003c/p\u003e","title":"Spring Boot with Maven Wrapper"},{"content":"In Spring Boot, @Autowired is an annotation that allows automatic dependency injection of beans. It is used to inject an instance of a class into another class.\nWhat is @Autowired in Spring Boot #@Autowired is an annotation used in Spring Boot to enable automatic dependency injection. It allows the Spring container to provide an instance of a required dependency when a bean is created. This annotation can be used on fields, constructors, and methods to have Spring provide the dependencies automatically. Dependency injection is a design pattern in which objects are passed their dependencies rather than creating them internally. In Spring Boot, @Autowired is used to inject objects into other objects. This allows for loose coupling between components and helps to keep code more maintainable.\nExample of @Autowired #Let\u0026rsquo;s look at an example of how to use the @Autowired annotation.\nWe have a CarService class that needs an EngineService instance to function properly. This can be injected into the CarService class using the @Autowired annotation.\n@Service public class CarService { @Autowired private EngineService engine; public void drive() { engine.start(); } } The @Autowired annotation specifies that the Spring container should supply the EngineService to the CarService class. When the container creates the CarService instance, it will automatically inject the EngineService instance into the CarService class.\nNote that in order for @Autowired to work, you need to have properly configured the Spring Boot application context with the required beans defined. You can define beans by annotating classes with @Component, @Service, @Repository, @Controller, or @Bean.\nUsing @Autowired in Private Fields #Private fields can be annotated with @Autowired to have Spring inject a dependency into the field.\nHere Spring uses reflection to access internally to the class and inject the component into the field.\n@Service public class CarService { @Autowired private EngineService engine; public void drive() { engine.start(); } } Using @Autowired in Constructors #Constructors can also be annotated with @Autowired to have Spring inject the dependency into the class.\nInject by constructors is the recommended use over the others ways to use Autowired.\n@Service public class CarService { private final EngineService engine; @Autowired public CarService(EngineService engine) { this.engine = engine; } public void drive() { engine.start(); } } Also in this way:\n@Service public class CarService { private final EngineService engine; public CarService(@Autowired EngineService engine) { this.engine = engine; } public void drive() { engine.start(); } } Using @Autowired in Set Methods #Set methods can also be annotated with @Autowired to have the dependency injected into the class by Spring.\n@Service public class CarService { private EngineService engine; @Autowired public void setEngine(EngineService engine) { this.engine = engine; } public void drive() { engine.start(); } } The \u0026lsquo;required\u0026rsquo; @Autowired parameter #By default, with the @Autowired annotation the dependency is required. But we could indicate that it is NOT required, so Spring will leave the dependency null.\n@Service public class CarWithNotRequiredService { @Autowired(required = false) private EngineService engine; // This could be null ! public void drive() { if (Objects.isNull(engine)) { // prevent null pointer System.out.println(\u0026#34;Engine is null!\u0026#34;); }else { engine.start(); } } } Conclusion #@Autowired is an annotation used in Spring Boot to use automatic dependency injection in classes that need others components.\nIt allows the Spring container to provide an instance of a necessary dependency when a component is created. This annotation can be used on fields, constructors, and methods, as well as with the “required” attribute to indicate whether a dependency is needed or not.\nThis code is in GitHub Spring Boot Code examples\n","date":"Mar 7, 2023","permalink":"https://gustavopeiretti.com/spring-boot-autowired-annotation/","section":"Posts","summary":"\u003cp\u003eIn Spring Boot, @Autowired is an annotation that allows automatic dependency injection of beans.\nIt is used to inject an instance of a class into another class.\u003c/p\u003e","title":"Understanding Spring Boot @Autowired Annotation"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/page/","section":"Pages","summary":"","title":"Pages"},{"content":"SPRING BOOT GITHUB CODE EXAMPLES # This is my GitHub to see all the Spring Boot sample codes ","date":"Mar 6, 2023","permalink":"https://gustavopeiretti.com/spring-boot-code-examples/","section":"Pages","summary":"","title":"Spring Boot Code Examples"},{"content":"In Spring Boot, a @Bean is a method-level annotation that is used to declare a bean and register it with the Spring container.\nWhat is @Configuration in Spring Boot? #@Configuration annotation is used in Spring Boot to indicate that a class contains one or more bean definitions.\nA bean is an object that is managed by the Spring framework and can be used to provide services or functionality to other parts of the application.\nWhen a class is annotated with @Configuration, it is treated as a source of bean definitions, and any methods within the class that are annotated with @Bean will be used to create and configure beans.\n@Configuration public class AppConfig { // beans definition here } What is a Bean in Spring Boot? #A Bean is an object that is managed by the Spring framework.\nIt is created and managed by the Spring container. Beans can be used to encapsulate and provide services, utilities, and functionalities to other components in an application.\n@Bean is an annotation that is used to declare a method as a bean so, to create a bean in Spring Boot, you simply annotate a method with @Bean.\nThe method should return an object that you want to register as a bean in the Spring container.\nThe Spring container will then manage the lifecycle of the bean and inject it into other components as needed.\nHere\u0026rsquo;s an example of how to define a bean in Spring Boot using the @Bean annotation. Note that this class is annotated with @Configuration so, we can create @Beans there.\n@Configuration public class AppConfig { @Bean public MultiplierService multiplier() { return new MultiplierService(2); } } In this example, MultiplierService is a class that provides some service that other components might use. The multiplier() method is annotated with @Bean, which tells Spring to treat it as a bean. When the Spring container starts up, it will call this method to create a new instance of MultiplierService. This instance will be managed by Spring and can be injected into other components that depend on it.\nNote that the @Bean annotation is used within a @Configuration class, which is a special type of Spring component that defines configuration information for the application.\nThis is de MultiplierService class that we want to add like a Bean in our Configuration.\npublic class MultiplierService { private final int multiplier; public MultiplierService(int multiplier) { this.multiplier = multiplier; } public int multiply(int value) { return value * multiplier; } } How to use a Bean we have created #You can use a bean that you have created by autowiring it into another class or component.\nHere\u0026rsquo;s an example of autowiring the ‘MultiplierService’ bean into our ‘AppService’:\n@Service public class AppService { private final MultiplierService multiplierService; public AppService(@Autowired MultiplierService multiplierService) { this.multiplierService = multiplierService; } public int calculate(int aValue) { return multiplierService.multiply(aValue); } } Note: Really you can omit @Autowired because so far we only have one defined Bean for the class and because if @Autowired is not present, Spring will look for a bean that satisfies the constructor.\nHow to give a name to a Bean #You can give a name to a bean by providing a name to the @Bean annotation. This will be used as the name of the bean in the Spring container.\n@Bean(name= \u0026#34;multiplierService\u0026#34;) public MultiplierService multiplier() { return new MultiplierService(2); } In this example, the @Bean annotation is given a value of “multiplierService”.\nThis will be used as the name of the bean in the Spring container instead of the default name, which is the name of the method that declares the bean (in this case, “multiplier”).\nIf you omit the string value from the @Bean annotation, Spring will use the default name based on the method name.\nHow to call a Bean by its name? #In Spring Boot, you can call a bean with a specific name using the @Qualifier annotation.\nThe @Qualifier annotation is used to specify the name of the bean that you want to use when there are multiple beans of the same type or simply when we want to particularly declare the bean to use.\nHere\u0026rsquo;s an example:\nWith @Qualifier we tell Spring exactly what bean we need.\n@Service public class AppService { private final MultiplierService multiplierService; public AppService(@Autowired @Qualifier(\u0026#34;multiplierService\u0026#34;) MultiplierService multiplierService) { this.multiplierService = multiplierService; } public int calculate(int aValue) { return multiplierService.multiply(aValue); } } Note that the name given in the @Qualifier annotation should match the name of the bean that you want to use. If the name doesn\u0026rsquo;t match any beans in the container, Spring will throw an exception at runtime.\nAlso note that if you only have one bean of a given type, you don\u0026rsquo;t need to use @Qualifier since Spring can automatically wire it in. However, if you have multiple beans of the same type, you need to specify which one to use using @Qualifier.\nWhat are alias names? #In Spring Boot, alias names are alternative names that can be given to a bean in addition to its primary name.\nYou can define alias names for a bean by using the @Bean annotation with a string array of alias names as shown in the example below:\n@Configuration public class AppConfig { @Bean(name = {\u0026#34;multiplierService\u0026#34;, \u0026#34;multiplierService-alias1\u0026#34;, \u0026#34;multiplierService-alias2\u0026#34;}) public MultiplierService multiplier() { return new MultiplierService(2); } } You can use any number of alias names for a bean, and the alias names can be any valid string value. When you reference a bean by an alias name, Spring resolves it to the primary bean with that name.\nWhat are initMethod and destroyMethod in @Bean? #In Spring Boot, initMethod and destroyMethod are optional attributes of the @Bean annotation that allow you to specify methods that should be called when the bean is initialized or destroyed, respectively.\nHere\u0026rsquo;s you can see how to use init and destroy method:\n@Configuration public class AppConfig { @Bean(name = {\u0026#34;multiplierService\u0026#34;, \u0026#34;multiplierService-alias1\u0026#34;, \u0026#34;multiplierService-alias2\u0026#34;}, initMethod = \u0026#34;init\u0026#34;, destroyMethod = \u0026#34;destroy\u0026#34;) public MultiplierService multiplier() { return new MultiplierService(2); } } In this example, the “multiplier()” method is annotated with @Bean which includes initMethod and destroyMethod attributes.\nThe initMethod attribute specifies that a method called “init()” should be called when the bean is initialized, and the destroyMethod attribute specifies that a method called “destroy()” should be called when the bean is destroyed.\nThe init() method can perform any initialization logic that the bean requires. This method is called after the bean has been created and its dependencies have been injected, but before the bean is made available for use.\nThe destroy() method can perform any cleanup logic that the bean requires. This method is called when the Spring container is shut down or the bean is destroyed by the container.\nNote that the methods specified in initMethod and destroyMethod should have a void return type and take no arguments. If the method has a return type or takes arguments, Spring will throw an exception at runtime.\npublic class MultiplierService { private final int multiplier; public MultiplierService(int multiplier) { this.multiplier = multiplier; } public int multiply(int value) { return value * multiplier; } public void init() { System.out.println(\u0026#34;Calling init method :)\u0026#34;); } public void destroy() { System.out.println(\u0026#34;Calling destroy method :(\u0026#34;); } } Running this example: #If we run this complete example with this Spring Boot main class:\n@SpringBootApplication public class SpringBootBeanApplication { private final AppService appService;; public SpringBootBeanApplication(AppService appService) { this.appService = appService; } public static void main(String[] args) { SpringApplication.run(SpringBootBeanApplication.class, args); } @PostConstruct public void doExamples() { System.out.println(\u0026#34;Calling bean method with this result: \u0026#34; + appService.calculate(123)); } } We can see this Output:\nINFO 17028 --- [ main] c.g.s.SpringBootBeanApplication : Starting SpringBootBeanApplication using Java 17.0.2 with PID 17028 (C:\\dev\\spring-boot-examples\\spring-boot-bean\\target\\classes started by gustavo.peiretti in C:\\dev\\spring-boot-examples\\spring-boot-bean) INFO 17028 --- [ main] c.g.s.SpringBootBeanApplication : No active profile set, falling back to 1 default profile: \u0026#34;default\u0026#34; Calling init method :) Calling bean method with this result: 246 INFO 17028 --- [ main] c.g.s.SpringBootBeanApplication : Started SpringBootBeanApplication in 0.607 seconds (process running for 1.122) Calling destroy method :( What is the life cycle of a @Bean? #In this example, the @Bean method is defined in a @Configuration class.\n1- The bean definition is then registered in the Spring container, and the container instantiates and initializes the bean\n2- Spring injecting any dependencies that the bean needs.\n3- Init method is called.\n3- Once the bean is fully initialized, it is available for use in the application.\n4- When the application shuts down or the bean is destroyed by the container, any destroy method specified in the @Bean annotation is called.\nConditionalOnProperty annotation with Spring \u0026lsquo;Beans\u0026rsquo; #@ConditionalOnProperty annotation is used to conditionally create a Spring bean depending on the configuration of a property.\nFor example, we are going to create a bean named senderMessagesSms if sender.sms has a value of true and in negative case, senderMessagesEmail it will be created.\n@ConditionalOnProperty(name = \u0026#34;sender.sms\u0026#34;, havingValue = \u0026#34;true\u0026#34;) @Bean(name = \u0026#34;senderMessagesSms\u0026#34;) public SenderMessages senderMessagesSms() { return new SenderMessagesSms(); } @ConditionalOnProperty(name = \u0026#34;sender.sms\u0026#34;, havingValue = \u0026#34;false\u0026#34;) @Bean(name = \u0026#34;senderMessagesEmail\u0026#34;) public SenderMessages senderMessagesEmail() { return new SenderMessagesEmail(); } But, ¿What happen if the property does not exist? For this case, we can use matchIfMissing parameter. So, if the property is not defined, the bean with that parameter set to true will be created.\nmatchIfMissing = true @ConditionalOnProperty(name = \u0026#34;sender.sms\u0026#34;, havingValue = \u0026#34;true\u0026#34;, matchIfMissing = true) @Bean(name = \u0026#34;senderMessagesSms\u0026#34;) public SenderMessages senderMessagesSms() { return new SenderMessagesSms(); } @ConditionalOnProperty(name = \u0026#34;sender.sms\u0026#34;, havingValue = \u0026#34;false\u0026#34;) @Bean(name = \u0026#34;senderMessagesEmail\u0026#34;) public SenderMessages senderMessagesEmail() { return new SenderMessagesEmail(); } Conclusion #This is a summary of what we covered:\nIn Spring Boot, a @Bean is a method-level annotation that is used to declare a bean and register it with the Spring container. A @Bean method must be defined in a @Configuration class, and it typically returns an instance of a class that you want to use as a bean in your application. You can optionally specify a name for the bean using the name attribute of the @Bean annotation. You can also specify an array of alias names for the bean using the value attribute of the @Bean annotation. You can use dependency injection to inject a @Bean into another class or component, which allows you to use the bean in your application. You can use the initMethod and destroyMethod attributes of the @Bean annotation to specify methods to be called when the bean is instantiated and destroyed. The lifecycle of a @Bean in Spring Boot includes registration, instantiation and initialization, dependency injection, and eventual destruction. If you need to create a bean under some condition use ConditionalOnProperty annotation. In conclusion, @Bean is a powerful annotation in Spring Boot that allows you to declare beans in a straightforward and intuitive way. You may register and use instances of your classes as beans in your application by creating @Bean methods in your @Configuration classes, and you can use Spring\u0026rsquo;s dependency injection architecture to efficiently manage your components\u0026rsquo; dependencies.\nThis code is in GitHub Spring Boot Code examples\n","date":"Mar 6, 2023","permalink":"https://gustavopeiretti.com/spring-boot-bean-annotation/","section":"Posts","summary":"\u003cp\u003eIn Spring Boot, a @Bean is a method-level annotation that is used to declare a bean and register it with the Spring container.\u003c/p\u003e","title":"Understanding Spring Boot @Configuration and @Bean Annotation"},{"content":"The @Value annotation in Spring Boot is useful for injecting external values into your application.\nIntroduction to @Value in Spring Boot #@Value annotation can inject values from property files, environment variables, system properties, and command line arguments. This annotation makes it easier to externalize your application configuration, allowing you to modify the external value without recompiling the code.\nHere we are going to understand how to use @Value with property files. All you have to do is add the @Value annotation in your class attribute indicating the property you want to be read.\nWe will look at how to use the @Value annotation in SpringBoot. Take a look at the next examples about how to use @Value with your property file.\nInject @Value in attributes #We said that In Spring Boot, the @Value annotation can be used to inject values from a property file. To do so, first, create a properties file containing the values you want to inject.\nFor example, we can create this application.properties that contains the following values:\napp.example.integer-value=9876 app.example.decimal-value=1.75 app.example.boolean-value=true Then, you can use the @Value annotation to inject these values into your Java class attributes.\nYou can include these fields in your Java class and annotate them with @Value to indicate the property name, as shown below:\n@Value(\u0026#34;${app.example.integer-value}\u0026#34;) private Integer valueInteger; @Value(\u0026#34;${app.example.decimal-value}\u0026#34;) private Double valueDouble; @Value(\u0026#34;${app.example.boolean-value}\u0026#34;) private Boolean valueBoolean; When the application is launched, the fields with @Value will be set to the values from the application.properties file. This makes it simple to externalize your application configuration, allowing you to change the values without recompiling the code.\nNote that Spring converts the property file value to the attribute type.\nYou should use this format ${propertyname}. If you don’t use this format the value will be literal and not from the property value.\nInject @Value in Constructors #The @Value annotation can also be used in constructors to inject values when the class is constructed.\nHere, we use the @Value annotation in a constructor to inject values from the application.properties file.\nThe constructor takes two parameters and annotates them with @Value to indicate the property name, as illustrated as follows. The class should be a component, in this case, we use directly @Component. But could be any type of component stereotype such as a Service, Repository, Configuration.\n@Component public class AppComponent { private final Integer valueInteger; private final Double valueDouble; public AppComponent(@Value(\u0026#34;${app.example.integer-value}\u0026#34;) Integer valueInteger, @Value(\u0026#34;${app.example.decimal-value}\u0026#34;) Double valueDouble) { this.valueInteger = valueInteger; this.valueDouble = valueDouble; } public Double sum() { return this.valueDouble + this.valueInteger; } } @Value with Default Values #We can also use the @Value annotation to set a default value for a field if the property is not found in the properties file.\nFor example, we can set the default value for this field like this:\n@Value(\u0026#34;${app.example.nonexistent-value:\u0026#39;This is a default value\u0026#39;\u0026#39;}\u0026#34;) private String defaultValue; Here, we have set the default value to This is a default value if the app.example.nonexistent-value property is not found in the properties file. This can be useful to set a default value when the property is not present in the configuration.\nExample @Value with Arrays Properties #The @Value annotation can also be used to inject values from an array of properties into your application. To do this, create a properties file containing the values of the array.\nFor example, we can make the following list of countries:\napp.example.countries=Argentina, Brazil, Italy, Spain Include a List\u0026lt;String\u0026gt; field in your Java class and annotate it with @Value to indicate the property name, see this:\n@Value(\u0026#34;${app.example.countries}\u0026#34;) private List\u0026lt;String\u0026gt; countries; You can also use this format to set a default value for an array of strings:\n@Value(\u0026#34;${app.example.countries:Argentina, Brazil, Italy, Spain}\u0026#34;) private List\u0026lt;String\u0026gt; countries; The List\u0026lt;String\u0026gt; countries array will be set to the default value of Argentina, Brazil, Italy, Spain if the app.example.countries property is not found in the properties file.\nUsing the @Value Annotation with Maps #The @Value annotation can also be used to inject values from a map defined with a single property into your application. To do this, create a properties file containing the values of the map.\nThis application.properties file contains the following value that contains a map:\napp.example.map-values=[keyA:\u0026#39;A\u0026#39;, keyB:\u0026#39;B\u0026#39;, keyC:\u0026#39;C\u0026#39;] Include a Map\u0026lt;String,String\u0026gt; field in your Java class with @Value to indicate the property name.\nNotice, the format changes → @Value(\u0026quot;#{${app.example.map-values}}\u0026quot;) . The name of this format is Spring Expression Language (SpEL).\n@Value(\u0026#34;#{${app.example.map-values}}\u0026#34;) private Map\u0026lt;String,String\u0026gt; mapValues; Example @Value with Enums #The @Value annotation can also be used to inject values from an enum. Create a properties file containing the enum values.\nFor example, we can create this application.properties file containing the following value that contains an enum:\napp.example.enum-value=RED Include an Enum field in your Java class and annotate it with @Value to indicate the property name:\n@Value(\u0026#34;${app.example.enum-value}\u0026#34;) private ColorEnum color; public enum ColorEnum { RED, GREEN, BLUE } Example @Value with Local Date #The @Value annotation can also be used to inject values from a Local Date.\nIn this application.properties the value contains a Local Date. You have to use the ISO-8601 calendar system yyyy/dd/mm, such as 2025-12-01\napp.example.local-date=2025-12-01 Your field with LocalDate in your Java class with @Value:\n@Value(\u0026#34;${app.example.local-date}\u0026#34;) private LocalDate localDate; Example @Value with LocalDateTime #The @Value annotation can also be used to inject values from a LocalDateTime. In this application.properties the value contains a LocalDateTime. Use the ISO-8601 calendar system yyyy/dd/mm/hh:mm:ss, such as 2025-12-01T09:00:00\napp.example.local-datetime=2025-12-01T09:00:00 Your field with LocalDateTime in your Java class with @Value:\n@Value(\u0026#34;${app.example.local-datetime}\u0026#34;) private LocalDateTime localDateTime; Running all of the previous examples #We have this property file.\napp.example.integer-value=9876 app.example.decimal-value=1.75 app.example.boolean-value=true # array app.example.countries=Argentina, Brazil, Italy, Spain # map app.example.map-values={keyA:\u0026#39;A\u0026#39;, keyB:\u0026#39;B\u0026#39;, keyC:\u0026#39;C\u0026#39;} # enum app.example.enum-value=RED # local date app.example.local-date=2025-12-01 # local date time app.example.local-datetime=2025-12-01T09:00:00 This component.\n@Component public class AppComponent { private final Integer valueInteger; private final Double valueDouble; public AppComponent(@Value(\u0026#34;${app.example.integer-value}\u0026#34;) Integer valueInteger, @Value(\u0026#34;${app.example.decimal-value}\u0026#34;) Double valueDouble) { this.valueInteger = valueInteger; this.valueDouble = valueDouble; } public Double sum() { return this.valueDouble + this.valueInteger; } } This Enum\npublic enum ColorEnum { RED, GREEN, BLUE } And this Spring Main class\n@SpringBootApplication public class SpringBootValueAnnotationApplication { @Value(\u0026#34;${app.example.integer-value}\u0026#34;) private Integer valueInteger; @Value(\u0026#34;${app.example.decimal-value}\u0026#34;) private Double valueDouble; @Value(\u0026#34;${app.example.boolean-value}\u0026#34;) private Boolean valueBoolean; @Value(\u0026#34;${app.example.nonexistent-value:\u0026#39;This is a default value\u0026#39;}\u0026#34;) private String defaultValue; @Value(\u0026#34;${app.example.countries}\u0026#34;) private List\u0026lt;String\u0026gt; countries; @Value(\u0026#34;#{${app.example.map-values}}\u0026#34;) private Map\u0026lt;String, String\u0026gt; mapValues; @Value(\u0026#34;${app.example.enum-value}\u0026#34;) private ColorEnum color; @Value(\u0026#34;${app.example.local-date}\u0026#34;) private LocalDate localDate; @Value(\u0026#34;${app.example.local-datetime}\u0026#34;) private LocalDateTime localDateTime; @Autowired private AppComponent appComponent; public static void main(String[] args) { SpringApplication.run(SpringBootValueAnnotationApplication.class, args); } @PostConstruct public void doExamples() { System.out.println(\u0026#34;-- Running examples --\u0026#34;); // attribute / field inject System.out.println(\u0026#34;-- attribute inject --\u0026#34;); System.out.println(valueInteger); System.out.println(valueDouble); System.out.println(valueBoolean); // constructor inject System.out.println(\u0026#34;-- component inject --\u0026#34;); System.out.println(appComponent.sum()); //default value System.out.println(\u0026#34;-- default value --\u0026#34;); System.out.println(defaultValue); // arrays System.out.println(\u0026#34;-- arrays --\u0026#34;); countries.forEach(System.out::println); // map System.out.println(\u0026#34;-- map --\u0026#34;); mapValues.forEach((k, v) -\u0026gt; System.out.println((k + \u0026#34;:\u0026#34; + v))); // Enum System.out.println(\u0026#34;-- enum --\u0026#34;); System.out.println(color); // local dates System.out.println(\u0026#34;-- local date --\u0026#34;); System.out.println(localDate); // local date time System.out.println(\u0026#34;-- local date time --\u0026#34;); System.out.println(localDateTime); } } Running this main class we will see the following in the console:\n-- Running examples -- -- attribute inject -- 9876 1.75 true -- component inject -- 9877.75 -- default value -- \u0026#39;This is a default value\u0026#39; -- arrays -- Argentina Brazil Italy Spain -- map -- keyA:A keyB:B keyC:C -- enum -- RED -- local date -- 2025-12-01 -- local date time -- Conclusion #In this article, we have learned how to use the @Value annotation in Spring Boot to inject values from properties files into your application and how to use the @Value annotation to inject values into a Component class. We have seen how to inject values from simple properties (string, integer), as well as arrays, maps, enums, LocalDate, and LocalDateTime. Now we know that @Value annotation simplify access to all values of our property file.\nThis code is in GitHub\n","date":"Feb 17, 2023","permalink":"https://gustavopeiretti.com/spring-boot-value-annotation/","section":"Posts","summary":"\u003cp\u003eThe @Value annotation in Spring Boot is useful for injecting external values into your application.\u003c/p\u003e","title":"Understanding Spring Boot @Value Annotation"},{"content":"@ConfigurationProperties is a feature in Spring Boot that allows you to bind external configurations to a Java class.\nIt maps property names to fields in a Java class, making it easy to manage external configurations.\nSo, we can use this Spring functionality if we want to set the properties into a Java class.\nDependencies #You\u0026rsquo;ll need at leas this dependency.\n\u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter\u0026lt;/artifactId\u0026gt; \u0026lt;/dependency\u0026gt; How to use Configuration Properties with a Java Pojo class #The properties can be specified from your application.properties files.\nThe annotated class can then be used to access the properties in your application code. This helps to separate the configuration from the implementation, making it easier to manage and maintain.\nHere is a simple example of how you could use @ConfigurationProperties in a Spring Boot application:\nIf we have this property file:\napp.name=The name of this app app.description=This description of this app We can set these properties in a Java class automatically. For that, you have to annotate the Java class with these two annotations:\n@ConfigurationProperties @Component The prefix in ConfigurationProperties has to be equal to the prefix of the property.\n@ConfigurationProperties(prefix = \u0026#34;app\u0026#34;) @Component public class AppInfo { private String name; private String description; // set and get.. @Override public String toString() { return \u0026#34;AppInfo{\u0026#34; + \u0026#34;name=\u0026#39;\u0026#34; + name + \u0026#39;\\\u0026#39;\u0026#39; + \u0026#34;, description=\u0026#39;\u0026#34; + description + \u0026#39;\\\u0026#39;\u0026#39; + \u0026#39;}\u0026#39;; } } Note how the property prefix is joined with the annotation and each property with the class attribute.\nHow to use Configuration Properties with a Spring Bean #This way is similar to the previous one we learned.\nFor example, for these properties:\napp.mail.hostname=host@mail.com app.mail.port=9000 app.mail.from=mailer@mail.com Let’s define the class AppConfig and annotate it with @Configuration. The class AppConfig is a class of @Configuration that defines a component with the annotation @Bean.\nThe mailData() * method returns an instance of MailData and annotates with @ConfigurationProperties passing as parameter the prefix \u0026ldquo;app.mail\u0026rdquo; to specify that its attributes (those of the MailData class) must be filled with properties that have the prefix \u0026ldquo;app.mail\u0026rdquo;.\n@Configuration public class AppConfig { @Bean @ConfigurationProperties(prefix = \u0026#34;app.mail\u0026#34;) public MailData mailData() { MailData mailData = new MailData(); return mailData; } } Running both examples #You can then use the bean or the component in other parts of your application through dependency injection, for example:\n@SpringBootApplication public class SpringBootConfigurationPropertiesApplication { @Autowired AppInfo appInfo; @Autowired MailData mailData; public static void main(String[] args) { SpringApplication.run(SpringBootConfigurationPropertiesApplication.class, args); } @PostConstruct public void post() { System.out.println(appInfo); System.out.println(mailData); } } The output of that is:\nAppInfo{name=\u0026#39;The name of this app\u0026#39;, description=\u0026#39;This description of this app\u0026#39;} MailData{hostName=\u0026#39;host@mail.com\u0026#39;, port=9000, from=\u0026#39;mailer@mail.com\u0026#39;} Conclusion: #@ConfigurationProperties is a Spring annotation used to map external configuration properties to fields in a Java class, making it easy to get property values in your services.\nThis code is in GitHub\n","date":"Feb 8, 2023","permalink":"https://gustavopeiretti.com/spring-boot-configuration-properties/","section":"Posts","summary":"\u003cp\u003e@ConfigurationProperties is a feature in Spring Boot that allows you to bind external configurations to a Java class.\u003c/p\u003e","title":"Spring Boot Configuration Properties"},{"content":"Spring Boot profiles provide a way to customize the configuration and behavior of your application, based on the environment it is running in.\nWhat are \u0026lsquo;profiles\u0026rsquo; in Spring Boot #In order to adapt your application\u0026rsquo;s configuration and behavior to the environment it is executing in, you can use Spring Boot profiles.\nUsing profiles, you can create multiple configurations, such as ‘development’, ‘testing’, ‘staging’, and ‘production’, and have different settings for each.\nThis allows you to tailor your application to fit the environment\u0026rsquo;s needs and ensure that it runs smoothly in each situation.\nDependencies do we need #This work for all Spring Boot applications, so you need:\nFor Spring Boot\ndependencies { implementation \u0026#39;org.springframework.boot:spring-boot-starter\u0026#39; testImplementation \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; } For Spring Boot Web Applications\ndependencies { implementation \u0026#39;org.springframework.boot:spring-boot-starter-web\u0026#39; testImplementation \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; } How do you work with properties and profiles? #By using profiles, Spring Boot enables you to use several properties files for different environments. You can make a properties file called ‘application-dev.properties’ and ‘application-prod.properties’ for each profile.\nThe values in application.properties (without the profile name) will apply for all environments unless overridden.\nTo activate a specific profile, you have different options:\nSet the \u0026ldquo;spring.profiles.active\u0026rdquo; property in your application.properties file. Set the \u0026ldquo;spring.profiles.active\u0026rdquo; in your JVM parameter when starting your application Set the “spring_profiles_active” in the system environment variable. Set the profile with Gradle param or maven pom When your Spring Boot application starts, it will look for the name of the property file corresponding to the profile that has been set.\nSet the \u0026ldquo;spring.profiles.active\u0026rdquo; property in your application.properties file. #So, we have to define this property spring.profiles.active and set de value for it.\nFor production\nIf we print the value of this property in the application we see the following for data.by.environment:\n@SpringBootApplication public class SpringBootProfilesApplication { private static final Logger logger = LoggerFactory.getLogger(SpringBootProfilesApplication.class); @Value(\u0026#34;${data.by.environment}\u0026#34;) // our property for the active profile private String dataByEnvironment; public static void main(String[] args) { SpringApplication.run(SpringBootProfilesApplication.class, args); } @PostConstruct public void doSomething() { logger.info(\u0026#34;Property data.by.environment value is {}\u0026#34;, dataByEnvironment); } } The output console:\nSet the \u0026ldquo;spring.profiles.active\u0026rdquo; in your JVM parameter when starting your application #A JVM system parameter can also be used to pass the profile name. This profile will become active when the application launches.\nTo do this you must pass this parameter to your JVM.\nHere we are passing the ‘prod’ profile.\n-Dspring.profiles.active=prod java.exe -Dspring.profiles.active=prod If you are using IntelliJ you can do that very simply:\nIf you are using Gradle, like this example. You can add these lines to your build.gradle file to send de VM arguments:\nbootRun { jvmArgs = [\u0026#34;-Dspring.profiles.active=prod\u0026#34;] } Set the “spring_profiles_active” in the system environment variable. #Linux:\nYou can set environment variables in Linux using the export command. To set a variable, use the following syntax:\nexport spring_profiles_active=prod To view the value of this specific environment variable, use the following command:\necho $spring_profiles_active Windows:\nIn Windows, you can set environment variables using the set command. To set a variable, use the following syntax:\nset spring_profiles_active=prod To view the value of this specific environment variable, use the following command:\necho %spring_profiles_active% Set the profile with the Gradle param #Gradle implements profiles via the -P (also known as -project-prop) command line argument.\n./gradlew bootRun -Pprod bootRun What happens if you don’t set any profile #If we don’t use any profiles, Spring will set a default profile and only will load the main property file application.properties and will ignore the other property files.\nHow to use Profile on the beans the Spring #A @Configuration is an annotation used in Spring Boot to indicate that a class provides configuration for the application. @Configuration classes can be used in conjunction with @Profile annotations to specify which configuration should be used for which environment.\nIf you want to create a configuration for a specific profile, you can do that with the @Profile annotation.\nLook at these two settings where we use profiles and we indicate which profile we want to use.\nUsing the @Profile annotation:\nNow on our property, we establish spring.profiles.active=prod.\nThe only configuration that will be executed by Spring will be that indicated as \u0026ldquo;prod”\nYou can exclude a configuration for a specific profile with a negative / NOT operator.\nHere we use @Profile(\u0026quot;!prod\u0026quot;) (note the exclamation to indicate a negative)\nIf we start Spring Boot with spring.profiles.active=prod we will see:\nConclusion #We learned how to use Spring Boot profiles to configure our application. The main purpose of using Spring Boot profiles is to allow developers to create multiple configuration sets for different environments. We walk through the process of setting up profiles with property files, VM arguments, and system variables. It also covers how to use Bean Configurations with profiles.\nYou can find all this code in GitHub\n","date":"Jan 23, 2023","permalink":"https://gustavopeiretti.com/spring-boot-profiles/","section":"Posts","summary":"\u003cp\u003eSpring Boot profiles provide a way to customize the configuration and behavior of your application, based on the environment it is running in.\u003c/p\u003e","title":"Spring Boot Profiles"},{"content":"Spring Boot provides a convenient way to create unit and integration tests for your Spring Boot applications.\nThe SpringBootTest annotation can be used to run a Spring Boot application as a test, and provides the following features:\nIt loads the Spring application context for the test. It can be used to test a slice of the application, including just the controllers, or the whole application. It can be used to test a single layer (e.g., only the controllers) or the whole application (all layers). Dependencies we need #You need these dependencies:\nIf you use Gradle\ndependencies { implementation \u0026#39;org.springframework.boot:spring-boot-starter-web\u0026#39; testImplementation \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; } If you use Maven\n\u0026lt;dependencies\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-web\u0026lt;/artifactId\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-test\u0026lt;/artifactId\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;/dependencies\u0026gt; Testing your controller with ‘SpringBootTest’ #Here is an example of a unit test that tests a single controller using the SpringBootTest annotation.\nSuppose, We have this controller:\n@RestController public class UserController { @GetMapping(\u0026#34;/api/hello\u0026#34;) public String hello() { return \u0026#34;Hello User\u0026#34;; } @GetMapping(\u0026#34;/api/user\u0026#34;) public UserDto user() { return new UserDto(1, \u0026#34;MyName\u0026#34;, \u0026#34;MySurname\u0026#34;); } } Note that you have to annotate your Test with these two annotations:\nSpringBootTest AutoConfigureMockMvc Spring will provide a MockMvc bean in order to use it for check your endpoints.\nUse:\nmovMvc.perform to call the API MockMvcRequestBuilders to map the URL of your controller. print() to print the result to the standard output (console) andExpect(status) to check the status response andExpect(content response) to validate the response coming from the controller. MockMvcRequestBuilders provide all types of methods for get, post, put, delete, etc.\nReview this post for more information about RestController\nHere you have a code example:\nIn the first test, we check the response like a String. In the second test we check the response like a JSON, and to do that we use ObjectMapper.\n@SpringBootTest @AutoConfigureMockMvc class UserControllerTest { @Autowired private MockMvc mockMvc; @Test void shouldReturnHello() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.get(\u0026#34;/api/hello\u0026#34;)) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().string(containsString(\u0026#34;Hello User\u0026#34;))); } @Test void shouldReturnUser() throws Exception { String expectedJson = new ObjectMapper() .writeValueAsString(new UserDto(1, \u0026#34;MyName\u0026#34;, \u0026#34;MySurname\u0026#34;)); this.mockMvc.perform(MockMvcRequestBuilders.get(\u0026#34;/api/user\u0026#34;)) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().json(expectedJson)); } } Testing your controller with TestRestTemplate #Also, you can test your controllers using a TestRestTemplate.\nIn this case, you have to use the same annotation SpringBootTest and provide the port to start a ‘web environment’, here we use the RANDOM_PORT value for the ‘webEnvironment’ parameter.\nThis ‘RANDOM_PORT ‘ will cause Spring to determine a random port and we will access this port using @Value(value = \u0026ldquo;${local.server.port}\u0026rdquo;)\nSpring Boot automatically provided the bean TestRestTemplate and we can add @Autowired to have access and use it.\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class UserControllerRandomPortTest { @Value(value = \u0026#34;${local.server.port}\u0026#34;) private int port; // The port that Spring randomly assigned. @Autowired private TestRestTemplate restTemplate; @Test public void shouldReturnHello() throws Exception { assertThat(this.restTemplate.getForObject(\u0026#34;http://localhost:\u0026#34; + port + \u0026#34;/api/hello\u0026#34;, String.class)).contains(\u0026#34;Hello User\u0026#34;); } @Test public void shouldReturnUser() throws Exception { String expectedJson = new ObjectMapper() .writeValueAsString(new UserDto(1, \u0026#34;MyName\u0026#34;, \u0026#34;MySurname\u0026#34;)); assertThat(this.restTemplate.getForObject(\u0026#34;http://localhost:\u0026#34; + port + \u0026#34;/api/user\u0026#34;, String.class)).isEqualTo(expectedJson); } } Testing your controller with WebMvcTest #In the previous example with SpringBootTest annotation Spring started full application context.\nBut We can narrow the tests to only the web layer by using WebMvcTest.\n@WebMvcTest is a Spring Boot annotation that is used to test the Spring MVC layer of a Spring application. It is used to test the web controllers in a Spring application.\nWhen you use @WebMvcTest, the test will:\nStart an application context that contains only the beans needed for testing the MVC layer (e.g. controllers, converters, validators). Mock the servlet environment (e.g. the request and response objects). Perform a full MVC test (i.e. with a running servlet container). To use @WebMvcTest, you need to:\nAnnotate the test class with @WebMvcTest. Autowire the MockMvc object in your test class. Here\u0026rsquo;s an example of how you might use @WebMvcTest to test a controller in a Spring application:\n@WebMvcTest(UserController.class) class UserControllerWebMvcTestTest { @Autowired private MockMvc mockMvc; @Test void shouldReturnHelloWorld() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.get(\u0026#34;/api/hello\u0026#34;)) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().string(containsString(\u0026#34;Hello User\u0026#34;))); } @Test void shouldReturnUser() throws Exception { String expectedJson = new ObjectMapper() .writeValueAsString(new UserDto(1, \u0026#34;MyName\u0026#34;, \u0026#34;MySurname\u0026#34;)); this.mockMvc.perform(MockMvcRequestBuilders.get(\u0026#34;/api/user\u0026#34;)) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().json(expectedJson)); } } In this example, @WebMvcTest is used to start an application context that contains only the beans needed for testing the MyController class. The MockMvc object is then used to send a GET request to the /my-controller/get-method URL and verify that the response has an HTTP status of 200 (OK) and a body of \u0026ldquo;Hello World\u0026rdquo;.\nNote, this test is the same that the previous examples, but in this case, Spring doesn\u0026rsquo;t start all context. Here Spring only starts the web layer, which is the controller context so this test should run faster.\nConclusion #We learn how to test our RestController in different ways in order to check your APIs and keep the integrity of requests and responses.\nTesting controllers in a Spring Boot application is important for several reasons:\nIt helps ensure that the controllers are working correctly and returning the expected results. It helps ensure that the controllers are robust and can handle different input and edge cases. It helps ensure that changes to the controllers don\u0026rsquo;t break existing functionality for those who are consuming them. \u003c?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?\u003eSpring Boot TestSpringBootTestContext LoaderUtilitiesMockMvcMockMvcRequestBuildersExpectsTestRestTemplateRandomPortWebMvcTestNO context LoaderOnly Test Controller You can find all this code in GitHub\n","date":"Jan 11, 2023","permalink":"https://gustavopeiretti.com/spring-boot-unit-test-rest-controller/","section":"Posts","summary":"\u003cp\u003eSpring Boot provides a convenient way to create unit and integration tests for your Spring Boot applications.\u003c/p\u003e","title":"How to create a Unit Test for a RestController in Spring Boot"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/rest-api/","section":"Tags","summary":"","title":"REST API"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/testing/","section":"Tags","summary":"","title":"Testing"},{"content":"In this post, we are going to integrate Swagger with our Spring Boot application.\nWhat is Swagger? #Swagger allows us to document our \u0026lsquo;APIS\u0026rsquo; in a simple and fast way. This allows us to keep the structure of our APIS with their signatures up to date.\nWhat is the easiest way to add Swagger to Spring Boot? #Spring Boot comes with an easy way to integrate Swagger.\nYou have to add these dependencies to your project.\nGradle\nimplementation \u0026#39;io.springfox:springfox-boot-starter:3.0.0 Maven\n\u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.springfox\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;springfox-boot-starter\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;3.0.0\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; Swagger config for Spring Boot #We need to create a Docket ‘bean’ to configure Swagger.\nThe “Docket class” provides convenient defaults and set-up methods.\nimport org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } } Let’s see:\nFirst, you define a Docket with a Swagger version. In this case SWAGGER_2. After that, with select() you obtain an instance of ApiSelectorBuilder. ApiSelectorBuilder allows you to control the exposed endpoints by Swagger.\nWith ApiSelectorBuilder, you can add more options to control what you will expose in Swagger using apis(RequestHandlerSelector) and paths(PathSelectors).\nHere we define ‘any’ for both parameters so that we will expose all APIs.\nRequestHandlerSelectors PathSelectors With this minimal configuration, we can see your Swagger documentation.\nRun Spring Boot with Swagger #Run your application and then visit the swagger URL.\nThe Swagger URL is the path to your application with the route /swagger-ui/#/\nhttp://localhost:8080/swagger-ui/#/\nAdding more information #If you want, you can add more information with ApiInfo by adding these parameters:\ntitle, description, version, termsOfServiceUrl, contact, license, license URL, vendor extensions @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build() .apiInfo(apiInfo()); // api own information } private ApiInfo apiInfo() { return new ApiInfo( \u0026#34;Spring Boot Example Swagger\u0026#34;, \u0026#34;Here some description of API.\u0026#34;, \u0026#34;API 1.0\u0026#34;, \u0026#34;Terms of service\u0026#34;, new Contact(\u0026#34;My name\u0026#34;, \u0026#34;www.mydomain.com\u0026#34;, \u0026#34;myeaddress@mydomain.com\u0026#34;), \u0026#34;License of API\u0026#34;, \u0026#34;API license URL\u0026#34;, Collections.emptyList()); } } Here you can see the new information added.\nHow to use Swagger to send a request? #You can use Swagger in order to send a request to your APIs.\nIn this example, we can send a ‘Post’ to “/api/user”\nSwagger send request\nComplete the body for the request and run with execute.\nYou can see the response to this request.\nSwagger send request body\nConclusion #In this article, we saw how to integrate Swagger into our Spring Boot project. We understood how easy it is to document our APIs and use Swagger to send requests to our controllers.\nYou can review this code on GitHub\n","date":"Jan 3, 2023","permalink":"https://gustavopeiretti.com/spring-boot-swagger-integration/","section":"Posts","summary":"\u003cp\u003eIn this post, we are going to integrate Swagger with our Spring Boot application.\u003c/p\u003e","title":"Integrating Swagger into Spring Boot"},{"content":"In this tutorial, we are going to see how to debug a Spring Boot Application with Gradle using the command line console.\nRemember, we learned in a previous post how to run Spring Boot Application. However, it is very common to run Spring Boot in debug mode in our daily development routine.\nWe can debug Spring Boot from the line command with this command:\nLook at this parameter \u0026quot;\u0026ndash;debug-jvm”\n./gradlew bootRun --debug-jvm This command will start Spring Boot and wait for us to connect our IDE to the port.\nNow we can open your IDE. In this example we use IntelliJ.\nFor this IDE you have to open menu /run/Edit Configurations\nNow, click on the “plus button” and choose “Remote JVM Debug”\nChange the port number from the same port as the console. Save with the “ok button”.\nGive the name you want in order to identify your own debug option.\nNow you can start your application in debug mode.\nBe careful to start the command first from the console and then from your IDE.\nYou can perform the same operations mentioned above with the buttons on the toolbar.\nConclusion: #Here we learned how to start a Spring Boot application in debug mode from the Gradle console and how to start debugging from your IDE by adding a JVM Remote debug.\n","date":"Sep 19, 2022","permalink":"https://gustavopeiretti.com/spring-boot-gradle-debug-console/","section":"Posts","summary":"\u003cp\u003eIn this tutorial, we are going to see how to debug a Spring Boot Application with Gradle using the command line console.\u003c/p\u003e","title":"How to debug Spring Boot from the Gradle command line"},{"content":"Here we are going to learn the basic command to build and, run Spring Boot application with Gradle Wrapper\nFor this post, we suppose that we have a Spring Boot project with Gradle.\nGradle Wrapper #You can use Gradle without installing it on your computer. Gradle wrapper (gradlew) is a script you can add to your project to execute and build without external installations.\nWe learn how to create a Spring Boot with Gradle wrapper here.\nWith Gradle Wrapper you can:\nInclude Gradle in your project without external installations. Change the Gradle version for your project without affecting other projects. Add Gradle to your system version control. Use the correct version of Gradle for your project. What, and why Gradle? #Gradle is used to compile, run tests, and build your application.\nGradle provides an easy way to create tasks and run them to execute different steps in an orderly and controlled mode.\nAt the same time, Gradle provides a solid system of dependencies.\nSome of the best characteristics of Gradle are:\nPerformance: it is faster and it has optimizations. JVM: Gradle runs on JVM and uses standard Java API. Extensibility: Gradle provides predefined tasks but, you can also provide your own tasks. ID support: Android Studio, IntelliJ, Eclipse, Etc have Gradle support Convention: Gradle uses conventions that allow you to quickly adopt this build system. Insight: provide detailed information you can use to understand what happens with your build. GRADLE FOLDER AND FILES #In a Spring Boot project with the Gradle build system, we have these folders and files:\ngradle folder: with the Gradle code compiled build.gradle file: this is its own main file. We edit this file to create our own tasks and add dependencies. gradlew file: script bash to run Gradle in Linux gradle.bat file: script batch to run Gradle in windows setting.gradle file: other settings like the name of the project The build.gradle file #Inside the build.gradle file, we can observe this sections\nPlugins: provide functionalities like compiling Java code, running Spring Boot, and setting project structure.\nGroup: the group of which this project will be part.\nVersion: the current version of the project.\nSource compatibility: the compatibility with the Java version.\nRepositories: the repository section is the place where we indicate from where we want to download the dependencies\nDependencies: the dependency section is where we write down the dependencies we require for our project.\nTask: a task is a sequence of actions with its name.\nPlugins you need in Spring Boot Project # Spring Boot: this plugin allows you to run Spring Boot applications, and create a package executable jar or war archives. Spring dependency management: this is a convenient plugin that will automatically import the spring-boot-dependencies from the version of Spring Boot that you are using. It lets you skip version numbers when declaring dependencies. Java: this plugin provides all necessary activities for a Java project like compilation, testing, and building capabilities. plugins{ id \u0026#39;org.springframework.boot\u0026#39; version \u0026#39;2.7.3\u0026#39; id \u0026#39;io.spring.dependency-management\u0026#39; version \u0026#39;1.0.13.RELEASE\u0026#39; id \u0026#39;java\u0026#39; } Main commands for Spring Boot and Gradle #We can see a short brief of Gradle with info about the version that we have in our project.\nLinux ./gradlew Windows gradlew.bat\nWe run the gradlew tasks command to know what tasks we have.\nIf we want more detail for a specific task, we can run ./gradlew help \u0026ndash;task For example ./gradlew help \u0026ndash;task bootRun\nThe main Gradle wrapper tasks of a Spring Boot project #To perform these tasks, we need the plug-ins that we already mention above.\nplugins{ id \u0026#39;org.springframework.boot\u0026#39; version \u0026#39;2.7.3\u0026#39; id \u0026#39;java\u0026#39; } Run Spring Boot project → gradlew bootRun\nWith this command, we start our application on the default port 8080.\nBuild Spring Boot project → gradlew build\nYou can run gradlew build -i to see more information. This command will run several tasks like configure, download dependencies, compile Java classes, run tests, and create “jar” files.\nThe executable jar files can be found with the name and version in build/libs folder. You can also see inside the build folder the sub-folders with the compiled classes, external dependencies and test results.\nThis creates an executable Java jar file.\nThe name comes from the settings.gradle file and the version comes from build.gradle\nClean Spring Boot project → gradlew clean\nThis command remove the build folder.\nRun Test Spring Boot project → gradlew test\nThis task will execute all tests in our project.\n./gradlew test -i (the “-i” param add more info to the console)\nNote that on the console we have a result test and an HTML report with good detail\nIf we open the index.html file in this location, we can see the report.\nThis report is very complete and can help you if you have many tests.\nConclusion: #This post taught us how to run, build, and execute tests in a Spring Boot project with Gradle. Gradle is an excellent build management and a good choice for your Spring Boot project.\nReferences:\nSpring Boot Gradle Plugin Reference Guide The Java Plugin (gradle.org)\n","date":"Sep 2, 2022","permalink":"https://gustavopeiretti.com/spring-boot-with-gradle-wrapper/","section":"Posts","summary":"\u003cp\u003eHere we are going to learn the basic command to build and, run Spring Boot application with Gradle Wrapper\u003c/p\u003e","title":"Spring Boot with Gradle Wrapper"},{"content":"When we are developing Spring Boot applications it is a very common need to create tables and load into its data. Spring Boot provides an easy way to load initial SQL queries to insert registries in our database. Here we are going to understand how to initialize data with SQL files that Spring can load when it is starting.\nSpring can load two files schema.sql and data.sql. These two files have to be in the resources folder.\nThe schema.sql file #We know that Spring can create tables using the entities class.\nPlease take a look at this article /spring-boot-database-connection-config/\nBut If we want to create tables using SQL sentences we can do it using the file schema.sql\nAssume you have a User Entity\n@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; private String name; private String surname; private LocalDate birthDate; public User() { } // getters.. setters } For this entity, we need a table user with these attributes: id, name, surname, birth_date\nSo, ¿what do we have to do to create this table on our own?\nWe have to create a resources/schema.sql with the columns, type of data, and other definitions you need.\nFile resources/schema.sql\ncreate table if not exists user ( id bigint not null primary key, birth_date date not null, name varchar(255) not null, surname varchar(255) not null ); The data.sql file #Spring Boot uses the data.sql file to run SQL queries when starting the application.\nFor example, we could have these queries in our resources/data.sql file to insert registries and populate the table.\nINSERT INTO user (id, birth_date, name, surname) VALUES (1, \u0026#39;1960-06-10\u0026#39;, \u0026#39;Paul\u0026#39;, \u0026#39;Hewson\u0026#39;); INSERT INTO user (id, birth_date, name, surname) VALUES (2, \u0026#39;1960-03-13\u0026#39;, \u0026#39;Adam\u0026#39;, \u0026#39;Clayton\u0026#39;); INSERT INTO user (id, birth_date, name, surname) VALUES (3, \u0026#39;1961-08-08\u0026#39;, \u0026#39;David\u0026#39;, \u0026#39;Evans\u0026#39;); Disable auto creation of tables #Be careful to add this property spring.jpa.hibernate.ddl-auto=none. Spring won\u0026rsquo;t use User.java class to create the table with this property with the value of none .\nYou can understand more about this property by visiting /spring-boot-database-connection-config/\nWith this property, the User.java entity class will not be used to create the tables. Our responsibility will be to create them manually or with the initialization using the SQL files.\nThe property indicates that we don’t want to use entity class to automatically create tables.\nspring.jpa.hibernate.ddl-auto=none Database initialization works with embedded databases like H2.\nSo, we need to add this property too, if we are using it for other non-embedded databases.\nEnable SQL data source initialization #spring.datasource.initialization-mode=always Starting our Spring Boot application #ok. Now, we are going to start our application to see the console.\nAdd this property to see data source logs with details.\nlogging.level.org.springframework.jdbc.datasource.init=DEBUG As we begin our application, we are able to see this:\nConclusion: #Spring Boot provides an easy way to create schemas and populate tables. We can perform this data source creation and initialization with two files, schema, and data.\nCheck the source code of this example here\n","date":"Aug 22, 2022","permalink":"https://gustavopeiretti.com/spring-boot-database-initialization-sql-files/","section":"Posts","summary":"\u003cp\u003eWhen we are developing Spring Boot applications it is a very common need to create tables and load into its data.\nSpring Boot provides an easy way to load initial SQL queries to insert registries in our database.\nHere we are going to understand how to initialize data with SQL files that Spring can load when it is starting.\u003c/p\u003e","title":"Spring Boot Init Database"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/database/","section":"Tags","summary":"","title":"Database"},{"content":"We are going to understand how to configure Spring Boot in order to connect with an H2 Database.\nWhat is an H2 Database #H2 is a lightweight Java database.\nIt is tiny, simple, and can be embedded in our Spring Boot application easily.\nThe H2 DB does not need the installation of database servers or complex configurations. H2 Database can be used in memory, without writing data on disk.\nThis is useful for testing and temporary data storage during the development phases. It is fast, open source pure writing in Java and supports standard SQL. H2 is not recommended for data storage in production.\nWhat dependencies do we need to use H2 with Spring Boot? #We are going to use these dependencies:\n\u0026#39;org.springframework.boot:spring-boot-starter-data-jpa\u0026#39; \u0026#39;com.h2database:h2\u0026#39; Spring Boot H2 Configuration #In order to configure Spring Boot, we need to add this property in our application.properties file.\nspring.datasource.url=jdbc:h2:mem:test_h2_db spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.h2.console.enabled=true Notice that we are configuring the DB in memory.\nHow to configure H2 to persist in a file? #We said that H2 is used in memory. However, we can also configure H2 to persist in a file.\n# h2 file spring.datasource.url=jdbc:h2:file:test_h2_db # with path and file #spring.datasource.url=jdbc:h2:file:/home/dev/test_h2_db spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.h2.console.enabled=true With this config, a file will be created and the data will be persisted in that file.\nH2 URL Console #H2 provides a basic but convenient admin console with which we can visualize our database schema, tables, and data.\nBy default, the console is disabled, but with this property, you can enable it.\n#enable console spring.h2.console.enabled=true How to access to H2 GUI #When Spring Boot starts with this property evaluated in true, we will be able to see the H2 URL to access the admin console.\nIn this case, Spring Boot started in “localhost:8080” so the h2 URL is\nhttp://localhost:8080/h2-console\nIf you want, you can change the default h2 URL /h2-console with this property.\nIn the init form, you have to change the JDBC URL, username, and password according to the information in the property file.\nThe H2 interface provides you access to the database in order to visualize and perform all the SQL queries you need.\nConclusion #H2 is an excellent solution to start developing an application faster, test it, and debug it.\nWe have seen how to configure and use an H2 database in Spring Boot both, in memory and in a file. Also how to open the H2 GUI in order to visualize and run SQL sentences.\nFor further reference, please consider the following url: H2 Engine Spring Boot\nCheck the source code of this example\n","date":"Aug 18, 2022","permalink":"https://gustavopeiretti.com/spring-boot-h2-database-config/","section":"Posts","summary":"\u003cp\u003eWe are going to understand how to configure Spring Boot in order to connect with an H2 Database.\u003c/p\u003e","title":"H2 Spring Boot configuration"},{"content":"Let\u0026rsquo;s see how to leave log records in Spring Boot.\nSpring Boot has Log4j libraries and uses SLF4J. This logging framework can be used with zero configuration very quickly.\nSo let\u0026rsquo;s see how easy it is to leave log records with Spring Boot.\nHow to create logs with Spring Boot #First, create a LOG using a LoggerFactory\n// import org.slf4j.Logger; // import org.slf4j.LoggerFactory; private final Logger LOG = LoggerFactory.getLogger(LogExampleController.class); Now, you can use LOG to registry messages.\nLOG.trace(\u0026#34;A TRACE Message\u0026#34;); LOG.debug(\u0026#34;A DEBUG Message\u0026#34;); LOG.info(\u0026#34;An INFO Message\u0026#34;); LOG.warn(\u0026#34;A WARN Message\u0026#34;); LOG.error(\u0026#34;An ERROR Message\u0026#34;); // FATAL is not available in slf4j Log with SLF4J #Note that we are using LoggerFactory. This LoggerFactory is part of SLF4J\nIf we read the documentation from LoggerFactory:\nThe LoggerFactory is a utility class producing Loggers for various logging APIs, most notably for log4j, logback and JDK 1.4 logging\nIn other words, SLF4J is a facade to unify different log frameworks.\nLog with Log4j (without SLF4J) #If we wanted to use Log4j directly we would have to create the LOG in this way.\n// import org.apache.logging.log4j.LogManager; // import org.apache.logging.log4j.Logger; private static final Logger LOG = LogManager.getLogger(Log4jExampleController.class); After, use LOG to registry messages.\nLOG.trace(\u0026#34;A TRACE Message without going through SLF4J\u0026#34;); LOG.debug(\u0026#34;A DEBUG Message without going through SLF4J\u0026#34;); LOG.info(\u0026#34;An INFO Message without going through SLF4J\u0026#34;); LOG.warn(\u0026#34;A WARN Message without going through SLF4J\u0026#34;); LOG.error(\u0026#34;An ERROR Message without going through SLF4J\u0026#34;); // FATAL is available in Log4j LOG.fatal(\u0026#34;A FATAL Message without going through SLF4J\u0026#34;); Which log levels can we use? #In the log, we have different levels that we can use depending of the type of message to be logged\nTRACE: this level is used to log events in great detail, superior to DEBUG. DEBUG: this level is used for logging when you \u0026lsquo;DEBUG\u0026rsquo; your application. They are more useful to debug an application when you are developing. INFO: The INFO level is used for informative messages related to the progress of the application and general messages. WARN: The WARN level is used for situations that could be harmful or risky. ERROR: The ERROR level is used to log error events within the application. FATAL: The FATAL level is used for very severe error events that may cause the application to abort. Log Priority #The priority of logs has this order: Trace has the lowest priority and Fatal has the highest priority.\n//lowest - - - - - - - - - - - - - highest Trace \u0026lt; Debug \u0026lt; Info \u0026lt; Warn \u0026lt; Error \u0026lt; Fatal How to change the log level in Spring Boot #By default, Spring configures the logs at the Info Level.\nThis means that it will display all Info logs and those with the highest priority to Info.\nIf you do not change the configuration, Spring will show logs from Info to Fatal\nIf we execute this Controller \u0026lsquo;http://localhost:8080/log\u0026rsquo;\nimport org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class LogExampleController { private final Logger LOG = LoggerFactory.getLogger(LogExampleController.class); @GetMapping(\u0026#34;/log\u0026#34;) public String logExample() { LOG.trace(\u0026#34;A TRACE Message\u0026#34;); LOG.debug(\u0026#34;A DEBUG Message\u0026#34;); LOG.info(\u0026#34;An INFO Message\u0026#34;); LOG.warn(\u0026#34;A WARN Message\u0026#34;); LOG.error(\u0026#34;An ERROR Message\u0026#34;); return \u0026#34;Hello Log\u0026#34;; } } The output console looks like that\nTo change the level, use the property file by setting the starting level\nlogging.level.root=ERROR Logs lower than ERROR will be discarded.\nHow to write log in a file #If you want to write logs into a file, you can add this property logging.file.name\nThis will create a file ‘logfile.log’.\nlogging.file.name=logfile.log Executing the controller /log with log level INFO. The file will be created as shown below\nRolling log files #Rolling log files means that log files will be recreated under some criteria.\nThis is useful to avoid having large files or log files with old information that is no longer necessary\nYou have to declare the following property logging.logback.rollingpolicy.file-name-patter in your application.properties file to activate the rolling file.\nWith this property, a new file will be created every day and the previous one will be renamed.\nlogging.file.name=logfile.log logging.logback.rollingpolicy.file-name-pattern=logfile-%d{yyyy-MM-dd}.%i.log Example, output for old files:\nlogfile.log ← current log file logfile-2022-08-10.0.log ← files from previous days logfile-2022-08-08.0.log logfile-2022-08-07.0.log Max size #This will set the maximum log file size to 1MB. If this size is exceeded, a new log file will be created. The default size is 10MB.\nlogging.file.name=logfile.log logging.logback.rollingpolicy.file-name-pattern=logfile-%d{yyyy-MM-dd}.%i.log logging.logback.rollingpolicy.max-file-size=1MB Example, output files:\nlogfile.log ← current log file, less than 1MB logfile-2022-08-11.0.log ← Log of the day. Reached 1MB logfile-2022-08-11.1.log ← Log of the day. Reached 1MB There are other properties that are very useful that I often use.\nlogging.logback.rollingpolicy.max-history ← Maximum number of archive log files to keep. (default 7) logging.logback.rollingpolicy.total-size-cap ← Total size of log backups to be kept. Please check the official documentation for the other properties.\nhttps://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html\nConclusion #We have learned how to create log files with Spring Boot that we can use during our developing task or during production execution.\nWe understood the different levels of logs also how to create files with these registries.\nThis code is in GitHub Spring Boot Code examples\n","date":"Aug 11, 2022","permalink":"https://gustavopeiretti.com/logging-with-spring-boot/","section":"Posts","summary":"\u003cp\u003eLet\u0026rsquo;s see how to leave log records in Spring Boot.\u003c/p\u003e","title":"Logging with Spring Boot"},{"content":"In this post, we will understand how to send an email with Spring Boot.\nThe dependency necessary #In order to send an email, you need this dependency\nbuild.gradle\nimplementation \u0026#39;org.springframework.boot:spring-boot-starter-mail\u0026#39; testImplementation \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; The configuration for sending emails in Spring #We need to define the JavaMailSender if we want to set the properties programmatically.\nYou can use JavaMailSenderImpl which implements JavaMailSender to define the mail server configuration. For example, for Gmail, the configuration could look like this:\nimport org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.JavaMailSenderImpl; import java.util.Properties; @Configuration public class MailSenderConfig { @Bean(\u0026#34;javaMailSender\u0026#34;) public JavaMailSender javaMailSender() { JavaMailSenderImpl sender = new JavaMailSenderImpl(); sender.setHost(\u0026#34;smtp.gmail.com\u0026#34;); sender.setPort(587); sender.setUsername(\u0026#34;user@gmail.com\u0026#34;); sender.setPassword(\u0026#34;password\u0026#34;); Properties props = sender.getJavaMailProperties(); props.put(\u0026#34;mail.transport.protocol\u0026#34;, \u0026#34;smtp\u0026#34;); props.put(\u0026#34;mail.smtp.auth\u0026#34;, \u0026#34;true\u0026#34;); props.put(\u0026#34;mail.smtp.starttls.enable\u0026#34;, \u0026#34;true\u0026#34;); props.put(\u0026#34;mail.debug\u0026#34;, \u0026#34;true\u0026#34;); return sender; } } Note. To use Google SMTP services you need to create a unique \u0026ldquo;app password\u0026rdquo; for the service.\nhttps://support.google.com/accounts/answer/185833?hl=en\nConfiguration using properties for sending e-mails in Spring #In the previous section, we defined the configuration by loading the properties in JavaMailSenderImpl class.\nHowever, we can skip this and define the properties directly in the http://application.properties file.\nIf you only set the properties, without creating the ‘bean config’, Spring will create the JavaMailSenderImpl for you.\nspring.mail.host=smtp.gmail.com spring.mail.port=587 spring.mail.username=user@gmail.com spring.mail.password=password spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true Sending an email with Spring #You can send a simple email, only text. #The SimpleMailMessage class provides a simple model for sending text-only messages.\nSimpleMailMessage message = new SimpleMailMessage(); message.setFrom(from); message.setTo(to); message.setSubject(subject); message.setText(text); mailSender.send(message); Also, you can send an email with attached files. #To send e-mails with attachments you need two classes.\nMimeMessage allows the addition of attachments and MimeMessageHelper helps us create the mail.\nMimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(text); helper.addAttachment(attachName, inputStream); mailSender.send(message); If you want, you can add HTML tags.\nFor example, here we add a text with a bold HTML tag.\nMimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(\u0026#34;\u0026lt;b\u0026gt;bold message\u0026lt;/b\u0026gt;\u0026#34;, true); // text with HTML tags helper.addAttachment(attachName, inputStream); mailSender.send(message); MIME message means “Multipurpose Internet Mail Extensions”. With MIME messages you can send HTML texts, and attach files (text, audio, images, etc)\nSummary of classes involved # JavaMailSender: interface to configure Spring Email JavaMailSenderImpl: implementation of JavaMailSender SimpleMailMessage: model to complete attributes necessaries to send an email. MimeMessage: a class that represents a MIME message. MimeMessageHelper: a helper class to create a MIME message. Example of service using JavaMailSender #Here we create a service and use JavaMailSender that we define in our previous configuration.\n@Service public class EmailService { private JavaMailSender mailSender; public EmailService(JavaMailSender mailSender) { this.mailSender = mailSender; } public void send(String from, String to, String subject, String text) { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(from); message.setTo(to); message.setSubject(subject); message.setText(text); mailSender.send(message); } public void sendWithAttach(String from, String to, String subject, String text, String attachName, InputStreamSource inputStream) throws MessagingException { MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(text, true); helper.addAttachment(attachName, inputStream); mailSender.send(message); } } Testing our Email Service #In order to check the functionality of our service we are going to use https://greenmail-mail-test.github.io/greenmail/\nGreenMail is an open-source framework that provides servers for testing our mail services.\nbuild.gradle\nimplementation \u0026#39;org.springframework.boot:spring-boot-starter-mail\u0026#39; testImplementation \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; testImplementation \u0026#39;com.icegreen:greenmail-junit5:1.6.9\u0026#39; We will define the properties to test with GreenMail.\n## test properties for test email Greenmail spring.mail.host=localhost spring.mail.port=3025 spring.mail.username=user@gmail.com spring.mail.password=password Email Service Test using GreenMail to validate EmailService\nimport com.icegreen.greenmail.configuration.GreenMailConfiguration; import com.icegreen.greenmail.junit5.GreenMailExtension; import com.icegreen.greenmail.util.ServerSetupTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import javax.mail.internet.MimeMessage; import java.io.File; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest class EmailServiceTest { @RegisterExtension static GreenMailExtension greenMail = new GreenMailExtension(ServerSetupTest.SMTP) .withConfiguration(GreenMailConfiguration .aConfig().withUser(\u0026#34;user@gmail.com\u0026#34;, \u0026#34;password\u0026#34;)); @Autowired private EmailService emailService; @Test void send() throws Exception { emailService.send(\u0026#34;gus@gmail.com\u0026#34;, \u0026#34;jhon@gmail.com\u0026#34;, \u0026#34;Hello\u0026#34;, \u0026#34;How are you?\u0026#34;); MimeMessage[] receivedMessages = greenMail.getReceivedMessages(); MimeMessage receivedMessage = receivedMessages[0]; assertEquals(\u0026#34;gus@gmail.com\u0026#34;, receivedMessage.getFrom()[0].toString()); assertEquals(\u0026#34;jhon@gmail.com\u0026#34;, receivedMessage.getAllRecipients()[0].toString()); assertEquals(\u0026#34;Hello\u0026#34;, receivedMessage.getSubject().trim()); assertEquals(\u0026#34;How are you?\u0026#34;, receivedMessage.getContent().toString().trim()); // others test assertions with receivedMessage.. } @Test void sendWithAttach() throws Exception { ClassPathResource classPathResource = new ClassPathResource(\u0026#34;info.txt\u0026#34;); File file = classPathResource.getFile(); FileSystemResource fileResource = new FileSystemResource(file); emailService.sendWithAttach(\u0026#34;gus@gmail.com\u0026#34;, \u0026#34;jhon@gmail.com\u0026#34;, \u0026#34;Hello\u0026#34;, \u0026#34;How are you?\u0026#34;, \u0026#34;info.txt\u0026#34;, fileResource); MimeMessage[] receivedMessages = greenMail.getReceivedMessages(); MimeMessage receivedMessage = receivedMessages[0]; assertEquals(\u0026#34;gus@gmail.com\u0026#34;, receivedMessage.getFrom()[0].toString()); assertEquals(\u0026#34;jhon@gmail.com\u0026#34;, receivedMessage.getAllRecipients()[0].toString()); assertEquals(\u0026#34;Hello\u0026#34;, receivedMessage.getSubject().trim()); // others test assertions with receivedMessage.. } } Conclusion: #In this post we learn how to configure the Java Email Sender with Spring Boot using \u0026lsquo;beans\u0026rsquo; configuration and property files. We also understood how to create a JUnit test with GreenMail.\nThe code : #As always you can see this code in GitHub. https://github.com/gustavopeiretti/spring-boot-examples/tree/master/spring-boot-email\n","date":"Jul 25, 2022","permalink":"https://gustavopeiretti.com/spring-boot-send-emails/","section":"Posts","summary":"\u003cp\u003eIn this post, we will understand how to send an email with Spring Boot.\u003c/p\u003e","title":"How to send emails with Spring Boot"},{"content":"Spring Boot allows you to connect a database simply with minimal configuration. Let\u0026rsquo;s see in this post how to connect to a database.\nHow to connect Spring Boot with database #You can create a database connection in Spring Boot with a few steps.\nDefine the database you are going to use. Include dependencies. Define connection settings in the property file. Define the database #In this example, we will use MySql, but the configuration applies to any database.\nThe only difference is the dependency necessary to connect your database with your service.\nDependencies to create a database connection in Spring Boot #To create a DB connection, you need the following dependencies.\nFor MySql you need:\n\u0026#39;mysql:mysql-connector-java:8.0.28\u0026#39; For PostgreSQL:\n\u0026#39;org.postgresql:postgresql\u0026#39; For Oracle:\n\u0026#39;com.oracle.database.jdbc:ojdbc8\u0026#39; For MSSQL:\n\u0026#39;com.microsoft.sqlserver:mssql-jdbc\u0026#39; Database connection settings in the property File #In these properties, we first set the connection path to the DB. Then we indicate the user and the password. With this minimal configuration and the dependency, it is enough for Spring to understand how to connect.\nThe minimum configuration to connect to a database is as follows:\nFor MySql:\nspring.datasource.url=jdbc:mysql://localhost:3306/your_database spring.datasource.username=your_user spring.datasource.password=your_password For PostgreSQL:\nspring.datasource.url=jdbc:postgresql://localhost:5432/your_database spring.datasource.username=your_user spring.datasource.password=your_password For Oracle:\nspring.datasource.url=jdbc:oracle://localhost:1521/your_database spring.datasource.username=your_user spring.datasource.password=your_password MSSQL:\nspring.datasource.url=jdbc:sqlserver://localhost:1433/your_database spring.datasource.username=your_user spring.datasource.password=your_password *Note that the port and url may change depending on the installation of each database.\nSpring can create the tables for you #If you want to delegate the creation of tables to Spring you can do it adding one property.\nspring.jpa.hibernate.ddl-auto=create This setting tells Spring whether to create the tables from the entities we have created.\nThis article explains more about this property.\nnone: no action will be performed. drop: the tables will be created from the entities and at the end, they will be deleted. create: the tables will be deleted and then created update: performs an update of the schema from the entities. validate: only performs a validation between the entities and the database schema. Let\u0026rsquo;s zoom in on this property \u0026ldquo;spring.jpa.hibernate.ddl-auto\u0026rdquo;\nIf we define this property as “create” Spring will destroy all tables and then create all of them.\nIn order to understand more about entities, review this other post\nFor example for this entity. Spring will do the following\nObserve in the Spring console what happens with this \u0026ldquo;create\u0026rdquo; configuration.\nIn order to see the Spring SQL sentences in the console, you need this configuration\nspring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true Conclusion #In this post, we learn how to configure a connection to a database and how to delegate the creation of database/tables to Spring.\n","date":"Jun 23, 2022","permalink":"https://gustavopeiretti.com/spring-boot-database-connection-config/","section":"Posts","summary":"\u003cp\u003eSpring Boot allows you to connect a database simply with minimal configuration.\nLet\u0026rsquo;s see in this post how to connect to a database.\u003c/p\u003e","title":"How to connect SpringBoot with Databases"},{"content":"An entity is the representation of information that we need in our application.\nThis entity could be a user, a product, or any data that our application needs to keep persistently to retrieve when needed.\nWhat is an entity for SpringBoot #An entity is an object, element, or \u0026rsquo;thing\u0026rsquo; with particular attributes that distinguish it. For example, it could be a \u0026lsquo;user\u0026rsquo; of which we need to know its attributes such as names, age, email, etc.\nHow to define an entity in SpringBoot #Let\u0026rsquo;s think of a simple entity. For example, an entity to store the users of the application.\nPay attention to these points in this example of entity:\nYou define the entity with an annotation @Entity It is necessary a primary key (PK) with @ID The value of this PK is generated automatically with this annotation @GeneratedValue with params AUTO There are others optional annotations that you can use. For example, you can add:\n@Table to define explicitly the name of the table. @Column to define the name of the column. If you don\u0026rsquo;t use these annotations (Table, Column), Spring will decide by convention those names.\nHow to use an entity in Spring Boot #Spring\u0026rsquo;s primary use entities to recognize wish classes represents the \u0026lsquo;model\u0026rsquo; of data. With this, Spring can perform the usual action with the database, such as insert, delete, search, etc.\nProbably the most common use is with repositories. Please, review this article in order to understand about repositories.\nOne to Many and Many to One Entity Relation #An entity may have one or more than one relationship with another entity.\nLet\u0026rsquo;s suppose we have as the entity \u0026lsquo;User\u0026rsquo; and the entity \u0026lsquo;Task\u0026rsquo; in own application. A User can perform \u0026lsquo;one or many\u0026rsquo; Task\nSQL CREATE TABLE Statement for one-to-many / manu-to-one Relation How to define a \u0026lsquo;one to many\u0026rsquo; between two entities?\nIn the first entity, you have to create a \u0026rsquo;list of Tasks\u0026rsquo; and annotate it with @OneToMany.\nUsing mappedBy we indicate that the relationship is unidirectional. In other words, a \u0026lsquo;User\u0026rsquo; has many \u0026lsquo;Tasks\u0026rsquo;, but one task will not have many users. How to define a \u0026lsquo;many to one\u0026rsquo; between two entities?\nIn the second entity, you have to create a reference to \u0026lsquo;User\u0026rsquo; and annotate with @ManyToOne\n@JoinColumn refers to the column that will establish the relationship with the user. One to One Entity Relation #In a One-to-One relationship we have an attribute on one entity that references another entity. A one-to-many or many-to-one relationship is not possible here.\nWe will have an object that contains a reference to another object.\nSQL CREATE TABLE Statement for one-to-one Relation In the first entity \u0026lsquo;User\u0026rsquo; you have to declare an \u0026lsquo;UserDetail\u0026rsquo; attribute.\nIn the second entity \u0026lsquo;UserDetail\u0026rsquo;, you declare which will be the column that will relate it to the \u0026lsquo;User\u0026rsquo;.\nNote, you have to indicate the column like \u0026lsquo;unique\u0026rsquo;. With that, you don\u0026rsquo;t have more than one \u0026lsquo;UserDetail\u0026rsquo; per User. To constrain 1-1 relationship between tables and do not allow more than UserDetail record per User.\nIn summary: # @OneToMany. Define a one-to-many relationship. mappedBy. Indicate which entity owns the one-to-many relationship uniquely. @ManyToOne. You use it to define the many-to-one relationship. @JoinColumn. To define the column that will be used as a key to achieving the relationship to the main entity. @OneToOne. Define a one-to-one relationship. unique = true. To create unique constrain Conclusion #We learned how to create entities and how to map two entities to each other using one-to-many, many-to-one, one-to-one relationships.\n","date":"Apr 6, 2022","permalink":"https://gustavopeiretti.com/spring-boot-entities-initial-concepts/","section":"Posts","summary":"\u003cp\u003eAn entity is the representation of information that we need in our application.\u003c/p\u003e\n\u003cp\u003eThis entity could be a user, a product, or any data that our application needs to keep persistently to retrieve when needed.\u003c/p\u003e","title":"Spring Boot Entities"},{"content":"In Java, we can use native libraries to create RSA public and private keys. We will create, store, and load public and private keys in this example.\nHow to create public and private RSA Keys with Java #The algorithm RSA consists of three steps: key generation, encryption and decryption\nUse KeyPairGenerator to generate a pair of keys. Get the keys and save Load keys and use to encrypt and decrypt Create Key Pair. Private and Public #Returns a KeyPairGenerator object that generates public/private key pairs for the specified algorithm RSA. Initializes the key pair generator for a certain keysize. In this case the generated key will have a size of 2048 bits.\nKeyPairGenerator kpg = KeyPairGenerator.getInstance(\u0026#34;RSA\u0026#34;); kpg.initialize(2048); Once you have initialized, you can create a key pair.\nKeyPair kp = kpg.generateKeyPair(); PrivateKey aPrivate = kp.getPrivate(); PublicKey aPublic = kp.getPublic(); Save Private and Public #Now, you save the keys\ntry (FileOutputStream outPrivate = new FileOutputStream(\u0026#34;key.priv\u0026#34;)) { outPrivate.write(aPrivate.getEncoded()); } try (FileOutputStream outPublic = new FileOutputStream(\u0026#34;key.pub\u0026#34;)) { outPublic.write(aPublic.getEncoded()); } Information about the keys. In the output of the console you can see that the keys are created in these codifications.\nPKCS#8 X.509 System.out.println(\u0026#34;Private key: \u0026#34; + aPrivate.getFormat()); System.out.println(\u0026#34;Public key: \u0026#34; + aPublic.getFormat()); // output.. // Private key: PKCS#8 // Public key: X.509 Load Private and Public keys #To read the key files, you need the bytes of the file. From there you must use PKCS8EncodedKeySpec to read the private key and X509EncodedKeySpec for the public key. Note that PKCS8EncodedKeySpec and X509EncodedKeySpec corresponds to the encoding you obtained previously.\nLoad Private Key in PrivateKey using KeyFactory\nFile privateKeyFile = new File(\u0026#34;key.priv\u0026#34;); byte[] privateKeyBytes = Files.readAllBytes(privateKeyFile.toPath()); KeyFactory privateKeyFactory = KeyFactory.getInstance(\u0026#34;RSA\u0026#34;); EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); PrivateKey privateKey = privateKeyFactory.generatePrivate(privateKeySpec); Load Public Key in PublicKey using KeyFactory\nFile publicKeyFile = new File(\u0026#34;key.pub\u0026#34;); byte[] publicKeyBytes = Files.readAllBytes(publicKeyFile.toPath()); KeyFactory publicKeyFactory = KeyFactory.getInstance(\u0026#34;RSA\u0026#34;); EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes); PublicKey publicKey = publicKeyFactory.generatePublic(publicKeySpec); Running this code #Both files are created at the root of the project. Then, you can move them where you need to use them.\nConclusion #In this post, you learned how to create RSA keys using Java standard libraries. If you want to learn how to encrypt and decrypt using those keys visit this article.\nYou can see this code in GitHub\n","date":"Mar 23, 2022","permalink":"https://gustavopeiretti.com/rsa-keys-java/","section":"Posts","summary":"\u003cp\u003eIn Java, we can use native libraries to create RSA public and private keys.\nWe will create, store, and load public and private keys in this example.\u003c/p\u003e","title":"How to generate RSA keys with Java"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/java/","section":"Tags","summary":"","title":"Java"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/categories/java-core/","section":"Categories","summary":"","title":"Java Core"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/security/","section":"Tags","summary":"","title":"Security"},{"content":"In this article we are going to use public and private RSA keys for encryption and decryption.\nHow to encrypt and decrypt RSA encryption algorithm with Java #The first thing you have to do is to read the keys.\nRead public key and use it to encryption. Read private key and use it to decryption. Review the previous article about how to create public and private RSA Keys with Java\nThe process to encrypt or decrypt #For encrypting and decrypting you need:\nLoad de key using KeyFactory Create a Cipher instance with de algorithm (in this example RSA) Define the mode and set the key. Call to cipher.doFinal to encrypt or decrypt. Load public key and encrypt with RSA #To load a public RSA key you have to use KeyFactory class and know how the file had encoded. The typically encode is X509.\nprivate PublicKey loadPublicKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { // reading from resource folder byte[] publicKeyBytes = getClass().getResourceAsStream(\u0026#34;/key.pub\u0026#34;).readAllBytes(); KeyFactory publicKeyFactory = KeyFactory.getInstance(\u0026#34;RSA\u0026#34;); EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes); PublicKey publicKey = publicKeyFactory.generatePublic(publicKeySpec); return publicKey; } Now, with this public key you can encrypt. In this case, you are going to encrypt a text.\npublic String encode(String toEncode) throws Exception { PublicKey publicKey = loadPublicKey(); Cipher cipher = Cipher.getInstance(\u0026#34;RSA\u0026#34;); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] bytes = cipher.doFinal(toEncode.getBytes(StandardCharsets.UTF_8)); return new String(Base64.getEncoder().encode(bytes)); } Load private key and decrypt with RSA #To load a private RSA key you have to use KeyFactory class and know how the file had encoded. The typically encode for decrypt is PKCS8.\nprivate PrivateKey loadPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { // reading from resource folder byte[] privateKeyBytes = getClass().getResourceAsStream(\u0026#34;/key.priv\u0026#34;).readAllBytes(); KeyFactory privateKeyFactory = KeyFactory.getInstance(\u0026#34;RSA\u0026#34;); EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); PrivateKey privateKey = privateKeyFactory.generatePrivate(privateKeySpec); return privateKey; } With this private key you can decrypt a text that was encrypted with the private pair.\npublic String decode(String toDecode) throws Exception { PrivateKey privateKey = loadPrivateKey(); Cipher cipher = Cipher.getInstance(\u0026#34;RSA\u0026#34;); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] bytes = cipher.doFinal(Base64.getDecoder().decode(toDecode)); return new String(bytes); } Running the example # Conclusion #In this post, you learned how to use RSA keys to encrypt and decrypt. If you want to learn how to create RSA keys with standard Java libraries this article.\nYou can see this code in GitHub\n","date":"Mar 22, 2022","permalink":"https://gustavopeiretti.com/rsa-encrypt-decrypt-java/","section":"Posts","summary":"\u003cp\u003eIn this article we are going to use public and private RSA keys for encryption and decryption.\u003c/p\u003e","title":"How to Encrypt and Decrypt using RSA keys with Java"},{"content":"In this post we will understand what a Repository Component is and how to create a CrudRepository in Spring Boot.\nWhat is a Repository component #A @Repository is a Spring component and stereotype that is part of the \u0026lsquo;persistence layer\u0026rsquo;. The persistence layer is the way our microservice stores and retrieves the entities it needs.\nAn entity is the class of our application that represents an object of your business, for example a User, Customer, Product, etc.\nIf our application needs a User (user with his first name, last name, date of birth) and needs to store it, this User is an entity of our domain model and is part of the persistence layer.\nA microservice is divided into layers, being the repository the persistence layer that has access to the data and can manipulate it.\nRead this other article where we have worked with the Components and Stereotypes in Spring Boot\nHow do we create the Repository component? #In Spring a \u0026lsquo;Repository\u0026rsquo; is the component in charge of resolving the access to the data of our microservice. If we need to save, modify, delete records of a \u0026lsquo;User\u0026rsquo; of the system; then the UserRepository component will be in charge of making direct changes on the User records.\nSpring provides us with the basic functionality to store, delete and search entities. For this we have all the interfaces that extend \u0026ldquo;org.springframework.data.repository.Repository\u0026rdquo;.\nFor our User entity we can think of the basic operations to create, modify and search (CRUD).\nCRUD is an acronym that refers to the four minimum functions on an entity \u0026ndash;\u0026gt; Create, Read, Update, Delete.\nOur entity looks like this:\n@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private String surname; private LocalDate birthDate; // sets, gets... CrudRepository #Let\u0026rsquo;s create an interface UserRepository that will extend CrudRepository.\nWe annotate the class \u0026lsquo;UserRepository\u0026rsquo; as a @Repository component.\nCrudRepository is a generic interface that receives two types. The first is the class that this interface will handle, and the second is the data type of the entity\u0026rsquo;s ID.\nThe methods provided by CrudRepository are:\nsave: saves an entity saveAll: saves the entities of an iterable list findById: searches for the identifier existsById: checks if an identifier exists findAll: returns all elements for the entity findAllById: searches for all elements having the identifier count: returns the total number of records for the entity deleteById: deletes a record for the identifier delete: deletes the entity deleteAllById: deletes all the elements corresponding to the id deleteAll(Iterable): deletes all the elements received in the parameter deleteAll(): deletes all elements Notice, that we do NOT implement the interface. We create a new interface and extend CrudRepository. Spring will be in charge of the implementation of the interface with the concrete class.\nOur UserRepository interface that extends CrudRepository.\nimport com.example.springbootcourse.model.User; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends CrudRepository\u0026lt;User, Long\u0026gt; { } With this we have already created our repository with the CRUD operations for our entity. We can use them from our service\nJPARepository #JPARepository inherits all CrudRepository methods. Therefore, we can use all the methods of the CrudRepository interface. Also, JPARepository inherits from PagingAndSortingRepository, with methods for find with sort and paging.\nJPARepository also adds other methods. JPARepository api.\nsaveAndFlush: saves an entity and flushes changes instantly. flush: flushes all pending changes to the database. saveAllAndFlush: saves all entities and flushes changes instantly. deleteAllInBatch: deletes the given entities in a batch deleteAllByIdInBatch: deletes the entities identifier deleteAllInBatch: deletes all entities in a batch getById: returns a reference to the entity with the given identifier findAll(Sort): returns all entities sorted findAll(Pageable): returns a Page of entities Custom method queries #In all @Repository, we can create a \u0026ldquo;custom query methods\u0026rdquo;. Spring automatically generates sql queries using the method name.\nFor example, this method will automatically generate this query:\n@Repository public interface UserRepository extends CrudRepository\u0026lt;User, Long\u0026gt; { List\u0026lt;User\u0026gt; findUserByNameAndBirthDate(String name, LocalDate birthDate); // result -\u0026gt; select u from User u where u.name = ? and u.birthdate = ?; } Observe, we created the methods using the names of the attributes of our \u0026lsquo;User\u0026rsquo; entity. In this case, we want to use \u0026ldquo;and\u0026rdquo; en our query.\nIt is possible to create queries with the most common SQL statements. Please, check\nSpring Query Methods\nConclusion #In this article we learned what is Repository in SpringBoot, and we created a CRUD using the Repository interface.\n","date":"Dec 1, 2021","permalink":"https://gustavopeiretti.com/spring-boot-repository-component/","section":"Posts","summary":"\u003cp\u003eIn this post we will understand what a Repository Component is and how to create a CrudRepository in Spring Boot.\u003c/p\u003e","title":"The Repository component in Spring Boot"},{"content":"In this post we will understand what a Service component is and how it is created in Spring Boot.\nWhat is a Service component #In this other article we learned about the Components and Stereotypes in Spring Boot\nWe understood that a @Service is a Spring component and stereotype that is part of \u0026rsquo;the service layer'.\nA microservice is divided into layers. The service is in the middle layer and contains the business logic.\nA \u0026lsquo;Service\u0026rsquo; component is the component in charge of solving the business logic within our application. If we have in our service to manage, for example, a \u0026lsquo;user\u0026rsquo; of the system; then the UserService component will be in charge of incorporating the functionalities in its methods.\nHow do we create the Service component? #What we need to do is to think about the operations we need to perform on our User and create the methods for that purpose. For this example, we will think about the basic operations to create, modify and search that we call CRUD.\nCRUD is an acronym that refers to the four minimum functions on an entity \u0026ndash;\u0026gt; Create, Read, Update, Delete.\nWe annotate the class \u0026lsquo;UserService\u0026rsquo; as @Service.\n@Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public User create(User user) { return userRepository.save(user); } public User update(User user) { return userRepository.save(user); } public User change(User user) { return userRepository.save(user); } public boolean remove(long id) { if (userRepository.existsById(id)) { userRepository.deleteById(id); return true; } else { return false; } } public Optional\u0026lt;User\u0026gt; find(long id) { return userRepository.findById(id); } } We see that our service delegates in another component, the Repository, the direct access to the data. The detail of this repository can be seen in another article.\nFrom a controller that we create we call the functionalities of the service.\nWe start our application to test. Read this article where I explain how to create the main application in Spring Boot and start it.\ngradlew booRun @RestController public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @GetMapping(\u0026#34;/api/user/{id}\u0026#34;) public User byId(@PathVariable(\u0026#34;id\u0026#34;) int id) { return userService.find(id).orElseThrow(); } @PostMapping(\u0026#34;/api/user/\u0026#34;) public User create(@RequestBody User user) { return userService.create(user); } @PutMapping(\u0026#34;/api/user/\u0026#34;) public User update(@RequestBody User user) { return userService.update(user); } @PatchMapping(\u0026#34;/api/user/\u0026#34;) public User change(@RequestBody User user) { return userService.change(user); } @DeleteMapping(\u0026#34;/api/user/{id}\u0026#34;) public boolean delete(@PathVariable(\u0026#34;id\u0026#34;) int id) { return userService.remove(id); } } We create, search and delete a user from the controller that calls the service.\nConclusion #In this article we learned how to create a Service in SpringBoot, and we understood the purpose of the @Service component in a Rest application.\n","date":"Nov 26, 2021","permalink":"https://gustavopeiretti.com/spring-boot-service-component/","section":"Posts","summary":"\u003cp\u003eIn this post we will understand what a Service component is and how it is created in Spring Boot.\u003c/p\u003e","title":"The Service component in Spring Boot"},{"content":"To create a Spring Boot project, we can use the IntelliJ wizard.\nCreate a SpringBoot project with Intellij #This option is for IntelliJ Ultimate. If you don\u0026rsquo;t have IntelliJ Ultimate, you can use Spring Initializr. We have another way to create projects easily using Intellij.\nIntelliJ has different options:\nChoose whether we will use Maven or Gradle for building our project. The versions of Spring and Java we will use. The data of your project for the group and the artifact. The dependencies you need. From the command line we can start the application.\ngradlew bootRun We can also use IntelliJ to start the application. For this we open the Spring Boot main class and from the main we start our application.\nConclusion #IntelliJ has the tools to simplify the initial creation and dependencies of your Spring Boot project.\n","date":"Nov 24, 2021","permalink":"https://gustavopeiretti.com/create-project-spring-boot-intellij/","section":"Posts","summary":"\u003cp\u003eTo create a Spring Boot project, we can use the IntelliJ wizard.\u003c/p\u003e","title":"How to create a Spring Boot Project with Intellij"},{"content":"To create a project in Spring Boot we can use \u0026lsquo;Spring Initializr\u0026rsquo; utility.\nSpring Initializr #Spring Initializr is a Spring tool that helps us to create an initial project, from scratch, by choosing in a simple way the dependencies we need. We open the site Spring Initializr\nThere we have multiple options:\nChoose whether we will use Maven or Gradle to build our project. The versions of Spring and Java we will use. The data of your project for the group and the artifact. The dependencies you need. For our project we will choose Gradle and the Spring Web dependency. Once you have chosen the options you can browse to preview your build.gradle and how your project will look like. In the GENERATE option you download the .zip file of the project ready to use.\nDownload the file and unzip it.\nWe open it with our IDE, in my case Intellij\nFrom the command line we can run the application.\ngradlew bootRun Conclusion #Spring Initializr is a tool that simplifies the initial creation and dependencies of your project.\nReferences #Spring Initializr GitHub\n","date":"Nov 15, 2021","permalink":"https://gustavopeiretti.com/create-project-spring-boot-initilizr/","section":"Posts","summary":"\u003cp\u003eTo create a project in Spring Boot we can use \u0026lsquo;Spring Initializr\u0026rsquo; utility.\u003c/p\u003e","title":"How to create a Spring Boot Project with Spring Initilizr"},{"content":"Spring Boot manages a properties file to carry general application settings.\nWhere is the application.properties file located? #The properties file is located in the src/main/resources folder of our application. This file allows us to configure Spring and define our own configurations for our application.\nThere are a large number of properties that can be set, we can see a list here. Note that there are sixteen categories that classify the properties, ranging from Sprint core, through data configurations to testing. through data configurations to testing.\nAn example of our properties file might look like this:\nIn this application.properties file we are using the properties already defined by Spring to give a name to our application, change the port it runs on and give it database settings. give a name to our application, change the port on which it runs and indicate database configurations.\nThe use of a property file in YAML format #YAML is a syntax format that also serves to store properties in a hierarchical format.\nFor example, if we take the above properties to a YAML format, our application.yml file would look like this:\nConclusion #A properties file in Spring Boot allows us to configure aspects of the application and set its own parameters. and set its own parameters. We have two formats of properties, the flat .properties and the .yml that give a hierarchical format.\n","date":"Nov 10, 2021","permalink":"https://gustavopeiretti.com/properties-file-spring-boot/","section":"Posts","summary":"\u003cp\u003eSpring Boot manages a properties file to carry general application settings.\u003c/p\u003e","title":"The Properties file in Spring Boot"},{"content":"In an application developed in Spring Boot we must be careful to order and structure the packages in a correct and understandable way. We will see the most standardized way to order packages in Spring Boot.\nHow should we order the packages in a Spring Boot application? #There is no mandatory form that Spring imposes on us for the naming and structure of our packages. However, there are recommendations, common usage and best practices.\nA good recommendation and good practice are to divide our project into layers. We can divide our project into a package for the controllers, another one for the services, the model of our data and the access to the database.\nIn another article we saw components and stereotypes . We saw that Spring proposes a division into Controller, Service, _Repository proposes a division into Controller, Service, Repository to order our code.\nTaking advantage of this we can create the packages for each stereotype in this way.\nController package for all the endpoints that our application has. Service package to add there classes that respond to the functionality and logic. Model package for the representations of our data model (entities). Repository package for the classes that establish the communication with the database. Our project would look like this.\n/\nIn addition to these packages for our classes we see other folders for the resources, and the package for the tests. In the resources folder we place the properties file.\nConclusion #We saw here the usual and classic distribution in the ordering of packages. Dividing packages into layers is the most commonly used application.\n","date":"Nov 1, 2021","permalink":"https://gustavopeiretti.com/package-structure-spring-boot/","section":"Posts","summary":"\u003cp\u003eIn an application developed in Spring Boot we must be careful to order and structure the packages in a correct and understandable way.\nWe will see the most standardized way to order packages in Spring Boot.\u003c/p\u003e","title":"The package structure in a Spring Boot application"},{"content":"We will understand the concept of components within a Spring Boot application and the use of stereotypes.\nWhat is a component (@Component) #A component is what allows Spring to detect the beans and place them inside its context to be used. We learned in another post some concepts about what Spring dependency injection is. We understood the concept of a bean and saw that beans are objects managed by Spring.\nWhen we indicate that a class is a @Component, what we are doing is telling Spring that we want it to create an instance and manage it.\n@Component public class MyClass { public void doSomething() { //.. } } Spring will do the following when it starts the application:\nIt will search inside the application for the classes annotated with @Component. Create an instance of the components Leave the component in its context It will look for who needs those components and will inject them into who needs them. What are stereotypes? #Stereotypes are @Component\u0026rsquo;s extending components.\nThe most common stereotypes are:\n@Controller / @RestController @Service @Repository All of them are also @Component, but oriented to be part of a particular \u0026rsquo;layer\u0026rsquo; of our service.\nA @Controller will be part of Spring\u0026rsquo;s controllers \u0026rsquo;layer\u0026rsquo;.\nA @Service will be part of the service \u0026rsquo;layer\u0026rsquo; in charge of business functionality.\nA @Repository will be part of the persistence \u0026rsquo;layer\u0026rsquo; whose function will be data access.\nNote, for example, the @Service annotation which is an alias of an @Component. The same is true for the rest of the stereotypes.\nHow to use @Controller, @Service, @Repository components #Recall that a rest controller is also a controller. We have several ways to use the components in our classes.\nReference by constructor: #Once we have created the components, we have several ways to require them.\nOne of them and the recommended one is through the constructor.\nSpring, when creating the instance, will recognize that this class needs another component in its constructor and will build the class using the required component. Note that the use of @Autowired is not necessary in this case.\nReference by attribute with @Autowired: #We can also reference a dependency by using the attributes using the @Autowired annotation.\nAutowired will load the attribute with the component using reflection.\nReference by setter with @Autowired: #In addition to the reference by constructor and by attributes, it is possible to add references in a set methods.\nConclusion #In this article, we learned what it is and how to use a Component in Spring and its stereotypes @Controller, @Service, @Repository to create a Rest application in Spring Boot.\nVisit these other posts where about services and repositories.\n","date":"Oct 22, 2021","permalink":"https://gustavopeiretti.com/spring-boot-components-stereotypes/","section":"Posts","summary":"\u003cp\u003eWe will understand the concept of components within a Spring Boot application and the use of stereotypes.\u003c/p\u003e","title":"What are Components and Stereotypes in Spring Boot?"},{"content":"In this post, we will understand what a controller is and how to create a controller in Spring Boot.\nWhat is a Rest Controller #A controller is a Spring component capable of receiving http requests and responding to them.\nThe classes we define as a controller is responsible for processing the requests that enter our application, validate them and give a response.\nA rest controller is a type of controller that receives requests with a specific format that complies with RESTful request formats usually and mostly in JSON , although sometimes others such as HTML, XML, or simply text are used.\nHow to create a RestController with Spring Boot #The first step to create a \u0026lsquo;rest controller\u0026rsquo; is to annotate the class with @RestController. With this annotation, Spring already knows that this class will be a component in charge of receiving calls.\n@RestController public class HelloWordController { } Once we have annotated the class, we can define the method, and the path in which it will receive the external call.\nWe write down the method that gives answer with @GetMapping, and we indicate the path in which it will answer. Here we define the path \u0026ldquo;/hello\u0026rdquo;.\n@RestController public class HelloWordController { @GetMapping(\u0026#34;/hello\u0026#34;) public String sayHello() { return \u0026#34;Hello dev\u0026#34;; } } We start the application.\ngradlew booRun You can read this article where I explain the Spring Boot main and how to start it\nNow we can invoke our RestController by a call on the path \u0026lsquo;/hello\u0026rsquo; that we defined previously.\nThe service raises on \u0026rsquo;localhost:8080\u0026rsquo; and the path is \u0026lsquo;/hello\u0026rsquo;. We see the response \u0026lsquo;Hello dev\u0026rsquo;.\nTypes of mappings in a Spring Boot rest controller #At the previous point, we created a mapping for the path \u0026lsquo;/hello\u0026rsquo; . We define this mapping as a @GetMapping.\nHowever, we should know that there are other types of mapping in Spring Boot.\nIn the methods of a mapping we can use:\nGet: to request information from a resource. Post: to send information to create or update a resource. Put: to send information to modify a resource. Patch: to update a part of the resource. Delete: to delete a specific resource. What is the difference between Post, Put, Patch?\nUsually, the difference between Post and Put is that Post is used to add a resource and Put is used to modify a particular resource.\nPatch is also used to update a resource but only a partiality of it.\nSpring Boot mapping examples #Next we see simple examples of mapping.\nFor the GetMapping case we are requesting by an id to the User resource. In order to receive this id we use PathVariable.\nFor PostMapping, PutMapping, PatchMapping we receive a request with the body of the User that we want to insert or update.\nThe use of RequestBody allows Spring to understand the info we send body of the request.\nIn the DeleteMapping we also receive id that identifies the object to delete and returns true / false depending on whether it could be deleted or not.\n@RestController public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @GetMapping(\u0026#34;/api/user/{id}\u0026#34;) public User byId(@PathVariable(\u0026#34;id\u0026#34;) int id) { return userService.find(id); } @PostMapping(\u0026#34;/api/user/\u0026#34;) public User create(@RequestBody User user) { return userService.create(user); } @PutMapping(\u0026#34;/api/user/\u0026#34;) public User update(@RequestBody User user) { return userService.update(user); } @PatchMapping(\u0026#34;/api/user/\u0026#34;) public User change(@RequestBody User user) { return userService.change(user); } @DeleteMapping(\u0026#34;/api/user/{id}\u0026#34;) public boolean delete(@PathVariable(\u0026#34;id\u0026#34;) int id) { return userService.remove(id); } } How would we make the call to each route? #Let\u0026rsquo;s make some calls using Postman\nGetMapping for the path /api/user/{id} with the id to search for\nPostMapping for the /api/user/ path sending the body with the data\nPutMapping for the path /api/user/ sending the body with the data\nPatchMapping for the path /api/user/ sending the body with the data\nDeleteMapping for the path /api/user/{id} with the id to delete\nConclusion #In this article, we learned how to create a Rest Controller in SpringBoot with a path defined by us and how to invoke it.\nWe learned the use of the necessary annotations to create a controller in Spring using RestController , GetMapping, PostMapping, PutMapping, PatchMapping, DeleteMapping., DeleteMapping., PostMapping, PostMapping, PutMapping, PatchMapping, DeleteMapping.\n","date":"Oct 21, 2021","permalink":"https://gustavopeiretti.com/spring-boot-create-controller/","section":"Posts","summary":"\u003cp\u003eIn this post, we will understand what a controller is and how to create a controller in Spring Boot.\u003c/p\u003e","title":"How to create a Rest controller in Spring Boot"},{"content":"To create a web application in Spring Boot we first need to determine the minimum libraries and then create the main java of the application to start the service. We will see here how to create the Spring Boot main to start it.\nThe minimum dependency Spring Boot needs to start up #For this application we will use the spring-boot-starter-web dependency that provides the whole library package for an application that responds to web requests.\ndependencies{ implementation \u0026#39;org.springframework.boot:spring-boot-starter-web\u0026#39; testImplementation \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; } In this other post we talked about these started dependencies and their usefulness for building our services.\nSpring Boot main and its annotation #To start our application the first thing we need to do is to create a class with the main method. We annotate the class with SpringBootApplication and instruct Spring to start with SpringApplication.run(\u0026hellip;) .\nWhat does the SpringBootApplication annotation do? #If we go inside the annotation SpringBootApplication we can see that this boot annotation is the sum of the annotations SpringBootConfiguration, EnableAutoConfiguration, ComponentScan.\nSpringBootConfiguration: indicates that a class provides the configuration of the application. It is an alias of @Configuration with the difference that SpringBootConfiguration allows Spring to find the configurations automatically.\n@EnableAutoConfiguration: allows Spring Boot to automatically configure the application and register the beans for use. This autoconfiguration is applied based on application dependencies. Autoconfiguration attempts to avoid tedious configurations by using Spring\u0026rsquo;s intelligence to make decisions regarding common configurations.\nComponentScan: gives Spring the directive to do a search for all components annotated inside the packages. That is, it will search for everything annotated as @Component and its child classes (Service, Repository, Controller) registering them in their context.\nSummarizing up to this point, the @SpringBootApplication annotation instructs Spring Boot to look for @Beans from config, it also enables auto-configuration by letting Spring make decisions regarding default configurations and performs a scan for components in the application.\nHow to start the application with SpringBootApplication #Once we already have the main of the application annotated with @SpringBootApplication and with the instruction SpringApplication.run(\u0026hellip;) , it is ready to start.\nOur application looks like this.\nWe use here Gradle as dependency and application build manager.\nbuild.gradle\nplugins { id \u0026#39;org.springframework.boot\u0026#39; version \u0026#39;2.5.4\u0026#39; id \u0026#39;io.spring.dependency-management\u0026#39; version \u0026#39;1.0.11.RELEASE\u0026#39; id \u0026#39;java\u0026#39; } group = \u0026#39;com.example\u0026#39; version = \u0026#39;0.0.1-SNAPSHOT\u0026#39; sourceCompatibility = \u0026#39;11\u0026#39; repositories { mavenCentral() } dependencies { implementation \u0026#39;org.springframework.boot:spring-boot-starter-web\u0026#39; testImplementation \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; } test { useJUnitPlatform() } What command is used to start Spring Boot? #The instruction to start our Spring Boot application from the command line is gradlew booRun .\nLocated in the path where we have our application we execute gradlew booRun .\ngradlew booRun In linux ./gradlew booRun\nIn Windows gradlew booRun\nConclusion #The Spring Boot main is quite simple, with a few lines and dependencies we can create and start our Spring Boot application.\nThe SpringBootApplication annotation is used for Spring to configure the application and look for the components we need. To start the application we use gradlew booRun with gradle .\n","date":"Oct 13, 2021","permalink":"https://gustavopeiretti.com/spring-boot-create-main-class/","section":"Posts","summary":"\u003cp\u003eTo create a web application in Spring Boot we first need to determine the minimum libraries and then create the \u003cem\u003emain java\u003c/em\u003e of the application to start the service.\nWe will see here how to create the Spring Boot main to start it.\u003c/p\u003e","title":"How to create the main class in Spring Boot"},{"content":"Dependency injection is a design pattern that aims to take the responsibility of creating the instances of the classes that another object needs and supply it so that this class can use them.\nWhat is dependency injection between classes? #Usually, our classes depend on other classes to work. For example, a class that needs to look up a record in the database will need another class to look it up. Let\u0026rsquo;s think about these two classes. Let\u0026rsquo;s call the first one CassA, which is in charge of making decisions about the business, and the second one ClassB, which will be in charge of accessing the database.\nIn dependency injection, an external \u0026lsquo;someone\u0026rsquo; takes care of the dependencies that the classes need\u0026hellip;.\nThe ClassA depends on the ClassB to access the data in the database.\nHere in ClassA we would create ClassB .\nThe ClassA would be responsible for creating the ClassB.\nInversion of control in Spring #Spring handles the concept of IoC (Inversion of Control) taking care of keeping in its \u0026lsquo;context\u0026rsquo; all the instances of our application and injecting that instance to whoever needs it.\nSpring calls these instances beans .\nThe beans are the instances of the classes that are available for reuse and are managed within the Spring container.\nIoC is the work Spring does by looking for these dependencies between objects and \u0026lsquo;setting\u0026rsquo; these beans to whoever needs them.\nSpring knows what dependencies exist between instances and takes care of satisfying them.\nIt searches its beans container for the appropriate instance and adds it to the object, thus fulfilling the dependency injection.\nHow we perform dependency injection with Spring #Spring gives us different ways to inject dependencies.\nThe most common and most recommended is by using annotations.\nThe general annotation to indicate that we want a class to be managed by the Spring container is @Component.\nBy annotating our class with @Component we tell Spring that we want that class to be a bean.\nTherefore, Spring will do a new of the class and create the instance.\n@Component public class ClassB { public void doSomething() { System.out.println(\u0026#34;working\u0026#34;); } } Our class ClassA needs ClassB .\nSpring realizes this dependency because our class is a component that in turn has in its constructor the ClassB .\nSpring will create the ClassB and then when instantiating the ClassA it will pass this dependency to it in the constructor parameter.\n@Component public class ClassA { private final ClassB classB; public ClassA(ClassB classB) { this.classB = classB; } public void doSomething() { System.out.println(\u0026#34;working\u0026#34;); classB.doAnotherJob(); } } What are the advantages of Dependency Injection? #Increased cohesion and reduced coupling:\nWhenever we build an application we must think about reducing coupling between classes and increasing cohesion.\nThis means that each class should have a single responsibility, should be very specific in that responsibility, and do it well (cohesion).\nBy coupling reduction, we mean that changes in one class should not impact another.\nBy creating our classes knowing that Spring will be in charge of creating and injecting them, it frees us to focus only on the functionality of our class under construction.\nWe create our class and define its responsibilities thinking only about the scope of that class. We establish what the methods of that class will be so that they can be used by others, but without being aware of other classes.\nReuse:\nA class is intended to be reusable by whoever needs it.\nA class responsible for accessing the database can be used by others through the contract defined in its methods and be injected into all those that need access to the database.\nArchitectural changes:\nUsing interfaces allows us to make internal changes while maintaining the class contract, without affecting other classes that use it.\nTests:\nUnit testing on classes is much simpler, and mocks can be used for classes outside the scope of the point test.\nConclusion #We understood the concept of dependency and IoC and how Spring helps us with the management of all dependencies between classes within our application. We saw that using Spring we can take care of creating our classes thinking only about their logic and leaving the task of dependencies in Spring. We understood the usefulness of IoC and its advantages.\n","date":"Oct 12, 2021","permalink":"https://gustavopeiretti.com/spring-injection-dependencies/","section":"Posts","summary":"\u003cp\u003eDependency injection is a design pattern that aims to take the responsibility of creating the instances of the classes that another object needs and supply it so that this class can use them.\u003c/p\u003e","title":"What is dependency injection in Spring"},{"content":"Spring Boot is a set of components that provide several tools to create services quickly and with minimal effort. Spring Boot uses preset configurations that save your time and avoid repetition in application development.\nIt also provides libraries for most of the needs in the creation of services, microservices and Rest applications.\nIn addition to this, it orders the architecture of your code giving you the initial bases for each project.\nSpring Boot is part of a series of projects which are part of the Spring Solutions ecosystem. Each Spring project solves a particular problem.\nIn this case Spring Boot solves the creation of production-oriented, fast-running applications with predefined configurations. It integrates easily with other Spring projects such as Spring Data, Spring Cloud, Spring Security, etc.\nYou can take a look at the Spring page for Spring projects. Among them, we see Spring Boot.\nWhat are the main features of Spring Boot: # It is lightweight and with a simple architecture focused on dependency injection. It gives you the initial dependencies grouped and ready to use. Preset and automatic configurations that save you effort in repetitive or cumbersome configurations. Access to third-party libraries through interfaces for use. Integrate Tomcat, Jetty or Undertow without the need to deploy files to application containers. Easy to test and with tools for testing. Significantly simplifies data persistence and data queries. Monitoring of our application. It is prepared for Cloud operation. Spring Boot works with Dependency Injection (IoC): #Spring uses this pattern called Inversion of Control (IoC). Inversion of control and injection is one of the main aspects of Spring Framework.\nSpring Boot being a layer above Spring Framework obviously uses this pattern to add to the parts of our code the different responsibilities it needs.\nThis pattern refers to the fact that a particular class is supplied with the subsequent classes that the first one needs by injecting them for it to use.\nSpring is the one that manages these dependencies by supplying them to whoever needs them.\nSpring Boot has initializing or Started dependencies: #Spring Boot\u0026rsquo;s \u0026ldquo;started\u0026rdquo; initializer dependencies provide you with the set of dependencies already bundled and ready to use.\nAll \u0026ldquo;started\u0026rdquo; initializers have the nomenclature spring-boot-starter.\nFor example the dependency package spring-boot-starter-web gives us the libraries to start a web application on a Tomcat, create a driver that receives a request and responds.\nAnother example of a \u0026ldquo;started\u0026rdquo; is spring-boot-starter-data-jpa which gives us access to the data in a Database.\nSpring Boot understands how to use these \u0026ldquo;started\u0026rdquo; and creates its default autoconfiguration.\nSpring Boot has an embedded Server: #Spring Boot also helps us developers create applications that run without having to think about the application server. We create standalone applications that run without relying on an external server.\nWe can see it as the ability to create \u0026ldquo;self-running\u0026rdquo; applications with a single command.\nSpring Boot has Autoconfiguration: #Spring Boot provides us with default configurations for our application. This gives us time to concentrate on solving the functionality from the beginning without repeating configurations over and over again.\nThis way your Spring Boot application decides the best configuration based on the dependencies you are using. For example, if you have a database dependency such as MySQL or PostgreSql, Spring will decide the appropriate configuration for it. If you want to add or modify any custom configuration, you can do it easily by modifying properties.\nSpring Boot provides logging and monitoring: #As standard Spring gives you leave everything ready to log on your application and leave logs that help you monitor status and errors.\nWhat kind of applications can we develop on Spring Boot? #With Spring Boot we can create enterprise microservices that support business functionality and provide the backend for web, mobile and database-driven data processing applications. Small and large applications in scalable cloud environments.\nConclusion #Spring Boot is a Java framework used to create web applications more easily and quickly. Some reasons you might consider using Spring Boot include:\nAutomatic configuration: Spring Boot takes care of much of the configuration and integration of different components, saving time and effort. Easy to use: Spring Boot provides a lot of out-of-the-box functionality, allowing developers to focus on writing business code instead of configuration. Scalability: Spring Boot is designed to be scalable, meaning it is easy to maintain and expand as the application grows. Integration with other frameworks: Spring Boot has extensive integration with other Java frameworks, allowing for easy integration of different tools and technologies. In conclusion, Spring Boot is a good option for developers looking to create web applications quickly and efficiently without having to worry about configuration and component integration. ","date":"Sep 8, 2021","permalink":"https://gustavopeiretti.com/spring-boot-what-is/","section":"Posts","summary":"\u003cp\u003eSpring Boot is a set of components that provide several tools to create services quickly and with minimal effort.\nSpring Boot uses preset configurations that save your time and avoid repetition in application development.\u003cbr\u003e\nIt also provides libraries for most of the needs in the creation of services, microservices and Rest applications.\u003c/p\u003e","title":"What is Spring Boot"},{"content":"Let\u0026rsquo;s see in this post how to implement and configure Apache Kafka with SpringBoot. Spring provides a simple way to integrate with Kafka by providing a template to easily send messages and annotations to receive messages. in a simple way and annotations to receive the messages. We will use a docker image with Kafka to test its execution.\nKafka gives us the infrastructure to send messages using producers and consumers that receive them. The messages being produced and consumed are sent through topics. A topic is the category of the message being sent.\nDependencies for Kafka in Spring Boot #We will need the following dependencies for our project\n\u0026#39;org.springframework.boot:spring-boot-starter-web\u0026#39; \u0026#39;org.springframework.kafka:spring-kafka\u0026#39; \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; \u0026#39;org.springframework.kafka:spring-kafka-test\u0026#39; Spring Boot project with Kafka #We will create our Spring Boot project\n@SpringBootApplication public class DemoKafkaApplication { public static void main(String[] args) { SpringApplication.run(DemoKafkaApplication.class, args); } } Defining a producer to send messages to a Kafka topic #We will define a service that will be in charge of producing a message to a Kafka topic.\nAs we can see below Spring provides us with a KafkaTemplate that we can use in our services or components.\nWe just have to send the message using kafkaTemplate.send(..)\nkafkaTemplate.send(\u0026#34;topic\u0026#34;, \u0026#34;message\u0026#34;) import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Component; @Component public class KafkaProducer { private static final Logger LOGGER = LoggerFactory.getLogger(KafkaProducer.class); private final KafkaTemplate\u0026lt;String, String\u0026gt; kafkaTemplate; public KafkaProducer(KafkaTemplate\u0026lt;String, String\u0026gt; kafkaTemplate) { this.kafkaTemplate = kafkaTemplate; } public void sendMessage(String message) { LOGGER.info(\u0026#34;Producing message {}\u0026#34;, message); this.kafkaTemplate.send(\u0026#34;TOPIC-DEMO\u0026#34;, message); } } Defining a consumer to receive Kafka\u0026rsquo;s topic messages #In this example we will also define a consumer to receive Kafka\u0026rsquo;s message.\nThis would usually be in another microservice, but we will do it here in order to simplify the example.\nimport org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Service; @Service public class KafkaConsumer { Logger logger = LoggerFactory.getLogger(KafkaConsumer.class); @KafkaListener(topics = \u0026#34;TOPIC-DEMO\u0026#34;) public void consume(String message) { logger.info(\u0026#34;Consuming Message {}\u0026#34;, message); } } We will create a CommandLineRunner to perform our test. #Just to visualize how our demo application works we will create a CommandLineRunner that will send messages every two seconds in a loop.\nimport com.gp.demokafka.producer.KafkaProducer; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class CommandLineAppStartupRunner implements CommandLineRunner { private final KafkaProducer producer; public CommandLineAppStartupRunner(KafkaProducer producer) { this.producer = producer; } @Override public void run(String... args) throws Exception { for (int i = 0; i \u0026lt; 10; i++) { producer.sendMessage(\u0026#34;Hello kafka !! \u0026#34; + i); Thread.sleep(2000); } } } Create a docker compose with Kafka #For our project we need Kafka in a docker container.\nWe will use a Kafka image from this Docker Hub route\nDocker Hub\nversion: \u0026#39;3\u0026#39; services: zookeeper: container_name: zookeeper_merge image: wurstmeister/zookeeper ports: - \u0026#34;2181:2181\u0026#34; networks: - kafka_merge_net kafka: container_name: kafka_merge image: wurstmeister/kafka depends_on: - zookeeper ports: - \u0026#34;9092:9092\u0026#34; environment: KAFKA_ADVERTISED_HOST_NAME: localhost KAFKA_ADVERTISED_PORT: 9092 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 ZK_SERVER: zookeeper:2181 ADVERTISED_HOST: localhost CONSUMER_THREADS: 5 BROKER_ID: 1 ADVERTISED_PORT: 9092 volumes: - /var/run/docker.sock:/var/run/docker.sock networks: - kafka_merge_net networks: kafka_merge_net: driver: bridge We start Kafka from the docker image #We must save the file docker-compose.yml and then run in the same location\ndocker-compose up Once started our docker with Kafka we can test our service. We see the execution of the loop that we previously defined every two seconds.\nWe start our project in Spring Boot #For this example I use gradle, so I start it gradlew bootRun.\nWe see in the console the output of our project\nSource code of this example #As always I leave the source code of this example for you to have it at hand.\nhttps://github.com/gustavopeiretti/spring-boot-examples/tree/master/spring-boot-kafka\n","date":"Jun 15, 2021","permalink":"https://gustavopeiretti.com/configuring-kafka-and-springBoot/","section":"Posts","summary":"\u003cp\u003eLet\u0026rsquo;s see in this post how to implement and configure \u003ca href=\"https://kafka.apache.org/\" target=\"_blank\" rel=\"noreferrer\"\u003eApache Kafka\u003c/a\u003e with SpringBoot. \u003cbr\u003e\u003c/p\u003e\n\u003cp\u003eSpring provides a simple way to integrate with Kafka by providing a template to easily send messages and annotations to receive messages.\nin a simple way and annotations to receive the messages.\nWe will use a docker image with Kafka to test its execution.\u003c/p\u003e","title":"Configuring Kafka and Spring Boot"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/kafka/","section":"Tags","summary":"","title":"Kafka"},{"content":"We will examine here how to use Spring WebClient to make calls to a service by sending request.\nWhat is Spring WebClient? #WebClient provides a common interface for making web requests in a non-blocking way. It is part of the Spring Web Reactive module and will replace the well-known RestTemplate. We will see below the dependencies we need, how to create a web client, and some more configurations that we can use with Spring WebClient.\nWhat dependencies do you need to use Spring WebClient? #The first thing we need is to define the dependencies.\nspring-boot-starter-webflux is the necessary dependency for the webclient mockserver-netty we will use it to mock the web server in the unit tests for this example \u0026lt;dependencies\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-webflux\u0026lt;/artifactId\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-test\u0026lt;/artifactId\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;exclusions\u0026gt; \u0026lt;exclusion\u0026gt; \u0026lt;groupId\u0026gt;org.junit.vintage\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;junit-vintage-engine\u0026lt;/artifactId\u0026gt; \u0026lt;/exclusion\u0026gt; \u0026lt;/exclusions\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.mock-server\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;mockserver-netty\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;5.11.1\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;/dependencies\u0026gt; The structure of this example looks like # How to create a WebClient? #To use WebClient we will use the builder provided by WebClient WebClient.builder()\nThis way we will create a WebClient instance with a base url.\nWebClient webClient = WebClient.builder() .baseUrl(\u0026#34;http://localhost:8899\u0026#34;) .build(); How to add default headers to the WebClient? #Commonly, when it comes to calls with a body Json, the header is added indicating that it is an application/json call.\nWe can indicate headers by default.\nWebClient webClient = WebClient.builder() .baseUrl(\u0026#34;https://run.mocky.io\u0026#34;) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .build(); How to send a request and receive a response with WebClient #Once we have our instance of WebClient we can send a request.\nIn this example, we have our request that we have defined as ClientRequest and our response in ClientResponse.\nWe will be sending a POST to an uri through webClient.post().uri(\u0026hellip;)\nThe retrieve method executes the HTTP request and returns the response.\nThe bodyToMono method takes the body from the retrieve and converts it to our response class that we specify.\nClientResponse response = webClient.post() .uri(\u0026#34;/accounts\u0026#34;) .body(Mono.just(request), ClientRequest.class) .retrieve() .bodyToMono(ClientResponse.class) .block(); How to configure a timeout in the WebClient? #We can configure the timeout of our WebClient by indicating a duration in seconds or any other duration provided by the Duration class.\nClientResponse response = webClient.post() .uri(\u0026#34;/accounts\u0026#34;) .body(Mono.just(request), ClientRequest.class) .retrieve() .bodyToMono(ClientResponse.class) .timeout(Duration.ofSeconds(3)) // timeout .block(); Another way to specify a timeout is through the configuration of a TcpClient where we can be more specific.\nNext we see the specification of a timeout for the connection and read/write of the WebClient.\n// tcp client timeout TcpClient tcpClient = TcpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000) .doOnConnected(connection -\u0026gt; connection.addHandlerLast(new ReadTimeoutHandler(3)) .addHandlerLast(new WriteTimeoutHandler(3))); WebClient webClient = WebClient.builder() .baseUrl(\u0026#34;http://localhost:8899\u0026#34;) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient))) // timeout .build(); ClientResponse response = webClient.post() .uri(\u0026#34;/accounts\u0026#34;) .body(Mono.just(request), ClientRequest.class) .retrieve() .bodyToMono(ClientResponse.class) .block(); return response; Manage http status in WebClient #We can know and manage any http status in our WebClient using the onStatus method.\nFor example, here in case of an error 500 we log in and throw an error using onStatus(\u0026hellip;) throwing an exception our ApiWebClientException.\nLet\u0026rsquo;s see what we do next, there is a lot here:\nWe create our webclient. We indicate that it will do a POST. It will receive a request from our ClientRequest class. It will do a retrieve executing the HTTP request If an HttpStatus 500 error occurs, it will evaluate it in onStatus and decide what to do with that error. Convert the response to our ClientResponse class. Wait 3 seconds maximum for the connection. ClientResponse response = webClient.post() .uri(\u0026#34;/accounts\u0026#34;) .body(Mono.just(request), ClientRequest.class) .retrieve() // handle status .onStatus(HttpStatus::is5xxServerError, clientResponse -\u0026gt; { logger.error(\u0026#34;Error endpoint with status code {}\u0026#34;, clientResponse.statusCode()); throw new ApiWebClientException(\u0026#34;HTTP Status 500 error\u0026#34;); // throw custom exception }) .bodyToMono(ClientResponse.class) .timeout(Duration.ofSeconds(3)) // timeout .block(); What does our finished web client look like? #Adding up everything we have seen before, our web client looks like this.\n@Component public class ApiWebClient { private static final Logger logger = LoggerFactory.getLogger(ApiWebClient.class); public ClientResponse createClient(ClientRequest request) { // tcp client timeout TcpClient tcpClient = TcpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000) .doOnConnected(connection -\u0026gt; connection.addHandlerLast(new ReadTimeoutHandler(3)) .addHandlerLast(new WriteTimeoutHandler(3))); WebClient webClient = WebClient.builder() .baseUrl(\u0026#34;http://localhost:8899\u0026#34;) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient))) // timeout .build(); ClientResponse response = webClient.post() .uri(\u0026#34;/accounts\u0026#34;) .body(Mono.just(request), ClientRequest.class) .retrieve() // handle status .onStatus(HttpStatus::is5xxServerError, clientResponse -\u0026gt; { logger.error(\u0026#34;Error endpoint with status code {}\u0026#34;, clientResponse.statusCode()); throw new ApiWebClientException(\u0026#34;HTTP Status 500 error\u0026#34;); // throw custom exception }) .bodyToMono(ClientResponse.class) .block(); return response; } public ClientResponse createClientWithDuration(ClientRequest request) { WebClient webClient = WebClient.builder() .baseUrl(\u0026#34;http://localhost:8899\u0026#34;) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .build(); ClientResponse response = webClient.post() .uri(\u0026#34;/accounts\u0026#34;) .body(Mono.just(request), ClientRequest.class) .retrieve() // handle status .onStatus(HttpStatus::is5xxServerError, clientResponse -\u0026gt; { logger.error(\u0026#34;Error endpoint with status code {}\u0026#34;, clientResponse.statusCode()); throw new ApiWebClientException(\u0026#34;HTTP Status 500 error\u0026#34;); // throw custom exception }) .bodyToMono(ClientResponse.class) .timeout(Duration.ofSeconds(3)) // timeout .block(); return response; } } How to create a test to test Spring WebClient #First, we define a Spring test in which we will use MockServer .\nFor each test, we raise a server on port 8899 and at the end of each test, we stop it.\nWe are going to create several tests to try different cases. We will try:\nA correct connection. A connection with an expired timeout. A connection that throws an error 500 and returns an error ApiWebClientException. Notice below that we lift the mock from the server and then stop it.\nClientAndServer mockServer = ClientAndServer.startClientAndServer(8899); mockServer.stop(); Then we set the expectations we want for the server.\nIn this example, we indicate that when a POST occurs for the path /account, it should respond with the body that we indicated, the header and with a delay time.\nmockServer.when(HttpRequest.request().withMethod(\u0026#34;POST\u0026#34;) .withPath(\u0026#34;/accounts\u0026#34;)). respond(HttpResponse.response() .withBody(\u0026#34;{ \\\u0026#34;name\\\u0026#34;: \\\u0026#34;Frank\\\u0026#34;, \\\u0026#34;email\\\u0026#34;: \\\u0026#34;frank@mail.com\\\u0026#34;}\u0026#34;) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .withDelay(TimeUnit.MILLISECONDS, 5000)); Let\u0026rsquo;s see how the unit tests look for different cases.\n@SpringBootTest public class ClientServiceTest { private static final Logger logger = LoggerFactory.getLogger(ClientServiceTest.class); @Autowired private ApiWebClient webClient; private ClientAndServer mockServer; @BeforeEach public void startServer() { mockServer = ClientAndServer.startClientAndServer(8899); } @AfterEach public void stopServer() { mockServer.stop(); } @Test void createShouldReturnTheResponse() { // set up mock server with a delay of 1 seconds mockServer.when(HttpRequest.request().withMethod(\u0026#34;POST\u0026#34;) .withPath(\u0026#34;/accounts\u0026#34;)). respond(HttpResponse.response() .withBody(\u0026#34;{ \\\u0026#34;name\\\u0026#34;: \\\u0026#34;Frank\\\u0026#34;, \\\u0026#34;email\\\u0026#34;: \\\u0026#34;frank@mail.com\\\u0026#34;}\u0026#34;) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .withDelay(TimeUnit.MILLISECONDS, 1000)); ClientRequest request = new ClientRequest(); request.setName(\u0026#34;Frank\u0026#34;); request.setName(\u0026#34;frank@mail.com\u0026#34;); ClientResponse response = webClient.createClient(request); assertThat(response).isNotNull(); assertThat(response.getName()).isEqualTo(\u0026#34;Frank\u0026#34;); assertThat(response.getEmail()).isEqualTo(\u0026#34;frank@mail.com\u0026#34;); } @Test void createWithTimeoutShouldThrowReadTimeOut() { // set up mock server with a delay of 5 seconds mockServer.when(HttpRequest.request().withMethod(\u0026#34;POST\u0026#34;) .withPath(\u0026#34;/accounts\u0026#34;)). respond(HttpResponse.response() .withBody(\u0026#34;{ \\\u0026#34;name\\\u0026#34;: \\\u0026#34;Frank\\\u0026#34;, \\\u0026#34;email\\\u0026#34;: \\\u0026#34;frank@mail.com\\\u0026#34;}\u0026#34;) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .withDelay(TimeUnit.MILLISECONDS, 5000)); ClientRequest request = new ClientRequest(); request.setName(\u0026#34;Frank\u0026#34;); request.setName(\u0026#34;frank@mail.com\u0026#34;); assertThrows(ReadTimeoutException.class, () -\u0026gt; webClient.createClient(request)); } @Test void createWithStatusShouldThrowACustomException() { // set up mock server with a http status 500 mockServer.when(HttpRequest.request().withMethod(\u0026#34;POST\u0026#34;) .withPath(\u0026#34;/accounts\u0026#34;)) .respond(HttpResponse.response().withStatusCode(500) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .withDelay(TimeUnit.MILLISECONDS, 1000)); ClientRequest request = new ClientRequest(); request.setName(\u0026#34;Frank\u0026#34;); request.setName(\u0026#34;frank@mail.com\u0026#34;); ApiWebClientException apiWebClientException = assertThrows(ApiWebClientException.class, () -\u0026gt; webClient.createClient(request)); assertTrue(apiWebClientException.getMessage().contains(\u0026#34;HTTP Status 500 error\u0026#34;)); } } Conclusion #We saw how to simply create a web client using Spring WebClient. We examined how to configure the client, send a request and, receive the response.\nYou can see this code at:\nhttps://github.com/gustavopeiretti/spring-boot-examples\n","date":"Oct 26, 2020","permalink":"https://gustavopeiretti.com/spring-boot-how-to-use-webclient/","section":"Posts","summary":"\u003cp\u003eWe will examine here how to use Spring WebClient to make calls to a service by sending request.\u003c/p\u003e","title":"Spring Boot - How to use WebClient"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/elasticsearch/","section":"Tags","summary":"","title":"Elasticsearch"},{"content":"In this example, we are going to understand how to use ElasticSearch geolocation. We will add documents with geolocation using geo_point and then search for those documents using coordinates.\nElasticSearch geolocation is a very useful tool that can help you, for example, to search for businesses, clients, etc., that are close to where a user is at a specific point.\nWhat are the steps to create an index with geolocation # You create an index with a POST and property: properties:location Create a document with a POST by completing the location You perform the search with a GET with a distance filter and location Create the geolocation index #The first thing you need to do is create an index in ElasticSearch with geolocation. The index will be called establishment and you are going to define it with the geo_point property so that it has geolocation support.\nDefine PUT to create an index with geolocation and run it. Notice the type geo_point that is defined inside properties:location\ncurl --location --request PUT \u0026#39;http://localhost:9200/establishment\u0026#39; \\ --header \u0026#39;Content-Type: application/json\u0026#39; \\ --data-raw \u0026#39;{ \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; } } } } Hot to Add documents to elastic with geolocation #In the establishment index, we create a document with ID 1 and indicate its location. Doing a PUT to the index you add a document with the geolocation coordinates. Notice here that inside location indicate the latitude and longitude coordinates of this index.\ncurl --location --request PUT \u0026#39;http://localhost:9200/establishment/_doc/1\u0026#39; \\ --header \u0026#39;Content-Type: application/json\u0026#39; \\ --data-raw \u0026#39;{ \u0026#34;text\u0026#34;: \u0026#34;Sports Shop ABC\u0026#34;, \u0026#34;location\u0026#34;: { \u0026#34;lat\u0026#34;: -31.397561, \u0026#34;lon\u0026#34;: -64.235415 } }\u0026#39; Here I only show you one insert for simplicity, but it is convenient to insert several documents in different coordinates (near and far from a point) to better visualize this example.\nSearch documents in elasticsearch with geolocation coordinates #Then you can search by proximity using kilometers from a point of origin.\nLook again at the filters we use for the search by geo_distance. Using the distance to where we want to search in distance and the point from which we want to search in location.\ncurl --location --request GET \u0026#39;http://localhost:9200/establishment/_search\u0026#39; \\ --header \u0026#39;Content-Type: application/json\u0026#39; \\ --data-raw \u0026#39;{ \u0026#34;query\u0026#34;: { \u0026#34;bool\u0026#34; : { \u0026#34;must\u0026#34; : { \u0026#34;match_all\u0026#34; : {} }, \u0026#34;filter\u0026#34; : { \u0026#34;geo_distance\u0026#34; : { \u0026#34;distance\u0026#34; : \u0026#34;10km\u0026#34;, \u0026#34;location\u0026#34; : { \u0026#34;lat\u0026#34; : -31.397948, \u0026#34;lon\u0026#34; : -64.254007 } } } } } }\u0026#39; Conclusion #In this short example we saw how to create a document containing geolocation coordinates. We use the geo_point property to create a document and then search for it by proximity. There are other types of searches that you can also examine, such as the geo_shape that other forms of geolocation search can provide.\nReferences: #Indexes with geo_point: Datatype geo-point\nSearch by geo-distance using the query geo_point: Search geo-point\n","date":"Jun 19, 2020","permalink":"https://gustavopeiretti.com/elastic-search-geolocation/","section":"Posts","summary":"\u003cp\u003eIn this example, we are going to understand how to use ElasticSearch geolocation.\nWe will add documents with geolocation using \u003cem\u003egeo_point\u003c/em\u003e and then search for those documents using coordinates.\u003c/p\u003e","title":"Elasticsearch - How to use geolocation"},{"content":"To configure a Spring Batch project we will start with the dependencies that we need to use Maven, then we will define the basic configuration and some simple aspects to connect to an embedded database.\nWhat is Spring Batch? #Spring Batch is a framework for process large batches of information in “batch mode”. The execution of batch processes is focused on solving the processing without user intervention and periodically. But to explain it better, we will say that with Spring Batch we can generate jobs (work) and divide them into steps (steps), such as reading data from a database to process them by applying some business rule, and then writing them to a file or back in the database.\nWe see that a Job can have several Steps and each Step a Reader, a Processor, and a Writer.\nWhat will you do in this example and understand how Spring Batch works?\nConnect to a Database Read all the records of a Table Process each record and generate new information Write the result of the process in another Table of the database. Let\u0026rsquo;s see the dependencies you need.\nDependencies needed for Spring Batch #For your project in Spring Batch you need the dependency \u0026ldquo;org.springframework.boot: spring-boot-starter-batch\u0026rdquo;. Also, for this example in which we will use a database in memory, we need the dependency of \u0026ldquo;com.h2database: h2\u0026rdquo; You will also need \u0026ldquo;org.springframework.boot: spring-boot-starter-data-jpa\u0026rdquo; to connect Spring Batch to the database.\nThese are all the dependencies you will use.\n\u0026lt;dependencies\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-batch\u0026lt;/artifactId\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;com.h2database\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;h2\u0026lt;/artifactId\u0026gt; \u0026lt;scope\u0026gt;runtime\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-test\u0026lt;/artifactId\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;exclusions\u0026gt; \u0026lt;exclusion\u0026gt; \u0026lt;groupId\u0026gt;org.junit.vintage\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;junit-vintage-engine\u0026lt;/artifactId\u0026gt; \u0026lt;/exclusion\u0026gt; \u0026lt;/exclusions\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.batch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-batch-test\u0026lt;/artifactId\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-data-jpa\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;RELEASE\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;compile\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-data-jpa\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;RELEASE\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;compile\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;/dependencies\u0026gt; General structure of your Spring Batch project #Your Spring Batch project will look like this for this example.\nWhat will you do with this tutorial to create a Spring Batch application? #** What we will do in this project example will be to create a Job that reads from a table containing credit cards, then when processing them determine the risk of the card based on an alleged payment date, and at the end save another entity with the result.**\nWhat will you do in this example?\nRead credit cards from the database Process the cards and apply a business rule for those cards: calculate the risk of the card according to the payment date. The process must generate a new entity with the result of the risk In the end, the process result is saved The Entities #Define two entities, one for the CreditCard and one for CreditCardRisk\npackage dev.experto.demo.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import java.util.Date; @Entity public class CreditCard { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Long cardNumber; private Date lastPay; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getCardNumber() { return cardNumber; } public void setCardNumber(Long cardNumber) { this.cardNumber = cardNumber; } public Date getLastPay() { return lastPay; } public void setLastPay(Date lastPay) { this.lastPay = lastPay; } @Override public String toString() { return \u0026#34;CreditCard{\u0026#34; + \u0026#34;id=\u0026#34; + id + \u0026#34;, cardNumber=\u0026#34; + cardNumber + \u0026#34;, lastPay=\u0026#34; + lastPay + \u0026#39;}\u0026#39;; } } package dev.experto.demo.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; import java.util.Date; @Entity public class CreditCardRisk { public static final int HIGH = 3; public static final int LOW = 2; public static final int NORMAL = 1; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Date date; private int risk; @OneToOne(optional = false) private CreditCard creditCard; public CreditCardRisk() { } public CreditCardRisk(CreditCard creditCard, Date date, int risk) { this.creditCard = creditCard; this.date = date; this.risk = risk; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public int getRisk() { return risk; } public void setRisk(int risk) { this.risk = risk; } public CreditCard getCreditCard() { return creditCard; } public void setCreditCard(CreditCard creditCard) { this.creditCard = creditCard; } @Override public String toString() { return \u0026#34;CreditCardRisk{\u0026#34; + \u0026#34;id=\u0026#34; + id + \u0026#34;, date=\u0026#34; + date + \u0026#34;, risk=\u0026#34; + risk + \u0026#39;}\u0026#39;; } } The Repository #You will have two repositories one for each entity that we will use later in the ItemReader and ItemWriter\npackage dev.experto.demo.repository; import dev.experto.demo.domain.CreditCard; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface CreditCardRepository extends JpaRepository\u0026lt;CreditCard, Long\u0026gt; { } package dev.experto.demo.repository; import dev.experto.demo.domain.CreditCardRisk; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface CreditCardRiskRespository extends JpaRepository\u0026lt;CreditCardRisk, Long\u0026gt; { } The Reader #There are many implementations for Spring Batch Reader available to read different data sources (eg files, database).\nHere you will create your own, from the main interface ItemReader. We define the reader that will implement ItemReader and that will use a Spring repository to obtain all CreditCard With the annotation BeforeStep, we perform a read operation on the database before starting the Reader. The _read () _ method will deliver each item in the list to the Processor.\nimport dev.experto.demo.domain.CreditCard; import dev.experto.demo.repository.CreditCardRepository; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.annotation.BeforeStep; import org.springframework.batch.item.ItemReader; import org.springframework.beans.factory.annotation.Autowired; import java.util.Iterator; public class CreditCardItemReader implements ItemReader\u0026lt;CreditCard\u0026gt; { @Autowired private CreditCardRepository respository; private Iterator\u0026lt;CreditCard\u0026gt; usersIterator; @BeforeStep public void before(StepExecution stepExecution) { usersIterator = respository.findAll().iterator(); } @Override public CreditCard read() { if (usersIterator != null \u0026amp;\u0026amp; usersIterator.hasNext()) { return usersIterator.next(); } else { return null; } } } The Processor #The Processor will be responsible for receiving a CreditCard and delivering a CreditCardRisk\nimport dev.experto.demo.domain.CreditCard; import dev.experto.demo.domain.CreditCardRisk; import org.springframework.batch.item.ItemProcessor; import java.time.LocalDate; import java.time.ZoneId; import java.util.Date; import static java.time.temporal.ChronoUnit.DAYS; public class CreditCardItemProcessor implements ItemProcessor\u0026lt;CreditCard, CreditCardRisk\u0026gt; { @Override public CreditCardRisk process(CreditCard item) { LocalDate today = LocalDate.now(); LocalDate lastDate = item.getLastPay().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); long daysBetween = DAYS.between(today, lastDate); int risk; if (daysBetween \u0026gt;= 20) { risk = CreditCardRisk.HIGH; } else if (daysBetween \u0026gt; 10) { risk = CreditCardRisk.LOW;; }else { risk = CreditCardRisk.NORMAL;; } CreditCardRisk creditCardRisk = new CreditCardRisk(item, new Date(), risk); return creditCardRisk; } } The Writer #The Writer also has many implementations in Spring Batch that you can use depending on what or where you are writing.\nAs we did for the Reader, we will create our own Writer from the interface. The Writer will receive the list of CreditCardRisk that the Processor has processed to save the result in the database.\nimport dev.experto.demo.domain.CreditCardRisk; import dev.experto.demo.repository.CreditCardRiskRespository; import org.springframework.batch.item.ItemWriter; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; public class CreditCardItemWriter implements ItemWriter\u0026lt;CreditCardRisk\u0026gt; { @Autowired private CreditCardRiskRespository respository; @Override public void write(List\u0026lt;? extends CreditCardRisk\u0026gt; list) throws Exception { respository.saveAll(list); } } The Listeners #The Listeners intercept parts of the Job process and receive or listen to what is happening during the execution. Spring Batch has numerous listeners for each part of the job step and you can use them to find out what happens at each stage.\nFor example, the following JobExecutionListener interface listens to the execution before starting the job and after finishing the Job.\npublic interface JobExecutionListener { void beforeJob(JobExecution var1); void afterJob(JobExecution var1); } Then implement the most common listeners to understand them.\npackage dev.experto.demo.listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecutionListener; import org.springframework.stereotype.Component; @Component public class CreditCardJobExecutionListener implements JobExecutionListener { private static final Logger LOGGER = LoggerFactory.getLogger(CreditCardJobExecutionListener.class); @Override public void beforeJob(JobExecution jobExecution) { LOGGER.info(\u0026#34;beforeJob\u0026#34;); } @Override public void afterJob(JobExecution jobExecution) { LOGGER.info(\u0026#34;afterJob: \u0026#34; + jobExecution.getStatus()); } } package dev.experto.demo.listener; import dev.experto.demo.domain.CreditCard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.ItemReadListener; public class CreditCardIItemReaderListener implements ItemReadListener\u0026lt;CreditCard\u0026gt; { private static final Logger LOGGER = LoggerFactory.getLogger(CreditCardIItemReaderListener.class); @Override public void beforeRead() { LOGGER.info(\u0026#34;beforeRead\u0026#34;); } @Override public void afterRead(CreditCard creditCard) { LOGGER.info(\u0026#34;afterRead: \u0026#34; + creditCard.toString()); } @Override public void onReadError(Exception e) { LOGGER.info(\u0026#34;onReadError\u0026#34;); } } package dev.experto.demo.listener; import dev.experto.demo.domain.CreditCard; import dev.experto.demo.domain.CreditCardRisk; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.ItemProcessListener; public class CreditCardItemProcessListener implements ItemProcessListener\u0026lt;CreditCard, CreditCardRisk\u0026gt; { private static final Logger LOGGER = LoggerFactory.getLogger(CreditCardItemProcessListener.class); @Override public void beforeProcess(CreditCard creditCard) { LOGGER.info(\u0026#34;beforeProcess\u0026#34;); } @Override public void afterProcess(CreditCard creditCard, CreditCardRisk creditCardRisk) { LOGGER.info(\u0026#34;afterProcess: \u0026#34; + creditCard + \u0026#34; ---\u0026gt; \u0026#34; + creditCardRisk); } @Override public void onProcessError(CreditCard creditCard, Exception e) { LOGGER.info(\u0026#34;onProcessError\u0026#34;); } } package dev.experto.demo.listener; import dev.experto.demo.domain.CreditCardRisk; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.ItemWriteListener; import java.util.List; public class CreditCardIItemWriterListener implements ItemWriteListener\u0026lt;CreditCardRisk\u0026gt; { private static final Logger LOGGER = LoggerFactory.getLogger(CreditCardIItemWriterListener.class); @Override public void beforeWrite(List\u0026lt;? extends CreditCardRisk\u0026gt; list) { LOGGER.info(\u0026#34;beforeWrite\u0026#34;); } @Override public void afterWrite(List\u0026lt;? extends CreditCardRisk\u0026gt; list) { for (CreditCardRisk creditCardRisk : list) { LOGGER.info(\u0026#34;afterWrite :\u0026#34; + creditCardRisk.toString()); } } @Override public void onWriteError(Exception e, List\u0026lt;? extends CreditCardRisk\u0026gt; list) { LOGGER.info(\u0026#34;onWriteError\u0026#34;); } } The application.properties file #You are going to configure the database connection here. This project uses an H2 database in memory to simplify the execution of this example.\nspring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect # create, create-drop, validate, update spring.jpa.hibernate.ddl-auto = update The file data.sql #Spring searches by default for files with sql extension inside the resources folder and executes them. This file will then complete the H2 database in memory with information prior to starting the application. In this way, we have data to process in previous memory when starting the Job.\n-- risk HIGH INSERT INTO credit_card (card_number,last_pay) VALUES (9991,CURRENT_DATE()-30); INSERT INTO credit_card (card_number,last_pay) VALUES (9992,CURRENT_DATE()-21); -- risk LOW INSERT INTO credit_card (card_number,last_pay) VALUES (9993,CURRENT_DATE()-20); INSERT INTO credit_card (card_number,last_pay) VALUES (9994,CURRENT_DATE()-11); -- risk NORMAL INSERT INTO credit_card (card_number,last_pay) VALUES (9995,CURRENT_DATE()-10); INSERT INTO credit_card (card_number,last_pay) VALUES (9996,CURRENT_DATE()-5); What is a chunk in Spring Batch? #This is a concept that you will use when configuring the Job. A chunk is a processing unit. With this value, you tell Spring Batch to process a certain number of records and when completing the amount send everything to the reader to commit. Note that the class the Item reader interface has the read method that receives a list. This list is the amount of chunk that was previously processed and whose amount you set in the chunk config.\nHow to set up the Job in Spring Batch #We said before that for Spring Batch a Job contains Steps and each Step generally requires (not always) a Reader, a Processor, and a Writer. Optionally you can add Listener to listen and know what is happening in each part of the batch process.\nThe Reader reads data. The Processor receives the Reader data and processes it and then delivers it to the Writer. The Writer receives the data that was processed and is responsible for saving it. Listeners who \u0026ldquo;listen\u0026rdquo; to what happens during the process. For this example, we will use some listener, the most common, which we said previously. Next you will create a configuration class to define all the parts of the Job.\nYou write this class with @Configuration and @EnableBatchProcessing\nWithin the class you will call JobBatchConfiguration you must define:\nA Spring bean for the Reader CreditCardItemReader A Spring bean for the Processor CreditCardItemProcessor A Spring bean for the Writer CreditCardItemWriter The beans for the Listeners CreditCardJobExecutionListener , CreditCardItemReaderListener, CreditCardItemProcessListener, CreditCardItemWriterListener Pay attention to how you define the Job and the Step that will be executed within the Job. To the Job, we indicate the listener that will listen and we establish the step (s). In the definition of the Step, we also indicate the listeners and each of the beans that we mentioned for the reader, processor, and writer. The \u0026ldquo;chunk\u0026rdquo; we arbitrarily set it to 100. This value you must think according to the need of your project.\npackage dev.experto.demo.config; import dev.experto.demo.domain.CreditCard; import dev.experto.demo.domain.CreditCardRisk; import dev.experto.demo.job.CreditCardItemProcessor; import dev.experto.demo.job.CreditCardItemReader; import dev.experto.demo.job.CreditCardItemWriter; import dev.experto.demo.listener.CreditCardItemProcessListener; import dev.experto.demo.listener.CreditCardIItemReaderListener; import dev.experto.demo.listener.CreditCardIItemWriterListener; import dev.experto.demo.listener.CreditCardJobExecutionListener; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.step.tasklet.TaskletStep; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @EnableBatchProcessing public class JobBatchConfiguration { @Autowired public JobBuilderFactory jobBuilderFactory; @Autowired public StepBuilderFactory stepBuilderFactory; @Bean public CreditCardItemReader reader() { return new CreditCardItemReader(); } @Bean public CreditCardItemProcessor processor() { return new CreditCardItemProcessor(); } @Bean public CreditCardItemWriter writer() { return new CreditCardItemWriter(); } @Bean public CreditCardJobExecutionListener jobExecutionListener() { return new CreditCardJobExecutionListener(); } @Bean public CreditCardIItemReaderListener readerListener() { return new CreditCardIItemReaderListener(); } @Bean public CreditCardItemProcessListener creditCardItemProcessListener() { return new CreditCardItemProcessListener(); } @Bean public CreditCardIItemWriterListener writerListener() { return new CreditCardIItemWriterListener(); } @Bean public Job job(Step step, CreditCardJobExecutionListener jobExecutionListener) { Job job = jobBuilderFactory.get(\u0026#34;job1\u0026#34;) .listener(jobExecutionListener) .flow(step) .end() .build(); return job; } @Bean public Step step(CreditCardItemReader reader, CreditCardItemWriter writer, CreditCardItemProcessor processor, CreditCardIItemReaderListener readerListener, CreditCardItemProcessListener creditCardItemProcessListener, CreditCardIItemWriterListener writerListener) { TaskletStep step = stepBuilderFactory.get(\u0026#34;step1\u0026#34;) .\u0026lt;CreditCard, CreditCardRisk\u0026gt;chunk(100) .reader(reader) .processor(processor) .writer(writer) .listener(readerListener) .listener(creditCardItemProcessListener) .listener(writerListener) .build(); return step; } } How to run Spring Batch #This project is create with Maven.\nFrom a Linux console inside the project folder.\n$ ./mvnw spring-boot:run From a windows console inside the project folder.\n\u0026gt; mvnw spring-boot:run Look in more detail at the log output.\nThe Job starts with the associated Step and the listener. The reader and the listener of the reader are executed. The processor and the processor listener are executed. The writer and the listener of the writer are executed. Conclusion: #With the help of this example, you have created a Spring Batch application using some of its most important features. If you need to create batch processes that execute unattended and high-load actions, this is an excellent framework to cover this objective.\nSource code of this example #As always I leave you the source code of this example so that you have it at hand.\nhttps://github.com/gustavopeiretti/springbatch-example\nhttps://gitlab.com/gustavopeiretti/springbatch-example\n","date":"Jan 3, 2020","permalink":"https://gustavopeiretti.com/how-to-create-an-application-with-spring-batch/","section":"Posts","summary":"\u003cp\u003eTo configure a Spring Batch project we will start with the dependencies that we need to use Maven, then we will define the basic configuration and some simple aspects to connect to an embedded database.\u003c/p\u003e","title":"How to create an application with Spring Batch"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/spring-batch/","section":"Tags","summary":"","title":"Spring Batch"},{"content":"","date":null,"permalink":"https://gustavopeiretti.com/tags/docker/","section":"Tags","summary":"","title":"Docker"},{"content":"In this post you will learn how to create a Spring Boot application with a PostgreSQL database to run inside a Docker container.\nWe have already been working on other posts with Spring Boot, Java, and Docker. Here are some links that can help you with this topic.\nSpring Boot y Docker Dependencies for Spring Boot with Postgresql #For this tutorial, you will use Gradle to manage the dependencies and the project build. The structure of your project will be at the end of this way:\nYou need to define the following dependencies to use Spring Boot with Postgresql:\n\u0026#39;org.springframework.boot:spring-boot-starter-web\u0026#39; \u0026#39;org.springframework.boot:spring-boot-starter-data-jpa\u0026#39; \u0026#39;org.postgresql:postgresql\u0026#39; The complete build.gradle file looks like this:\nplugins { id \u0026#39;org.springframework.boot\u0026#39; version \u0026#39;2.2.1.RELEASE\u0026#39; id \u0026#39;io.spring.dependency-management\u0026#39; version \u0026#39;1.0.8.RELEASE\u0026#39; id \u0026#39;java\u0026#39; } group = \u0026#39;com.example\u0026#39; version = \u0026#39;0.0.1-SNAPSHOT\u0026#39; sourceCompatibility = \u0026#39;1.8\u0026#39; repositories { mavenCentral() } dependencies { implementation \u0026#39;org.springframework.boot:spring-boot-starter-web\u0026#39; implementation \u0026#39;org.springframework.boot:spring-boot-starter-data-jpa\u0026#39; runtimeOnly \u0026#39;org.postgresql:postgresql\u0026#39; testImplementation(\u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39;) { exclude group: \u0026#39;org.junit.vintage\u0026#39;, module: \u0026#39;junit-vintage-engine\u0026#39; } } test { useJUnitPlatform() } The Spring Boot main method for the project #You must define the main of your application with the @SpringBootApplication annotation\n@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } The rest of the components for the project: model, repository, controller, and properties #Model #You are going to create a User entity that will be a very simple model to store in the PostgreSQL database\nimport javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class UserModel { @Id @GeneratedValue private Long id; private String name; // set and get… } Repository #Create a repository for our User model. Extends the Spring JpaRepository class.\n@Repository public interface UserRespository extends JpaRepository\u0026lt;UserModel, Long\u0026gt; { } Controller #Create a controller with basic rest points for this example.\nYou will define three rest points:\n\u0026ldquo;/user/all\u0026rdquo; to return all user \u0026ldquo;/user/{id}\u0026rdquo; to return one User by ID \u0026ldquo;/user/save\u0026rdquo; to save User model import com.experto.springbootpostgresqldocker.model.UserModel; import com.experto.springbootpostgresqldocker.repository.UserRespository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import org.springframework.web.server.ResponseStatusException; @RestController public class UserController { private UserRespository userRespository; @Autowired public UserController(UserRespository userRespository) { this.userRespository = userRespository; } @GetMapping(\u0026#34;/user/all\u0026#34;) Iterable\u0026lt;UserModel\u0026gt; all() { return userRespository.findAll(); } @GetMapping(\u0026#34;/user/{id}\u0026#34;) UserModel userById(@PathVariable Long id) { return userRespository.findById(id).orElseThrow(() -\u0026gt; new ResponseStatusException( HttpStatus.NOT_FOUND)); } @PostMapping(\u0026#34;/user/save\u0026#34;) UserModel save(@RequestBody UserModel user) { return userRespository.save(user); } } File application.properties #Now you define the file the configuration that the database will have with the connection URL, username and password. We will see later that these default values leave the PostgreSQL image that we will use in the docker-compose configuration file.\nThe spring.jpa.hibernate.ddl-auto property has these options create, create-drop, validate, update\nFrom the spring documentation we have:\ncreate: create the database schema by destroying the data. create-drop: deletes the schema at the end of the session. validate: only validate the schema without making changes to the database tables. update: update the schema with the changes you make in your entities. File _resources/application.properties _ .\nspring.datasource.url=jdbc:postgresql://dbpostgresql:5432/mydb spring.datasource.username=postgres spring.datasource.password=password spring.jpa.hibernate.ddl-auto=create Docker configuration for Spring Boot with PostgreSQL #The Dockerfile file #In the Dockerfile file we will give the following instructions to Docker.\nFROM openjdk:8-jdk-alpine MAINTAINER experto.com VOLUME /tmp EXPOSE 8080 ADD build/libs/springbootpostgresqldocker-0.0.1-SNAPSHOT.jar springbootpostgresqldocker.jar ENTRYPOINT [\u0026#34;java\u0026#34;,\u0026#34;-Djava.security.egd=file:/dev/./urandom\u0026#34;,\u0026#34;-jar\u0026#34;,\u0026#34;/springbootpostgresqldocker.jar\u0026#34;] FROM: use a Docker image here [https://hub.docker.com/_/openjdk] with a jdk8 and a Linux alpine server.\nMAINTAINER: contact information\nVOLUME: the folder where it will work\nEXPOSE: the port to be exposed\nADD: copy the jar file of our springbootpostgresqldocker-0.0.1-SNAPSHOT.ja application in the Docker container with the name springbootpostgresqldocker.jar\nENTRYPOINT: executes the statement when starting the docker container\nThe file_docker-compose.yml_ #You must create a docker-compose.yml file in which you will establish two services.\nThe first service you will call app refers to the SpringBoot service you set up in the Dockerfile. Within that service the build instruction indicates that this service comes from the Dockerfile that you previously defined.\nThe second service you will call dbpostgresql uses a postgresql image of the docker hub that docker will download from there. We leave the password, user, and name of the DB that comes by default.\nversion: \u0026#39;3.1\u0026#39; services: app: container_name: app-springboot-postgresql image: app-springboot-postgresql build: ./ ports: - \u0026#34;8080:8080\u0026#34; depends_on: - dbpostgresql dbpostgresql: image: postgres ports: - \u0026#34;5432:5432\u0026#34; environment: - POSTGRES_PASSWORD=password - POSTGRES_USER=postgres - POSTGRES_DB=mydb Run Spring Boot with PostgreSQL in the Docker container #Build your project to create the jar file #In this example we are using Gradle. So what you have to do is build like this:\n./gradlew build This will leave the jar file of your project in the /build/libs folder of your project.\nDocker compose build to create the image and run the application inside docker #After you have made a build of your project and have the jar file available, you can launch the container.\ndocker-compose up --build Test your Spring Boot + PostgreSQL + Docker application #Remember that we had previously created a UserController with a post to save the User and a get to get the users.\nNow you run this post. Note that you save a User and the response returns the same User with the ID already assigned.\nPost /user/save\ncurl -s -X POST \\ http://localhost:8080/user/save \\ -H \u0026#39;Content-Type: application/json\u0026#39; \\ -d \u0026#39;{\u0026#34;name\u0026#34;:\u0026#34;Moana\u0026#34;}\u0026#39; Then you make a get with the ID of the new user that you previously saved.\nGet /user/save\ncurl -s -X GET \\ http://localhost:8080/user/1 Conclusion: #In this post you created a simple app with Spring Boot using two Docker images. The first for the SpringBoot service and the second for PostgreSQL. You executed the Docker container with the images and then saved a new User in the PostgreSQL database using the rest point you defined for the User.\nThe code : #As always you can see this code in Github and Gitlab. https://github.com/gustavopeiretti/springboot-postgresql-docker-example\nhttps://gitlab.com/gustavopeiretti/springboot-postgresql-docker-example\n","date":"Dec 10, 2019","permalink":"https://gustavopeiretti.com/spring-boot-with-postgresql-and-docker-compose/","section":"Posts","summary":"\u003cp\u003eIn this post you will learn how to create a Spring Boot application with a PostgreSQL database to run inside a Docker container.\u003c/p\u003e","title":"Spring Boot with PostgreSQL and Docker Compose"},{"content":"We will learn how to run a Spring Boot microservice inside a Docker container\nThis post assumes you already have Docker installed and know how to run a Java Hello World inside a Docker container. Now we will learn how to run a Spring Boot microservice application within Docker.\nMinimum dependencies of a Spring Boot microservice #The first thing we are going to do is define the dependencies we need. Spring Boot requires at least these dependencies:\norg.springframework.boot:spring-boot-starter-web org.springframework.boot:spring-boot-starter-test The configuration for Gradle of these dependencies is:\nplugins { id \u0026#39;org.springframework.boot\u0026#39; version \u0026#39;2.1.9.RELEASE\u0026#39; id \u0026#39;io.spring.dependency-management\u0026#39; version \u0026#39;1.0.8.RELEASE\u0026#39; id \u0026#39;java\u0026#39; } group = \u0026#39;com.gustavopeiretti\u0026#39; version = \u0026#39;0.0.1-SNAPSHOT\u0026#39; sourceCompatibility = \u0026#39;1.8\u0026#39; repositories { mavenCentral() } dependencies { implementation \u0026#39;org.springframework.boot:spring-boot-starter-web\u0026#39; testImplementation \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; } The configuration for Maven of these dependencies for Spring Boot:\n\u0026lt;project xmlns=\u0026#34;http://maven.apache.org/POM/4.0.0\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xsi:schemaLocation=\u0026#34;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\u0026#34;\u0026gt; \u0026lt;modelVersion\u0026gt;4.0.0\u0026lt;/modelVersion\u0026gt; \u0026lt;parent\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-parent\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;2.1.9.RELEASE\u0026lt;/version\u0026gt; \u0026lt;relativePath/\u0026gt; \u0026lt;!-- lookup parent from repository --\u0026gt; \u0026lt;/parent\u0026gt; \u0026lt;groupId\u0026gt;com.gustavopeiretti\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;springbootdocker\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;0.0.1-SNAPSHOT\u0026lt;/version\u0026gt; \u0026lt;name\u0026gt;springbootdocker\u0026lt;/name\u0026gt; \u0026lt;description\u0026gt;Demo project for Spring Boot with Docker\u0026lt;/description\u0026gt; \u0026lt;properties\u0026gt; \u0026lt;java.version\u0026gt;1.8\u0026lt;/java.version\u0026gt; \u0026lt;/properties\u0026gt; \u0026lt;dependencies\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-web\u0026lt;/artifactId\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-test\u0026lt;/artifactId\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;/dependencies\u0026gt; \u0026lt;build\u0026gt; \u0026lt;plugins\u0026gt; \u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;/plugin\u0026gt; \u0026lt;/plugins\u0026gt; \u0026lt;/build\u0026gt; \u0026lt;/project\u0026gt; Create the Spring Boot microservice #You must create the main class that Spring will start. We annotate the class with @SpringBootApplication.\nThe @SpringBootApplication annotation is equivalent to using @Configuration + @EnableAutoConfiguration + @ComponentScan with its default attributes.\nCheck out this other post for more details about the main class\n@SpringBootApplication public class SpringbootdockerApplication { public static void main(String[] args) { SpringApplication.run(SpringbootdockerApplication.class, args); } } Then create a \u0026lsquo;rest controller\u0026rsquo; that you annotate with RestController. Create a Home class and annotate the method with RequestMapping. The home method below maps the base path of your services. You can read more about RestController\n@RestController public class Home { @RequestMapping(\u0026#34;/\u0026#34;) public String home() { return \u0026#34;Hello Spring Boot with Docker\u0026#34;; } } .\nYou can run the application from the console.\nIf you use gradle gradle bootRun If you use maven mvn spring-boot:run If you use the gradle wrapper ./gradlew bootRun This is the console for ./gradlew bootRun Open the URL localhost:8080. Finish the execution of SpringBoot with Gradle by pressing Ctrl + C. If you cannot finish gradlew when you press ctrl + c, you will have to open another console and run ./gradlew -stop\nBuild your Spring Boot application #Before continuing with the other steps, be sure to make a build of the project to make available the jar file that we will need later.\nwith gradle #Gradle leaves the jar in the \\build\\libs folder of your project with the name you have in the settings.gradle file.\ngradlew build Gradle create jar file with the name you have specified in the settings.gradle file. with maven #Maven leave the jar in the \\target folder of your project with the name you have defined in the artifactId tag of your pom.xml file\nmvnw package Create a Docker file to run SpringBoot #ok, you already have your service application running. Now, You will start configuring Docker so that your service runs there.\nTo create the Docker configuration for SpringBoot, create a Dockerfile text file with these instructions:\nFROM openjdk:8-jdk-alpine VOLUME /tmp EXPOSE 8080 ARG JAR_FILE=build/libs/springbootdocker-0.0.1-SNAPSHOT.jar ADD ${JAR_FILE} app.jar ENTRYPOINT [\u0026#34;java\u0026#34;,\u0026#34;-Djava.security.egd=file:/dev/./urandom\u0026#34;,\u0026#34;-jar\u0026#34;,\u0026#34;/app.jar\u0026#34;] FROM: Note that in the first line you use a docker image that is already armed with linux and java 8. That is, our service will run on a linux and Java 8 system.\nADD: The ADD instruction copies our application into Docker. Our gradle or maven config leaves the file jar with the name \u0026ldquo;springbootdocker-0.0.1-SNAPSHOT.jar\u0026rdquo;. This springbootdocker-0.0.1-SNAPSHOT.jar file is added to the container with the instruction ADD with the name app.jar If the path of your jar application is elsewhere, you must modify it with the correct route. In the event that you have created your app with maven, you must use the path of the maven target.\nENTRYPOINT: Then we execute the file when starting docker with the instruction ENTRYPOINT\nOnce the Dockerfile file is defined, you run docker build. The -t parameter defines the name that we will give to the container and that we will use later to execute it.\ndocker build -t springbootdockerexample . Look in the console with what happens with your Docker config you created. In each step you see that the linux image with java 8 (FROM) is created, after port 8080 is exposed from the container to the container host (EXPOSE), the jar (ADD) is copied and executed (ENTRYPOINT) .\nAfter the build of the docker is finished, you can execute it with the name you gave it.\nRunning Docker with Spring Boot #With the docker image ready, you can now run it with docker run The -p parameter tells Docker to expose port 8080 of our application that is running inside the container, on port 5000 of the operating system.\ndocker run -p 5000:8080 springbootdockerexample Now you open the URL pointing to the port you told docker. In this case 5000 http://localhost:5000/\nSmile your application is working in a Docker container! Create the Docker image with Spring Boot using Gradle #If you use Gradle you can add a plugin to build the image and execute it directly from the Gradle commands. For this, you have to modify the build.gradle file by adding this plugin https://github.com/palantir/gradle-docker\nThe new thing you add is what you see in buildscript, then the apply of the plugin and finally a new task docker.\n// docker: new plugin buildscript { dependencies { classpath \u0026#34;gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.22.1\u0026#34; } } plugins { id \u0026#39;org.springframework.boot\u0026#39; version \u0026#39;2.1.9.RELEASE\u0026#39; id \u0026#39;io.spring.dependency-management\u0026#39; version \u0026#39;1.0.8.RELEASE\u0026#39; id \u0026#39;java\u0026#39; } group = \u0026#39;com.gustavopeiretti\u0026#39; version = \u0026#39;0.0.1-SNAPSHOT\u0026#39; sourceCompatibility = \u0026#39;1.8\u0026#39; repositories { mavenCentral() } dependencies { implementation \u0026#39;org.springframework.boot:spring-boot-starter-web\u0026#39; testImplementation \u0026#39;org.springframework.boot:spring-boot-starter-test\u0026#39; } // docker: plugin apply apply plugin: \u0026#39;com.palantir.docker\u0026#39; // docker: new task docker docker { dependsOn build name \u0026#34;${project.name}\u0026#34; files bootJar.archivePath buildArgs([\u0026#39;JAR_FILE\u0026#39;: \u0026#34;${bootJar.archiveName}\u0026#34;]) } Let\u0026rsquo;s analyze the new docker task of the gradlew build file that we have modified:\ndependsOn build we tell you that this task depends on the build of gradle name \u0026ldquo;${project.name}\u0026rdquo; will be the name of the container, we will give you the name of the project that we have in settings.gradle files bootJar.archivePath will make the jar file generated by the build available buildArgs ([\u0026lsquo;JAR_FILE\u0026rsquo;: \u0026ldquo;$ {bootJar.archiveName}\u0026rdquo;]) sends as an argument the name of the jar file. Running the Docker image with Spring Boot using Gradle #If you have already modified your build file by adding the com.palantir.docker plugin, you can directly execute the build and create your image from gradle. From your console, you will use gradlew build docker to build an image\ngradlew build docker docker run -p 5000:8080 springbootdocker Create the Docker image with Spring Boot using Maven #In the case of using Maven, you must add this plugin if you want to create the image directly from mvn https://github.com/spotify/dockerfile-maven\n\u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;com.spotify\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;dockerfile-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.4.9\u0026lt;/version\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;repository\u0026gt;${project.artifactId}\u0026lt;/repository\u0026gt; \u0026lt;buildArgs\u0026gt; \u0026lt;JAR_FILE\u0026gt;target/${project.build.finalName}.jar\u0026lt;/JAR_FILE\u0026gt; \u0026lt;/buildArgs\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;executions\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;id\u0026gt;default\u0026lt;/id\u0026gt; \u0026lt;phase\u0026gt;install\u0026lt;/phase\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;build\u0026lt;/goal\u0026gt; \u0026lt;goal\u0026gt;push\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;/execution\u0026gt; \u0026lt;/executions\u0026gt; \u0026lt;/plugin\u0026gt; Your full pom.xml looks like this:\n\u0026lt;project xmlns=\u0026#34;http://maven.apache.org/POM/4.0.0\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xsi:schemaLocation=\u0026#34;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\u0026#34;\u0026gt; \u0026lt;modelVersion\u0026gt;4.0.0\u0026lt;/modelVersion\u0026gt; \u0026lt;parent\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-parent\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;2.1.9.RELEASE\u0026lt;/version\u0026gt; \u0026lt;relativePath/\u0026gt; \u0026lt;!-- lookup parent from repository --\u0026gt; \u0026lt;/parent\u0026gt; \u0026lt;groupId\u0026gt;com.gustavopeiretti\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;springbootdocker\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;0.0.1-SNAPSHOT\u0026lt;/version\u0026gt; \u0026lt;name\u0026gt;springbootdocker\u0026lt;/name\u0026gt; \u0026lt;description\u0026gt;Demo project for Spring Boot with Docker\u0026lt;/description\u0026gt; \u0026lt;properties\u0026gt; \u0026lt;java.version\u0026gt;1.8\u0026lt;/java.version\u0026gt; \u0026lt;/properties\u0026gt; \u0026lt;dependencies\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-web\u0026lt;/artifactId\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-test\u0026lt;/artifactId\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;/dependencies\u0026gt; \u0026lt;build\u0026gt; \u0026lt;plugins\u0026gt; \u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;/plugin\u0026gt; \u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;com.spotify\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;dockerfile-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.4.13\u0026lt;/version\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;repository\u0026gt;${project.artifactId}\u0026lt;/repository\u0026gt; \u0026lt;buildArgs\u0026gt; \u0026lt;JAR_FILE\u0026gt;target/${project.build.finalName}.jar\u0026lt;/JAR_FILE\u0026gt; \u0026lt;/buildArgs\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;executions\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;id\u0026gt;default\u0026lt;/id\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;build\u0026lt;/goal\u0026gt; \u0026lt;goal\u0026gt;push\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;/execution\u0026gt; \u0026lt;/executions\u0026gt; \u0026lt;/plugin\u0026gt; \u0026lt;/plugins\u0026gt; \u0026lt;/build\u0026gt; \u0026lt;/project\u0026gt; Running the Docker image with Spring Boot using Maven #Once you have added the https://github.com/spotify/dockerfile-maven plugin you run:\nmvnw dockerfile:build docker run -p 5000:8080 springbootdocker When you execute docker run your app will remain in the url localhost:5000\nA summary of the docker commands that were useful in this post:\ndocker build to create the docker image docker run to run the docker image docker images see the docker images you have available. As always this code can be found by GitHub #https://github.com/gustavopeiretti/spring-boot-examples/tree/master/spring-boot-docker-example\nConclusion #You learned how to create a Spring Boot Rest application, configure a dockerfile for your application, build your Docker container and run your microservice from the container. You also learned some basic docker commands.\n","date":"Nov 12, 2019","permalink":"https://gustavopeiretti.com/how-to-create-a-microservice-with-spring-boot-and-docker/","section":"Posts","summary":"\u003cp\u003eWe will learn how to run a Spring Boot microservice inside a Docker container\u003c/p\u003e","title":"How to create a microservice with Spring Boot and Docker"},{"content":"Let’s examine how to change the time zone of a date in java in different ways.\nHow to change the timezone of a java.util.Date using SimpleDateFormat #We must be clear that the Date class in Java does not have a time zone.\njava.util.Date represents the number of seconds from midnight January 1, 1970 to zero hours (UTC time).\nThis means, java.util.Date will always return the time for the time zone that is by default defined for the system.\nWhat you need to do to change the time zone to a Date is:\nCreate a DateFormat with the time zone for the area you want Apply the DateFormat to the Date by obtaining a string with modified Recreate an object Date from that string import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; public class TimeZoneChangeDateExample { private static final String DATE_FORMAT = \u0026#34;dd-MM-yyyy hh:mm:ss a\u0026#34;; public static void main(String[] args) throws ParseException { // the date Calendar cal = Calendar.getInstance(); cal.set(2017, 06, 29, 8, 30); Date date = cal.getTime(); // format with tz TimeZone timeZone = TimeZone.getTimeZone(\u0026#34;Europe/Amsterdam\u0026#34;); SimpleDateFormat formatterWithTimeZone = new SimpleDateFormat(DATE_FORMAT); formatterWithTimeZone.setTimeZone(timeZone); // change tz using formatter String sDate = formatterWithTimeZone.format(date); // string to object date SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); Date dateWithTimeZone = formatter.parse(sDate); // string to Date Object System.out.println(\u0026#34;The actual date is: \u0026#34; + formatter.format(date)); System.out.println(\u0026#34;The date in \u0026#34; + timeZone.getID() + \u0026#34; is: \u0026#34; + sDate); System.out.println(\u0026#34;Object date: \u0026#34; + formatter.format(dateWithTimeZone)); } } The output of this example.\nThe actual date is: 29-07-2017 08:30:54 AM The date in Europe/Amsterdam is: 29-07-2017 01:30:54 PM Object date: 29-07-2017 01:30:54 PM How to change the timezone of a Date using Calendar #To change the time zone using the calendar class you must:\nCreate a Calendar Setting time zone to calendar Get the values through the specific gets. Note: if you try to get the date directly, calendar.getTime(), you will get the date always passed to the local time because what it returns is a java.util.Date and as we said before this one does not have the time zone.\nimport java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimeZone; public class TimeZoneChangeCalendarExample { private static final String DATE_FORMAT = \u0026#34;dd-MM-yyyy hh:mm:ss a\u0026#34;; public static void main(String[] args) throws ParseException { // calendar with tx TimeZone timeZone = TimeZone.getTimeZone(\u0026#34;Europe/Amsterdam\u0026#34;); Calendar calendar = Calendar.getInstance(); calendar.set(2017, 06, 29, 8, 30); calendar.setTimeZone(timeZone); // get calendar using fields int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND); SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); System.out.println(\u0026#34;The actual date is: \u0026#34; + formatter.format(calendar.getTime())); System.out.print(\u0026#34;The date in \u0026#34; + timeZone.getID() + \u0026#34; is: \u0026#34;); System.out.print(\u0026#34; Day:\u0026#34; + dayOfMonth); System.out.print(\u0026#34; Month:\u0026#34; + (month + 1)); // base zero System.out.print(\u0026#34; Year:\u0026#34; + year); System.out.print(\u0026#34; Hour:\u0026#34; + hourOfDay); System.out.print(\u0026#34; Min:\u0026#34; + minute); System.out.print(\u0026#34; Sec:\u0026#34; + second); System.out.println(); // calendar getTime with DateFormat SimpleDateFormat formatterWithTimeZone = new SimpleDateFormat(DATE_FORMAT); formatterWithTimeZone.setTimeZone(timeZone); System.out.println(\u0026#34;Calendar.getTime() - Date in Local TZ:\u0026#34; + formatterWithTimeZone.format(calendar.getTime())); } } Output.\nThe actual date is: 29-07-2017 03:30:22 AM The date in Europe/Amsterdam is: Day:29 Month:7 Year:2017 Hour:8 Min:30 Sec:22 Calendar.getTime() - Date in Local TZ:29-07-2017 08:30:22 AM How to change the timezone of a Date using Java 8+ #To change the time zone of a date in Java 8+:\nCreate a LocalDateTime Setting the original time zone at LocalDateTime Change the time zone of the original date import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; public class TimeZoneChangeZonedDateTime { public static void main(String[] args) { LocalDateTime localDateTime = LocalDateTime.of(2018, 06, 29, 8, 30); // zone from Buenos Aires ZoneId zoneBuenosAires = ZoneId.of(\u0026#34;America/Buenos_Aires\u0026#34;); ZonedDateTime asiaZonedDateTime = localDateTime.atZone(zoneBuenosAires); // zone from Amsterdan ZoneId zoneAmsterdan = ZoneId.of(\u0026#34;Europe/Amsterdam\u0026#34;); ZonedDateTime nyDateTime = asiaZonedDateTime.withZoneSameInstant(zoneAmsterdan); // print dateTime with tz System.out.println(\u0026#34;Date : \u0026#34; + asiaZonedDateTime); System.out.println(\u0026#34;Date : \u0026#34; + nyDateTime); } } Output:\nDate : 2018-06-29T08:30-03:00[America/Buenos_Aires] Date : 2018-06-29T13:30+02:00[Europe/Amsterdam] Conclusion #This post shows three ways to change the time zone for a date, starting on how to change the time zone for a java.util.Date, then for a java.util.Calendar and finally in Java8+ making use of the new api java.time.\nCode: Code of this post here ","date":"Jun 29, 2018","permalink":"https://gustavopeiretti.com/how-to-change-time-zone-date/","section":"Posts","summary":"","title":"How to change the time zone of a date"},{"content":"I\u0026rsquo;m Gustavo Peiretti, a Senior Backend Developer specializing in Java, Spring Boot, and microservices architecture. I care deeply about clean architecture and solid coding practices — not as abstract principles, but as the difference between a codebase that\u0026rsquo;s a pleasure to work in and one that fights you at every turn.\nOver the years I\u0026rsquo;ve worked across the full software development lifecycle: designing solutions, building them, shipping them to production, and living with the consequences of those decisions during maintenance. That full-cycle experience is what shapes how I approach architecture today — I try to build things that are easy to reason about months or years later, not just easy to ship today.\nTechnical learning doesn\u0026rsquo;t stop at the day job. I maintain a set of personal full-stack projects — including an expense tracker, a flashcards app, and a task management tool — as a way to keep experimenting with new tools, patterns, and ideas outside the constraints of any single employer. You\u0026rsquo;ll find case studies and notes from that work throughout this site.\nThis site is where I write about what I\u0026rsquo;m building, the technical decisions behind it, and what I\u0026rsquo;m currently exploring. If something here is useful to you, or you\u0026rsquo;d like to get in touch, feel free to reach out at contacto@gustavopeiretti.com.\nOutside of code, I enjoy reading, photography, and spending time with my family — the things that keep the rest in perspective.\n","date":"Nov 20, 2007","permalink":"https://gustavopeiretti.com/about-me/","section":"Pages","summary":"","title":"About"}]