背景:
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>0span>/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 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 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);
}
}