背景:
1、 我們做表單提交時如果提交成功則跳轉到成功頁面或其他業務邏輯頁面,如果失敗要在表單裏提示用戶哪些字段參數錯了,由於form submit後會自動刷新頁面,這樣就無法在用戶原來編輯的表單提醒用戶哪些字段出了錯誤。
2、因爲業務需求,我們表單裏會包含一到多個圖片需要上傳。
解決:
表單消息提醒解決:
step1、
通過PrintWriter writer = response.getWriter();
writer.write(“錯誤或異常消息”);
writer.flush();
將錯誤消息傳到前端,ajax可以在回調中獲取到這些錯誤、異常消息
step2、
controller中若果要返回錯誤或異常消息則使用step1中的方法返回消息,若正常則正常返回ModelAndView。
表單包含圖片解決:具體看代碼部分
1、form表單屬性裏要包含method=”POST” enctype=”multipart/form-data”
2、js中使用FormData
3、controller裏只需要設置表單對應的業務bean裏文件字段類型爲MultipartFile即可接收
詳細代碼如下:
JSP代碼
其中包含正常的表單,再加一個文件上傳
<form id="publishTable" class="jhw-content jhw-haveHeader jhw-noFooter" method="POST" enctype="multipart/form-data">
<ul class="jhw-issueList">
<li>
<a class="jhw-cell jhw-cell-m mui-table-view-cell"href="javascript:;">
<div class="jhw-cell__hd">
<i class="iconfont icon-label"></i>
</div>
<div class="jhw-cell__bd">
標題 :<input class="jhw-party-title focusBox" type="text" name="title" id="" value="" maxlength="20" />
</div>
</a>
</li>
<li>
<div class="jhw-cell-cont jhw-issue-intro">
<p class="jhw-issue-intro-title">聚餐介紹</p>
<div class="jhw-textInputBox">
<textarea name="tableExplain" class="focusBox table_explain" spellcheck="false"
rows="4" cols="" maxlength="500" placeholder="聊一聊和飯局有關的事情吧..."></textarea>
<p class="mui-text-right">
<span>0</span>/500
</p>
</div>
<div class="jhw-img-updata-box jhw-img-updata-box-alone">
<div class="jhw-img-updata-Btn space">
<div class="image-delete"></div>
<input class="tableImg" type="file" name="tableImg" value="" accept="image/*">
</div>
<div class="jhw-img-updata-intro">上傳一張圖片來吸引你的江湖飯友</div>
</div>
</div>
</li>
</ul>
</form>
JS代碼
FormData 使用參考:
https://developer.mozilla.org/zh-CN/docs/Web/API/FormData/Using_FormData_Objects
$.ajax({
type: "POST",
url: path+"/publish/publishtable",
data: new FormData($("#publishTable" )[0]),
cache: false,
async: false,
processData: false,
contentType: false,
success: function (data) {
alert("處理結果:"+data.isSuccess);
if(data == null){ //登錄失效
alert("處理失敗");
}
if(data.isSuccess == 0){ //處理失敗
alert(data.message);
}else{
$("#publishTableBody").html(data);
}
},
error: function (XMLHttpRequest,textStatus,errorThrown) {
alert("error: "+textStatus+" "+errorThrown);
}
});
Controller代碼
H5PublishController.java
@RequestMapping("/publishtable")
@ExceptionHandler
@ResponseBody
public ModelAndView doPublishTable(HttpServletResponse response, ParamsTableBo paramsTableBo, ModelMap modelMap){
JceLog.info("進入發佈拼桌------------------>");
ResultVo<String> resultVo = new ResultVo<>();
ModelAndView modelAndView = new ModelAndView();
if (paramsTableBo == null) {
JceLog.error("上傳文件參數爲null");
resultVo.setIsOverdue(0);
resultVo.setMessage("上傳文件參數爲null");
return writeExcInfo(response, JSONObject.toJSONString(resultVo));
}
try {
MultipartFile tableImage = paramsTableBo.getTableImg();
tableImage = null;
if (tableImage == null || tableImage.getOriginalFilename() == null || tableImage.getOriginalFilename().length() == 0) {
JceLog.info("圖片沒有上傳");
resultVo.setIsOverdue(0);
resultVo.setMessage("圖片沒有上傳");
return writeExcInfo(response, JSONObject.toJSONString(resultVo));
}
modelMap.addAttribute("resultVo", resultVo);
modelAndView.setViewName("redirect:/h5index/toindex");
return modelAndView;
} catch (Exception e) {
// TODO: handle exception
JceLog.error("發佈拼桌異常:"+e.getMessage());
resultVo.setIsOverdue(0);
return writeExcInfo(response, JSONObject.toJSONString(resultVo));
}
}
ParamsTableBo.java
/** * @ClassName TableDetailBo
* @Description TODO(拼桌參數bo, 用作拼桌表單提交與修改等業務處理)
* * @author Jce * @Date 2018年1月8日 下午2:16:39
* * @version 1.0.0 */
public class ParamsTableBo {
private Integer ttid;
private Integer initiatorid;
private String tableExplain;
private String restaurantName;
private Integer restaurantid;
private String sexRequire;
private Integer checkNumber;
private Integer attentNumber;
private Integer commentid;
private Integer createUserid;
private String createName;
private String title;
/** 拼桌是否啓動, 0:已啓動,-1:各種原因解散,1:未開始,2:已完成*/ private String startstatus;
/** 拼桌圖片*/
private MultipartFile tableImg;
。。。。。省略getset
}
writeExcInfo方法
/**
* @Description (TODO 將異常以json格式返回到前端,可以在ajax的回調中獲取到)
* @param response
* @param exceptInfo
* @return
*/
public ModelAndView writeExcInfo(HttpServletResponse response, String exceptInfo){
response.setCharacterEncoding("utf-8");
try {
PrintWriter writer = response.getWriter();
writer.write(exceptInfo);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
方案二、
JSP代碼 ,jsp部分跟方案一 一樣
其中包含正常的表單,再加一個文件上傳
JS代碼
這種方式缺點是處理成功後跳轉頁面傳遞的參數只能通過get方式傳遞
$(".doPublish").click(function(){
$.ajax({
type: "POST",
url: path+"/publish/publishtable",
data: new FormData($("#publishTable" )[0]),
cache: false,
async: false,
processData: false,
contentType: false,
success: function (data) {
if(data == null || data == undefined || data == ""){
alert("處理失敗,請稍候重試!");
return;
}
alert("發佈拼桌:"+data.isSuccess+" "+data.urlStr);
if(data.isSuccess == 1){ //處理成功,跳轉頁面或其他controller
window.location.href=path + data.urlStr;
}
},
error: function (XMLHttpRequest,textStatus,errorThrown) {
alert("error: "+textStatus+" "+errorThrown);
}
});
});
Controller代碼
這種方式返回封裝的結果對象json字符串,比方案二更爲簡單,但是傳參不方便,只能通過拼參數的方式傳遞
@RequestMapping(value="/publishtable" ,produces="text/json;charset=UTF-8")
@ResponseBody
public String doPublishTable(HttpServletResponse response, ParamsTableBo paramsTableBo){
JceLog.info("進入發佈拼桌------------------>");
ResultVo<String> resultVo = new ResultVo<>();
if (paramsTableBo == null) {
JceLog.error("上傳文件參數爲null");
resultVo.setIsOverdue(0);
resultVo.setMessage("上傳文件參數爲null");
return JSONObject.toJSONString(resultVo);
}
try {
MultipartFile tableImage = paramsTableBo.getTableImg();
if (tableImage == null || tableImage.getOriginalFilename() == null || tableImage.getOriginalFilename().length() == 0) {
JceLog.info("圖片沒有上傳");
resultVo.setIsOverdue(0);
resultVo.setMessage("圖片沒有上傳");
return JSONObject.toJSONString(resultVo);
}
resultVo.setIsSuccess(1);
resultVo.setMessage("發佈成功");
resultVo.setUrlStr("/h5index/toindex?params=jce666"); //應該跳轉到個人-->我發起的飯局
JceLog.info("結果:"+JSONObject.toJSONString(resultVo));
return JSONObject.toJSONString(resultVo);
} catch (Exception e) {
// TODO: handle exception
JceLog.error("發佈拼桌異常:"+e.getMessage());
resultVo.setIsOverdue(0);
return JSONObject.toJSONString(resultVo);
}
}