JDK1.7+Tomcat7.0+Eclipse+SSM+Bootstrap(含Bootstrap Table)
【心情很复杂,来一首“预谋”——专为“bug与我的相互伤害”做的歌——"反正它都不难受它只要自由,它都不会理会我的感受,退到无路可走不如就放开手,我也想要自由",可是想放手都由不得我呀~~~】
参考:
两个forEach数据遍历相同的数据在复选框打钩jsp页面复选框更具传过来的数据勾选【遍历List显示复选框】
了解:
Jsp标签中foreach使用
menu主要代码:
<div class="main-container">
<div class="sidebar">
<nav class="sidebar-nav">
<ul class="nav">
<li class="nav-item nav-dropdown">
<a href="#" class="nav-link nav-dropdown-toggle">
<i class="icon icon-graph"></i> 公共信息管理 <i class="fa fa-caret-left"></i>
</a>
<ul class="nav-dropdown-items">
<li class="nav-item">
<a href="${pageContext.request.contextPath }/noticeDetail/index" class="nav-link" target="myIframe">
<i class="icon icon-graph"></i> 通知公告管理
</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="content">
<iframe name="myIframe" style="width:100%;height:100%;float:;top:-300px;border: 0;background-color: white;" id="myIframe" src="${pageContext.request.contextPath}/tabs.jsp"></iframe>
</div>
</div>
通知公告的控制器:
@Controller
@RequestMapping(value="/noticeDetail")
public class NoticeDetailController {
@Resource
NoticeDetailService ndService;
@Resource
DepService depService;
@Resource
ClassService clsService;
@RequestMapping(value="/index")
public String index(Map map){
List<DepartmentVo> depList=depService.findAllDep();
List<ClassVo> clsList=clsService.list();
map.put("depList",depList);
map.put("clsList",clsList);
return "qyf/noticeDetailList";
}
@RequestMapping("/list")
@ResponseBody
public Map list(@RequestBody Map<String,Object> params,NoticeDetailVo nd){
......................
}
@RequestMapping("/add")
public String add(NoticeDetailVo nd){
......................
}
}
jsp的body
新增按钮:
<div id="toolbar" class="btn-group">
<button id="btn_add" type="button" class="btn btn-default" data-toggle="modal" data-target="#modal-1">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增
</button>
...........................
</div>
点击新增弹出的模态框的表单:
<div class="modal fade" id="modal-1" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-full" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" style="width:200px;">请选择类别</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form method="post" id="form1" name="form1">
<div class="modal-body">
<!--最后才发现,这个控件无需添加,因为我的需求就是:新增时出现那个模态框,而修改时无需弹出模态框,后面一大串的异常呀更改呀,都是因为这个控件传值问题导致的-->
<input type="hidden" id="noticeId" name="noticeId">
<div class="form-group">
<label for="typeId" class="control-label">发送类别</label>
<select id="typeId" class="form-control" id="typeId" name="typeId"><!-- 也可以多个属性 onchange="showTypeId()" -->
<option value="1" >所有人</option>
<option value="2" >所有员工</option>
<option value="3" >指定部门</option>
<option value="4" >所有学生</option>
<option value="5" >指定班级</option>
</select>
<div class="col-sm-offset-2" id="depIds1" name="depIds1">
<div class="checkbox">
<c:forEach items="${depList}" var="d" varStatus="state">
<label class="checkbox-inline">
<input type="checkbox" id="depIds" name="depIds" value="${d.depId }">${d.depName }
</label>
</c:forEach>
</div>
</div>
<div class="col-sm-offset-2" id="clsIds" name="clsIds">
<div class="checkbox">
<c:forEach items="${clsList}" var="c">
<label class="checkbox-inline">
<input type="checkbox" id="classIds" name="classIds" value="${c.classId }">${c.className }
</label>
</c:forEach>
</div>
</div>
</div>
</div>
</form>
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" name="next" id="next">下一步</button>
</div>
</div>
</div>
</div>
脚本:
<script>
$("#typeId").click(function(){
var index=document.getElementById("typeId").selectedIndex;
//alert("索引------"+index);//当下标或索引为3时,就显示div(下拉框使用点击事件,就不能有alert,否则影响下拉框伸展和选中项)
if(index==4){//当点击"指定班级"
$("#clsIds").show()//显示div
$("#depIds1").hide();
}else if(index==2){//当点击"指定部门"
$("#depIds1").show()//显示div
$("#clsIds").hide();
}else{//当上一步点击的是"指定班级或部门",他们的div都要隐藏
$("#clsIds").hide();//隐藏div
$("#depIds1").hide();//隐藏div
}
});
</script>
借鉴:
用JS初始化html中的下拉框select【文章里写的与上面那篇里的不同,可以看看】
出现那个模态框只用于新增(因人而异,反正我的需求就是:新增时出现那个模态框,而修改时无需弹出模态框),而且发现我想要的初始化下拉框,很简单:
<script>
...................
//一点新增按钮时,初始化新增
$("#btn_add").click(function(){
$("#clsIds").hide();//隐藏div
$("#depIds1").hide();//隐藏div
$("#typeId").val(1);//初始化下拉框,默认选择value为1的项
$('input:checkbox').each(function () {//初始化复选框
$(this).attr('checked',false);
});
})
....................
</script>
借鉴:
动态初始化checkBox复选框及修改时赋值【新增修改都先ajax给后台再传页面并控制,但是并不是我想要的(因为在进入页面前,我已经获取了对应Javabean的List了,用c标签的foreach遍历出来,不用ajax访问后台然后才得到想要的List)】
复选框checkbox初始化问题。急急急!!!!!!【论坛讨论】
bootstrap-table checkbox(复选框)初始化部分选中【一样使用了bootstrap table,但是看了有点懵,data-formatter="stateFormatter" data-select="false" data-checkbox="true"???我的复选框不放在th里】
BootStrap-table 复选框默认选中(checkbox)【这个跟上一个差不多,但是跟简便】
使用bootstrap 的下拉菜单实现select的下拉复选框多选【[/笑哭]搜的是“初始化下拉框、复选框”,不知道怎么就出现了“初始化下拉复选框”,不过也可以看看】
bootstrap select插件 下拉框 、复选框 、使用详解、附.重置 bootstrap-select下拉框复选框中的值/easyui树的复选框中的值。【该小编其他文章写的还不错,但他也是说的下拉复选框,还有下载插件,反正没有我想要的答案】
在js中怎样获得checkbox里选中的多个值?(jQuery)【JQuery里获取的值但是不传后台】
在js中怎样获得checkbox里选中的多个值?【是上个的延伸吧】
参考:
jquery操作复选框(checkbox)的12个小技巧总结【初始化复选框】
点击新增按钮时,初始化复选框,上面有代码;但是,在下拉框中选择,前一步选择“指定部门”,还在出现的多选框中多选,后一步选择“指定班级”,也在出现的多选框中多选,接下来一步,回来选择“指定部门”,发现,“前一步”选择的多选项还是“打钩√”的,即没有初始化,要初始化的话,在每个if或else里加上代码:
$("#typeId").click(function(){
//function showTypeId(){//如果select里有属性onchange="showTypeId()",用这行代码
var index=document.getElementById("typeId").selectedIndex;
//alert("索引------"+index);//当下标或索引为3时,就显示div(下拉框使用点击事件,就不能有alert,否则影响下拉框伸展和选中项)
if(index==4){//当点击"指定班级"
$("#clsIds").show()//显示div
$("#depIds1").hide();
$('input:checkbox').each(function () {
$(this).attr('checked',false);
});
}else if(index==2){//当点击"指定部门"
$("#depIds1").show()//显示div
$("#clsIds").hide();
$('input:checkbox').each(function () {
$(this).attr('checked',false);
});
}else{//当上一步点击的是"指定班级或部门",他们的div都要隐藏
$("#clsIds").hide();//隐藏div
$("#depIds1").hide();//隐藏div
$('input:checkbox').each(function () {
$(this).attr('checked',false);
});
}
});
选中复选框的value,form自动获取复选框勾选的值,并通过ajax传至后台:
$("#next").click(function(){
var form = new FormData(document.getElementById("form1"));
。。。。。ajax代码
}
参考:
jquery和javaScript 清空 select下拉框里的所有选项【empty()】
使用$().empty(),清空下拉框选项,然后初始化下拉框!!!
jsp的body主要代码:
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<div class="panel-body" style="padding-bottom: 0px;">
<div id="toolbar" class="btn-group">
<button id="btn_add" type="button" class="btn btn-default"
data-toggle="modal" data-target="#myModal">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增
</button>
<button id="btn_edit" type="button" class="btn btn-default"
data-toggle="modal" data-target="#myModal">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>修改
</button>
<button id="btn_delete" type="button" class="btn btn-default">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>删除
</button>
</div>
<table id="tb_departments"></table>
</div>
</div>
</div>
<!-- Modal模态框 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<!--下面div的属性中 modal-lg表示大模态框,不写表示中等, modal-sm表示小模态框-->
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">部门资料</h4>
</div>
<div class="modal-body">
<!-- 弹出框的表单 -->
<form action="" name="dep" id="formInfo" method="post">
<!-- 隐藏控件 -->
<input type="hidden" name="depId" id="depId" />
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label>部门名称:</label> <input type="text" class="form-control"
name="depName" id="depName" placeholder="部门名称"
aria-describedby="depName">
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label>部门级别:</label>
<select name="parentId" id="parentId" class="form-control" data-live-search="true" data-size="2">
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-4">
<div class="form-group">
<label>负责人:</label> <input type="text" class="form-control"
name="chairman" id="chairman" placeholder="部门负责人"
aria-describedby="chairman">
</div>
<div class="form-group">
<label>备注:</label>
<textarea class="form-control" name="remark" id="remark"
rows="2"></textarea>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer" align="center">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" id="save" class="btn btn-primary"
data-dismiss="modal">保存</button>
</div>
</div>
</div>
</div>
脚本主要代码(可能有些问题,但是不大):
//初始化新增
$("#btn_add").click(function(){
//清空下拉框选项
$("#parentId").empty();
//初始化下拉框
$.ajax({
url : "${pageContext.request.contextPath}/dep/AlldepId", //所需要的列表接口地址
method:"post",
success : function(data) {
$("#parentId").append("<option value='0'>无</option>");
for(var i=0;i<data.length;i++){
$("#parentId").append("<option value='"+data[i].depId+"'>"+data[i].depName+"</option>");
}
}
});
$("#depId").val("0");
$("#depName").val("");
$("#parentId").val("0");
$("#chairman").val("");
$("#remark").val("");
});
//初始化修改
$("#btn_edit").click(function(){
//首先判断是否选中需要修改的数据
var arrselections = $("#tb_departments").bootstrapTable('getSelections');
if (arrselections.length <= 0) {
toastr.info('请选择需要修改的数据');
return false;
}
//使用getSelections即可获得,row是json格式的数据
var row = $.map($('#tb_departments').bootstrapTable('getSelections'),function (row) {
// 转成JSON格式
var jsonData = JSON.stringify(row);
// 转成JSON对象
var result = $.parseJSON(jsonData);
//清空下拉框选项
$("#parentId").empty();
//加载相应的下拉框选项
$("#parentId").append("<option value='"+result.parentId+"'>"+result.depName+"</option>");
//初始化下拉框
$.ajax({
url : "${pageContext.request.contextPath}/dep/AlldepId", //所需要的列表接口地址
method:"post",
success : function(data) {
//alert(result.depId);
$("#parentId").append("<option value='0'>无</option>");
//加载下拉框所有选项
for(var i=0;i<data.length;i++){
//默认选中的选项不可再次显示
if(result.depId!=data[i].depId){
$("#parentId").append("<option value='"+data[i].depId+"'>"+data[i].depName+"</option>");
}
}
}
});
$("#depId").val(result.depId);
$("#depName").val(result.depName);
//$("#parentId").val(result.parentId);
$("#chairman").val(result.chairman);
$("#remark").val(result.remark);
});
});
学习:
jquery之---$.each详细
jQuery中$.each()方法的使用
ajax方法参数详解与$.each()和jquery里面each方法的区别
jquery的$().each,$.each的区别
$.ajax 和$.post的区别
jQuery serialize() 方法
Bootstrap 模态框(Modal)插件数据传值
借鉴:
jquery-读取form表单中的所有数据列表【按钮的点击事件获取但不传后台,目前,对我无用】
ajax返回值显示为undefined【我尝试按钮点击事件获取form表单数据,弹出的表单数据都是undefined(改用form.get("typeId"),能够获取表单里的控件值),而且进不了后台,死在add方法的门口(反正现在还没解决掉。。。补充:到最后解决了,真的莫名其妙,不知道是不是“contentType:"json"”有问题)】
bootstrap table 获取数据后的前台页面(后台怎么传就不必详细说明了吧)【script的很详细,可是我的和他的不同,目前,用不上】
如何使用name属性获取form表单数据并传输到后台
jquery获取复选框checkbox被选中的值【讲解很详细 用得上不???】
bootstrap table post提交数据,后台无法接收的问题【$.post(url,data,callback)里改contentType:"application/x-www-form-urlencoded; charset=UTF-8",没什么反应】
ajax post提交form表单 报400错误 解决方法【也是经历过的人,但是大小写我的对上了,也没有时间类型的字段新增。。。还是没有解决我的问题,蓝瘦~】
---------下面讲的是痛苦报错经历,可以忽略,直接看我的总结-------------------
(有人说:传给data的{}里的数据,都不能空,所以我做了if判断等操作,弹框出现的值正是if语句里赋的值,可是传到后台都是报错的,而且传的都是[Object object],方法的Javabean参数接收的值都是空【int类型的为0,String类型的为null】)
$("#next").click(function(){
//复选框获取错误,只获取了一个
var classIds = $('input:checkbox[name="classIds"]:checked').val();
var depIds = $('input:checkbox[name="depIds"]:checked').val();
var noticeId=$("#noticeId").val();
var typeId=$("#typeId").val();
alert("1111111111111noticeId=="+noticeId+" classIds=="+classIds+" depIds=="+depIds+" typeId=="+typeId);
//alert(form.get("typeId"));//有值
if(noticeId=="")
noticeId=0;
if(classIds==undefined)
classIds="noon";
if(depIds==undefined)
depIds="noon";
alert("22222222222noticeId=="+noticeId+" classIds=="+classIds+" depIds=="+depIds+" typeId=="+typeId);
alert(typeId);
$.ajax({
url : "${pageContext.request.contextPath }/noticeDetail/add",
type : "post",
//data : form,
data:{"noticeId":noticeId,"typeId":typeId,"classIds":classIds,"depIds":depIds},
//cache : false,
processData : false,
traditional:true,
datatype:"json",
contentType :"application/x-www-form-urlencoded; charset=utf-8",
error : function(result) {
toastr.error("网络错误,请重试!!"+result.status);
}
});
});
三月 12, 2019 10:14:35 上午 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet [SpringMVC] in context with path [/HTGlory] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Optional int parameter 'noticeId' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.] with root cause
java.lang.IllegalStateException: Optional int parameter 'noticeId' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.handleNullValue(AbstractNamedValueMethodArgumentResolver.java:192)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:96)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
根据报的错,有人说:将controller层接收数据的int的类型改为将Integer,但,改了之后,还是报这个错(但我没有撤消,补充:我重启Tomcat,好像继续报这个错,但随着自己代码的改动,不报这个错,而是报NullPointException或500或400);还有人说:方法的参数加上注解:@RequestParam(value ="typeId",required = false,defaultValue = "0") int typeId,可是对我的来说没有用(所以我撤消了),接下来呢,不断得报500(Internal Server Error)或400(Bad Request)!!!【其实还是ajax出的问题,请看到下面的讲解】
参考:
java.lang.IllegalStateException: Optional int parameter 'i' is not present but cannot be translated【第一个说法】
java.lang.IllegalStateException: Optional int parameter 'studentid' is present but cannot be transla【第二个说法】
或
改之后,结果一样,会报500或400: (可以说,不管你先上面的代码还是先这段代码,结果一样报错)
$("#next").click(function(){
var form = new FormData(document.getElementById("form1"));
alert(form.typeId+" typeId=="+$("#typeId").val());//undefined!!!
$.ajax({
url : "${pageContext.request.contextPath }/noticeDetail/add",
type : "post",
data : form,
//cache : false,
processData : false,
//contentType : false,
datatype:"json",
contentType :"application/json;charset=utf-8",
error : function(result) {
toastr.error("网络错误,请重试!!"+result.status);
}
});
});
点“下一步”按钮,弹出“typeId==2”,说明能取得到控件值,“undefined”:获取方式有问题,用:form.get("typeId"),就能得到表单的name为typeId的值:
但是传后台,值都为空(为空是为空,但是看得出来:int类型的noticeId和typeId已经改了Integer类型):
改成简单些,只传typeId,结果还是一样会报错(报其他错了):
$("#next").click(function(){
var typeId=$("#typeId").val();
$.ajax({
url : "${pageContext.request.contextPath }/noticeDetail/add",
//type : "post",
//data : form,
data:{"typeId":typeId},
cache : false,
processData : false,
//traditional:true,
datatype:"json",
contentType :"application/x-www-form-urlencoded; charset=utf-8",
error : function(result) {
toastr.error("网络错误,请重试!!"+result.status);
}
});
});
严重: Servlet.service() for servlet [SpringMVC] in context with path [/HTGlory] threw exception [Request processing failed; nested exception is java.lang.NumberFormatException: null] with root cause
java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at com.ht.qyf.controller.NoticeDetailController.add(NoticeDetailController.java:98)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
三月 12, 2019 2:15:55 下午 org.apache.catalina.core.StandardContext reload
信息: Reloading Context with name [/HTGlory] has started
三月 12, 2019 2:15:55 下午 org.apache.catalina.core.ApplicationContext log
信息: Destroying Spring FrameworkServlet 'SpringMVC'
三月 12, 2019 2:15:55 下午 org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
严重: The web application [/HTGlory] registered the JDBC driver [com.alibaba.druid.proxy.DruidDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
三月 12, 2019 2:15:55 下午 org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
严重: The web application [/HTGlory] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
三月 12, 2019 2:15:55 下午 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
【呃呃呃~哦不~~~】咳咳~是“request.getParameter("typeId")”为null,所以parseInt(返回类型是int)不了,debug模式查看:
将typeId的类型int改成包装类Integer,int默认0,Integer默认null嘛~但是改了又怎样,改来改去,最后我还是不需要这行代码(但是Javabean里的noticeId的类型int要改成Integer,那么if语句的条件改成nd.getNoticeId()==null;后面的成功结果跟这个有关,当然还是那句话“int默认0,Integer默认null”【可以说,页面传过来的noticeId是null值(noticeId放在input的hidden类型控件中),若进不来add()方法里面,则是因为null值赋值不了给int类型的noticeId】)
学习:
parseInt()
参考:
java.lang.NumberFormatException: null at java.lang.Integer.parseInt(Integer.java:415) at java.lang
然后我又改,结果(成功了):
真的很莫名其妙——我出现了异常(传form值给后台,可是add的Javabean参数对应的属性值都为空),然后我就改:改用$.post、改用form表单提交、‘多加个datatype属性,改contentType,注释cache,加上traditional(默认false)’,可是,最终,回到原点(但是原先改的noticeId为Integer类型,没有撤消),居然就好了???笑也不是 哭也不是
$("#next").click(function(){
var form = new FormData(document.getElementById("form1"));
//alert($('#form1').serialize());//连载,连播;通过序列化表单值创建 URL 编码文本字符串"noticeId=&typeId=1"
//复选框获取错误
//var classIds = $('input:checkbox[name="classIds"]:checked').val();
//alert(form.get("typeId"));//有值
$.ajax({
url : "${pageContext.request.contextPath }/noticeDetail/add",
type : "post",
data : form,
//datatype:"json",//这个放开注释也没事
//contentType :"application/json;charset=utf-8",
cache : false,
processData : false,
contentType : false,
error : function(result) {
toastr.error("网络错误,请重试!!"+result.status);
}
});
});
发现:
alert(" typeId=="+form.get("typeId")+" noticeId=="+form.get("noticeId")+" classIds=="+form.get("classIds")+" depIds=="+form.get("depIds"));
input的多选框CheckBox、文本text、单选框radio等等类型页面获取的value都是字符串(不管你输入的是数字还是字符串),input的隐藏hidden类型页面获取的value是“”(没有null、没有0、没有空格的空);我用ajax传值进去【我的add()的参数是Javabean/实体类对象变量“NoticeDetailVo nd”】,它会自动将data的值(key:value,即 表单控件name:控件value)赋给key名一样的属性/变量,而且能自动parse解析成对应的类型,typeId、classIds、depIds的值都赋值给了nd里的变量(给int类型变量的控件值自动转成整型,给String类型变量的控件值自动转成字符串类型),但是表单隐藏控件noticeId的值赋值不了int类型的noticeId变量,改成Integer类型之后,表单隐藏控件noticeId的值才能赋值给noticeId变量
(按理说,控件不管是什么类型,通过ajax或表单提交,对应的控件值都能自动传成对应变量的类型,而且隐藏控件以外的控件值为空(传至后台 隐藏控件值与有值的控件值),自动不传后台(那么取不到值的Javabean对象里的变量会自动0或者null,
但是点“下一步或提交”,突然出现400,那么是隐藏控件noticeId作祟!!!他传给了Javabean对象的noticeId变量,但是noticeId变量是int类型,noticeId控件值为null值,赋值不了noticeId变量
【我前几天写过一个页面(叫A),新增时也有hidden(新增与修改在同个模态框,所以有hidden类型的input控件),传给后台的值自动转为数字0;而且,我这个通知公告页面的总体框架就是复制A页面的,通知公告模态框也有hidden类型的input控件,但,传给后台的值自动转为null(①点击新增按钮时,将隐藏控件noticeId初始化,否则默认 为“”不是null不是0的空②或者 当noticeId的int类型转为Integer类型,才能进入add()方法而不是继续报500或400异常)!!!
】),
而且我居然忘了:(在讲“初始化下拉框”时,我讲过)“我的需求就是:新增时出现那个模态框,而修改时无需弹出模态框 ”,
那么意思是:我并不需要noticeId这个hidden隐藏控件,因为我的noticeId是数据表主键,insert的时候能自动递增,无需手动输入,所以这个问题的产生,本可以避免的。。。。
所以又改了下:
将Integer改会int
没有noticeId隐藏控件(当只有typeId控件有值,就只传它):
-----------------------------------The End(接下来总结)-------------------------------
总结:
1、form.get("typeId")获取表单某控件的值(typeId是id值)
2、var form = new FormData(document.getElementById("form的id名")); //无论是复选框还是单选框、文本框,都能获取对应的值) 将获取的form值(给ajax的data属性,要是通过谷歌F12快捷键打开的DevTools窗口,看到进入的方法为400或500,请检查:(1)URL写错没,(2)除了URL、data属性的属性有没有写错,(3)form表单的控件的name与id值是不是对应着方法的Javabean参数的属性(大小写必须一致)(4)确定所有控件值在页面都能获取(5)有没有hidden类型的控件(对应Javabean的变量也是int类型)
(2)
type : "post",
cache : false,
processData : false,
contentType : false,
success : function(result) {
//我add()的return是转到其他页面,所以我没有success属性
},
error : function(result) {
alert("网络错误,请重试!!");
}
若,前四个都确定没有错!!!而且第五个回答是“有”,那么问题解决方案在“4、”
3、若使用Integer.parseInt(...某个值...),从String转为int或Integer,若值为null,那么就会报错
4、 ajax传值,发现隐藏控件对应的主键值为“”,
一:点击新增按钮时初始化,即:
//在脚本里初始化新增
$("#btn_add").click(function(){
$("#noticeId").val(0);
。。。。。
$('#myModal').modal();//打开模态框
});
二: 将对应的Javabean里的变量的int类型改为Integer类型(或者说,要去的那个方法的“参数变量——那个Javabean对象”里的某属性/变量的类型为int改为Integer类型)
学习:
github最值得收藏的Bootstrap3后台管理框架
bootstrap fileinput文件上传附加参数的传递以及后台参数的读取
借鉴:
拼凑字符串时,去除末尾多余字符的几个方法(Java)【目前用不上,但是他讲的是json值去除末尾多余字符的方法】
参考:
js中substr,substring,indexOf,lastIndexOf等的用法
JS四种方法去除字符串最后的逗号
我的depIds、clsIds,最末尾多了逗号“,”
通过depIds.substring(0, depIds.lastIndexOf(','));去除末尾的逗号:
--------------------------------------分割线-----------------------------
当点击某按钮,触发点击事件,为了取后台某些值,然后调试呀(利用谷歌DevTools和Eclipse的Debug模式),发现后台方法进去了,也取到了值,但return出了问题,导致ajax获取不了值,直接跳到ajax的error方法“出现错误”!!!
//成功之后的代码,宿舍楼栋(btn_susheloudon是按钮的Id名,tb_departments是列表的table标签的id名),myModalFloor是模态框的Id名
$("#btn_susheloudon").click(function(){
var arrselections = $("#tb_departments").bootstrapTable('getSelections');
if (arrselections.length <= 0) {
toastr.info('请选择有效数据');
return;
}
if (arrselections.length > 1) {
toastr.warning('只能选择一行进行编辑');
return;
}
var row=$.map(arrselections,function(row){
$.ajax({
url : "${pageContext.request.contextPath}/dormitory/findDorm",
type : "post",
data :{
"dormiId":row.dormiId
},
cache:false,
success : function(result) {
alert("1111111111111111111"+result+"..............."+result.floor.floorId);
//if(result.count>0){
$('#floorId2').val(result.floor.floorId);
$("#floorName").val(result.floor.floorName);
$('#address').val(result.floor.address);
$('#floorManager').val(result.floor.floorManager);
//}
},error : function(result) {
toastr.error('出现错误!');
}
});
$('#myModalFloor').modal();//打开提示框
});
});
我的findDorm方法:通过宿舍id找到楼栋id,然后条件为楼栋id查找对应的楼栋信息
-- MyBatis对应代码
<select id="findById" parameterType="int" resultType="dormiFloorVo">
select * from dormifloor where floorId iN (SELECT dormiFloorId from dormitory
where dormiId=#{0});
</select>
这三种方法,都让ajax取不到值 :
或
或
后台有对应的SQL语句,但是ajax娶不到值,页面弹出“出现错误!” 的错误警告。
改:(成功了)
总结:
在方法定义Map、ModelMap、Model等参数的三种情况:
方法里想从ajax中获取值,在方法里定义Map类型的参数:
@RequestMapping(value = "list")
@ResponseBody
public Map list(@RequestBody Map<String, Object> params) {
int offset = Integer.parseInt(params.get("offset").toString());
int limit = Integer.parseInt(params.get("limit").toString());
List list = dormitoryService.list2(offset, limit);
params = new HashMap<String, Object>();
params.put("rows", list);
params.put("total", dormitoryService.count());
return params;
}
或者
在方法里传值给页面的select的c:foreach标签,也可以在方法里定义Map、ModelMap、Model、MapAndView(这个类型很少用,一般不会用这个)类型的参数:
@RequestMapping(value = "index")
public String lists(Model model) {
dorList = dormitoryService.dorList();
layerList = dormitoryService.layerList();
model.addAttribute("dorList", dorList);
model.addAttribute("layerList", layerList);
return "cy/dormitoryList";
}
<div class="form-group">
<label for="layerId" class="control-label">宿舍楼层</label>
<select id="layerId" class="form-control" name="dormiLayerId">
<c:forEach items="${layerList}" var="t">
<option value="${t.layerId}" >${t.layerName }</option>
</c:forEach>
</select>
</div>
或者
从页面转到另外个页面:通过window.location.href跳转,实际就是通过控制器转向另外个页面,那个后台方法,要成功返回json类型,而不是[object Object],方法定义Map类型参数,且不可参数定义为ModelMap类型!!!
//初始化修改
$("#btn_edit").click(function(){
var arrselections = $("#tb_departments").bootstrapTable('getSelections');
if (arrselections.length <= 0) {
toastr.info('请选择有效数据');
return;
}
if (arrselections.length > 1) {
toastr.warning('只能选择一行进行编辑');
return;
}
var row=$.map(arrselections,function(row){
var jsonData = JSON.stringify(row);
var data = $.parseJSON(jsonData);// 转成JSON对象
window.location.href="${pageContext.request.contextPath }/noticeDetail/updateById?id="+data.noticeId;
//动态输出跳转,路径还是要加上绝对路径的(注意绝对路径后要加上'/'否则404"项目名noticeDetail/index")!!!
});
});
//查找要修改的信息
@RequestMapping("/updateById")
//要成功返回的json类型,方法类型一定要Map,不可ModelMap类型
public String update2(@RequestParam(value="id",required=false) int noticeId,Map map){
System.out.println("-----update-----noticeId="+noticeId);
NoticeDetailVo nd=ndService.ndById(noticeId);
map.put("ndVo",nd);//Map不能new HashMap(),而是要放在参数那!!!
return "qyf/noticeDetailAdd";
}
不能在方法定义Map、ModelMap、Model等参数而是new HashMap()的情况:
无需获取ajax的值且要将后台处理的了值传给ajax,要new Hash(),才传的到ajax的success的function里:
@RequestMapping("/findDorm")
@ResponseBody
public Object findDorm(int dormiId) {
Map map=new HashMap();
DormiFloorVo floor=dormitoryService.findDorm(dormiId);
map.put("floor", floor);
return map;
}
//宿舍楼栋
$("#btn_susheloudon").click(function(){
var arrselections = $("#tb_departments").bootstrapTable('getSelections');
if (arrselections.length <= 0) {
toastr.info('请选择有效数据');
return;
}
if (arrselections.length > 1) {
toastr.warning('只能选择一行进行编辑');
return;
}
var row=$.map(arrselections,function(row){
$.ajax({
url : "${pageContext.request.contextPath}/dormitory/findDorm",
type : "post",
data :{
"dormiId":row.dormiId
},
cache:false,
success : function(result) {
$('#floorId2').val(result.floor.floorId);
$("#floorName").val(result.floor.floorName);
$('#address').val(result.floor.address);
$('#floorManager').val(result.floor.floorManager);
},error : function(result) {
toastr.error('出现错误!');
}
});
$('#myModalFloor').modal();//打开提示框
});
});
SSM的ajax:
①从页面传form至后台(如add),
⑴
add之后无需传值给ajax,而且转向其他页面,可以不用“@ResponseBody”注解(该注解作用:"将返回值转成json类型再给ajax反应到页面")
@RequestMapping("/add")
public String add(NoticeDetailVo nd,Map map){
{
if(nd.getNoticeId()==0){
System.out.println("-----------add------"+nd);//自动调用toString()
int i=nd.getTypeId();
depIds=depIds.substring(0, depIds.lastIndexOf(','));//将末尾多余的','去除
clsIds=depIds.substring(0, clsIds.lastIndexOf(','));//将末尾多余的','去除
System.out.println("depIds=="+depIds+" clsIds=="+clsIds);
if(i==1){
nd.setDepIds(depIds);
nd.setClassIds(clsIds);
}else if(i==2){
nd.setDepIds(depIds);
}else if(i==4){
nd.setClassIds(clsIds);
}
ndService.add(nd);
nd=ndService.ndById(nd.getNoticeId());
map.put("ndVo", nd);
}
return "qyf/noticeDetailAdd";
//从表单提交到这方法,无需@ResponseBody注解,那么我转向其他页面,直接return其他页面
}
或者
⑵
add之后,要回到传ajax的页面,必须加个@ResponseBody ,而且无需传值给ajax,可以选择(这三个是我经常做的操作):一:方法为void类型,二:方法为String类型,return "",三:方法为int类型,return 0。【(success里没有什么操作,只是弹出“成功”提示)选择一,新增没问题的话,直接去success里,若选择二或三,新增没问题的话,随便你传什么值,都会去success里】
// 新增或修改
@RequestMapping(value = "/add")
@ResponseBody
public void add(DormitoryVo dormitory) {
dormitoryService.saveOrUpdate(dormitory);
}
否则(“虽无需传值给ajax,但还是不加@ResponseBody”的话):
新增正常,但是返回时,不是去success的function而是去error的function里:
②从页面传某个值(如:主键Id)至后台(举例:del),
del之后,要回到传ajax的页面,必须加个@ResponseBody ,而且无需传值给ajax,可以选择(这两个是我经常对删除方法做的操作):一:方法为String类型,return "",二:方法为int类型,return 0。【(success里没有什么操作,只是弹出“成功”提示)若选择二或一,删除没问题的话,随便你传什么值,都会去success里】
// 删除
@RequestMapping("/del")
@ResponseBody
public int del( DormitoryVo dormitory) {
dormitoryService.del(dormitory.getDormiId());
return 0;// 若删除成功了,但页面一直说"出现错误",解决的话,就是要给返回值,String也行,int也行
}
//删除确认框删除
$("#del").click(function(){
var arrselections = $("#tb_departments").bootstrapTable('getSelections');
var row=$.map(arrselections,function(row){
$.ajax({
url : "${pageContext.request.contextPath }/dormitory/del",
type : "post",
data :{
'dormiId':row.dormiId
},
dataType:"json",
success : function(result) {
toastr.success('删除数据成功');
$("#tb_departments").bootstrapTable("destroy");
oTable.Init();
},
error : function(result) {
toastr.error('出现错误!');
}
});
});
});
否则(“虽无需传值给ajax,加了@ResponseBody,但方法类型为void,无返回值”的话):
删除正常,但是返回时,不是去success的function而是去error的function里:
----------------------------------分割线--------------------------------
了解:
append 译文:附加; 添加; 贴上
jQuery 文档操作 - append() 方法
参考:
JS给div赋值的问题
jquery动态为个span,input,div,等标签赋值的方法总结,js动态隐藏div,
但是,有时,排版好丑(因为固定了宽度):
了解:
css div自适应高度height
参考:
CSS实现如何让div宽度从零开始自适应【让div的宽度自适应】
然后我改用<span>标签:
了解:
span 译文:跨度,墩距; 一段时间
HTML <span> 标签
这个标签,相对来说,更自适应 :
--------------------------------分割线--------------------------
参考:
关于 There is no getter for property named 'id' in 'class java.lang.Integer'
报了:“There is no getter for property named 'id' in 'class java.lang.Integer'”这个异常,在对应方法的参数那加上注解“@Param”,就好了
--------------------------分割线--------------------------
了解:
jQuery change() 方法【菜鸟教程】
jQuery 事件 - change() 方法【W3School】
参考:
jQuery的change函数,以及on函数的change事件,使用和区别
<!-- 查看学生宿舍模态框 -->
<div class="modal fade" id="myModalLook" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" style="width:200px;">宿舍分配</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form name="formInfoDorm" id="formInfoDorm" method="post">
<div class="form-inline">
<table>
<tr>
<td style="width:200px" align="center">
<select id="studNameLeft" multiple="multiple" style="height:300px;width:200px"></select>
</td>
<td style="width:200px" align="center">
<select id="clsId" class="form-control" name="classId">
<c:forEach items="${classList }" var="c">
<option value="${c.classId }">${c.className }</option>
</c:forEach>
</select><br><br>
<input type="button" class="btn btn-primary" id="addLeft" value="分配 <<"><br><br/><input type="button" class="btn btn-primary" id="removeRight" value="移出 >>">
</td>
<td style="width:200px" align="center">
<select id="studNameRight" multiple="" style="height:300px;width:200px"></select>
</td>
</tr>
</table>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">关闭</button>
<button type="button" id="save3" class="btn btn-primary" data-dismiss="modal">保存</button>
</div>
</div>
</div>
</div>
$("#clsId").change(function(){
//alert("val方法的获取:"+$("#clsId").find("option:selected").val());
var id=$("#clsId").find("option:selected").val();
var url="${pageContext.request.contextPath}/dormitory/findById";
var str="";
$.post(
url,
{"id":id},
function(data) {
$.each(data, function (key, value) {
//alert(value.studId+"................."+value.studName)
//result.push({ value: value.empId, text: value.empName});
str+="<option value='"+value.studId+"'>"+value.studName+"</option>";
});
$("#studNameRight").html(str);
})
});
参考:
用jquery获取select标签中选中的option值及文本的示例
Jquery获取select选中的文本与值 【获取select选择的XX讲的更详细】