springmvc与ajax交互详解编程语言

在实际开发中我们经常需要前后台交互,那么springmvc与ajax之间交互这里记录下在实际开发中遇到的细节问题。

jsp页面:

<fieldset id="login" style="width:600px; border:1px solid #000;border-left:none;border-right:none">    
	<legend style="">用户登录</legend>    
	<p align="center">账号:<input type="text" name="username" /></p>    
	<p align="center">密码:<input type="password" name="password" /></p>    
	<p align="center"><input type="submit" id="submit1" value="登录" /></p>   
</fieldset>

ajax请求如下:

<script type="text/javascript"> 
    $(function() { 
	$("#submit1").click(function() { 
	    var json = { 
	        'username':$(':input[name=username]').val(), 
		'password':$(':input[name=password]').val() 
	    }; 
	    //json字符串 {"username":"admin","password":"123456"} 
	    var postdata = JSON.stringify(json);//json对象转换json字符串 
	    alert(postdata); 
	    $.ajax({ 
		type : 'POST', 
		contentType : 'application/json',//注意类型 
		/** 
                  *(默认: true) 默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串), 
                  * 都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。 
                  * 如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。 
                 */ 
		processData : false, 
		url : '<%=path%>/databind/requestbodybind', 
		dataType : 'json', 
		data : postdata, 
		success : function(data) { 
		    alert('username : '+data.username+'/npassword : '+data.password); 
		}, 
		error : function() { 
		    alert('error...'); 
		} 
	  }); 
       });			 
    }); 
</script> 


tip:我们可以看到在用contentType : ‘application/json’发起请求,data我们传的是一个json字符串,而不是json对象,一开始我也认为是可以的,结果不行,直接传对象报错,不妨亲自试试。

SpringMVC需要提供的方法如下:

@RequestMapping(value="requestbodybind", method = {RequestMethod.POST}) 
@ResponseBody 
public Account requestBodyBind(@RequestBody Account account){ 
      System.out.println("requestbodybind:" + account); 
      return account; 
}

那还是
contentType : ‘application/json’发起的请求,我们能不能用如下的方式接收值呢

@RequestMapping(value="json", method = {RequestMethod.POST}) 
@ResponseBody 
public Account json(String username, String password){ 
Account account = new Account(); 
account.setUsername(username); 
account.setPassword(password); 
return account; 
}

答案是不可以的,会抛异常,
400 Bad Request

究其原因是:contentType : ‘application/json’数据发送后台接收必须是Modle,不能是单个属性,[email protected]
如果我们把contentType换成默认的contentType : ‘application/x-www-form-urlencoded’呢,前后台又该怎么写?

ajax写法如下:

$(function(){ 
    $("#submit").click(function(){ 
           $.ajax({ 
               type: "POST", 
               /* contentType : 'application/x-www-form-urlencoded',*/ 
               url:  '<%=path%>/databind/json', 
               dataType: "json", 
               data: {username:$('#username').val(), 
                      password:$('#password').val()}, 
               success: function(data){ 
                    alert('username : '+data.username+'/npassword : '+data.password); 
               } 
           });  
    }); 
});

