本項目完整實現了知乎風格的首頁,包含:
| 層面 | 技術 |
|---|---|
| 後端框架 | Spring MVC + Spring Security |
| 視圖技術 | JSP + JSTL |
| 前端交互 | jQuery + 原生 JS (Canvas) |
| 構建工具 | Maven |
| 數據庫 | MySQL (用戶表) |
單頁應用結構:
<div class="index-box">
<div class="index-header"><h1 class="logo"></h1><h2 class="title">Speed4C開發平台</h2></div>
<div class="index-body">
<div class="nav-sliders">
<a id="loginButton" class="login active">登錄</a>
<a class="registered">注冊</a>
<span class="on"></span> <!-- 滑塊指示器 -->
</div>
<div class="change">
<!-- 登錄表單 -->
<div class="login-box">
<form id="loginForm" action="${pageContext.request.contextPath}/j_spring_security_check" method="post">
<div class="wrap">
<div class="phone"><input type="email" id="username" name='j_username' placeholder="用戶名"><label class="error loginName">請輸入登錄名</label></div>
<div class="password"><input type="password" id="password" name='j_password' placeholder="密碼"><label class="error loginPass">密碼</label></div>
</div>
<div class="button" id="login">登錄</div>
<div class="remember"><label><input id="rememberMe" name="_spring_security_remember_me" type="checkbox">記住我</label><a>無法登陸?</a></div>
</form>
<div class="other"><span>社交賬號登錄</span><div class="other-login"><a>QQ</a><a>微信</a><a>微博</a></div></div>
<div class="other"><span>${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}</span></div> <!-- 顯示登錄失敗信息 -->
</div>
<!-- 註冊表單 -->
<div class="registered-box" style="display:none;">
<form id="registerForm" method="post" action="registerUser.do">
<div class="wrap">
<div class="phone"><input type="email" name="name" id="name" placeholder="用戶名(郵箱)"><label class="error name">請輸入用戶名</label></div>
<div class="password"><input type="password" id="passwor" name="passwor" placeholder="密碼"><label class="error pass">請輸入密碼</label></div>
<div class="password"><input type="password" id="pssworAgain" placeholder="再次輸入密碼"><label class="error passagain">請再次輸入密碼</label></div>
<div class="password"><input type="text" id="code" name="" maxlength="6" placeholder="驗證碼"><label class="error passwor code">請輸入驗證碼</label><div class="verification-code" id="createCade"></div></div>
</div>
<div class="button" id="register">注冊</div>
</form>
</div>
</div>
</div>
</div>
<canvas id="canvas" class="stage"></canvas>
<script>
"use strict";
(function(w, canvas) {
var ctx = canvas.getContext("2d"), ... // 初始化粒子系統
// 粒子類:位置、半徑、移動邏輯、繪製、連線
function Particle(x, y, delay) { ... }
// 滑鼠移動更新中心點
canvas.addEventListener("mousemove", e => { center.x = e.clientX - rect.left; center.y = e.clientY - rect.top; });
// 動畫循環
function animate() { ctx.clearRect(0,0,w,h); particles.forEach(p => p.draw(ctx, particles, center)); requestAnimationFrame(animate); }
animate();
// 窗口縮放重置
window.addEventListener("resize", () => { ... });
})(this, document.querySelector(".stage"));
</script>
效果:滑鼠移動時粒子聚合,形成流動光點網絡,極具科技感。
var jcPublic = {
// 標籤切換
Tab: function() {
$(".nav-sliders>a").click(function() {
$(this).addClass("active").siblings().removeClass("active");
var idx = $(this).index();
$(".on").stop().animate({left: $(this).width()*idx+5}, 300);
$(this).parents(".index-body").children(".change").children().eq(idx).show().siblings().hide();
});
},
// 登錄表單提交 (配合 Spring Security)
login: function() {
$("#login").click(function() {
var $form = $("#loginForm");
var username = $("#username").val(), password = $("#password").val();
// 前端驗證
if (!username || !password) { $form.find("label").addClass("move"); return; }
if (!document.getElementById("username").checkValidity()) { ... return; }
$form.submit(); // 交給 Spring Security 處理
});
},
// 註冊 AJAX 提交
register: function() {
$("#register").click(function() {
var name = $("#name").val(), pass = $("#passwor").val(), pass2 = $("#pssworAgain").val(), code = $("#code").val();
// 完整驗證:非空、郵箱格式、兩次密碼一致、驗證碼正確
if (code !== window.code) { ... return createCode(); } // 驗證碼錯誤刷新
$.ajax({
type: "POST", url: "registerUser.do", dataType: "json",
data: {name: name, password: pass},
success: function(msg) {
alert(msg.messageString);
if (msg.messageString == "注冊成功") { $("#loginButton").click(); $("#registerForm")[0].reset(); }
}
});
});
},
// 驗證碼生成與點擊刷新
createCode: function() { ... },
clickCode: function() { $("#createCade").click(createCode); }
};
$(function(){ jcPublic.register(); jcPublic.Tab(); jcPublic.login(); jcPublic.createCode(); jcPublic.clickCode(); });
<http auto-config="true" use-expressions="true">
<form-login login-page="/index.jsp"
login-processing-url="/j_spring_security_check"
default-target-url="/home.jsp"
authentication-failure-url="/index.jsp?error=true"
username-parameter="j_username"
password-parameter="j_password" />
<remember-me key="speed4cKey" token-validity-seconds="1209600" />
<logout logout-url="/j_spring_security_logout" logout-success-url="/index.jsp" />
<intercept-url pattern="/home.jsp" access="isAuthenticated()" />
<intercept-url pattern="/**" access="permitAll" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username, password, enabled from users where username=?"
authorities-by-username-query="select username, role from user_roles where username=?" />
</authentication-provider>
</authentication-manager>
@Controller
public class RegisterController {
@Autowired private UserService userService;
@RequestMapping(value="/registerUser.do", method=RequestMethod.POST)
@ResponseBody
public Map register(@RequestParam String name, @RequestParam String password) {
Map result = new HashMap<>();
try {
userService.register(name, password); // 含唯一性檢查、密碼加密
result.put("messageString", "注冊成功");
} catch (Exception e) {
result.put("messageString", e.getMessage());
}
return result;
}
}
src/main/webapp/
├── index.jsp # 主頁面
├── home.jsp # 登錄成功頁
├── js/
│ ├── jquery.js
│ └── app.js # 提取 jcPublic 邏輯
├── css/
│ └── style.css # 提取內聯樣式
├── images/ # Logo、二維碼等
└── WEB-INF/
├── web.xml
├── spring-mvc.xml
└── spring-security.xml
此項目展示了傳統 JSP + jQuery + Spring Security 構建現代感登錄頁的完整路徑,代碼結構清晰,易於理解與擴展。