有人告诉我,在Servlet中为response.getWriter()编写HTML不是一个好的做法,这就是JSP出现的原因。
但在Ajax的情况下,我看到的是,我必须向Servlet中的response.getWriter()写入HTML,以便由JSP中XMLHttpRequest
对象的responseText
属性选择它。
Ajax还有其他方法可以完成同样的任务吗?
这是我的例子。我有两个下拉菜单位置和部门。当用户选择特定位置时,我会使用Ajax在Department下拉列表中显示其部门。出于测试目的,对地点和部门进行了硬编码。
我有两个类别地点和部门:
public class Location implements Serializable {
private int id;
private String description;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
@Override
public String toString() {
return "Location [id=" + id + ", description=" + description + "]";
}
}
public class Department implements Serializable {
private int id;
private String description;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
@Override
public String toString() {
return "Department [id=" + id + ", description=" + description + "]";
}
}
我有一个JSPLocationDepartment.JSP:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function locationChanged() {
var newLocation = document.getElementById("select_location").value;
var ajaxCallObject = getAjaxCallObject();
ajaxCallObject.onreadystatechange=function() {
if (ajaxCallObject.readyState==4) {
if (ajaxCallObject.status==200) {
alert("locationChanged(): success of ajaxCallObject");
document.getElementById("div_department").innerHTML = ajaxCallObject.responseText;
} else {
alert("locationChanged(): failure of ajaxCallObject");
}
}
}
ajaxCallObject.open("GET", "DepartmentServlet?location=" + newLocation, true);
ajaxCallObject.send(null);
}
function getAjaxCallObject() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
return new ActiveXObject('Microsoft.XMLHTTP');
}
}
</script>
</head>
<body>
<form action="">
<table>
<tr>
<td>Location</td>
<td>
<div id="div_location">
<select id="select_location" onchange="locationChanged();">
<option></option>
<option id="1">Head Office</option>
<option id="2">Regional Office</option>
</select>
</div>
</td>
</tr>
<tr>
<td>Department</td>
<td>
<div id="div_department">
<select id="select_department">
</select>
</div>
</td>
</tr>
</table>
</form>
</body>
</html>
这是我的servletDepartmentServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("DepartmentServlet: doGet(): START -----");
String location = null;
List<Department> departmentList = null;
Department department = null;
StringBuffer sb = null;
location = request.getParameter("location");
if (location != null && location.equalsIgnoreCase("Head Office")) {
departmentList = new ArrayList<Department>();
department = new Department();
department.setId(1);
department.setDescription("Sales");
departmentList.add(department);
department = new Department();
department.setId(2);
department.setDescription("Support");
departmentList.add(department);
} else if (location != null && location.equalsIgnoreCase("Regional Office")) {
departmentList = new ArrayList<Department>();
department = new Department();
department.setId(1);
department.setDescription("Sales");
departmentList.add(department);
}
sb = new StringBuffer();
sb.append("<select id="select_department">");
if (departmentList != null) {
for (Department d : departmentList) {
sb.append("<option id="" + d.getId() + "">");
sb.append(d.getDescription());
sb.append("</option>");
}
}
sb.append("</select>");
PrintWriter out = response.getWriter();
out.write(sb.toString());
}
我遇到的一个问题是,现在Servlet需要知道JSP中Department下拉列表的select标记的id是什么,即"select_Department"。
更新
我更希望servlet将List作为请求属性发送。所以基本上Servlet没有这些代码行:
sb = new StringBuffer();
sb.append("<select id="select_department">");
if (departmentList != null) {
for (Department d : departmentList) {
sb.append("<option id="" + d.getId() + "">");
sb.append(d.getDescription());
sb.append("</option>");
}
}
sb.append("</select>");
PrintWriter out = response.getWriter();
out.write(sb.toString());
相反,Servlet有这样一行代码:
request.setAttribute("DepartmentList", departmentList);
然后在JSP中,我可以在Ajax的回调函数中访问请求的这个属性并循环通过它,构建select
标签的新HTML,然后替换当前的HTML。
感谢
Ajax调用的全部思想是发送数据。不发送html响应,而是从后端发送json/xml,并让前端html/js使用jquery或任何其他js库提供的支持模板技术构建html。
以下是我在评论中提到的getJSON示例:
JSP:
$(document).ready(function() {
$.getJSON("http://localhost:8080/TestWeb/test", function(data) {
$.each(data, function(key, val) {
console.log(key+' '+ val);
});
});
});
Servlet:
Map<String, Object> data = new HashMap<String, Object>();
data.put( "name", "Mars" );
data.put( "age", 32 );
data.put( "city", "NY" );
JSONObject json = new JSONObject();
json.putAll( data );
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().println(json);