博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringMVC中使用Ajax请求以json格式返回null值
阅读量:4971 次
发布时间:2019-06-12

本文共 3296 字,大约阅读时间需要 10 分钟。

 

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

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

转载于:https://www.cnblogs.com/zemul/p/10652980.html

你可能感兴趣的文章
day02
查看>>
我是怎么招聘程序员的
查看>>
gvim 配置Pydiction
查看>>
Linux安装指定mysql版本
查看>>
Exception in thread "main" java.lang.ClassNotFoundException: 解决方法
查看>>
移动应用(手机应用)开发IM聊天程序解决方案
查看>>
[转载] K3漏油器全紫铜替换原硅胶垫教程。标准姿势
查看>>
python set
查看>>
VC中使用ADO操作数据库的方法
查看>>
如何判断域名是否被微信拦截 被已经被微信封了的的域名网址如何在微信中正常打开...
查看>>
分布式锁的三种实现方式
查看>>
AJAX原生JS代码
查看>>
ThinkPHP提示错误
查看>>
poj 2109 pow函数也能这么用?p的开n次方
查看>>
Oracle database link
查看>>
清北学堂2017NOIP冬令营入学测试P4749 F’s problem(f)
查看>>
POJ 1840 Eqs HASH
查看>>
python调用shell小技巧
查看>>
TL431的几种常用用法
查看>>
BZOJ 1833: [ZJOI2010]count 数字计数( dp )
查看>>