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

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