Building a Java-based Smart Parking System involves creating a system that allows users to find, reserve, and pay for parking spots in real-time. Below is a step-by-step guide to building such a system, including the key components, design considerations, and example code snippets.
1. Requirements Analysis
Before starting, define the requirements for the system:
- User Roles: Admin (manage parking spots) and User (find and reserve parking spots).
- Parking Spot Management: Add, update, delete, and view parking spots.
- Parking Reservation: Allow users to reserve parking spots.
- Real-Time Availability: Show real-time availability of parking spots.
- Payment Integration: Integrate a payment gateway for parking fees.
- Security: Secure access to the system for authenticated users.
2. System Design
Modules
- User Management
- Register and authenticate users.
- Parking Spot Management
- Add, update, delete, and view parking spots.
- Parking Reservation
- Allow users to reserve parking spots.
- Real-Time Availability
- Show real-time availability of parking spots.
- Payment Integration
- Process payments for parking reservations.
- Security
- Secure access to the system for authenticated users.
Database Design
- User Table:
user_id
,username
,password
,role
- Parking Spot Table:
spot_id
,location
,status
,reserved_by
,reservation_time
- Reservation Table:
reservation_id
,user_id
,spot_id
,start_time
,end_time
,status
3. Technology Stack
- Backend: Java (Spring Boot)
- Frontend: Thymeleaf (for simplicity) or Angular/React (for advanced UI)
- Database: MySQL or H2 (for testing)
- Build Tool: Maven or Gradle
- Security: Spring Security for authentication and authorization
- Payment Gateway: Integrate with a payment gateway like Stripe or PayPal
4. Implementation
Step 1: Set Up the Project
Create a Spring Boot project using Spring Initializr with the following dependencies:
- Spring Web
- Spring Data JPA
- Spring Security
- Thymeleaf (for UI)
- MySQL Driver (or H2 for testing)
Step 2: Define Entities
Create Java classes for the database tables.
User.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
private String username;
private String password;
private String role; // "ADMIN" or "USER"
// Getters and Setters
}
ParkingSpot.java
@Entity
public class ParkingSpot {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long spotId;
private String location;
private String status; // "AVAILABLE", "RESERVED"
private Long reservedBy;
private LocalDateTime reservationTime;
// Getters and Setters
}
Reservation.java
@Entity
public class Reservation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long reservationId;
private Long userId;
private Long spotId;
private LocalDateTime startTime;
private LocalDateTime endTime;
private String status; // "ACTIVE", "COMPLETED"
// Getters and Setters
}
Step 3: Create Repositories
Use Spring Data JPA to create repositories for database operations.
UserRepository.java
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username); // For authentication
}
ParkingSpotRepository.java
public interface ParkingSpotRepository extends JpaRepository<ParkingSpot, Long> {
List<ParkingSpot> findByStatus(String status); // For available spots
}
ReservationRepository.java
public interface ReservationRepository extends JpaRepository<Reservation, Long> {
List<Reservation> findByUserId(Long userId); // For user's reservations
}
Step 4: Implement Services
Create service classes to handle business logic.
UserService.java
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void registerUser(User user) {
userRepository.save(user);
}
public boolean authenticateUser(String username, String password) {
Optional<User> user = userRepository.findByUsername(username);
return user.isPresent() && user.get().getPassword().equals(password);
}
}
ParkingSpotService.java
@Service
public class ParkingSpotService {
@Autowired
private ParkingSpotRepository parkingSpotRepository;
public List<ParkingSpot> getAvailableSpots() {
return parkingSpotRepository.findByStatus("AVAILABLE");
}
public void reserveSpot(Long spotId, Long userId) {
ParkingSpot spot = parkingSpotRepository.findById(spotId).orElseThrow();
spot.setStatus("RESERVED");
spot.setReservedBy(userId);
spot.setReservationTime(LocalDateTime.now());
parkingSpotRepository.save(spot);
}
public void releaseSpot(Long spotId) {
ParkingSpot spot = parkingSpotRepository.findById(spotId).orElseThrow();
spot.setStatus("AVAILABLE");
spot.setReservedBy(null);
spot.setReservationTime(null);
parkingSpotRepository.save(spot);
}
}
ReservationService.java
@Service
public class ReservationService {
@Autowired
private ReservationRepository reservationRepository;
public void createReservation(Long userId, Long spotId, LocalDateTime startTime, LocalDateTime endTime) {
Reservation reservation = new Reservation();
reservation.setUserId(userId);
reservation.setSpotId(spotId);
reservation.setStartTime(startTime);
reservation.setEndTime(endTime);
reservation.setStatus("ACTIVE");
reservationRepository.save(reservation);
}
public void completeReservation(Long reservationId) {
Reservation reservation = reservationRepository.findById(reservationId).orElseThrow();
reservation.setStatus("COMPLETED");
reservationRepository.save(reservation);
}
public List<Reservation> getUserReservations(Long userId) {
return reservationRepository.findByUserId(userId);
}
}
Step 5: Create Controllers
Create controllers to handle HTTP requests.
UserController.java
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
public void registerUser(@RequestBody User user) {
userService.registerUser(user);
}
@PostMapping("/authenticate")
public boolean authenticateUser(@RequestParam String username, @RequestParam String password) {
return userService.authenticateUser(username, password);
}
}
ParkingSpotController.java
@RestController
@RequestMapping("/parking-spots")
public class ParkingSpotController {
@Autowired
private ParkingSpotService parkingSpotService;
@GetMapping("/available")
public List<ParkingSpot> getAvailableSpots() {
return parkingSpotService.getAvailableSpots();
}
@PostMapping("/reserve")
public void reserveSpot(@RequestParam Long spotId, @RequestParam Long userId) {
parkingSpotService.reserveSpot(spotId, userId);
}
@PostMapping("/release")
public void releaseSpot(@RequestParam Long spotId) {
parkingSpotService.releaseSpot(spotId);
}
}
ReservationController.java
@RestController
@RequestMapping("/reservations")
public class ReservationController {
@Autowired
private ReservationService reservationService;
@PostMapping
public void createReservation(@RequestParam Long userId, @RequestParam Long spotId,
@RequestParam LocalDateTime startTime, @RequestParam LocalDateTime endTime) {
reservationService.createReservation(userId, spotId, startTime, endTime);
}
@PostMapping("/complete")
public void completeReservation(@RequestParam Long reservationId) {
reservationService.completeReservation(reservationId);
}
@GetMapping("/{userId}")
public List<Reservation> getUserReservations(@PathVariable Long userId) {
return reservationService.getUserReservations(userId);
}
}
Step 6: Implement Security
Use Spring Security to secure the application.
SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserRepository userRepository;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(username -> userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found")));
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/users/**", "/parking-spots/**", "/reservations/**").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic();
}
}
Step 7: Frontend (Optional)
Use Thymeleaf or a frontend framework like Angular/React to create a user interface for the system.
5. Testing
- Use JUnit and Mockito for unit testing.
- Test the application using Postman or Swagger for API testing.
6. Deployment
- Package the application as a JAR/WAR file and deploy it to a server (e.g., Tomcat).
- Use Docker for containerization and Kubernetes for orchestration (optional).
Example Use Cases
- User Registration
- User registers with details like username and password.
- Parking Spot Reservation
- User reserves a parking spot.
- Parking Spot Release
- User releases a reserved parking spot.
- Reservation Management
- User views and completes their reservations.