SpringMVC中使用Ajax POST请求以json格式传递参数服务端通过request.getParameter("name")无法获取参数值问题分析

SpringMVC中使用Ajax POST请求以json格式传递参数服务端通过request.getParameter("name")无法获取参数值问题分析

一:问题demo展示

在开发新需求,调试代码的时候发现一个问题,就是HttpServletRequest 获取不到ajax post请求的json参数!下面是伪代码是整个请求的逻辑!

1.前台JS请求代码(伪代码)

	var _phoneId = "123456789";
	
	var closeUrl=contextPath+"/close";

	ajax(closeUrl,{"phoneId":_phoneId},"post",false,callbackForSessionClose,null,'json');
	
	function ajax(url,reqData,type,async,successBack,errorBack,statusText,dataType){
		
		$.ajax({
			type : type,
			url : url,
			dataType : dataType,
			async : async,
			timeout : "60000",
			contentType : "application/json",
			data : JSON.stringify(reqData),
			success : function(data) {
				// 成功的处理逻辑
             
            },
			error : function(data) {
				// 错误的处理逻辑
			}
			
		});
	}

2.后台代码(伪代码)

	@RequestMapping(value="/close",method=RequestMethod.POST)
	@ResponseBody
	public String closeSession(HttpServletRequest request){
		String response;
		try{
			String phoneId = request.getParameter("phoneId");
			if(phoneId == "123456789"){
				response = "success";
			}else{
				response = "error";
			}
		}catch (ServiceException e) {
			//业务异常处理逻辑
		}catch (Exception e) {
			//非业务异常处理逻辑
		
		}
		return response;
	}

二:问题分析

正常的post请求(不包括ajax请求)在http头中的content-type为application/x-www-form-urlencoded,这时在java后台可以通过request.getParameter(name)的形式获取.但是通过原生ajax请求时,在java后台通过request.getParameter(name)的形式却无法获取到传入的参数.

原因是原生ajax请求时,在http头中的content-type为text/plain;charset=UTF-8.当请求到达tomcat服务器时,服务器只对application/x-www-form-urlencoded形式的http,post请求进行读取body体中的参数,并放到request的parameter中,对于原生ajax请求则直接忽略,不会读取body体中的参数,才导致request.getParameter(name)读取不到参数.

根据上面的分析结合自己的当前系统,发现系统封装的ajax默认content-type为application/json,那么这种方式在java后台通过request.getParameter(name)的形式是不能获取到传入的参数的!

三:解决方案

1.[前台解决方案]修改Ajax post请求的contentType和data

修改前:

		contentType : "application/json",
		data : JSON.stringify(reqData),
		

修改后:

		contentType : "application/x-www-form-urlencoded",
		data : reqData, //不需要使用JSON.stringify()

后台代码不变!

2.[后台解决方案]使用@RequestBody

前台js代码不变!

后台代码修改:

新增一个类:

	public class CloseRequestVO implements Serializable{
		
		private String phoneId;
		//省略get set方法
		//....
		
	}
	@RequestMapping(value="/close",method=RequestMethod.POST)
	@ResponseBody
	public String closeSession(@RequestBody CloseRequestVO requestVO){
		String response;
		try{
			String phoneId = requestVO.getPhoneId();
			if(phoneId == "123456789"){
				response = "success";
			}else{
				response = "error";
			}
		}catch (ServiceException e) {
			//业务异常处理逻辑
		}catch (Exception e) {
			//非业务异常处理逻辑
		
		}
		return response;
	}

后台通过request.getParameter(name)方式就可以获取到参数.

上面两种方式选择适合自己系统的方案即可!

四:@RequestBody简单介绍

@RequestBody : @RequestBody是指方法参数应该被绑定到HTTP请求Body上

申明:在SpringMVC环境中,@RequestBody接收的是一个Json对象的字符串,而不是一个Json对象。
所以
第一:@RequestBody需要接的参数是一个String化的json,前台js代码可以直接使用JSON.stringify(json)这个方法来转化;

第二:从@RequestBody名称上来看,也就是说要读取的数据在请求体(body)里,所以要发post请求;

第三:@RequestBody接收的是一个String的Json,那么要设置请求contentType,contentType:"application/json,明确的告诉服务器发送的内容是json。

五:参考资料

jquery通过ajax-json访问java后台传递参数,通过request.getParameter获取不到参数的说明

@RequestBody应用


**如果您觉得这篇博文对你有帮助,请点个赞,谢谢!** **如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!**

欢迎访问我的csdn博客,我们一同成长!

"不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!"

博客首页http://blog.csdn.net/u010648555

posted @ 2018-01-17 14:31  阿飞云漫步  阅读(2297)  评论(0编辑  收藏  举报