🎯 Recommended Samples
Balanced sample collections from various categories for you to explore
Spring Boot Samples
Spring Boot framework examples including REST APIs, dependency injection, JPA, security, and modern Spring Boot features
💻 Spring Boot Hello World java
🟢 simple
⭐
Basic Spring Boot application setup and Hello World REST API with dependency injection
⏱️ 20 min
🏷️ spring boot, java, rest, web
Prerequisites:
Java basics, Maven/Gradle, REST API concepts
// Spring Boot Hello World Examples
// 1. Maven Dependencies (pom.xml)
/*
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>hello-spring-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-boot</name>
<description>Hello World Spring Boot Application</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
*/
// 2. Main Application Class
package com.example.hellospringboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(HelloWorldApplication.class, args);
// Display application information
String[] beanNames = context.getBeanDefinitionNames();
System.out.println("Application started with " + beanNames.length + " beans");
// You can access beans here if needed
// HelloWorldController controller = context.getBean(HelloWorldController.class);
}
}
// 3. Basic REST Controller
package com.example.hellospringboot.controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class HelloWorldController {
// Basic Hello World endpoint
@GetMapping("/hello")
public String helloWorld() {
return "Hello, World!";
}
// Hello with path variable
@GetMapping("/hello/{name}")
public ResponseEntity<Map<String, String>> helloName(@PathVariable String name) {
Map<String, String> response = new HashMap<>();
response.put("message", "Hello, " + name + "!");
response.put("status", "success");
return ResponseEntity.ok(response);
}
// Hello with query parameters
@GetMapping("/greet")
public ResponseEntity<Map<String, Object>> greet(
@RequestParam(defaultValue = "World") String name,
@RequestParam(defaultValue = "en") String lang) {
Map<String, Object> response = new HashMap<>();
String greeting;
switch (lang.toLowerCase()) {
case "es":
greeting = "Hola";
break;
case "fr":
greeting = "Bonjour";
break;
case "de":
greeting = "Hallo";
break;
default:
greeting = "Hello";
}
response.put("greeting", greeting + ", " + name + "!");
response.put("language", lang);
response.put("timestamp", System.currentTimeMillis());
return ResponseEntity.ok(response);
}
// POST endpoint example
@PostMapping("/hello")
public ResponseEntity<Map<String, Object>> postHello(@RequestBody Map<String, String> request) {
Map<String, Object> response = new HashMap<>();
String name = request.getOrDefault("name", "World");
response.put("message", "Hello, " + name + "!");
response.put("received", request);
response.put("timestamp", System.currentTimeMillis());
return new ResponseEntity<>(response, HttpStatus.CREATED);
}
// PUT endpoint example
@PutMapping("/hello/{id}")
public ResponseEntity<Map<String, Object>> updateHello(
@PathVariable String id,
@RequestBody Map<String, String> request) {
Map<String, Object> response = new HashMap<>();
response.put("id", id);
response.put("updated", true);
response.put("data", request);
response.put("message", "Hello updated successfully!");
return ResponseEntity.ok(response);
}
// DELETE endpoint example
@DeleteMapping("/hello/{id}")
public ResponseEntity<Map<String, String>> deleteHello(@PathVariable String id) {
Map<String, String> response = new HashMap<>();
response.put("id", id);
response.put("message", "Hello deleted successfully!");
response.put("status", "deleted");
return ResponseEntity.ok(response);
}
}
// 4. Service Layer Example
package com.example.hellospringboot.service;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
@Service
public class HelloService {
private final AtomicLong counter = new AtomicLong();
private final List<String> greetings = new ArrayList<>();
public HelloService() {
// Initialize with some default greetings
greetings.add("Hello, World!");
greetings.add("Bonjour le monde!");
greetings.add("¡Hola mundo!");
}
public String getSimpleHello() {
return "Hello from service! Counter: " + counter.incrementAndGet();
}
public String getPersonalizedHello(String name) {
return "Hello, " + name + "! Service called at " + LocalDateTime.now();
}
public List<String> getAllGreetings() {
return new ArrayList<>(greetings);
}
public String addGreeting(String greeting) {
greetings.add(greeting);
return "Greeting added: " + greeting;
}
public String getGreetingStats() {
return String.format("Total greetings: %d, Service calls: %d",
greetings.size(), counter.get());
}
}
// 5. Controller with Service Injection
package com.example.hellospringboot.controller;
import com.example.hellospringboot.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/service")
public class HelloServiceController {
private final HelloService helloService;
// Constructor injection (recommended)
@Autowired
public HelloServiceController(HelloService helloService) {
this.helloService = helloService;
}
@GetMapping("/hello")
public String getServiceHello() {
return helloService.getSimpleHello();
}
@GetMapping("/hello/{name}")
public String getPersonalizedServiceHello(@PathVariable String name) {
return helloService.getPersonalizedHello(name);
}
@GetMapping("/greetings")
public List<String> getAllGreetings() {
return helloService.getAllGreetings();
}
@PostMapping("/greetings")
public Map<String, String> addGreeting(@RequestBody Map<String, String> request) {
String greeting = request.get("greeting");
String result = helloService.addGreeting(greeting);
return Map.of(
"message", result,
"status", "success"
);
}
@GetMapping("/stats")
public Map<String, String> getStats() {
return Map.of(
"statistics", helloService.getGreetingStats(),
"status", "success"
);
}
}
// 6. Application Configuration
package com.example.hellospringboot.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class AppConfig {
// CORS configuration
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
};
}
}
// 7. Custom Exception Handler
package com.example.hellospringboot.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<Object> handleIllegalArgumentException(
IllegalArgumentException ex, WebRequest request) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("status", HttpStatus.BAD_REQUEST.value());
body.put("error", "Bad Request");
body.put("message", ex.getMessage());
body.put("path", request.getDescription(false));
return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());
body.put("error", "Internal Server Error");
body.put("message", ex.getMessage());
body.put("path", request.getDescription(false));
return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
// 8. Health Check Controller
package com.example.hellospringboot.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/health")
public class HealthController {
@GetMapping
public Map<String, Object> health() {
Map<String, Object> health = new HashMap<>();
health.put("status", "UP");
health.put("timestamp", LocalDateTime.now());
health.put("application", "Hello Spring Boot");
health.put("version", "1.0.0");
return health;
}
@GetMapping("/detailed")
public Map<String, Object> detailedHealth() {
Map<String, Object> health = new HashMap<>();
health.put("status", "UP");
health.put("timestamp", LocalDateTime.now());
health.put("application", "Hello Spring Boot");
health.put("version", "1.0.0");
// Database check (simulated)
health.put("database", Map.of(
"status", "UP",
"details", "Connection successful"
));
// Memory check
Runtime runtime = Runtime.getRuntime();
health.put("memory", Map.of(
"total", runtime.totalMemory(),
"free", runtime.freeMemory(),
"used", runtime.totalMemory() - runtime.freeMemory(),
"max", runtime.maxMemory()
));
return health;
}
}
// 9. Model/DTO Classes
package com.example.hellospringboot.model;
public class HelloRequest {
private String name;
private String language;
private String message;
// Constructors
public HelloRequest() {}
public HelloRequest(String name, String language, String message) {
this.name = name;
this.language = language;
this.message = message;
}
// Getters and Setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package com.example.hellospringboot.model;
import java.time.LocalDateTime;
public class HelloResponse {
private String message;
private String status;
private LocalDateTime timestamp;
private Object data;
// Constructors
public HelloResponse() {
this.timestamp = LocalDateTime.now();
}
public HelloResponse(String message, String status) {
this();
this.message = message;
this.status = status;
}
// Getters and Setters
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
// 10. Application Properties (src/main/resources/application.yml)
/*
spring:
application:
name: hello-spring-boot
server:
port: 8080
servlet:
context-path: /
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: when-authorized
logging:
level:
com.example.hellospringboot: DEBUG
org.springframework.web: INFO
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
info:
app:
name: Hello Spring Boot Application
version: 1.0.0
description: A simple Spring Boot Hello World application
*/
💻 Spring Boot with JPA and Hibernate java
🟡 intermediate
⭐⭐⭐⭐
Spring Boot application with JPA/Hibernate for database operations, entities, repositories, and data access
⏱️ 45 min
🏷️ spring boot, jpa, hibernate, database, orm
Prerequisites:
Spring Boot basics, SQL concepts, Entity relationships
// Spring Boot JPA and Hibernate Examples
// 1. Maven Dependencies (pom.xml additions)
/*
<dependencies>
<!-- Existing dependencies -->
<!-- JPA and Database -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database (for development) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- MySQL Database (for production) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
*/
// 2. User Entity
package com.example.hellospringboot.entity;
import jakarta.persistence.*;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message = "Name is required")
@Size(min = 2, max = 100, message = "Name must be between 2 and 100 characters")
@Column(nullable = false)
private String name;
@NotBlank(message = "Email is required")
@Email(message = "Email should be valid")
@Column(nullable = false, unique = true)
private String email;
@Column(name = "phone_number")
private String phoneNumber;
private Integer age;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private UserRole role = UserRole.USER;
@Column(name = "is_active")
private Boolean active = true;
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
// One-to-Many relationship
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Post> posts = new HashSet<>();
// Constructors
public User() {
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}
public User(String name, String email) {
this();
this.name = name;
this.email = email;
}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public UserRole getRole() {
return role;
}
public void setRole(UserRole role) {
this.role = role;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public Set<Post> getPosts() {
return posts;
}
public void setPosts(Set<Post> posts) {
this.posts = posts;
}
@PreUpdate
protected void onUpdate() {
this.updatedAt = LocalDateTime.now();
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + ''' +
", email='" + email + ''' +
", role=" + role +
", active=" + active +
'}';
}
}
// 3. User Role Enum
package com.example.hellospringboot.entity;
public enum UserRole {
USER,
ADMIN,
MODERATOR
}
// 4. Post Entity
package com.example.hellospringboot.entity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
@Entity
@Table(name = "posts")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message = "Title is required")
@Size(max = 200, message = "Title must not exceed 200 characters")
@Column(nullable = false)
private String title;
@NotBlank(message = "Content is required")
@Column(columnDefinition = "TEXT")
private String content;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private PostStatus status = PostStatus.DRAFT;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
// Constructors
public Post() {
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}
public Post(String title, String content, User user) {
this();
this.title = title;
this.content = content;
this.user = user;
}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public PostStatus getStatus() {
return status;
}
public void setStatus(PostStatus status) {
this.status = status;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
@PreUpdate
protected void onUpdate() {
this.updatedAt = LocalDateTime.now();
}
}
// 5. Post Status Enum
package com.example.hellospringboot.entity;
public enum PostStatus {
DRAFT,
PUBLISHED,
ARCHIVED
}
// 6. User Repository
package com.example.hellospringboot.repository;
import com.example.hellospringboot.entity.User;
import com.example.hellospringboot.entity.UserRole;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Find by email
Optional<User> findByEmail(String email);
// Find by name (case insensitive)
List<User> findByNameIgnoreCase(String name);
// Find by role and active status
List<User> findByRoleAndActive(UserRole role, Boolean active);
// Find by age range
List<User> findByAgeBetween(Integer minAge, Integer maxAge);
// Custom query with pagination
@Query("SELECT u FROM User u WHERE " +
"(:name IS NULL OR LOWER(u.name) LIKE LOWER(CONCAT('%', :name, '%'))) AND " +
"(:email IS NULL OR LOWER(u.email) LIKE LOWER(CONCAT('%', :email, '%'))) AND " +
"(:role IS NULL OR u.role = :role)")
Page<User> findUsersWithFilters(@Param("name") String name,
@Param("email") String email,
@Param("role") UserRole role,
Pageable pageable);
// Count users by role
long countByRole(UserRole role);
// Check if email exists
boolean existsByEmail(String email);
// Native SQL query
@Query(value = "SELECT * FROM users WHERE created_at >= :startDate", nativeQuery = true)
List<User> findUsersCreatedAfter(@Param("startDate") String startDate);
// Find users with most posts
@Query("SELECT u FROM User u LEFT JOIN u.posts p GROUP BY u ORDER BY COUNT(p) DESC")
List<User> findUsersWithMostPosts(Pageable pageable);
}
// 7. Post Repository
package com.example.hellospringboot.repository;
import com.example.hellospringboot.entity.Post;
import com.example.hellospringboot.entity.PostStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.time.LocalDateTime;
import java.util.List;
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
// Find by user
List<Post> findByUserId(Long userId);
// Find by status
List<Post> findByStatus(PostStatus status);
// Find by user and status
List<Post> findByUserIdAndStatus(Long userId, PostStatus status);
// Search posts by title or content
@Query("SELECT p FROM Post p WHERE " +
"LOWER(p.title) LIKE LOWER(CONCAT('%', :keyword, '%')) OR " +
"LOWER(p.content) LIKE LOWER(CONCAT('%', :keyword, '%'))")
Page<Post> searchPosts(@Param("keyword") String keyword, Pageable pageable);
// Find posts created within date range
@Query("SELECT p FROM Post p WHERE p.createdAt BETWEEN :startDate AND :endDate")
List<Post> findPostsByDateRange(@Param("startDate") LocalDateTime startDate,
@Param("endDate") LocalDateTime endDate);
// Count posts by user
long countByUserId(Long userId);
// Find recently published posts
@Query("SELECT p FROM Post p WHERE p.status = :status ORDER BY p.createdAt DESC")
List<Post> findRecentPosts(@Param("status") PostStatus status, Pageable pageable);
}
// 8. User Service
package com.example.hellospringboot.service;
import com.example.hellospringboot.entity.User;
import com.example.hellospringboot.entity.UserRole;
import com.example.hellospringboot.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
@Transactional
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User createUser(User user) {
if (userRepository.existsByEmail(user.getEmail())) {
throw new IllegalArgumentException("Email already exists: " + user.getEmail());
}
return userRepository.save(user);
}
public User updateUser(Long id, User userDetails) {
User user = getUserById(id);
user.setName(userDetails.getName());
user.setEmail(userDetails.getEmail());
user.setPhoneNumber(userDetails.getPhoneNumber());
user.setAge(userDetails.getAge());
user.setRole(userDetails.getRole());
user.setActive(userDetails.getActive());
return userRepository.save(user);
}
public void deleteUser(Long id) {
User user = getUserById(id);
userRepository.delete(user);
}
@Transactional(readOnly = true)
public User getUserById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("User not found with id: " + id));
}
@Transactional(readOnly = true)
public Optional<User> getUserByEmail(String email) {
return userRepository.findByEmail(email);
}
@Transactional(readOnly = true)
public Page<User> getAllUsers(Pageable pageable) {
return userRepository.findAll(pageable);
}
@Transactional(readOnly = true)
public Page<User> searchUsers(String name, String email, UserRole role, Pageable pageable) {
return userRepository.findUsersWithFilters(name, email, role, pageable);
}
@Transactional(readOnly = true)
public List<User> getUsersByRole(UserRole role) {
return userRepository.findByRoleAndActive(role, true);
}
@Transactional(readOnly = true)
public List<User> getUsersByAgeRange(Integer minAge, Integer maxAge) {
return userRepository.findByAgeBetween(minAge, maxAge);
}
@Transactional(readOnly = true)
public long getUserCount() {
return userRepository.count();
}
@Transactional(readOnly = true)
public long getUserCountByRole(UserRole role) {
return userRepository.countByRole(role);
}
}
// 9. User Controller
package com.example.hellospringboot.controller;
import com.example.hellospringboot.entity.User;
import com.example.hellospringboot.entity.UserRole;
import com.example.hellospringboot.service.UserService;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User createdUser = userService.createUser(user);
return new ResponseEntity<>(createdUser, HttpStatus.CREATED);
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.getUserById(id);
return ResponseEntity.ok(user);
}
@GetMapping
public ResponseEntity<Page<User>> getAllUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sortBy,
@RequestParam(defaultValue = "asc") String sortDir) {
Sort sort = sortDir.equalsIgnoreCase("desc") ?
Sort.by(sortBy).descending() : Sort.by(sortBy).ascending();
Pageable pageable = PageRequest.of(page, size, sort);
Page<User> users = userService.getAllUsers(pageable);
return ResponseEntity.ok(users);
}
@GetMapping("/search")
public ResponseEntity<Page<User>> searchUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) String email,
@RequestParam(required = false) UserRole role,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Pageable pageable = PageRequest.of(page, size);
Page<User> users = userService.searchUsers(name, email, role, pageable);
return ResponseEntity.ok(users);
}
@GetMapping("/email/{email}")
public ResponseEntity<User> getUserByEmail(@PathVariable String email) {
Optional<User> user = userService.getUserByEmail(email);
return user.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@GetMapping("/role/{role}")
public ResponseEntity<List<User>> getUsersByRole(@PathVariable UserRole role) {
List<User> users = userService.getUsersByRole(role);
return ResponseEntity.ok(users);
}
@GetMapping("/age-range")
public ResponseEntity<List<User>> getUsersByAgeRange(
@RequestParam Integer minAge,
@RequestParam Integer maxAge) {
List<User> users = userService.getUsersByAgeRange(minAge, maxAge);
return ResponseEntity.ok(users);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @Valid @RequestBody User userDetails) {
User updatedUser = userService.updateUser(id, userDetails);
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}")
public ResponseEntity<Map<String, String>> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.ok(Map.of(
"message", "User deleted successfully",
"status", "success"
));
}
@GetMapping("/stats")
public ResponseEntity<Map<String, Object>> getUserStats() {
Map<String, Object> stats = Map.of(
"totalUsers", userService.getUserCount(),
"adminCount", userService.getUserCountByRole(UserRole.ADMIN),
"userCount", userService.getUserCountByRole(UserRole.USER),
"moderatorCount", userService.getUserCountByRole(UserRole.MODERATOR)
);
return ResponseEntity.ok(stats);
}
}
// 10. Database Configuration (application.yml)
/*
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password: password
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.H2Dialect
defer-datasource-initialization: true
h2:
console:
enabled: true
path: /h2-console
sql:
init:
mode: always
data-locations: classpath:data.sql
*/
// 11. Sample Data (src/main/resources/data.sql)
/*
INSERT INTO users (name, email, phone_number, age, role, is_active, created_at, updated_at) VALUES
('John Doe', '[email protected]', '123-456-7890', 30, 'USER', true, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Jane Smith', '[email protected]', '098-765-4321', 25, 'ADMIN', true, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Bob Johnson', '[email protected]', '555-123-4567', 35, 'USER', true, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Alice Brown', '[email protected]', '555-987-6543', 28, 'MODERATOR', true, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Charlie Wilson', '[email protected]', '555-246-8135', 42, 'USER', false, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO posts (title, content, status, user_id, created_at, updated_at) VALUES
('First Post', 'This is my first blog post content.', 'PUBLISHED', 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Draft Article', 'This is still a draft and needs more work.', 'DRAFT', 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Spring Boot Tutorial', 'Learn how to create Spring Boot applications.', 'PUBLISHED', 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Java Programming', 'Advanced Java programming concepts and best practices.', 'PUBLISHED', 3, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Web Development', 'Modern web development with JavaScript frameworks.', 'ARCHIVED', 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
*/
💻 Spring Boot Security and JWT java
🔴 complex
⭐⭐⭐⭐⭐
Spring Boot application with Spring Security, JWT authentication, authorization, and secure API endpoints
⏱️ 60 min
🏷️ spring boot, security, jwt, authentication, authorization
Prerequisites:
Spring Boot basics, Security concepts, JWT tokens
// Spring Boot Security and JWT Examples
// 1. Maven Dependencies (pom.xml additions)
/*
<dependencies>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT Support -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<!-- Existing dependencies -->
</dependencies>
*/
// 2. JWT Utility Class
package com.example.hellospringboot.security;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.util.Date;
@Component
public class JwtTokenProvider {
@Value("${app.jwt.secret:mySecretKey}")
private String jwtSecret;
@Value("${app.jwt.expiration:86400}")
private int jwtExpirationInMs;
private SecretKey getSigningKey() {
return Keys.hmacShaKeyFor(jwtSecret.getBytes());
}
public String generateToken(Authentication authentication) {
UserDetails userPrincipal = (UserDetails) authentication.getPrincipal();
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpirationInMs * 1000);
return Jwts.builder()
.setSubject(userPrincipal.getUsername())
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(getSigningKey(), SignatureAlgorithm.HS512)
.compact();
}
public String getUsernameFromToken(String token) {
Claims claims = Jwts.parserBuilder()
.setSigningKey(getSigningKey())
.build()
.parseClaimsJws(token)
.getBody();
return claims.getSubject();
}
public Date getExpirationDateFromToken(String token) {
Claims claims = Jwts.parserBuilder()
.setSigningKey(getSigningKey())
.build()
.parseClaimsJws(token)
.getBody();
return claims.getExpiration();
}
public boolean validateToken(String token) {
try {
Jwts.parserBuilder()
.setSigningKey(getSigningKey())
.build()
.parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException ex) {
// Log error
return false;
}
}
public String refreshToken(String token) {
final Date createdDate = new Date();
final Date expirationDate = calculateExpirationDate(createdDate);
final Claims claims = getAllClaimsFromToken(token);
claims.setIssuedAt(createdDate);
claims.setExpiration(expirationDate);
return Jwts.builder()
.setClaims(claims)
.signWith(getSigningKey(), SignatureAlgorithm.HS512)
.compact();
}
private Date calculateExpirationDate(Date createdDate) {
return new Date(createdDate.getTime() + jwtExpirationInMs * 1000);
}
private Claims getAllClaimsFromToken(String token) {
return Jwts.parserBuilder()
.setSigningKey(getSigningKey())
.build()
.parseClaimsJws(token)
.getBody();
}
}
// 3. JWT Authentication Filter
package com.example.hellospringboot.security;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenProvider tokenProvider;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
try {
String jwt = getJwtFromRequest(request);
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
String username = tokenProvider.getUsernameFromToken(jwt);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception ex) {
logger.error("Could not set user authentication in security context", ex);
}
filterChain.doFilter(request, response);
}
private String getJwtFromRequest(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
}
// 4. Custom User Details Service
package com.example.hellospringboot.security;
import com.example.hellospringboot.entity.User;
import com.example.hellospringboot.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException {
User user = userRepository.findByEmail(usernameOrEmail)
.orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + usernameOrEmail));
if (!user.getActive()) {
throw new UsernameNotFoundException("User account is disabled");
}
return UserPrincipal.create(user);
}
}
// 5. User Principal Class
package com.example.hellospringboot.security;
import com.example.hellospringboot.entity.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class UserPrincipal implements UserDetails {
private Long id;
private String email;
private String password;
private Collection<? extends GrantedAuthority> authorities;
public UserPrincipal(Long id, String email, String password, Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.email = email;
this.password = password;
this.authorities = authorities;
}
public static UserPrincipal create(User user) {
List<GrantedAuthority> authorities = Collections.singletonList(
new SimpleGrantedAuthority("ROLE_" + user.getRole().name())
);
return new UserPrincipal(
user.getId(),
user.getEmail(),
user.getPassword(),
authorities
);
}
public Long getId() {
return id;
}
@Override
public String getUsername() {
return email;
}
@Override
public String getPassword() {
return password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
// 6. Security Configuration
package com.example.hellospringboot.config;
import com.example.hellospringboot.security.JwtAuthenticationFilter;
import com.example.hellospringboot.security.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(customUserDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests(authz -> authz
// Public endpoints
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/h2-console/**").permitAll()
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/products/**").permitAll()
// Admin endpoints
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/users/**").hasAnyRole("ADMIN", "MODERATOR")
// Protected endpoints
.requestMatchers("/api/profile/**").authenticated()
.requestMatchers("/api/posts/**").authenticated()
// Everything else requires authentication
.anyRequest().authenticated()
)
.authenticationProvider(authenticationProvider())
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
// Allow H2 console frames
http.headers().frameOptions().disable();
return http.build();
}
}
// 7. Authentication DTOs
package com.example.hellospringboot.dto;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public class LoginRequest {
@NotBlank
@Email
private String email;
@NotBlank
@Size(min = 6, max = 40)
private String password;
// Getters and Setters
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package com.example.hellospringboot.dto;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public class SignUpRequest {
@NotBlank
@Size(min = 2, max = 50)
private String name;
@NotBlank
@Size(max = 60)
@Email
private String email;
@NotBlank
@Size(min = 6, max = 40)
private String password;
// Getters and Setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package com.example.hellospringboot.dto;
public class JwtAuthenticationResponse {
private String accessToken;
private String tokenType = "Bearer";
private Long expiresIn;
public JwtAuthenticationResponse(String accessToken, Long expiresIn) {
this.accessToken = accessToken;
this.expiresIn = expiresIn;
}
// Getters and Setters
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getTokenType() {
return tokenType;
}
public void setTokenType(String tokenType) {
this.tokenType = tokenType;
}
public Long getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(Long expiresIn) {
this.expiresIn = expiresIn;
}
}
// 8. Authentication Service
package com.example.hellospringboot.service;
import com.example.hellospringboot.dto.JwtAuthenticationResponse;
import com.example.hellospringboot.dto.LoginRequest;
import com.example.hellospringboot.dto.SignUpRequest;
import com.example.hellospringboot.entity.User;
import com.example.hellospringboot.entity.UserRole;
import com.example.hellospringboot.repository.UserRepository;
import com.example.hellospringboot.security.JwtTokenProvider;
import com.example.hellospringboot.security.UserPrincipal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class AuthService {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private JwtTokenProvider tokenProvider;
@Transactional
public JwtAuthenticationResponse authenticateUser(LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getEmail(),
loginRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.generateToken(authentication);
return new JwtAuthenticationResponse(jwt, 86400L); // 24 hours
}
@Transactional
public User registerUser(SignUpRequest signUpRequest) {
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
throw new RuntimeException("Email is already taken!");
}
User user = new User();
user.setName(signUpRequest.getName());
user.setEmail(signUpRequest.getEmail());
user.setPassword(passwordEncoder.encode(signUpRequest.getPassword()));
user.setRole(UserRole.USER);
user.setActive(true);
return userRepository.save(user);
}
@Transactional(readOnly = true)
public User getCurrentUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.getPrincipal() instanceof UserPrincipal) {
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
return userRepository.findById(userPrincipal.getId())
.orElseThrow(() -> new RuntimeException("User not found"));
}
throw new RuntimeException("User not authenticated");
}
}
// 9. Authentication Controller
package com.example.hellospringboot.controller;
import com.example.hellospringboot.dto.JwtAuthenticationResponse;
import com.example.hellospringboot.dto.LoginRequest;
import com.example.hellospringboot.dto.SignUpRequest;
import com.example.hellospringboot.entity.User;
import com.example.hellospringboot.service.AuthService;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthService authService;
@PostMapping("/login")
public ResponseEntity<JwtAuthenticationResponse> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
JwtAuthenticationResponse response = authService.authenticateUser(loginRequest);
return ResponseEntity.ok(response);
}
@PostMapping("/register")
public ResponseEntity<User> registerUser(@Valid @RequestBody SignUpRequest signUpRequest) {
User user = authService.registerUser(signUpRequest);
return new ResponseEntity<>(user, HttpStatus.CREATED);
}
@GetMapping("/me")
public ResponseEntity<User> getCurrentUser() {
User user = authService.getCurrentUser();
return ResponseEntity.ok(user);
}
}
// 10. Protected Resource Example
package com.example.hellospringboot.controller;
import com.example.hellospringboot.entity.User;
import com.example.hellospringboot.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/profile")
public class ProfileController {
@Autowired
private AuthService authService;
@GetMapping
public ResponseEntity<User> getProfile() {
User user = authService.getCurrentUser();
return ResponseEntity.ok(user);
}
@GetMapping("/info")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<Map<String, Object>> getProfileInfo() {
User user = authService.getCurrentUser();
Map<String, Object> info = new HashMap<>();
info.put("user", user);
info.put("message", "This is your protected profile information");
info.put("accessLevel", "Authenticated User");
return ResponseEntity.ok(info);
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<Map<String, String>> getAdminInfo() {
return ResponseEntity.ok(Map.of(
"message", "This is admin-only information",
"accessLevel", "Administrator"
));
}
@GetMapping("/moderator")
@PreAuthorize("hasAnyRole('ADMIN', 'MODERATOR')")
public ResponseEntity<Map<String, String>> getModeratorInfo() {
return ResponseEntity.ok(Map.of(
"message", "This is moderator+ level information",
"accessLevel", "Moderator or Administrator"
));
}
}
// 11. Application Properties (application.yml)
/*
app:
jwt:
secret: mySecretKey123456789012345678901234567890
expiration: 86400 # 24 hours in seconds
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password: password
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.H2Dialect
default_schema: PUBLIC
h2:
console:
enabled: true
path: /h2-console
settings:
web-allow-others: true
# Logging
logging:
level:
com.example.hellospringboot: DEBUG
org.springframework.security: DEBUG
org.springframework.web: INFO
io.jsonwebtoken: DEBUG
*/