这里不得不提下,虽然data这里看起来传的是一个json对象,但由于使用了application/x-www-form-urlencoded,最终可以通过firebug可以看到,其实最终传过去的还是username=admin&password=123456,当然你也可以直接传字符串过去,但是有一点要注意,真实项目中字段还是特别多的,这样拼接会相当繁琐,然而我们知道还有个方法供我们使用,
jQuery给我们提供的$(“#login”).serialize()序列化表单。

$(function(){ 
    $("#submit").click(function(){ 
           var params = $("#login").serialize();//序列化表单 
           alert(params); 
           $.ajax({ 
               type: "POST", 
               url:  '<%=path%>/databind/json', 
               dataType: "json", 
               data: params, 
               success: function(data){ 
                    alert('username : '+data.username+'/npassword : '+data.password); 
               } 
           });  
    }); 
});

后台接收方式如下:

@RequestMapping(value="json", method = {RequestMethod.POST}) 
@ResponseBody 
public Account json(String username,String password){ 
    Account account = new Account(); 
    account.setUsername(username); 
    account.setPassword(password); 
    return account; 
}

那这里要提出一个疑问,如果我需要接受的字段特别多呢,难道我在方法中也需要一个一个参数的去写嘛,比如有20个,还不得累死。

答案是当然啦

@RequestMapping(value="/json", method = {RequestMethod.POST}) 
@ResponseBody 
public Account json(Account account){ 
    System.out.println(account); 
    return account; 
}

此外,这里不得不提一件事情,很多人一看到要拿model接收传参,[email protected],springmvc才会帮你把相关值封装到model里面去,我在这里告诉你,千万不要这样想,这个注解不是随便就用的,它的用途是帮你转换json->model、 xml->model,你好好的表单提交,用的contentType:application/x-www-form-urlencoded,何必画蛇添足加上这个注解呢。

总结:

<script type="text/javascript"> 
    $(function() { 
	$("#submit1").click(function() { 
	    var json = { 
		'username':$(':input[name=username]').val(), 
		 'password':$(':input[name=password]').val() 
	    }; 
	    //json字符串 {"username":"admin","password":"123456"} 
	    var postdata = JSON.stringify(json);//json对象转换json字符串 
	    alert(postdata); 
	    $.ajax({ 
		type : 'POST', 
		contentType : 'application/json', 
		/** 
                  *(默认: true) 默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串), 
                  * 都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。 
                  * 如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。 
                 */ 
		processData : false, 
		url : '<%=path%>/databind/requestbodybind', 
		dataType : 'json', 
		data : postdata, 
		success : function(data) { 
		    alert('username : '+data.username+'/npassword : '+data.password); 
		}, 
		error : function() { 
		    alert('error...'); 
		} 
	     }); 
	});					 
    }); 
</script> 

以上$.ajax()中 contentType : ‘application/json’,则data必须转换为json对象且后台方法参数必须用model接受,否则报400错误,则后台接受参数为:

@RequestMapping(value="requestbodybind", method = {RequestMethod.POST}) 
@ResponseBody 
public Account requestBodyBind(@RequestBody Account account){ 
      System.out.println("requestbodybind:" + account); 
      return account; 
}

默认$.ajax()中的contentType:’application/x-www-form-urlencoded’发送的数据格式为“xx=yy&uu=ii”data数据不是json对象,它是发送信息至服务器时内容编码类型。
如下$.ajax()没有写contentType则默认类型为’application/x-www-form-urlencoded’,则data传递的参数类型为单个属性.

function initArrivePerson(divId) { 
	var jqids = $("#jqid").val();//获得警情id 
	$.ajax({ 
		 type:"post",    
		 url:basePath + "kscj/findArrivePerson.do", 
		 data:{"jqid":jqids}, 
		 dataType:"json", 
		 async: false, 
		 cache:false, 
		 success : function(data) { 
			 $("#"+divId).html(""); 
			 var arrivePerson=""; 
			 for (var i=0;i<data.length;i++) { 
				 arrivePerson+="<span>"; 
				 arrivePerson+="<input type=/"checkbox/"  name=/"cjrxm/"  value=/'"+data[i].sjybh+"/'/><span>"+data[i].sjyxm+""; 
				 arrivePerson+="<input type=/"hidden/"  name=/"cjdbh/"  value=/'"+data[i].cjdbh+"/'/>"; 
				 arrivePerson+=""; 
			 } 
			 $("#"+divId).append(arrivePerson);  
		 } 
	}); 
}

则后台接受参数为:

@RequestMapping(value = "/findArrivePerson", produces = {"application/json;charset=UTF-8"}) 
@ResponseBody 
public List<TItmpTcsDisposal> findArrivePerson(HttpServletRequest req, HttpServletResponse resp, String jqid){ 
    List<TItmpTcsDisposal> arriveList = titmpGpsLocateinfoService.findNoRepeat(jqid); 
    return arriveList; 
}

补充:

[email protected],什么时候不该用

前面我们已经看到了,接受单个基本类型值的参数,只要在方法中分别写下,并且并不需要使用什么注解就能拿到传过来的值,[email protected],并且看到很多地方都在用。
其实呢这个注解,有它的用处,并不是一无是处,首先作为基本类型的参数,如果不使用注解,是可传可不传的如果为null并不会报错[email protected],那么此时该参数就是必传的了,如果不传就会报错,然而还是可以通过配置来让其可不必传,[email protected](value=”username”, required=false),此外,该注解还可以设置如果前台没有传值过来,会给一个默认值,[email protected](value=”username”, defaultValue=”ruo”)。
我对该注解做的总结是:如果你某个参数不是必传的,就别用它了,如果是必传的,请一定用上它,如果必传参数可以有默认值的话,还请加上defaultValue默认值。

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/11196.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论