Building a Homestay Booking System for Android with Spring Boot
This article outlines the development of a homestay booking application for the Android platform. The system is designed to provide users with a mobile interface for browsing available accommodations, viewing announcements, and managing bookings. It serves three primary user roles: administrators, guests (users), and property owners (merchants).
Unlike traditional desktop applications, this system is optimized for mobile use, allowing users to access real-time information about homestay listings directly from their Android devices.
The backend server is built using the Spring Boot framwork to ensure stability and mitigate compatibility issues. Data persistence is handled by a MySQL database. Application logic, written primarily in Java, processes user requests and facilitates data exchange between the Android client and the database server. This architecture is intended to enhance information flow, improve data transmission efficiency, and deliver a feature-rich, user-friendly booking experience.
Keywords: Android Application, Homestay Booking, Spring Boot, Java, MySQL
Backend Controller Code Examples
The following code snippets illustrate key back end components, rewritten for clarity and structure while maintaining original functionality.
1. Merchant (Vendor) Management Controller
This controller handles authentication and CRUD operations for property owners/vendors.
package com.example.homestay.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.homestay.common.utils.Result;
import com.example.homestay.entity.Vendor;
import com.example.homestay.service.VendorService;
import com.example.homestay.service.AuthTokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/vendor")
public class VendorController {
@Autowired
private VendorService vendorService;
@Autowired
private AuthTokenService authTokenService;
/**
* Vendor Login
*/
@PostMapping("/login")
public Result login(@RequestParam String account,
@RequestParam String password,
HttpServletRequest request) {
QueryWrapper<Vendor> query = new QueryWrapper<>();
query.eq("vendor_account", account);
Vendor vendor = vendorService.getOne(query);
if (vendor == null || !vendor.getPassword().equals(password)) {
return Result.error("Invalid account or password");
}
String token = authTokenService.createToken(vendor.getId(), account, "vendor", "Property Owner");
return Result.ok().put("accessToken", token);
}
/**
* Vendor Registration
*/
@PostMapping("/register")
public Result register(@RequestBody Vendor newVendor) {
QueryWrapper<Vendor> checkQuery = new QueryWrapper<>();
checkQuery.eq("vendor_account", newVendor.getVendorAccount());
if (vendorService.getOne(checkQuery) != null) {
return Result.error("Account already exists");
}
newVendor.setId(System.currentTimeMillis());
vendorService.save(newVendor);
return Result.ok("Registration successful");
}
/**
* Retrieve Paginated Vendor List (Backend)
*/
@GetMapping("/page")
public Result getVendorPage(@RequestParam Map<String, Object> params,
Vendor searchCriteria) {
// Implementation for paginated query with filters
// ...
return Result.ok().put("pageData", pageResult);
}
}
2. Accommodation Listing Controller
This controller manages the homestay/room listings, including views and recommendations.
package com.example.homestay.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.homestay.common.utils.PageResult;
import com.example.homestay.common.utils.Result;
import com.example.homestay.entity.RoomListing;
import com.example.homestay.service.RoomListingService;
import com.example.homestay.service.UserFavoriteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
@RestController
@RequestMapping("/api/listing")
public class RoomListingController {
@Autowired
private RoomListingService listingService;
@Autowired
private UserFavoriteService favoriteService;
/**
* Get Listing Details and Increment View Count
*/
@GetMapping("/detail/{id}")
public Result getListingDetail(@PathVariable("id") Long listingId, HttpServletRequest request) {
RoomListing listing = listingService.getById(listingId);
if (listing != null) {
listing.setViewCount(listing.getViewCount() + 1);
listing.setLastViewed(new Date());
listingService.updateById(listing);
}
return Result.ok().put("listing", listing);
}
/**
* Save a New Room Listing
*/
@PostMapping("/save")
public Result createListing(@RequestBody RoomListing listing, HttpServletRequest request) {
Long userId = (Long) request.getSession().getAttribute("currentUserId");
listing.setId(System.currentTimeMillis());
listing.setPostedBy(userId);
listingService.save(listing);
return Result.ok("Listing created");
}
/**
* Collaborative Filtering: Recommend listings based on user favorites.
*/
@GetMapping("/recommendations")
public Result getRecommendations(@RequestParam Map<String, Object> params,
HttpServletRequest request) {
String userId = request.getSession().getAttribute("currentUserId").toString();
String categoryField = "room_type";
int limit = params.get("limit") == null ? 10 : Integer.parseInt(params.get("limit").toString());
// 1. Fetch user's favorite items
List<UserFavorite> favorites = favoriteService.list(
new QueryWrapper<UserFavorite>()
.eq("user_id", userId)
.eq("entity_name", "room_listing")
.orderByDesc("created_time")
);
List<RoomListing> recommendedListings = new ArrayList<>();
Set<Long> addedIds = new HashSet<>();
// 2. Find listings matching favorite categories
if (favorites != null && !favorites.isEmpty()) {
for (UserFavorite fav : favorites) {
List<RoomListing> similar = listingService.list(
new QueryWrapper<RoomListing>().eq(categoryField, fav.getCategory())
);
for (RoomListing item : similar) {
if (!addedIds.contains(item.getId())) {
recommendedListings.add(item);
addedIds.add(item.getId());
}
}
}
}
// 3. If insufficient recommendations, add popular listings
if (recommendedListings.size() < limit) {
QueryWrapper<RoomListing> popularQuery = new QueryWrapper<>();
popularQuery.orderByDesc("view_count");
List<RoomListing> popular = listingService.list(popularQuery);
for (RoomListing item : popular) {
if (!addedIds.contains(item.getId())) {
recommendedListings.add(item);
addedIds.add(item.getId());
if (recommendedListings.size() >= limit) break;
}
}
}
// 4. Limit final list size
if (recommendedListings.size() > limit) {
recommendedListings = recommendedListings.subList(0, limit);
}
return Result.ok().put("recommendations", recommendedListings);
}
}