<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anh Trần Tuấn</title>
    <description>The latest articles on DEV Community by Anh Trần Tuấn (@anh_trntun_4732cf3d299).</description>
    <link>https://dev.to/anh_trntun_4732cf3d299</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1505219%2Face20e07-bae9-401e-b700-8b3000bf1cc1.png</url>
      <title>DEV Community: Anh Trần Tuấn</title>
      <link>https://dev.to/anh_trntun_4732cf3d299</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anh_trntun_4732cf3d299"/>
    <language>en</language>
    <item>
      <title>Design Multi-Step Forms Efficiently on the Server-Side with Java</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Wed, 13 Aug 2025 09:00:22 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/design-multi-step-forms-efficiently-on-the-server-side-with-java-4op</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/design-multi-step-forms-efficiently-on-the-server-side-with-java-4op</guid>
      <description>&lt;h2&gt;
  
  
  1. Understanding Multi-Step Forms on the Server-Side
&lt;/h2&gt;

&lt;p&gt;A multi-step form breaks a single large form into smaller, sequential steps. Each step collects a subset of data, and users proceed through each step until completion. On the server side, this requires managing: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;State across steps&lt;/strong&gt; to ensure continuity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validation&lt;/strong&gt; for each step's data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error handling&lt;/strong&gt; to guide users back when issues arise.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Core Approach to Implementing Multi-Step Forms
&lt;/h2&gt;

&lt;p&gt;Let’s dive into an effective implementation using Spring MVC as the server-side framework. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Structuring the Form Flow
&lt;/h3&gt;

&lt;p&gt;The first step is to define how the form progresses across steps. Each step should be represented by a dedicated endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Controller
@RequestMapping("/multi-step-form")
public class MultiStepFormController {

    @GetMapping("/step1")
    public String showStep1(Model model) {
        model.addAttribute("formData", new FormData());
        return "step1";
    }

    @PostMapping("/step1")
    public String handleStep1(@ModelAttribute FormData formData, HttpSession session) {
        session.setAttribute("formData", formData); // Save data in session
        return "redirect:/multi-step-form/step2"; // Redirect to the next step
    }

    @GetMapping("/step2")
    public String showStep2(HttpSession session, Model model) {
        FormData formData = (FormData) session.getAttribute("formData");
        if (formData == null) {
            return "redirect:/multi-step-form/step1"; // Redirect to step 1 if session is empty
        }
        model.addAttribute("formData", formData);
        return "step2";
    }

