Search Tutorials


Spring Boot AI + Azure OpenAI - Prompt Engineering Example | JavaInUse

Spring Boot AI + Azure OpenAI - Prompt Engineering Example

Prompt engineering is the practice of crafting effective inputs to get the best possible outputs from AI language models like OpenAI. When we interact with AI systems, the way we phrase our requests dramatically impacts the quality, relevance, and usefulness of the responses you receive. Think of it as learning to communicate clearly with a powerful but sometimes literal-minded assistant.

Key Principles of Effective Prompting

  • Giving Clear and Precise Instructions
  • Giving the Model Time to Think
  • Summarizing
  • Inferring
  • Zero Shot and Few Shot
  • Prompting Chain of Thought
  • Using System Messages
To understand the above principles we will make use of a scenario where a developer is developing an authentication system.

Giving Clear and Precise Instructions -

Be specific about what you want, including details like tone, format, or scope, so the AI doesn't guess or wander off-topic.

Scenario -

Poor: "Write code to handle users"
Better: "Create a Java class for user management that:
  • Handles user registration and login
  • Stores user data in PostgreSQL using Spring Data JPA
  • Implements password encryption using BCrypt
  • Includes email verification
  • Has methods for password reset
  • Handles session management with Spring Security"

Giving the Model Time to Think -

Encourage the AI to process step-by-step or reflect before answering, especially for complex tasks, rather than rushing a response.

Scenario -

Poor:
"How to sort this array?"
Better:
"Let's analyze this sorting problem:
Input characteristics:
  • Array size: 1 million elements
  • Data type: Integers
  • Memory constraints: 1GB
  • Current state: Partially sorted
Algorithm selection:
  • Arrays.sort(): Uses TimSort, O(n log n), stable, good for partially sorted data
  • Collections.sort(): Similar performance characteristics
  • Custom QuickSort: O(n log n), but not stable
  • MergeSort implementation: O(n log n), stable, more memory
Implementation considerations:
  • Primitive array vs ArrayList
  • Parallel sorting with parallelSort()
  • Custom Comparator needs
  • Error handling and boundary cases

Summarizing -

Ask the AI to condense information into a shorter, digestible form while keeping the key points.

Scenario -

Poor
"What does this code do?"
Better:
"Let's summarize this Java codebase:
Core Functionality:
  • REST API for e-commerce platform using Spring Boot
  • Handles product inventory and orders
  • Integrates with payment gateway
Key Components:
  • Controllers: OrderController, ProductController, UserController
  • Services: PaymentService, NotificationService, InventoryService
  • Models: Product, Order, User entities with JPA annotations
Technical Stack:
  • Spring Boot with Spring Data JPA
  • PostgreSQL database
  • Redis for caching
  • AWS S3 for storage via Spring Cloud AWS"

Inferring -

Ask the AI to deduce or interpret something based on limited or indirect information. Inference prompts encourage the AI to analyze patterns, draw conclusions, and make educated guesses when explicit data is unavailable. This approach is particularly valuable for debugging, code analysis, and understanding complex systems.

Scenario -

Poor:
"Why is my application slow?"
Better:
"Based on these application logs and metrics, infer the most likely performance bottlenecks:"
System Information:
  • Spring Boot application with 200+ REST endpoints
  • JVM heap usage consistently above 85%
  • Database connection pool shows frequent timeouts
  • Response times spike every day at 2:00 PM
Performance Metrics:
  • Average response time: 2300ms vs 800ms last week
  • CPU utilization: 75% on app servers
  • Slow database queries increased by 40%
  • Garbage collection pauses: 15 occurrences per hour
Code Changes:
// Recently modified repository method:
@Query("SELECT u FROM User u JOIN FETCH u.roles JOIN FETCH u.preferences WHERE u.lastLoginDate > :date")
List findRecentActiveUsers(@Param("date") LocalDate date);
Another example:
Poor:
"What's wrong with this code?"
Better:
"Infer potential issues in this Spring Security configuration:"
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/api/**").authenticated()
                .anyRequest().permitAll()
            .and()
            .csrf().disable()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(10);
    }
}
Context:
  • Application handles financial transactions
  • Mobile client and web interface access the same API
  • Customer reported unauthorized access last week
  • No authentication failures recorded in logs
Expected inference:
The AI should analyze the code and context to identify potential security vulnerabilities, such as:
  • Missing JWT or token validation configuration
  • CSRF protection disabled despite financial transactions
  • Overly permissive access control for sensitive operations
  • Possible authentication bypass through unprotected endpoints
  • Authentication mechanism not fully implemented or specified

Zero Shot and Few Shot -

  • Zero-Shot: Ask the AI to do something without examples, relying on its general knowledge.
  • Few-Shot: Provide a couple of examples to guide the AI's response pattern.

Scenario -

Zero-shot: "Write a Java method to validate email addresses"
Few-shot:
//Example 1:
//Input: "test@email.com"
//Output: true

//Example 2:
//Input: "invalid.email@"
//Output: false

//Example 3:
//Input: "user@domain.co.uk"
//Output: true

//Now write a method that follows these patterns

Chain of Thought -

Prompt the AI to reason through a problem step-by-step, showing its logic explicitly.

Scenario -

Poor: "Fix this bug in the payment system"
Better: "Let's debug this Java payment issue systematically:" Error Analysis:
logger.error("Transaction failed: InvalidCurrency");
Code Review:
public boolean processPayment(double amount, String currency) {
// Currency validation missing
return stripeClient.charge(amount, currency);
}
Environment Check:
Production vs Test API keys
Currency configuration in application.properties
Spring profiles active
Solution Design:
private static final List VALID_CURRENCIES = 
Arrays.asList("USD", "EUR", "GBP");

private boolean validateCurrency(String currency) {
if (!VALID_CURRENCIES.contains(currency)) {
    throw new InvalidCurrencyException("Currency not supported: " + currency);
}
return true;
}
Implementation and Testing:
public boolean processPayment(double amount, String currency) {
validateCurrency(currency);
return stripeClient.charge(amount, currency);
}

Using System Messages -

Set a context or role for the AI upfront to shape all its responses (like a hidden instruction).

Scenario -

Poor:
"Write code for a website"
Better:
"Act as a senior Java developer who specializes in:
  • Spring Boot applications
  • Angular with TypeScript frontend
  • RESTful API design
  • Security best practices
  • Performance optimization
Create a scalable web application architecture that:
  • Uses microservices with Spring Cloud
  • Implements OAuth2 with Spring Security
  • Includes CI/CD pipeline with Jenkins
  • Has comprehensive testing with JUnit and Mockito
  • Follows SOLID principles and clean code practices

Download Source Code

Download it -
Spring Boot AI + Azure OpenAI Hello World Example