如何存储与服务大量用户自动生成HTML页面?Java Web应用实现咨询
Hey Antonio, great question—let’s break down how to build this Java Web app while keeping your pages persistent through redeploys and handling dynamic routing smoothly. Here’s a practical, scalable approach tailored to your needs:
The biggest mistake you could make is saving user-generated HTML as static files on your server. Not only do these get wiped during redeploys, but managing publish states and unique paths becomes a nightmare. Instead, use a persistent database to store every page’s metadata and content.
Recommended Database Schema (PostgreSQL example)
This table tracks all user pages, their paths, publish status, and content:
CREATE TABLE user_pages ( id SERIAL PRIMARY KEY, user_nickname VARCHAR(50) NOT NULL, page_suffix VARCHAR(100) NOT NULL DEFAULT '', html_content TEXT NOT NULL, is_published BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Ensure no duplicate pages per user UNIQUE(user_nickname, page_suffix) );
user_nickname: Maps to the root path (e.g.,johnfor/john)page_suffix: Empty string for the user’s main page;pageOnefor/john/pageOneis_published: Controls whether the page is accessible publicly
You need a way to catch all requests to /userNickname/** and route them to the correct page from the database. Here’s how to do it with Spring MVC, the most common Java Web framework:
Controller Example
@Controller public class UserPageController { @Autowired private UserPageRepository pageRepo; // JPA repository for the table above @GetMapping("/{userNickname}/**") public String serveUserPage( @PathVariable String userNickname, HttpServletRequest request, Model model ) { // Extract the page suffix from the request URI String fullPath = request.getRequestURI(); String pageSuffix = fullPath.substring(userNickname.length() + 2); // Skip "/userNickname/" // Handle the main page (empty suffix) if (pageSuffix.isBlank()) { pageSuffix = ""; } // Fetch the page from the database Optional<UserPage> page = pageRepo.findByUserNicknameAndPageSuffix(userNickname, pageSuffix); if (page.isEmpty()) { return "error/404"; // Return 404 if page doesn't exist } UserPage userPage = page.get(); if (!userPage.isPublished()) { return "user/unpublished"; // Custom page for unpublished content } // Pass the HTML content to your template for rendering model.addAttribute("pageContent", userPage.getHtmlContent()); return "user/page-template"; // A Thymeleaf/JSP template that renders the HTML } // API endpoint for users to save/update their pages @PostMapping("/api/user/pages") @ResponseBody public ResponseEntity<String> savePage(@RequestBody UserPageRequest request) { // Add validation here: ensure the current user owns the nickname! UserPage page = pageRepo.findByUserNicknameAndPageSuffix( request.getUserNickname(), request.getPageSuffix() ).orElse(new UserPage()); page.setUserNickname(request.getUserNickname()); page.setPageSuffix(request.getPageSuffix()); page.setHtmlContent(sanitizeHtml(request.getHtmlContent())); // Sanitize to prevent XSS page.setPublished(request.isPublished()); pageRepo.save(page); return ResponseEntity.ok("Page saved successfully"); } // Helper to clean user-provided HTML (prevents XSS attacks) private String sanitizeHtml(String rawHtml) { // Use Jsoup to strip dangerous tags/scripts return Jsoup.clean(rawHtml, Whitelist.basicWithImages()); } }
Since all page data lives in the database (not on the application server’s filesystem), redeploying your app won’t touch any user-generated content. As long as your database connection stays intact, every page will be available immediately after deployment—no need to regenerate anything.
- Caching: For high-traffic pages, add a Redis cache to store published HTML content. Use a key like
user_page:{nickname}:{suffix}and invalidate the cache whenever a user updates their page. This reduces database load significantly. - Versioning: Add a
versioncolumn to the table if you want users to roll back to previous page versions. - Custom Error Pages: Create branded 404/unpublished pages to keep the user experience consistent.
内容的提问来源于stack exchange,提问作者Antonio Marras