    @PostMapping("/step2")
    public String handleStep2(@ModelAttribute FormData formData, HttpSession session) {
        session.setAttribute("formData", formData);
        return "redirect:/multi-step-form/step3";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup ensures that each step can access the data submitted in the previous steps via the session. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 Managing State
&lt;/h3&gt;

&lt;p&gt;State management is central to server-side multi-step forms. HTTP sessions are commonly used to store the data for the duration of the form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;session.setAttribute("formData", formData);
FormData formData = (FormData) session.getAttribute("formData");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Consideration:&lt;/strong&gt; Sessions are memory-intensive. Configure session timeouts carefully, especially for large-scale applications. For better scalability, consider persisting data in a database after each step. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 Validating Each Step
&lt;/h3&gt;

&lt;p&gt;Validation is essential to prevent invalid data from propagating to subsequent steps. Use Spring’s validation framework to handle this: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 Validation Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
public class Step1Validator implements Validator {

    @Override
    public boolean supports(Class&amp;lt;?&amp;gt; clazz) {
        return FormData.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        FormData formData = (FormData) target;
        if (formData.getName() == null || formData.getName().isEmpty()) {
            errors.rejectValue("name", "field.required", "Name is required");
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Integrate the validator into the controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@PostMapping("/step1")
public String handleStep1(@ModelAttribute @Valid FormData formData, BindingResult result, HttpSession session) {
    if (result.hasErrors()) {
        return "step1"; // Return to the same step with error messages
    }
    session.setAttribute("formData", formData);
    return "redirect:/multi-step-form/step2"; // Proceed to the next step
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This modular validation ensures each step can handle its specific requirements independently. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.4 Navigating Between Steps
&lt;/h3&gt;

&lt;p&gt;Navigation logic ensures that users don’t skip steps unintentionally. Use server-side checks to validate the current state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@GetMapping("/step2")
public String showStep2(HttpSession session, Model model) {
    FormData formData = (FormData) session.getAttribute("formData");
    if (formData == null) {
        return "redirect:/multi-step-form/step1"; // Redirect to step 1
    }
    model.addAttribute("formData", formData);
    return "step2";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By redirecting users to the appropriate step, we prevent navigation errors and ensure a smooth flow. &lt;/p&gt;

&lt;h3&gt;
  
  
  3. Enhancing the Multi-Step Form
&lt;/h3&gt;

&lt;h3&gt;
  
  
  3.1 Persisting Data for Scalability
&lt;/h3&gt;

&lt;p&gt;Instead of relying entirely on sessions, persist form data into a database after each step. This ensures the form can resume even if the session is lost:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entity
public class FormData {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String address;
    // Additional fields
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the form data during each step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@PostMapping("/step2")
public String handleStep2(@ModelAttribute @Valid FormData formData, BindingResult result) {
    if (result.hasErrors()) {
        return "step2";
    }
    formDataRepository.save(formData);
    return "redirect:/multi-step-form/step3";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Providing Meaningful Feedback
&lt;/h3&gt;

&lt;p&gt;A multi-step form must provide clear feedback to users at every step. Use error messages and progress indicators to guide the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Progress Indicator --&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;p&amp;gt;Step 2 of 3&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;!-- Display Errors --&amp;gt;
&amp;lt;div th:if="${#fields.hasErrors()}"&amp;gt;
    &amp;lt;p th:each="err : ${#fields.errors('name')}" th:text="${err}"&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Handling Long-Running Processes
&lt;/h3&gt;

&lt;p&gt;If a step involves long-running tasks, such as uploading files or calling external APIs, use asynchronous processing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@PostMapping("/step3")
public CompletableFuture&amp;lt;String&amp;gt; handleStep3(@ModelAttribute FormData formData) {
    return CompletableFuture.supplyAsync(() -&amp;gt; {
        externalService.processData(formData);
        return "redirect:/multi-step-form/complete";
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach prevents blocking and improves user experience. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Best Practices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Keep Each Step Focused&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design each step to collect only the data necessary for that stage. Avoid overwhelming users with too many fields. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secure Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Protect the form data with CSRF tokens and secure session management practices to prevent tampering. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test for Edge Cases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thoroughly test scenarios like session expiry, incomplete data, and invalid submissions to ensure resilience. &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Conclusion
&lt;/h2&gt;

&lt;p&gt;Implementing an effective multi-step form on the server side with Java requires attention to detail in state management, validation, and navigation. By following the techniques outlined in this article, you can build scalable and user-friendly forms tailored to your application’s needs. &lt;/p&gt;

&lt;p&gt;Have questions or need clarification? Leave a comment below, and I’ll be happy to help! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Java/design-multistep-forms-efficiently-on-the-serverside-with-java" rel="noopener noreferrer"&gt;Design Multi-Step Forms Efficiently on the Server-Side with Java&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>java</category>
      <category>frontendjava</category>
    </item>
    <item>
      <title>Secrets to Masking Sensitive Data Before Sending to the Frontend in Java</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Tue, 12 Aug 2025 09:00:18 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/secrets-to-masking-sensitive-data-before-sending-to-the-frontend-in-java-3o4d</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/secrets-to-masking-sensitive-data-before-sending-to-the-frontend-in-java-3o4d</guid>
      <description>&lt;h2&gt;
  
  
  1. Why Masking Sensitive Data is Essential
&lt;/h2&gt;

&lt;p&gt;Masking data refers to transforming sensitive information into a partially or entirely obfuscated format to prevent unauthorized access or exposure. Before diving into the technical aspects, it's crucial to understand why this practice matters. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protecting User Privacy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User privacy laws such as GDPR and CCPA enforce strict guidelines on how personal data should be handled. Masking data helps businesses comply with these regulations by ensuring only non-identifiable data is shared. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mitigating Security Risks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even if your backend is secure, exposing sensitive data in its raw form to the frontend increases the attack surface. Masking sensitive information significantly reduces the potential damage caused by data leaks. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Techniques for Masking Data in Java
&lt;/h2&gt;

&lt;p&gt;Java provides robust libraries and tools to implement masking strategies effectively. Here, we’ll cover various approaches, from basic manual masking to leveraging libraries. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Basic Manual Masking
&lt;/h3&gt;

&lt;p&gt;The simplest way to mask data is to manually replace specific characters with symbols such as *. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example: Masking a Credit Card Number&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DataMaskingUtil {

    public static String maskCreditCard(String creditCardNumber) {
        if (creditCardNumber == null || creditCardNumber.length() &amp;lt; 6) {
            throw new IllegalArgumentException("Invalid credit card number");
        }

        int prefixLength = 4;
        int suffixLength = 4;
        String prefix = creditCardNumber.substring(0, prefixLength);
        String suffix = creditCardNumber.substring(creditCardNumber.length() - suffixLength);
        String masked = "*".repeat(creditCardNumber.length() - prefixLength - suffixLength);

        return prefix + masked + suffix;
    }

    public static void main(String[] args) {
        String cardNumber = "1234567812345678";
        System.out.println(maskCreditCard(cardNumber)); // Output: 1234 ******** 5678
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The prefix and suffix are retained for identification purposes.&lt;/li&gt;
&lt;li&gt;The rest of the digits are replaced with *, ensuring sensitive parts remain hidden.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 Using Regular Expressions for Flexible Masking
&lt;/h3&gt;

&lt;p&gt;Regular expressions provide a powerful way to mask patterns in strings, such as email addresses or Social Security numbers. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example: Masking an Email Address&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class EmailMaskingUtil {

    public static String maskEmail(String email) {
        if (email == null || !email.contains("@")) {
            throw new IllegalArgumentException("Invalid email address");
        }

        String[] parts = email.split("@");
        String localPart = parts[0];
        String domain = parts[1];

        String maskedLocalPart = localPart.charAt(0) + "*".repeat(Math.max(0, localPart.length() - 2)) + localPart.charAt(localPart.length() - 1);

        return maskedLocalPart + "@" + domain;
    }

    public static void main(String[] args) {
        String email = "john.doe@example.com";
        System.out.println(maskEmail(email)); // Output: j ******* e@example.com
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only the first and last characters of the local part are exposed.&lt;/li&gt;
&lt;li&gt;Regular expressions split the email into identifiable components for flexible manipulation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 Masking JSON Data Using Libraries
&lt;/h3&gt;

&lt;p&gt;When handling structured data, like JSON, masking requires more sophisticated tools. Libraries such as Jackson can be extended to mask sensitive fields dynamically. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example: Masking Fields in JSON&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

class User {
    @JsonProperty("name")
    private String name;

    @JsonProperty("creditCard")
    private String creditCard;

    public User(String name, String creditCard) {
        this.name = name;
        this.creditCard = creditCard;
    }

    public String getName() {
        return name;
    }

    public String getMaskedCreditCard() {
        return DataMaskingUtil.maskCreditCard(this.creditCard);
    }
}

public class JsonMaskingDemo {
    public static void main(String[] args) throws JsonProcessingException {
        User user = new User("John Doe", "1234567812345678");
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(user)); 
        // Output: {"name":"John Doe","creditCard":"1234 ******** 5678"}
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sensitive fields such as credit card numbers are masked during serialization.&lt;/li&gt;
&lt;li&gt;Custom masking logic is applied using utility functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Best Practices for Data Masking
&lt;/h2&gt;

&lt;p&gt;Masking data effectively requires more than writing code. Best practices ensure robustness and compliance. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mask at the Right Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Data should ideally be masked at the service layer before it reaches the API response. This ensures the backend itself doesn’t leak sensitive information. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audit and Monitor Logs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make sure your logging systems don’t inadvertently capture sensitive data before masking. Use log sanitizers to handle this. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Advanced Techniques: Leveraging Frameworks
&lt;/h2&gt;

&lt;p&gt;Frameworks like Spring provide built-in mechanisms for masking data in specific scenarios, such as logging. &lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 Masking Sensitive Data in Spring Logs
&lt;/h3&gt;

&lt;p&gt;Spring Boot’s Logback allows you to customize log patterns and mask sensitive fields. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuration Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
    &amp;lt;appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"&amp;gt;
        &amp;lt;encoder&amp;gt;
            &amp;lt;pattern&amp;gt;%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %replace(%msg){'\d{16}', ' ****'}%n&amp;lt;/pattern&amp;gt;
        &amp;lt;/encoder&amp;gt;
    &amp;lt;/appender&amp;gt;
    &amp;lt;root level="info"&amp;gt;
        &amp;lt;appender-ref ref="CONSOLE" /&amp;gt;
    &amp;lt;/root&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Conclusion
&lt;/h2&gt;

&lt;p&gt;Masking sensitive data is a critical part of any secure application. By using manual techniques, regular expressions, or powerful libraries, Java developers can ensure sensitive information remains hidden from unauthorized eyes. Remember, this is just one layer of defense in a multi-layered security strategy. &lt;/p&gt;

&lt;p&gt;Do you have questions or unique scenarios regarding masking data? Feel free to comment below—I’d be happy to discuss and provide further insights! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Java/secrets-to-masking-sensitive-data-before-sending-to-the-frontend-in-java" rel="noopener noreferrer"&gt;Secrets to Masking Sensitive Data Before Sending to the Frontend in Java&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>java</category>
      <category>securityserver</category>
    </item>
    <item>
      <title>Reasons and Ways to Fix 'Required a Bean That Could Not Be Found' in Spring Boot</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Sun, 10 Aug 2025 09:00:08 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/reasons-and-ways-to-fix-required-a-bean-that-could-not-be-found-in-spring-boot-32eb</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/reasons-and-ways-to-fix-required-a-bean-that-could-not-be-found-in-spring-boot-32eb</guid>
      <description>&lt;h2&gt;
  
  
  1. What Does 'Required a Bean That Could Not Be Found' Mean?
&lt;/h2&gt;

&lt;p&gt;Spring Boot relies on dependency injection to wire beans together. When a component or class requires a bean (via @Autowired or constructor injection), Spring searches for it in the application context. If it cannot find the required bean, this error occurs. &lt;/p&gt;

&lt;p&gt;The error might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'com.example.service.MyService' available.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This indicates that Spring could not locate a bean of type MyService to inject into the dependent class. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Common Cause: Missing Bean Definition
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Example of the Problem
&lt;/h3&gt;

&lt;p&gt;Consider the following scenario:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
public class MyController {

    private final MyService myService;

    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }

    @GetMapping("/hello")
    public String sayHello() {
        return myService.getMessage();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the MyService class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MyService {
    public String getMessage() {
        return "Hello, Spring!";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run the application, it throws the error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No qualifying bean of type 'com.example.service.MyService' available.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem? Spring does not know about MyService because it is not a Spring-managed bean. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 Step-by-Step Solution
&lt;/h3&gt;

&lt;p&gt;To fix this, you must annotate MyService with a Spring stereotype such as @Component, @Service, or define it explicitly in a configuration class. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Annotating with @Service&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class MyService {
    public String getMessage() {
        return "Hello, Spring!";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes Spring recognize MyService as a bean and adds it to the application context. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Explicit Configuration with &lt;a class="mentioned-user" href="https://dev.to/bean"&gt;@bean&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, if you prefer not to use annotations, define the bean in a configuration class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyService();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spring will now instantiate MyService and make it available for injection. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Debugging the Error: Identifying the Root Cause
&lt;/h2&gt;

&lt;p&gt;To efficiently debug this error, follow these steps: &lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 Enable Debug Logs
&lt;/h3&gt;

&lt;p&gt;Enable debug logging to understand how Spring processes your beans. Add this to your application.properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logging.level.org.springframework=DEBUG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will log bean creation details and can reveal why a particular bean is missing. &lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Check for Bean Scanning Issues
&lt;/h3&gt;

&lt;p&gt;Spring Boot only scans the package of the main application class (@SpringBootApplication) and its sub-packages. If your bean is in a different package, Spring won’t detect it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of the Problem:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, if MyService is in com.example.service but the main class is in com.example.app, the bean won’t be detected. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Specify the package explicitly using @ComponentScan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootApplication
@ComponentScan(basePackages = {"com.example.service", "com.example.app"})
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Advanced Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Missing Qualifier for Multiple Beans
&lt;/h3&gt;

&lt;p&gt;If multiple beans of the same type exist and Spring cannot determine which one to inject, you may still encounter this error. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class MyServiceA implements MyService {
    public String getMessage() {
        return "Message from Service A";
    }
}

@Service
public class MyServiceB implements MyService {
    public String getMessage() {
        return "Message from Service B";
    }
}

@RestController
public class MyController {

    private final MyService myService;

    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Error:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No qualifying bean of type 'com.example.service.MyService' available: expected single matching bean but found 2: myServiceA,myServiceB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution: Use @Qualifier&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
public class MyController {

    private final MyService myService;

    @Autowired
    public MyController(@Qualifier("myServiceA") MyService myService) {
        this.myService = myService;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, @Qualifier specifies which implementation to use. &lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 Conditional Beans
&lt;/h3&gt;

&lt;p&gt;Conditional annotations like @ConditionalOnProperty or &lt;a class="mentioned-user" href="https://dev.to/profile"&gt;@profile&lt;/a&gt; might inadvertently exclude a bean. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Bean
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public MyService myService() {
    return new MyService();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If feature.enabled=true is missing in application.properties, the bean won’t be loaded. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ensure the required conditions are met in the configuration. &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Best Practices to Avoid This Error
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Always Annotate Bean Classes Properly&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use annotations like @Component, @Service, @Repository, or @Configuration to make Spring recognize your beans. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be Explicit About Scans&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For large projects, explicitly define @ComponentScan to avoid bean scanning issues. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use @Qualifier for Ambiguity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Always use @Qualifier when multiple implementations exist for the same interface. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Leverage Profiles and Conditions Carefully&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ensure that profile-specific beans or conditional beans are correctly configured and their conditions are met. &lt;/p&gt;

&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;The required a bean that could not be found error is a common pitfall in Spring Boot development but is relatively straightforward to resolve with a systematic approach. By ensuring beans are properly defined, scanned, and configured, you can eliminate this issue entirely. &lt;/p&gt;

&lt;p&gt;Have you faced this error in a unique scenario? Share your questions or experiences in the comments below, and let’s discuss solutions! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Spring/reasons-and-ways-to-fix-required-a-bean-that-could-not-be-found-in-spring-boot" rel="noopener noreferrer"&gt;Reasons and Ways to Fix 'Required a Bean That Could Not Be Found' in Spring Boot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>spring</category>
      <category>springbean</category>
    </item>
    <item>
      <title>Solving FileNotFoundException When Handling MultipartFile in Spring Boot</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Sat, 09 Aug 2025 09:00:22 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/solving-filenotfoundexception-when-handling-multipartfile-in-spring-boot-eon</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/solving-filenotfoundexception-when-handling-multipartfile-in-spring-boot-eon</guid>
      <description>&lt;h2&gt;
  
  
  1. Understanding the FileNotFoundException
&lt;/h2&gt;

&lt;p&gt;This exception occurs when your application attempts to access a file or directory that does not exist at the specified path. In the context of MultipartFile, this is often due to mishandling file storage or incorrect paths in your code. &lt;/p&gt;

&lt;h3&gt;
  
  
  What Triggers FileNotFoundException?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Temporary File Handling&lt;/strong&gt; : MultipartFile stores uploaded files in temporary locations, which can expire unexpectedly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incorrect Paths&lt;/strong&gt; : Using relative paths or incorrect directory configurations often causes the application to fail in locating the file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permission Issues&lt;/strong&gt; : The application might lack sufficient permissions to access or create the intended file or directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.2 A Real-Life Example of the Problem
&lt;/h3&gt;

&lt;p&gt;Let’s consider a typical file upload endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@PostMapping("/upload")
public ResponseEntity&amp;lt;String&amp;gt; uploadFile(@RequestParam("file") MultipartFile file) {
    try {
        // Save the file to a specific directory
        String uploadDir = "/uploads/";
        Path filePath = Paths.get(uploadDir + file.getOriginalFilename());

        // Ensure the directory exists
        Files.createDirectories(filePath.getParent());

        // Save the file
        file.transferTo(filePath);

        return ResponseEntity.ok("File uploaded successfully!");
    } catch (IOException e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("Error while uploading file: " + e.getMessage());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What Could Go Wrong? &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Missing /uploads/ Directory&lt;/strong&gt; : If /uploads/ does not exist, the FileNotFoundException occurs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporary File Expiry&lt;/strong&gt; : The MultipartFile content might not persist long enough for file.transferTo() to execute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File System Permissions&lt;/strong&gt; : If the server lacks write permissions, the operation fails.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.3 Debugging the Error
&lt;/h3&gt;

&lt;p&gt;To resolve the issue, follow these steps: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enable Detailed Logging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add debug logs around file handling operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log.debug("Uploading file to path: {}", filePath.toString());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Check Permissions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the application user with sufficient privileges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod -R 755 /uploads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Test File Path&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Verify the resolved path and ensure it matches expectations. For example, print the resolved path before the file operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System.out.println(filePath.toAbsolutePath());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Solutions to Handle MultipartFile Properly
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Use Configurable File Storage
&lt;/h3&gt;

&lt;p&gt;Hardcoding paths is risky. Instead, externalize the storage directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;file.upload-dir=/var/uploads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update your code to use this property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Value("${file.upload-dir}")
private String uploadDir;

@PostMapping("/upload")
public ResponseEntity&amp;lt;String&amp;gt; uploadFile(@RequestParam("file") MultipartFile file) {
    try {
        Path filePath = Paths.get(uploadDir + "/" + file.getOriginalFilename());
        Files.createDirectories(filePath.getParent());
        file.transferTo(filePath);
        return ResponseEntity.ok("File uploaded successfully!");
    } catch (IOException e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("Error while uploading file: " + e.getMessage());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why It Works&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The property-based approach ensures flexibility.&lt;/li&gt;
&lt;li&gt;Paths can be modified without redeploying the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 Handle Temporary Files Explicitly
&lt;/h3&gt;

&lt;p&gt;Instead of relying on the default behavior, explicitly manage temporary files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@PostMapping("/upload")
public ResponseEntity&amp;lt;String&amp;gt; uploadFile(@RequestParam("file") MultipartFile file) {
    try {
        File tempFile = File.createTempFile("upload-", file.getOriginalFilename());
        file.transferTo(tempFile);
        // Move the file to the desired directory
        Path destination = Paths.get(uploadDir + "/" + file.getOriginalFilename());
        Files.move(tempFile.toPath(), destination, StandardCopyOption.REPLACE_EXISTING);
        return ResponseEntity.ok("File uploaded successfully!");
    } catch (IOException e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("Error while uploading file: " + e.getMessage());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why It Works&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Temporary files ensure content availability during processing.&lt;/li&gt;
&lt;li&gt;Explicit movement to the target directory prevents FileNotFoundException.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 Test Scenarios Thoroughly
&lt;/h3&gt;

&lt;p&gt;Always test your application in the environments it will run in (e.g., local, staging, production). Use these test cases: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upload large files to simulate delays.&lt;/li&gt;
&lt;li&gt;Test with restricted permissions.&lt;/li&gt;
&lt;li&gt;Use edge cases such as uploading files with invalid names.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.4 Embrace Exception Handling
&lt;/h3&gt;

&lt;p&gt;Catch and log all file-related exceptions to provide meaningful feedback to users. Enhance the earlier example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;catch (FileNotFoundException e) {
    log.error("File not found: {}", e.getMessage());
    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("File path is invalid.");
} catch (IOException e) {
    log.error("IO Error: {}", e.getMessage());
    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body("An error occurred while processing the file.");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Best Practices for MultipartFile in Spring Boot
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Always Validate the File
&lt;/h3&gt;

&lt;p&gt;Check for null files and validate the file type before processing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (file.isEmpty() || !file.getContentType().startsWith("image/")) {
    throw new IllegalArgumentException("Invalid file. Only image files are allowed.");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Secure File Uploads
&lt;/h3&gt;

&lt;p&gt;Avoid storing files in web-accessible directories to mitigate security risks. Instead, use a service layer to serve files. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@GetMapping("/files/{filename}")
public ResponseEntity&amp;lt;Resource&amp;gt; getFile(@PathVariable String filename) {
    Path file = Paths.get(uploadDir).resolve(filename);
    Resource resource = new UrlResource(file.toUri());
    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(resource);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Monitor Disk Space
&lt;/h3&gt;

&lt;p&gt;Use monitoring tools to track disk usage. A full disk can cause FileNotFoundException. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Conclusion
&lt;/h2&gt;

&lt;p&gt;Handling MultipartFile properly in Spring Boot requires attention to detail, from correctly configuring file storage to implementing robust exception handling. By understanding the root causes of FileNotFoundException and adopting the solutions above, you can ensure a reliable file upload mechanism. &lt;/p&gt;

&lt;p&gt;Have you faced similar issues with MultipartFile? Let us know in the comments below, and feel free to share any questions! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Java/solving-filenotfoundexception-when-handling-multipartfile-in-spring-boot" rel="noopener noreferrer"&gt;Solving FileNotFoundException When Handling MultipartFile in Spring Boot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>java</category>
      <category>fileexception</category>
    </item>
    <item>
      <title>Upload Files with Special Characters to S3 Buckets and Handle Presigned URL Errors</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Fri, 08 Aug 2025 09:00:25 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/upload-files-with-special-characters-to-s3-buckets-and-handle-presigned-url-errors-4k0m</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/upload-files-with-special-characters-to-s3-buckets-and-handle-presigned-url-errors-4k0m</guid>
      <description>&lt;h2&gt;
  
  
  1. Understanding the Problem
&lt;/h2&gt;

&lt;p&gt;Before diving into solutions, let’s examine why files with special characters can cause issues when uploading to S3. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 How S3 Handles Special Characters
&lt;/h3&gt;

&lt;p&gt;Amazon S3 uses URIs (Uniform Resource Identifiers) to access objects. Certain characters—like /, @, or :—have special meanings in URIs, while others may require encoding to work properly. For instance: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spaces are often converted to %20.&lt;/li&gt;
&lt;li&gt;Reserved characters like ? and &amp;amp; can cause the URL to break if not encoded.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.2 The Role of Presigned URLs
&lt;/h3&gt;

&lt;p&gt;A presigned URL allows temporary access to S3 resources. The AWS SDK automatically generates these URLs with query parameters and signatures. However, improper handling of special characters in the file name or key can lead to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signature mismatch errors.&lt;/li&gt;
&lt;li&gt;403 Forbidden responses.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.3 Encoding and Decoding Challenges
&lt;/h3&gt;

&lt;p&gt;Many developers overlook encoding requirements, leading to mismatches between how the URL is generated and consumed. Improper encoding can also result in corrupted file names on upload. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Methods to Upload Files with Special Characters to S3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Generating Presigned URLs Correctly
&lt;/h3&gt;

&lt;p&gt;The first step is to ensure that presigned URLs are generated with proper encoding. Here’s an example in Java using the AWS SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GeneratePresignedUrlRequest;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Date;

public class S3PresignedUrlExample {
    public static void main(String[] args) {
        String bucketName = "your-bucket-name";
        String objectKey = "my file@123#.txt"; // File with special characters

        // Encode the key
        String encodedKey = URLEncoder.encode(objectKey, StandardCharsets.UTF_8);

        S3Client s3Client = S3Client.builder()
                .credentialsProvider(ProfileCredentialsProvider.create())
                .build();

        // Generate the presigned URL
        var presignedUrlRequest = GeneratePresignedUrlRequest.builder()
                .bucket(bucketName)
                .key(encodedKey)
                .expiration(Date.from(Instant.now().plusSeconds(3600)))
                .build();

        String presignedUrl = s3Client.utilities().getUrl(presignedUrlRequest).toExternalForm();
        System.out.println("Presigned URL: " + presignedUrl);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encoding Special Characters&lt;/strong&gt; : Using URLEncoder.encode ensures that special characters are converted to their URI-encoded forms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Presigned URL Expiration&lt;/strong&gt; : The expiration time ensures temporary access, minimizing security risks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 Uploading Files Using Presigned URLs
&lt;/h3&gt;

&lt;p&gt;Once the presigned URL is generated, you can use tools like curl or libraries like HttpClient in Java to upload the file. Below is an example in Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

public class S3FileUpload {
    public static void main(String[] args) throws IOException {
        String presignedUrl = "https://example-bucket.s3.amazonaws.com/my%20file%40123%23.txt?AWSAccessKeyId=..."; 
        File file = new File("path/to/your/file/my file@123#.txt");

        HttpURLConnection connection = (HttpURLConnection) new URL(presignedUrl).openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("PUT");

        // Upload file
        try (var outputStream = connection.getOutputStream();
             var inputStream = new FileInputStream(file)) {
            inputStream.transferTo(outputStream);
        }

        int responseCode = connection.getResponseCode();
        if (responseCode == 200) {
            System.out.println("File uploaded successfully.");
        } else {
            System.out.println("Failed to upload file. Response code: " + responseCode);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Presigned URL Usage&lt;/strong&gt; : The URL includes the key, query parameters, and signature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handling Special Characters&lt;/strong&gt; : The encoded key (my%20file%40123%23.txt) ensures compatibility with the S3 API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 Common Issues and Solutions
&lt;/h3&gt;

&lt;p&gt;Even with the right setup, errors can occur. Below are common issues and their resolutions: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Signature Mismatch:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cause&lt;/strong&gt; : Inconsistent encoding between presigned URL generation and usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt; : Always encode special characters and ensure both client and server handle URLs identically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;403 Forbidden:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cause&lt;/strong&gt; : Expired presigned URL or incorrect bucket permissions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt; : Ensure the URL is generated with sufficient validity and verify S3 bucket policies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Corrupted File Names:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cause&lt;/strong&gt; : Improper decoding on the S3 side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt; : Decode the file name correctly when processing S3 events.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Beyond File Uploads: Related Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Bucket Policies and IAM Roles
&lt;/h3&gt;

&lt;p&gt;Special characters in file names may also interact with bucket policies. Always use IAM roles with the least privilege and validate permissions for specific actions like s3:PutObject. &lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 File Metadata Handling
&lt;/h3&gt;

&lt;p&gt;When uploading files, include metadata such as Content-Type and Content-Disposition to ensure the file is served correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;connection.setRequestProperty("Content-Type", "text/plain");
connection.setRequestProperty("Content-Disposition", "attachment; filename="my file@123#.txt"");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Conclusion
&lt;/h2&gt;

&lt;p&gt;Uploading files with special characters to an S3 bucket is challenging but manageable with proper encoding, presigned URL generation, and error handling. By understanding how S3 processes object keys and signatures, you can avoid common pitfalls and ensure seamless uploads. &lt;/p&gt;

&lt;p&gt;Got questions or stuck on a specific issue? Comment below, and I’ll be happy to help! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Java/upload-files-with-special-characters-to-s3-buckets-and-handle-presigned-url-errors" rel="noopener noreferrer"&gt;Upload Files with Special Characters to S3 Buckets and Handle Presigned URL Errors&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>java</category>
      <category>s3awsjavafile</category>
    </item>
    <item>
      <title>Why ‘String Cannot Be Converted to JSONObject’ Occurs and How to Fix It</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Thu, 07 Aug 2025 09:00:21 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/why-string-cannot-be-converted-to-jsonobject-occurs-and-how-to-fix-it-2l6p</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/why-string-cannot-be-converted-to-jsonobject-occurs-and-how-to-fix-it-2l6p</guid>
      <description>&lt;h2&gt;
  
  
  1. Understanding the Error: What Does It Mean?
&lt;/h2&gt;

&lt;p&gt;When Java processes JSON data using libraries like org.json or Gson, it requires the input to follow strict JSON formatting. The error String cannot be converted to JSONObject indicates that the application attempted to parse a string as a JSON object, but the string failed to meet the JSON structure requirements. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 Basic Definition of JSONObject
&lt;/h3&gt;

&lt;p&gt;A JSONObject in Java represents a JSON object. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "key": "value",
  "anotherKey": 42
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure contains key-value pairs, which JSONObject can easily process. If the input string is missing required syntax, such as braces {} or is malformed, Java throws this error. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 Common Causes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The string is not in valid JSON format (e.g., a plain string instead of JSON).&lt;/li&gt;
&lt;li&gt;The string contains additional characters, such as a newline or whitespace, that prevent parsing.&lt;/li&gt;
&lt;li&gt;The API response is unexpected, such as returning XML or plain text instead of JSON.&lt;/li&gt;
&lt;li&gt;Improper encoding or decoding during transmission.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Resolving the Issue with Practical Examples
&lt;/h2&gt;

&lt;p&gt;Let's address how to debug and fix this issue in Java. Each method below includes an example and a detailed explanation. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn366iiybq81ibi7ap35c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn366iiybq81ibi7ap35c.png" alt="Image" width="280" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Validate the Input String
&lt;/h3&gt;

&lt;p&gt;Before attempting to parse, ensure the string is valid JSON. Using a validation library or method helps avoid unnecessary exceptions. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.json.JSONObject;

public class JsonValidator {
    public static boolean isValidJson(String json) {
        try {
            new JSONObject(json);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static void main(String[] args) {
        String input = "{ "name": "Tuan Anh", "age": 30 }";
        if (isValidJson(input)) {
            System.out.println("Valid JSON: " + input);
        } else {
            System.out.println("Invalid JSON");
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This code checks whether a given string is valid JSON.&lt;/li&gt;
&lt;li&gt;If the string is invalid, you can handle it gracefully instead of letting the application crash.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 Handle Unexpected API Responses
&lt;/h3&gt;

&lt;p&gt;Sometimes, the error occurs because the string comes from an API that doesn’t consistently return JSON. For example, an error response might be plain text. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.json.JSONObject;

public class ApiResponseHandler {
    public static void processResponse(String response) {
        try {
            JSONObject jsonObject = new JSONObject(response);
            System.out.println("Parsed JSON: " + jsonObject);
        } catch (Exception e) {
            System.out.println("Invalid response format: " + response);
        }
    }

    public static void main(String[] args) {
        String apiResponse = "&amp;lt;html&amp;gt;Error 404: Not Found&amp;lt;/html&amp;gt;"; // Simulated API response
        processResponse(apiResponse);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This code demonstrates how to safeguard against non-JSON responses from APIs.&lt;/li&gt;
&lt;li&gt;By wrapping the parsing operation in a try-catch block, it catches exceptions and logs invalid data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 Strip Unnecessary Characters
&lt;/h3&gt;

&lt;p&gt;Sometimes, strings contain unwanted characters such as whitespace or escape sequences. Stripping these can help.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.json.JSONObject;

public class JsonCleaner {
    public static String cleanJsonString(String input) {
        return input.trim(); // Removes leading and trailing whitespace
    }

    public static void main(String[] args) {
        String rawInput = " {"key":"value"} ";
        String cleanedInput = cleanJsonString(rawInput);

        try {
            JSONObject jsonObject = new JSONObject(cleanedInput);
            System.out.println("Cleaned and Parsed JSON: " + jsonObject);
        } catch (Exception e) {
            System.out.println("Error parsing JSON");
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This solution trims unnecessary spaces or characters from the string before parsing.&lt;/li&gt;
&lt;li&gt;It’s particularly useful when dealing with inconsistent input formats.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Preventive Measures and Best Practices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Always Validate API Responses&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use libraries such as Jackson or org.json to handle JSON, but always validate the response to ensure it adheres to expected formats. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitor Encoding Issues&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Encoding problems, especially when transferring data between systems, often cause malformed JSON. Double-check encoding standards (e.g., UTF-8). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use a Robust JSON Library&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For better error handling and more advanced features, consider using Gson or Jackson. These libraries provide better utilities for working with JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class GsonExample {
    public static void main(String[] args) {
        String jsonString = "{ "name": "Tuan Anh", "role": "Developer" }";

        try {
            JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
            System.out.println("Parsed with Gson: " + jsonObject);
        } catch (Exception e) {
            System.out.println("Failed to parse JSON");
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Common Pitfalls and Troubleshooting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Relying on Assumptions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Avoid assuming all inputs are correctly formatted. Always validate inputs before parsing. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ignoring Exception Details&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Exception messages often reveal why parsing fails. For example, an error might indicate that a specific key is missing or malformed. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skipping API Documentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ensure the API's documentation specifies its response format. If not, handle all possible cases (e.g., JSON, plain text, or XML). &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Conclusion
&lt;/h2&gt;

&lt;p&gt;Handling the String cannot be converted to JSONObject error requires understanding JSON structures, validating inputs, and preparing for unexpected data. With proper preventive measures and robust error handling, you can ensure your application processes JSON data reliably. Have you faced challenges with JSON parsing in Java? Feel free to share your questions or experiences in the comments below! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Java/why-string-cannot-be-converted-to-jsonobject-occurs-and-how-to-fix-it" rel="noopener noreferrer"&gt;Why ‘String Cannot Be Converted to JSONObject’ Occurs and How to Fix It&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>java</category>
      <category>stringexception</category>
    </item>
    <item>
      <title>Why Your Spring Data JPA Entity Classes Are Not Recognized and How to Fix It</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Wed, 06 Aug 2025 09:00:17 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/why-your-spring-data-jpa-entity-classes-are-not-recognized-and-how-to-fix-it-1ihc</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/why-your-spring-data-jpa-entity-classes-are-not-recognized-and-how-to-fix-it-1ihc</guid>
      <description>&lt;h2&gt;
  
  
  1. Understanding the Issue
&lt;/h2&gt;

&lt;p&gt;Spring Data JPA relies on entity classes to interact with your database. If these classes are not properly recognized, you might encounter exceptions like EntityNotFoundException or NoSuchBeanDefinitionException. These issues typically stem from misconfigurations in your project. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 What Is an Entity in JPA?
&lt;/h3&gt;

&lt;p&gt;An entity in JPA represents a table in the database. Each instance of the entity corresponds to a row in that table. To define an entity, the class is annotated with @Entity, and the primary key is specified using &lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class Product {
    @Id
    private Long id;
    private String name;
    private Double price;

    // Getters and Setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.2 Common Symptoms
&lt;/h3&gt;

&lt;p&gt;If Spring cannot recognize your entity classes, you might encounter: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;javax.persistence.PersistenceException: Unable to locate entity.&lt;/li&gt;
&lt;li&gt;Failed application startup due to missing beans.&lt;/li&gt;
&lt;li&gt;No operations performed on the database despite correct query logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Reasons Behind the Issue
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Missing Entity Scan Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spring Boot automatically scans for entities in the same package or sub-packages as the @SpringBootApplication class. If your entities reside in a different package, they won't be detected. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incorrect Persistence Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The persistence.xml or application.properties might be missing key details about your entities. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing JPA Annotations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Entities must be annotated with @Entity. Without it, Spring won’t recognize the class as an entity. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency Issues&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the necessary JPA dependencies are not included, the application won’t be able to process entity classes. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Fixing the Issue
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Specify the Package in Entity Scan
&lt;/h3&gt;

&lt;p&gt;If your entities are in a different package, explicitly define the package using @EntityScan in your main application class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;

@SpringBootApplication
@EntityScan(basePackages = "com.example.entities")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Correctly Annotate Entity Classes
&lt;/h3&gt;

&lt;p&gt;Ensure every entity class has the @Entity annotation and a defined primary key using &lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Verify Dependencies
&lt;/h3&gt;

&lt;p&gt;Include the necessary dependencies for Spring Data JPA in your pom.xml or build.gradle. &lt;/p&gt;

&lt;p&gt;For Maven:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-data-jpa&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;com.h2database&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;h2&amp;lt;/artifactId&amp;gt;
    &amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Gradle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4 Configure application.properties
&lt;/h3&gt;

&lt;p&gt;Ensure the application.properties or application.yml file correctly points to your database and JPA configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Related Concepts and Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Testing Entity Recognition
&lt;/h3&gt;

&lt;p&gt;Always test your configurations with a simple repository query to ensure your entities are recognized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Repository
public interface ProductRepository extends JpaRepository&amp;lt;Product, Long&amp;gt; {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootTest
public class ProductRepositoryTest {
    @Autowired
    private ProductRepository productRepository;

    @Test
    public void testSaveProduct() {
        Product product = new Product();
        product.setId(1L);
        product.setName("Sample Product");
        product.setPrice(99.99);
        productRepository.save(product);

        Optional&amp;lt;Product&amp;gt; retrieved = productRepository.findById(1L);
        assertTrue(retrieved.isPresent());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Use @Configuration for Advanced Scanning
&lt;/h3&gt;

&lt;p&gt;For more complex setups, use a custom configuration class to scan specific packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Configuration
@EntityScan(basePackages = {"com.example.custom.entities"})
@EnableJpaRepositories(basePackages = {"com.example.custom.repositories"})
public class JpaConfig {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 Debugging Tips
&lt;/h3&gt;

&lt;p&gt;Use @EnableJpaRepositories to ensure repositories are being scanned. &lt;/p&gt;

&lt;p&gt;Enable debug logging for Hibernate to track entity issues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=trace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.4 Avoid Common Pitfalls
&lt;/h3&gt;

&lt;p&gt;Ensure unique table names in @Table. &lt;/p&gt;

&lt;p&gt;Don’t forget the @GeneratedValue annotation for auto-increment IDs. &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Conclusion
&lt;/h2&gt;

&lt;p&gt;Ensuring Spring Data JPA recognizes your entity classes is critical for a seamless database integration. From annotating classes correctly to configuring package scans and dependencies, every step plays a vital role. By following the methods outlined in this article, you can resolve entity recognition issues effectively. &lt;/p&gt;

&lt;p&gt;Do you have questions or face challenges not covered here? Comment below, and let’s discuss! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Spring/why-your-spring-data-jpa-entity-classes-are-not-recognized-and-how-to-fix-it" rel="noopener noreferrer"&gt;Why Your Spring Data JPA Entity Classes Are Not Recognized and How to Fix It&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>spring</category>
      <category>jpahibernatespring</category>
    </item>
    <item>
      <title>Building a Detailed Role-Based Access Control System with Spring Security and Spring Boot</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Tue, 05 Aug 2025 09:00:40 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/building-a-detailed-role-based-access-control-system-with-spring-security-and-spring-boot-3m03</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/building-a-detailed-role-based-access-control-system-with-spring-security-and-spring-boot-3m03</guid>
      <description>&lt;h2&gt;
  
  
  1. Introduction to Role-Based Access Control (RBAC)
&lt;/h2&gt;

&lt;p&gt;RBAC is a widely adopted model where permissions are assigned to roles, and roles are assigned to users. It simplifies the management of permissions and ensures scalability in complex systems. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 Why RBAC Matters
&lt;/h3&gt;

&lt;p&gt;Imagine a system with hundreds of users and dozens of operations. Assigning permissions directly to users becomes a nightmare to manage. Roles abstract this complexity by grouping permissions, making it easier to maintain and audit. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 Core Components of RBAC
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Users&lt;/strong&gt; : Individuals using the system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Roles&lt;/strong&gt; : Collections of permissions, e.g., ADMIN, USER.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions&lt;/strong&gt; : Granular actions like READ, WRITE, DELETE.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Setting Up the Spring Boot Application
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Basic Project Configuration
&lt;/h3&gt;

&lt;p&gt;First, create a Spring Boot project with the following dependencies: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring Security&lt;/li&gt;
&lt;li&gt;Spring Web&lt;/li&gt;
&lt;li&gt;Spring Data JPA&lt;/li&gt;
&lt;li&gt;H2 Database (for demo purposes)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your pom.xml should include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-security&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-data-jpa&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;com.h2database&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;h2&amp;lt;/artifactId&amp;gt;
    &amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Database Schema for Roles and Permissions
&lt;/h3&gt;

&lt;p&gt;Define the database schema with entities for User, Role, and Permission:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;

    @ManyToMany(fetch = FetchType.EAGER)
    private Set&amp;lt;Role&amp;gt; roles = new HashSet&amp;lt;&amp;gt;();
}

@Entity
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToMany(fetch = FetchType.EAGER)
    private Set&amp;lt;Permission&amp;gt; permissions = new HashSet&amp;lt;&amp;gt;();
}

@Entity
public class Permission {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Populating Initial Data
&lt;/h3&gt;

&lt;p&gt;Use a CommandLineRunner to seed the database with default roles and permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Bean
CommandLineRunner init(RoleRepository roleRepo, PermissionRepository permRepo, UserRepository userRepo) {
    return args -&amp;gt; {
        Permission readPermission = permRepo.save(new Permission("READ_PRIVILEGE"));
        Permission writePermission = permRepo.save(new Permission("WRITE_PRIVILEGE"));

        Role adminRole = new Role();
        adminRole.setName("ADMIN");
        adminRole.getPermissions().add(readPermission);
        adminRole.getPermissions().add(writePermission);
        roleRepo.save(adminRole);

        User adminUser = new User();
        adminUser.setUsername("admin");
        adminUser.setPassword(new BCryptPasswordEncoder().encode("password"));
        adminUser.getRoles().add(adminRole);
        userRepo.save(adminUser);
    };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Implementing Role-Based Authorization
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Configuring Spring Security
&lt;/h3&gt;

&lt;p&gt;Define a custom security configuration to enable role-based access control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .anyRequest().authenticated()
            .and()
            .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService())
            .passwordEncoder(new BCryptPasswordEncoder());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Custom UserDetailsService
&lt;/h3&gt;

&lt;p&gt;Implement a custom UserDetailsService to load user details from the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class CustomUserDetailsService implements UserDetailsService {
    private final UserRepository userRepository;

    public CustomUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -&amp;gt; new UsernameNotFoundException("User not found"));

        Set&amp;lt;GrantedAuthority&amp;gt; authorities = user.getRoles().stream()
            .flatMap(role -&amp;gt; role.getPermissions().stream())
            .map(permission -&amp;gt; new SimpleGrantedAuthority(permission.getName()))
            .collect(Collectors.toSet());

        return new org.springframework.security.core.userdetails.User(
            user.getUsername(),
            user.getPassword(),
            authorities
        );
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Testing the System
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Secured Endpoints
&lt;/h3&gt;

&lt;p&gt;Create a controller with secured endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
@RequestMapping("/admin")
public class AdminController {
    @GetMapping
    public String adminDashboard() {
        return "Welcome to Admin Dashboard";
    }
}

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping
    public String userDashboard() {
        return "Welcome to User Dashboard";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Testing with Postman
&lt;/h3&gt;

&lt;p&gt;Use basic authentication with username admin and password password. &lt;/p&gt;

&lt;p&gt;Access /admin: Should return Welcome to Admin Dashboard. &lt;/p&gt;

&lt;p&gt;Access /user: Should return a 403 error. &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Extending RBAC with Advanced Features
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hierarchical Roles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implement role hierarchies, e.g., ADMIN inherits USER privileges. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamic Permissions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fetch permissions dynamically from the database and update security rules without restarting the application. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auditing and Logging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Track unauthorized access attempts and log them for security analysis. &lt;/p&gt;

&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;Building a detailed RBAC system with Spring Security and Spring Boot requires careful planning, but the flexibility and scalability it offers make it a worthwhile endeavor. By following the steps outlined in this guide, you can implement a robust and secure authorization mechanism tailored to your application's needs. &lt;/p&gt;

&lt;p&gt;If you have any questions or need further clarification, feel free to leave a comment below! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Spring/building-a-detailed-rolebased-access-control-system-with-spring-security-and-spring-boot" rel="noopener noreferrer"&gt;Building a Detailed Role-Based Access Control System with Spring Security and Spring Boot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>spring</category>
      <category>securityspring</category>
    </item>
    <item>
      <title>Secrets to Optimizing and Organizing Liquibase Scripts in Spring Boot for Seamless Database Migrations</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Mon, 04 Aug 2025 09:00:13 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/secrets-to-optimizing-and-organizing-liquibase-scripts-in-spring-boot-for-seamless-database-127</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/secrets-to-optimizing-and-organizing-liquibase-scripts-in-spring-boot-for-seamless-database-127</guid>
      <description>&lt;h2&gt;
  
  
  1. Understanding Liquibase in Spring Boot
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 What is Liquibase?
&lt;/h3&gt;

&lt;p&gt;Liquibase is an open-source database schema management tool that simplifies tracking, versioning, and deploying database changes. By using XML, YAML, JSON, or SQL files called changelogs, Liquibase allows developers to apply consistent schema changes across environments. &lt;/p&gt;

&lt;p&gt;In Spring Boot, integrating Liquibase is straightforward. Simply add the following dependency to your pom.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.liquibase&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;liquibase-core&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With minimal configuration in application.properties, Liquibase will automatically run migrations on application startup. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 The Problem with Poorly Organized Scripts
&lt;/h3&gt;

&lt;p&gt;While Liquibase is a robust tool, its power can become a liability if not managed properly. Issues such as redundant scripts, conflicting changes, or overly large changelogs often lead to errors during deployment. These problems are amplified in projects involving multiple teams or microservices. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Secrets to Optimizing and Organizing Liquibase Scripts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Split Changelogs into Logical Units
&lt;/h3&gt;

&lt;p&gt;Instead of maintaining a monolithic db.changelog-master.xml, split it into smaller, logically grouped files. For instance, separate tables, procedures, and indexes into different changelogs: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Directory Structure:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/main/resources/db/changelog/
    ├── db.changelog-master.xml
    ├── tables/
    │ ├── create-user-table.xml
    │ ├── create-order-table.xml
    ├── procedures/
    │ ├── add-audit-procedure.xml
    ├── indexes/
        ├── add-index-on-user.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Master Changelog Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;databaseChangeLog&amp;gt;
    &amp;lt;include file="tables/create-user-table.xml"/&amp;gt;
    &amp;lt;include file="tables/create-order-table.xml"/&amp;gt;
    &amp;lt;include file="procedures/add-audit-procedure.xml"/&amp;gt;
    &amp;lt;include file="indexes/add-index-on-user.xml"/&amp;gt;
&amp;lt;/databaseChangeLog&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why It Works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improves readability and maintainability.&lt;/li&gt;
&lt;li&gt;Reduces conflicts in teams working on different features.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 Use Contexts for Environment-Specific Changes
&lt;/h3&gt;

&lt;p&gt;Not all database changes apply universally across all environments. Liquibase supports contexts to filter scripts based on the environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;changeSet id="1" author="tuananh" context="dev"&amp;gt;
    &amp;lt;createTable tableName="dev_only_table"&amp;gt;
        &amp;lt;column name="id" type="int" autoIncrement="true"/&amp;gt;
        &amp;lt;column name="name" type="varchar(255)"/&amp;gt;
    &amp;lt;/createTable&amp;gt;
&amp;lt;/changeSet&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In application.properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.liquibase.contexts=dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Contexts ensure that dev-only or staging-specific scripts do not accidentally run in production, improving safety during deployments. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Optimizing Liquibase Execution
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Checksums to Prevent Unintended Changes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Liquibase uses checksums to detect whether a script has been modified after it was applied. However, developers often run into checksum mismatches. The best practice is to avoid modifying applied scripts. Instead, create a new changeSet. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anti-Pattern:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;changeSet id="1" author="tuananh"&amp;gt;
    &amp;lt;addColumn tableName="user"&amp;gt;
        &amp;lt;column name="new_column" type="varchar(255)"/&amp;gt;
    &amp;lt;/addColumn&amp;gt;
&amp;lt;/changeSet&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If new_column changes after it’s already applied, it will cause issues. Instead, create a new changeSet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;changeSet id="2" author="tuananh"&amp;gt;
    &amp;lt;dropColumn tableName="user" columnName="new_column"/&amp;gt;
    &amp;lt;addColumn tableName="user"&amp;gt;
        &amp;lt;column name="updated_column" type="varchar(255)"/&amp;gt;
    &amp;lt;/addColumn&amp;gt;
&amp;lt;/changeSet&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Leverage Precondition Checks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To avoid running changes in unintended states, use preconditions. Preconditions ensure that scripts are executed only when certain conditions are met. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;changeSet id="3" author="tuananh"&amp;gt;
    &amp;lt;preConditions onFail="MARK_RAN"&amp;gt;
        &amp;lt;not&amp;gt;
            &amp;lt;tableExists tableName="user"/&amp;gt;
        &amp;lt;/not&amp;gt;
    &amp;lt;/preConditions&amp;gt;
    &amp;lt;createTable tableName="user"&amp;gt;
        &amp;lt;column name="id" type="int" autoIncrement="true"/&amp;gt;
        &amp;lt;column name="name" type="varchar(255)"/&amp;gt;
    &amp;lt;/createTable&amp;gt;
&amp;lt;/changeSet&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Best Practices for Collaborative Development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Naming Conventions for Scripts
&lt;/h3&gt;

&lt;p&gt;Adopt a consistent naming convention for your changeSets and changelogs. Use a pattern such as &lt;br&gt;
   _ &lt;br&gt;
  &lt;br&gt;
    _ &lt;br&gt;
   &lt;br&gt;
     for easy tracking. &lt;br&gt;
    &lt;br&gt;
   &lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20241122_add_user_table.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Code Reviews for Database Changes
&lt;/h3&gt;

&lt;p&gt;Just like application code, database scripts should undergo peer reviews to catch potential issues. Tools like Pull Requests in GitHub can ensure adherence to conventions. &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Advanced Tips for Scaling Liquibase in Microservices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Isolate Databases Per Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In microservices architectures, avoid a shared database schema. Each service should manage its database and Liquibase scripts independently. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automate Validation in CI/CD&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Integrate Liquibase checks into your CI/CD pipelines using the liquibase validate command to catch syntax errors or schema conflicts before they reach production. &lt;/p&gt;

&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;By organizing Liquibase scripts logically, leveraging contexts, and incorporating best practices, you can transform your database migration process into a well-oiled machine. The examples above illustrate how small tweaks can prevent big headaches in the long run. Have any questions about Liquibase or want to share your experiences? Let me know in the comments below! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Spring/secrets-to-optimizing-and-organizing-liquibase-scripts-in-spring-boot-for-seamless-database-migrations" rel="noopener noreferrer"&gt;Secrets to Optimizing and Organizing Liquibase Scripts in Spring Boot for Seamless Database Migrations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>spring</category>
      <category>databasespringsql</category>
    </item>
    <item>
      <title>Secrets to Designing an Effective UserDTO in Spring Boot Applications</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Sun, 03 Aug 2025 09:00:43 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/secrets-to-designing-an-effective-userdto-in-spring-boot-applications-1900</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/secrets-to-designing-an-effective-userdto-in-spring-boot-applications-1900</guid>
      <description>&lt;h2&gt;
  
  
  1. What is a UserDTO, and Why is it Important?
&lt;/h2&gt;

&lt;p&gt;The UserDTO is a lightweight object used to encapsulate user-related data and transfer it between layers of an application, such as the controller, service, and repository. Unlike an entity, a DTO doesn’t map directly to the database. Instead, it focuses on delivering only the necessary data, improving performance and abstraction. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfzf0kmmy6g67memsp5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfzf0kmmy6g67memsp5m.png" alt="Image" width="447" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 Bridging the Layers with a UserDTO
&lt;/h3&gt;

&lt;p&gt;When you have a large User entity with sensitive information like passwords, exposing it directly to a client through REST APIs can be problematic. Here’s where UserDTO comes in handy—it extracts only the required fields for transmission. &lt;/p&gt;

&lt;p&gt;Consider a typical User entity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String email;
    private String password; // Sensitive data
    private boolean active;

    // Getters and setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a corresponding UserDTO:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserDTO {
    private String username;
    private String email;
    private boolean active;

    // Getters and setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UserDTO omits the password field, ensuring sensitive data doesn’t leak unintentionally. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Key Principles of Designing an Effective UserDTO
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Minimalism: Include Only What’s Needed
&lt;/h3&gt;

&lt;p&gt;A UserDTO should contain only the fields required for the specific operation. Overloading it with unnecessary fields increases payload size and complicates maintenance. &lt;/p&gt;

&lt;p&gt;If you’re creating a user list for the admin panel, you might include fields like username and active, but omit email.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserListDTO {
    private String username;
    private boolean active;

    // Getters and setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Flexibility Through Nested DTOs
&lt;/h3&gt;

&lt;p&gt;For complex user-related data, you can nest DTOs within a parent UserDTO. This approach is particularly useful when dealing with relationships like roles or addresses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserDTO {
    private String username;
    private String email;
    private boolean active;
    private List&amp;lt;RoleDTO&amp;gt; roles;

    // Getters and setters
}

public class RoleDTO {
    private String name;

    // Getters and setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This design allows you to encapsulate related data cleanly and avoids direct dependencies on the entity structure. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Implementing and Mapping UserDTO in Spring Boot
&lt;/h2&gt;

&lt;p&gt;To effectively implement UserDTO in a Spring Boot application, mapping between entities and DTOs is crucial. &lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 Using Libraries Like MapStruct for Efficient Mapping
&lt;/h3&gt;

&lt;p&gt;Manual mapping can be tedious and error-prone. A library like MapStruct automates this process. &lt;/p&gt;

&lt;p&gt;Add the MapStruct dependency to your pom.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.mapstruct&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;mapstruct&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.5.3.Final&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.mapstruct&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;mapstruct-processor&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.5.3.Final&amp;lt;/version&amp;gt;
    &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a mapper interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Mapper(componentModel = "spring")
public interface UserMapper {
    UserDTO toDTO(User user);
    User toEntity(UserDTO userDTO);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can use the UserMapper in your service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class UserService {

    private final UserRepository userRepository;
    private final UserMapper userMapper;

    public UserService(UserRepository userRepository, UserMapper userMapper) {
        this.userRepository = userRepository;
        this.userMapper = userMapper;
    }

    public UserDTO getUserById(Long id) {
        User user = userRepository.findById(id).orElseThrow(() -&amp;gt; new RuntimeException("User not found"));
        return userMapper.toDTO(user);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Advanced Considerations for UserDTO Design
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Custom Validation in UserDTO
&lt;/h3&gt;

&lt;p&gt;When accepting user data from external sources, validation is essential to ensure data integrity. Use annotations like @NotNull, @Email, and @Size to validate fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserDTO {
    @NotNull
    private String username;

    @Email
    private String email;

    @Size(min = 6, message = "Password must be at least 6 characters long")
    private String password;

    private boolean active;

    // Getters and setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Versioning UserDTO for API Evolution
&lt;/h3&gt;

&lt;p&gt;APIs evolve, and so should DTOs. To support backward compatibility, version your DTOs when adding new fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Version 1
public class UserDTO_v1 {
    private String username;
    private String email;
}

// Version 2
public class UserDTO_v2 extends UserDTO_v1 {
    private boolean active;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Best Practices for Managing UserDTO in Spring Boot
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Avoid Tight Coupling Between Entity and DTO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use a dedicated service or mapper class to handle the conversion logic. Directly coupling the entity and DTO makes your application brittle and harder to maintain. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep DTOs Context-Specific&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of using one massive UserDTO for all use cases, create context-specific DTOs like UserDetailDTO, UserListDTO, and UserUpdateDTO. &lt;/p&gt;

&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;Designing an effective UserDTO in Spring Boot applications requires careful consideration of data flow, performance, and maintainability. By adhering to principles like minimalism, flexibility, and separation of concerns, you can ensure your DTOs are robust and future-proof. Tools like MapStruct simplify mapping, while practices like validation and versioning enhance reliability. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;What challenges have you faced while designing DTOs? Let’s discuss in the comments below!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Spring/secrets-to-designing-an-effective-userdto-in-spring-boot-applications" rel="noopener noreferrer"&gt;Secrets to Designing an Effective UserDTO in Spring Boot Applications&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>spring</category>
      <category>datatypedto</category>
    </item>
    <item>
      <title>Reasons You’re Not Receiving JWT Tokens and How to Fix It in Spring Security</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Sat, 02 Aug 2025 09:00:01 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/reasons-youre-not-receiving-jwt-tokens-and-how-to-fix-it-in-spring-security-10ii</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/reasons-youre-not-receiving-jwt-tokens-and-how-to-fix-it-in-spring-security-10ii</guid>
      <description>&lt;h2&gt;
  
  
  1. Understanding Why JWT Tokens Are Not Received
&lt;/h2&gt;

&lt;p&gt;JWT issues can arise at several stages of the token lifecycle: generation, delivery, or validation. Let’s break these down. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 Misconfigured Security Filters
&lt;/h3&gt;

&lt;p&gt;Spring Security relies heavily on filters to handle authentication. If your custom JWT filter isn’t properly registered or configured, Spring Security might bypass it entirely, preventing token generation or validation. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt; : Missing OncePerRequestFilter in your Spring Security configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("Authorization");

        if (token == null || !token.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);
            return;
        }

        // Proceed to validate and authenticate the token
        // Token validation logic here
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you forget to add this filter in your security configuration, the token will never be processed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.2 Missing or Incorrect Authorization Header
&lt;/h3&gt;

&lt;p&gt;The Authorization header in HTTP requests carries the JWT. If the client forgets to include this header or formats it incorrectly, the server will not receive the token. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common Mistake&lt;/strong&gt; : Sending a raw token without the Bearer prefix.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization: Bearer &amp;lt;your-jwt-token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the header is sent as Authorization: &lt;br&gt;
   (without Bearer), the filter will fail to parse it. Modify the filter to include validation for the prefix: &lt;br&gt;
 &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (!token.startsWith("Bearer ")) {
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Authorization header");
    return;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.3 Expired or Invalid Token
&lt;/h3&gt;

&lt;p&gt;Tokens have a limited lifespan defined during their generation. An expired token will fail validation, resulting in 401 Unauthorized responses. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example: Token Generation with Expiration&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public String generateToken(String username) {
    return Jwts.builder()
            .setSubject(username)
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // Token valid for 1 hour
            .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
            .compact();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt; : Ensure the token hasn’t expired before making requests. Additionally, verify the client’s system clock if you’re facing unexpected expiration issues. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.4 Incorrect Secret Key or Algorithm Mismatch
&lt;/h3&gt;

&lt;p&gt;The JWT is signed with a secret key using a specific algorithm. Any mismatch between the server’s and client’s key or algorithm can lead to validation failures. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of Algorithm Mismatch:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Signing the token with HS256
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the client attempts to validate with a different algorithm (e.g., HS512), the server will reject the token. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Fixing JWT Issues in Spring Security
&lt;/h2&gt;

&lt;p&gt;Once the root cause is identified, you can implement solutions to resolve the issues effectively. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Registering Custom Filters Correctly
&lt;/h3&gt;

&lt;p&gt;Make sure your JWT authentication filter is added in the correct order in the Spring Security filter chain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeRequests()
        .antMatchers("/api/auth/**").permitAll()
        .anyRequest().authenticated()
        .and()
        .addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Validating Tokens Properly
&lt;/h3&gt;

&lt;p&gt;Use &lt;strong&gt;utility methods&lt;/strong&gt; to validate the token’s structure, expiration, and signature. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example: Token Validation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public boolean validateToken(String token) {
    try {
        Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
        return true;
    } catch (ExpiredJwtException e) {
        System.out.println("Token has expired: " + e.getMessage());
    } catch (UnsupportedJwtException | MalformedJwtException | IllegalArgumentException e) {
        System.out.println("Invalid token: " + e.getMessage());
    }
    return false;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure the filter uses this method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String jwt = token.substring(7); // Remove "Bearer " prefix
if (!validateToken(jwt)) {
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid or expired token");
    return;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Adding CORS Support
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cross-Origin Resource Sharing (CORS)&lt;/strong&gt; can block tokens sent via browser-based requests if the CORS configuration is missing. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example: Global CORS Configuration&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("http://localhost:3000")
                    .allowedMethods("GET", "POST", "PUT", "DELETE")
                    .allowCredentials(true);
        }
    };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.4 Debugging Tips for Missing Tokens
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Enable Logs&lt;/strong&gt; : Use Spring Security debugging to trace request and filter execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logging.level.org.springframework.security=DEBUG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Check Request Headers&lt;/strong&gt; : Use tools like Postman or curl to ensure headers are being sent correctly. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validate Secret Keys&lt;/strong&gt; : Confirm the secret key is consistent across environments. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Conclusion
&lt;/h2&gt;

&lt;p&gt;JWT integration with Spring Security is straightforward when properly configured. However, minor missteps in filters, headers, or token validation can lead to frustrating issues. By following the steps outlined above—such as registering filters, handling headers correctly, and configuring token validation—you can ensure a robust JWT authentication system. &lt;/p&gt;

&lt;p&gt;Do you have any lingering questions or challenges related to JWT implementation in Spring Security? Let’s discuss them in the comments below! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Spring/reasons-youre-not-receiving-jwt-tokens-and-how-to-fix-it-in-spring-security" rel="noopener noreferrer"&gt;Reasons You’re Not Receiving JWT Tokens and How to Fix It in Spring Security&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>spring</category>
      <category>jwtsecurityspring</category>
    </item>
    <item>
      <title>DTO and Entity Separation is Crucial for Java Backend Applications</title>
      <dc:creator>Anh Trần Tuấn</dc:creator>
      <pubDate>Fri, 01 Aug 2025 09:00:40 +0000</pubDate>
      <link>https://dev.to/anh_trntun_4732cf3d299/dto-and-entity-separation-is-crucial-for-java-backend-applications-1kn3</link>
      <guid>https://dev.to/anh_trntun_4732cf3d299/dto-and-entity-separation-is-crucial-for-java-backend-applications-1kn3</guid>
      <description>&lt;h2&gt;
  
  
  1. What are DTOs and Entities?
&lt;/h2&gt;

&lt;p&gt;Before exploring their nuances, it is crucial to define these two terms. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 Entities: The Foundation of Persistence
&lt;/h3&gt;

&lt;p&gt;Entities represent the database table mappings in Java applications. Annotated with @Entity, these objects contain fields that correspond to columns in a database table. They are typically used in JPA/Hibernate to handle database operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;

    // Getters and Setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the User entity maps directly to a table in the database, making it tightly coupled to the database schema. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 DTOs: Simplifying Data Communication
&lt;/h3&gt;

&lt;p&gt;DTOs, on the other hand, are plain Java objects (POJOs) designed to transfer data between different layers of an application. They focus solely on carrying data, often in a more lightweight format than entities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserDTO {
    private String name;
    private String email;

    // Getters and Setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, UserDTO omits database-specific annotations and fields, focusing only on the information required by the client. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.3 The Key Difference
&lt;/h3&gt;

&lt;p&gt;The primary distinction lies in their purpose: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entities are database-centric and used for persistence operations.&lt;/li&gt;
&lt;li&gt;DTOs are client-centric and used for communication between application layers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Why Separate DTOs and Entities?
&lt;/h2&gt;

&lt;p&gt;While combining DTOs and Entities might seem convenient, it introduces significant challenges that can snowball over time. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Tight Coupling and Schema Changes
&lt;/h3&gt;

&lt;p&gt;Entities are tightly coupled to the database schema. If a database schema changes, the corresponding entity must also change. Using entities directly as DTOs means any schema change can cascade into breaking API changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Entity directly exposed as API response
@Entity
public class Product {
    @Id
    private Long id;
    private String name;
    private double price;
    private String internalCode; // Newly added field
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding internalCode to the Product entity inadvertently exposes sensitive data if used directly in API responses. A DTO could have prevented this. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 Overfetching and Underfetching Data
&lt;/h3&gt;

&lt;p&gt;Entities often contain fields irrelevant to client requests. When used directly, they can lead to overfetching (sending unnecessary data) or underfetching (not providing required fields).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ProductDTO {
    private String name;
    private double price;

    // Constructor, Getters, and Setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, ProductDTO ensures only relevant fields are included, improving performance and security. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 Improved Validation and Transformation
&lt;/h3&gt;

&lt;p&gt;DTOs allow for specific validation logic and data transformation tailored to client needs, reducing complexity in entities. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. How to Work with DTOs and Entities
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mapping Between DTOs and Entities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the key tasks is converting between DTOs and Entities. This can be done manually or using libraries like MapStruct or ModelMapper.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserMapper {
    public static UserDTO toDTO(User user) {
        UserDTO dto = new UserDTO();
        dto.setName(user.getName());
        dto.setEmail(user.getEmail());
        return dto;
    }

    public static User toEntity(UserDTO dto) {
        User user = new User();
        user.setName(dto.getName());
        user.setEmail(dto.getEmail());
        return user;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Using MapStruct for Efficiency
&lt;/h3&gt;

&lt;p&gt;MapStruct automates the mapping process with annotations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Mapper
public interface UserMapper {
    UserDTO toDTO(User user);
    User toEntity(UserDTO dto);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using MapStruct eliminates boilerplate code while ensuring accuracy. &lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Layering for Clear Separation
&lt;/h3&gt;

&lt;p&gt;Architectural layering further enforces separation: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Controller Layer&lt;/strong&gt; : Accepts DTOs as input and sends DTOs as output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service Layer&lt;/strong&gt; : Handles business logic and mapping between DTOs and Entities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository Layer&lt;/strong&gt; : Operates directly on Entities for database interactions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Best Practices for DTOs and Entities
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Avoid Bi-directional Mapping&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common mistake is embedding one object type in another, creating circular dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class OrderDTO {
    private UserDTO user; // Can lead to circular references
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, use identifiers or simplified objects to represent relationships. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep DTOs Lean&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Include only the necessary fields in DTOs to minimize payload size and improve performance. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separate Input and Output DTOs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use distinct DTOs for incoming requests and outgoing responses to better align with API requirements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserRequestDTO {
    private String name;
    private String email;
}
public class UserResponseDTO {
    private Long id;
    private String name;
    private String email;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Common Errors and Troubleshooting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Performance Issues with Mapping&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Overusing manual mapping can degrade performance in large applications. Optimize by adopting automated mapping tools. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validation Conflicts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ensure validations are applied consistently across layers. Use DTOs for input validation and entities for database constraints. &lt;/p&gt;

&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;In Java backend applications, properly handling DTOs and Entities is essential for maintaining a scalable and maintainable architecture. By separating these two concepts, developers can avoid tight coupling, enhance performance, and ensure robust validation. Have you faced challenges when working with DTOs and Entities? Share your experiences or questions in the comments below! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read posts more at&lt;/strong&gt; : &lt;a href="https://www.tuanh.net/blog/Spring/dto-and-entity-separation-is-crucial-for-java-backend-applications" rel="noopener noreferrer"&gt;DTO and Entity Separation is Crucial for Java Backend Applications&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codeproject</category>
      <category>spring</category>
      <category>dtobackendserializat</category>
    </item>
  </channel>
</rss>
