項目結構
WebRoot/
├── js/
│ └── jquery-1.7.2.min.js
├── index.jsp
└── WEB-INF/
├── web.xml
└── classes/
└── servlet/
└── ValueGetController.class
前端 JSP 代碼
<%@ page language="java" pageEncoding="GBK"%>
<%
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<!DOCTYPE html>
<html>
<head>
<title>下拉選單異步加載演示</title>
<script type="text/javascript" src="<%=basePath %>js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(function() {
$("#record").append("頁面加載完成。<br/>");
});
function getFirstFloorValue(element) {
$("#record").append("<br/>正在獲取第一級選項...<br/>");
$.ajax({
url: 'ValueGetController',
type: 'post',
data: { action: 'GetFirstFloorValue' },
dataType: 'json',
success: function(data) {
$("#record").append("數據獲取成功,正在渲染...<br/>");
$(element).empty();
$.each(data, function(index, value) {
$(element).append($("<option>").val(value).text(value));
});
$("#record").append("下拉選單更新完成!<br/>");
},
error: function(xhr, status, error) {
$("#record").append("請求失敗: " + error + "<br/>");
}
});
}
</script>
</head>
<body>
<div>
<select id="select1" onfocus="getFirstFloorValue(this)">
<option value="">點擊加載選項</option>
</select>
</div>
<div>
<h3>操作日誌:</h3>
<span id="record"></span>
</div>
</body>
</html>
後端 Servlet 代碼
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
public class ValueGetController extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("GBK");
response.setContentType("application/json;charset=GBK");
PrintWriter out = response.getWriter();
String action = request.getParameter("action");
if ("GetFirstFloorValue".equals(action)) {
String[] values = getFirstFloorValue();
JSONArray jsonArray = JSONArray.fromObject(values);
out.print(jsonArray.toString());
out.flush();
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
private String[] getFirstFloorValue() {
return new String[] { "選項一", "選項二", "選項三", "選項四" };
}
}
web.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>ValueGetController</servlet-name>
<servlet-class>servlet.ValueGetController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ValueGetController</servlet-name>
<url-pattern>/ValueGetController</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
依賴 JAR
json-lib-2.4-jdk15.jar(JSON 序列化)
ezmorph-1.0.6.jar(json-lib 依賴)
commons-lang、commons-beanutils、commons-collections、commons-logging
關鍵點總結
- dataType: 'json':jQuery 自動解析響應為 JS 對象/數組
- contentType: 'application/json':Servlet 設置響應頭,瀏覽器正確識別
- 中文編碼:請求
request.setCharacterEncoding、響應 response.setContentType(...charset=GBK)、頁面 pageEncoding="GBK" 三者一致
- 異步非阻塞:用戶可繼續操作頁面,加載完成自動更新
- 錯誤處理:
error 回調捕獲網絡/服務端異常
進階擴展
- 多級聯動:一級選擇觸發二級加載,傳遞父級 ID 參數
- 緩存機制:首次加載存入
sessionStorage,二次訪問直接讀取
- 防抖/節流:輸入框搜索建議場景限制請求頻率
- 安全防範:CSRF Token 驗證、SQL 注入防護(PreparedStatement)