• SpringMVC中使用Ajax请求以json格式返回null值


    一:问题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;
        }

    四:@RequestBody简单介绍

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

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

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

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





    ---恢复内容结束---

  • 相关阅读:
    python os模块
    python time、datetime模块
    python 导入模块、包
    python json、pickle
    python 装饰器
    python 生成器、迭代器
    python 内置函数
    python 函数的参数
    python 编码解码
    python 文件读写、shutil模块
  • 原文地址:https://www.cnblogs.com/zemul/p/10652980.html
Copyright © 2020-2023  润新知