前端透過 jQuery AJAX 發送 POST 請求,傳遞 JSON 格式資料;Spring MVC 控制器接收解析後處理業務邏輯,最終以 JSON 格式回應。本文示範兩種回傳 JSON 的方式:ModelAndView 配合 MappingJackson2JsonView,以及現代更推薦的 @ResponseBody 直接回傳物件。
function saveSynchronizedVcHorse(obj) {
var ss = $("#SynchronizedSelection div");
var cacheSelectAry = [];
for (var i = 0; i < ss.length; i++) {
var checkbox = ss.eq(i).find('label').find("input[type='checkbox']");
if ($(checkbox).attr('checked')) {
cacheSelectAry.push($(checkbox).attr('value'));
}
}
if (cacheSelectAry.length === 0) {
alert("請選擇城市");
return;
}
// 構建 JSON 字串(建議使用 JSON.stringify)
var jsonData = {
exceptionId: exceptionId,
cityIds: cacheSelectAry
};
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json", // 關鍵:告知伺服器請求體為 JSON
url: "../main/saveSynchronizedData",
data: JSON.stringify(jsonData),
success: function(msg) {
alert(msg.main); // msg 為後端回傳的 JSON 物件
},
error: function() {
alert("請求失敗");
}
});
}
@RequestMapping(value = "/saveSynchronizedData", method = RequestMethod.POST)
@ResponseBody
public ModelAndView saveSynchronizedData(@RequestBody SynchronizedBean bean) {
Map<String, String> map = new HashMap<>();
try {
if (bean != null && bean.getCityIds() != null) {
for (String cityCode : bean.getCityIds()) {
VCHousePo po = new VCHousePo();
po.setExceptionId(bean.getExceptionId());
po.setCustomerCode(cityCode);
po.setCreateTime(new Date());
po.setExceptionState(0);
vcHService.add(po);
}
}
map.put("msg", "success");
} catch (Exception e) {
e.printStackTrace();
map.put("msg", "error");
}
// 使用 MappingJackson2JsonView 將 Map 序列化為 JSON
return new ModelAndView(new MappingJackson2JsonView(), map);
}
關鍵點:
@RequestBody 自動將請求體 JSON 反序列化為 SynchronizedBean 物件MappingJackson2JsonView 來自 org.springframework.web.servlet.view.json 套件<mvc:annotation-driven /> 以自動註冊 Jackson 轉換器@RequestMapping(value = "/saveSynchronizedData", method = RequestMethod.POST)
@ResponseBody
public ResultDTO<String> saveSynchronizedData(@RequestBody SynchronizedBean bean) {
try {
if (bean != null && bean.getCityIds() != null) {
for (String cityCode : bean.getCityIds()) {
VCHousePo po = new VCHousePo();
po.setExceptionId(bean.getExceptionId());
po.setCustomerCode(cityCode);
po.setCreateTime(new Date());
po.setExceptionState(0);
vcHService.add(po);
}
}
return ResultDTO.success("success");
} catch (Exception e) {
e.printStackTrace();
return ResultDTO.error("error");
}
}
搭配統一回應封裝類:
public class ResultDTO<T> {
private boolean success;
private T data;
private String message;
public static <T> ResultDTO<T> success(T data) {
ResultDTO<T> r = new ResultDTO<>();
r.setSuccess(true);
r.setData(data);
return r;
}
public static <T> ResultDTO<T> error(String msg) {
ResultDTO<T> r = new ResultDTO<>();
r.setSuccess(false);
r.setMessage(msg);
return r;
}
// getter/setter 省略
}
success: function(response) {
if (response.success) {
console.log("業務資料:", response.data);
} else {
alert("失敗:" + response.message);
}
}
@RequestBody + @ResponseBody 實現 RESTful 風格交互ResultDTO)便於前端統一錯誤處理contentType: "application/json" 並使用 JSON.stringify()