This is my personal project for a service that is consisted of useful utility tool to help my development process as a Backend Developer. It is useful when needing to develop features related to common enterprise needs.
This service can be used to be develop into another service client.
A email management system with time delay feature:
- Template-based HTML emails with dynamic variables
- Multiple file attachments support
- Delay mechanism, DB records / logging
- Multiple recipients (To, CC, BCC)
- OpenAPI spec available at
docs/email-api.json
Dynamic configuration management:
- Store configurations in database
- Live refresh via Spring Actuator (
/actuator/refresh) - Easy configuration updates through database
- A lightweight PDF generation that accepts an inline Thymeleaf HTML template and JSON data
- Renders HTML, converts it to PDF (via Flying Saucer / iText)
- Returns PDF bytes as base64.
- OpenAPI spec available at
docs/pdf-generator-api.json
PDF Generation- Send Teams Message
- Data Export (CSV, Excel, PDF)
- Java 8+
- Maven 3.8+
- Docker & Docker Compose (optional, for local development)
- PostgreSQL database
- Clone the repository:
git clone https://github.com/yourusername/spring-boot-personal-utilities.git
cd spring-boot-personal-utilities- Setup environment variables:
# Edit .env with your actual credentials
cp .env.example .env- Start PostgreSQL and pgAdmin:
docker-compose build
docker-compose up -dThis will start:
- PostgreSQL on port
5332 - pgAdmin4 on port
5050→ http://localhost:5050
- Build and run:
mvn clean install
mvn spring-boot:runUtilities will start on http://localhost:8080
@Autowired
private EmailService emailService;
public void sendWelcomeEmail(String userEmail, String userName) throws Exception {
EmailDTO emailDTO = new EmailDTO();
emailDTO.setEmailId(UUID.randomUUID().toString());
emailDTO.setEmailType("NOTIFICATION");
emailDTO.setSender("noreply@yourcompany.com");
emailDTO.setReceiver(userEmail);
emailDTO.setSubject("Welcome to Our Platform!");
emailDTO.setTemplateName("welcome_template");
// Template variables
Map<String, Object> params = new HashMap<>();
params.put("userName", userName);
params.put("year", LocalDate.now().getYear());
emailDTO.setParams(params);
String result = emailService.sendEmail(emailDTO, null);
log.info("Email sent: {}", result);
}public void sendInvoice(MultipartFile[] invoiceFiles) throws Exception {
EmailDTO emailDTO = new EmailDTO();
emailDTO.setEmailId("INV-" + UUID.randomUUID().toString());
emailDTO.setEmailType("INVOICE");
emailDTO.setSender("billing@yourcompany.com");
emailDTO.setReceiver("customer@example.com");
emailDTO.setSubject("Your Invoice #12345");
emailDTO.setTemplateName("invoice_template");
emailDTO.setPriority("1"); // High priority
Map<String, Object> params = new HashMap<>();
params.put("invoiceNumber", "12345");
params.put("amount", "$1,234.56");
params.put("dueDate", "2025-10-31");
emailDTO.setParams(params);
String result = emailService.sendEmail(emailDTO, invoiceFiles);
log.info("Invoice sent: {}", result);
}public void sendAnnouncement() throws Exception {
EmailDTO emailDTO = new EmailDTO();
emailDTO.setEmailId(UUID.randomUUID().toString());
emailDTO.setEmailType("ANNOUNCEMENT");
emailDTO.setSender("info@yourcompany.com");
emailDTO.setReceiver("team@example.com");
emailDTO.setCc("manager@example.com;director@example.com"); // Multiple CC
emailDTO.setBcc("archive@example.com"); // BCC for record
emailDTO.setSubject("Q4 Company Update");
emailDTO.setTemplateName("announcement_template");
String result = emailService.sendEmail(emailDTO, null);
log.info("Announcement sent: {}", result);
}Store HTML templates in the EMAIL_TEMPLATE table:
INSERT INTO EMAIL_TEMPLATE (TEMPLATE_ID, TEMPLATE)
VALUES (
'welcome_template',
'<html>
<body style="font-family: Arial, sans-serif;">
<h1>Welcome {{userName}}! 👋</h1>
<p>Thank you for joining us in {{year}}.</p>
<p>We''re excited to have you on board!</p>
<hr/>
<p style="color: #666;">Best regards,<br/>The Team</p>
</body>
</html>'
);curl -X POST http://localhost:8080/api/utilities/mailer/send-email \
-F 'dto={"emailId":"test-123","emailType":"NOTIFICATION","sender":"noreply@example.com","receiver":"user@example.com","subject":"Test Email","templateName":"welcome_template","params":{"userName":"John Doe","year":"2025"}};type=application/json' \
-F "files=@/path/to/document.pdf"import com.nivleking.springboot.dto.ConfigMapData;
@Service
public class MyService {
@Autowired
private ConfigMapData emailHost;
@Autowired
private ConfigMapData emailPort;
@Resource()
private Map<String, String> emailDelayMap;
public void useConfig() {
log.info("SMTP Host: {}", emailHost.getValue());
log.info("SMTP Port: {}", emailPort.getValue());
log.info("Promotional email delay: {} ms", emailDelayMap.get("PROMOTIONAL"));
}
}- Update database:
UPDATE CONFIG_SERVER
SET CONFIG_VALUE = 'smtp.office365.com'
WHERE CONFIG_NAME = 'com.nivleking.springboot.email.smtp.host';- Refresh application:
curl -X POST http://localhost:8080/actuator/refreshimport com.nivleking.springboot.dto.ConfigMapData;
// 1. Add to CONFIG_SERVER table
INSERT INTO CONFIG_SERVER (PROPERTIES, VALUE) VALUES ('com.nivleking.springboot.my.new.config','my-value');
// 2. Create Bean with RefreshScope annotation in UtilitiesConfiguration
@Bean
@RefreshScope
public ConfigMapData myNewConfig() {
return new ConfigMapData(configServerHolder.getConfig("com.nivleking.springboot.my.new.config", "default-value"));
}
// 3. Inject and use
@Autowired
private ConfigMapData myNewConfig;// localhost:8080/api/utilities/pdf-generator/generate
{
"template": "<html><body><h1>Invoice for [[${data.customer}]]</h1><p>Amount: [[${data.amount}]]</p></body></html>",
"data": {
"customer": "John Doe",
"amount": "USD 100.00"
}
}@Autowired
private PdfGeneratorService pdfGeneratorService;
public void generate() throws Exception {
String inputJson = "{\"template\":\"<html><body><h1>[[${data.name}]]</h1></body></html>\",\"data\":{\"name\":\"Alice\"}}";
byte[] pdfBytes = pdfGeneratorService.parseThymeleafTemplate(inputJson);
// pdfBytes contains raw PDF bytes; optionally encode to base64 for API response
String base64 = Base64.getEncoder().encodeToString(pdfBytes);
}curl -X POST http://localhost:8080/api/utilities/pdf-generator/generate \
-H "Content-Type: application/json" \
-d '{
"template":"<html><body><h1>Invoice for [[${data.customer}]]</h1><p>Amount: [[${data.amount}]]</p></body></html>",
"data":{"customer":"John Doe","amount":"USD 100.00"}
}'Complete API documentation is available in OpenAPI 3.0.3 format:
- Send Email OpenAPI JSON:
docs/api.json - PDF Generator OpenAPI JSON:
docs/api.json - SwaggerHub: API Documentation 🌐