后台SpringMVC接收map类型参数
背景:有时候我们可能需要发ajax到后台,并且携带一些参数,如果参数数量少,我们可以直接在后台写参数便可,如果前台提交的是表单,我们可以利用spring mvc提供的封装参数的方法进行接收,但假如是另外一种情况,前台向后台发送ajax请求并且携带很多参数,而后台并没有对应的实体类进行接收又该如何处理,当然很多人可能会想到,根据请求中携带的参数,在后台定义一个实体类,在根据mvc的封装特性接收不就好了,这样的做法是可以实现的,但是假如很多地方都是这样的多参数的请求,难道都根据参数去建立对应的实体类吗?这样就会让后台变得臃肿,冗余,所以,后来思考是否可以使用map作为参数,传递到后台接收,这里记下笔记,作为记录。
刚刚我说的这种情况,可能在后台系统中会遇到的比较多,最常见的就是搜索框表单,搜索框内有多个搜索条件,有时可能有一二十个,这种情况下,我们当然考虑使用map来解决。因为map的数据结构为key-value形式,所以我们可以遍历搜索框表单,将表单的name作为map的key,表单的value作为map的value.思路就到这里,接下来贴代码:
假如是上面类似这样的搜索框,我们点击搜索的时候,要根据用户选择或输入的条件去发送请求到后台获取相应的数据,这样就不可避免的会携带很多参数(可能有些搜索框更复杂)。
首先:遍历表单组成map,在通过map转化成json字符串
[code]//得到搜索框数据 function getFromData() { var dataMap = new Map(); $("#form_id input,select").each(function(){ var value= $(this).val(); //input 值 var name= $(this).attr('name'); dataMap.set(name,value); }); //Map转为Json的方法 let obj= Object.create(null); for (let[k,v] of dataMap) { obj[k] = v; } return obj; } //发送ajax请求(第一种方式,推荐):1.contentType 可以不填 2.发送数据为json对象 let obj=getFromData(); $.ajax({ url: "srarch_data/search_data_detail.action", type: "post", dataType:'json', data: {"jsonData":JSON.stringify(obj)}, success: function (json) { } }); //发送ajax请求(第二种方式):1.必须填写contentType 2.发送数据为json字符串 $.ajax({ url: "srarch_data/search_data_detail.action", type: "post", dataType:'json', contentType : 'application/json;charset=utf-8', data: JSON.stringify(obj), success: function (json) { } });
接下来是后台接收
[code] //第一种ajax请求对应的后台接口 @RequestMapping("search_data_detail") @ResponseBody public void searchInfo(@RequestParam Map<String,String> map){ Map<String, Object> jsonMap= JsonToMap.jsonToMap(map.get("jsonData")); for (Map.Entry<String,Object> entry:jsonMap.entrySet()){ System.out.print("得到键为:==="+entry.getKey()); System.out.println("得到值为:==="+entry.getValue()); } } //第二种ajax请求后台对应的后台接口 @RequestMapping("search_data_detail") @ResponseBody public void searchInfo(@RequestBody Map<String,String> map) { for (Map.Entry<String,String> entry:map.entrySet()){ System.out.print("得到键为:==="+entry.getKey()); System.out.println("得到值为:==="+entry.getValue()); } }
想必大家都知道@RequestParam,可以获取请求中所有的参数,包括我传的jsondata,贴一下JsonToMap,是一JSON转换为map对象的工具类方法,因为在后台我们用map更方便,包括传入mybatis时也可以直接传Map。
[code]/** * @Auther: HeJD * @Date: 2018/8/6 18:26 * @Description:JSON转MAP工具类 */ public class JsonToMap{ /** * 将json字符串转为Map对象 * 如果json复杂,结果可能是map嵌套map * @param jsonStr 入参,json格式字符串 * @return 返回一个map */ public static Map<String, Object> jsonToMap(String jsonStr) { Map<String, Object> map = new HashMap<>(); if(jsonStr != null && !"".equals(jsonStr)){ //最外层解析 JSONObject json = JSONObject.fromObject(jsonStr); for (Object k : json.keySet()) { Object v = json.get(k); //如果内层还是数组的话,继续解析 if (v instanceof JSONArray) { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); Iterator<JSONObject> it = ((JSONArray) v).iterator(); while (it.hasNext()) { JSONObject json2 = it.next(); list.add(jsonToMap(json2.toString())); } map.put(k.toString(), list); } else { map.put(k.toString(), v); } } return map; }else{ return null; } } }
上面两种方式的结果都是一样的:
这里记录一下可能出现的问题,当我们接收前台的json数据并转换为map,作为参数直接传递给mybatis时,即便xml中有做非null和非“”判断,但还是会进入,导致出现 null(jsonNull)这种情况,出现这个的原因是因为,如下:
json里的null与"null"。
处理对象:将Json形式的字符串转换成JSONObject对象。
问题:如果在Json串中存在value是“null”的情况下,下面的语句根据不同状况会生成不同结果。
执行语句:
JSONObject Jsob =JSONObject.fromObject(sJson);
情景1:sjson =”{name:\”null\”}”
情景2:sjson =”{name: \”null\”}” 注意:冒号后面有空格
执行结果:
在情景1的情况下,生成的Jsob中,name的value是”“null””
在情景2的情况下,生成的Jsob中,name的value是null
总结:
没有空格的情况下,JSONObject会把”null”作为一个字符串来处理,也就会加上转义符号。
有空格的情况下,JSONObject会把”null”转换为JSONNULL,也就是没有引号。
既然知道是由空格引发的问题,所以我们的解决方案便是去掉空格,所以我们将修改后的js如下:
[code]//得到搜索框数据 function getFromData() { var dataMap = new Map(); $("#form_solo_id input,select").each(function(){ var value= $.trim($(this).val()); //去空格后的input 值 var name= $(this).attr('name'); dataMap.set(name,value); }); let obj= Object.create(null); for (let[k,v] of dataMap) { obj[k] = v; } return obj; }
这样问题得以解决,特此记录
再次更新:这次是终结此类问题的!!!
spring框架中有个一个工具类:WebUtils
里面有一个静态方法: WebUtils.getParametersStartingWith(ServletRequest request, String prefix);
原来别人早就考虑好了这种类似的情况,具体使用如下:
假如你有一个这样的表单
[code]<form class="layui-form"> <div class="layui-inline"> <input type="text" value="" name="s_roleName" placeholder="输入角色名" class="layui-input search_input"> <input type="text" value="" name="s_nickNAME" placeholder="输入昵称" class="layui-input search_input"> </div> </form>
那么提交不用像前面那样子了,可以直接在后台:
[code] public ServerResponse list(ServletRequest request){ //获取所有前缀为s_的name存入map中 Map<String,Object> map = WebUtils.getParametersStartingWith(request, "s_"); for (Map.Entry<String,Object> entry :map.entrySet()){ System.out.println("遍历map得到键为:"+entry.getKey()); System.out.println("遍历map得到值为:"+entry.getValue()); } }
键值不带前缀,是去掉前缀的!!!!
最后贴一篇参考文章,写的很好:https://www.geek-share.com/detail/2701936270.html
阅读更多- 提高生产力:SpringMVC中,使用扩展数据类型TypedMap接收Web请求参数
- 提高生产力:SpringMVC中,使用扩展数据类型TypedMap接收Web请求参数
- 提高生产力:SpringMVC中,使用扩展数据类型TypedMap接收Web请求参数
- 提高生产力:SpringMVC中,使用扩展数据类型TypedMap接收Web请求参数
- springMVC学习(6)-包装pojo类型、数组、list、Map类型参数绑定
- SpringMVC无法接收日期类型的参数
- Spring boot后台接收前端传过来的form-date类型的参数
- 解决angular的post请求后SpringMVC后台接收不到参数值问题的方法
- 解决angular的post请求后SpringMVC后台接收不到参数值问题的方法
- SpringMVC接收日期类型参数的自定义转换
- AngularJs中$http发送post或者get请求,SpringMVC后台接收不到参数值的解决办法
- springmvc使用map接收form表单的参数
- 帆软报表和jeecg的进一步整合--ajax给后台传递map类型的参数
- springMVC前台传数组类型,后台用list类型接收实例代码
- 分享知识-快乐自己:SpringMvc整合遇到-前台传JSON参数,后台实体类对象接收
- angular的post请求,SpringMVC后台接收不到参数值的解决办法(参考加自创)
- springmvc 接受 map类型的参数
- SpringMVC使用@PathVariable ,参数接收使用基本类型
- 前台js传入json或map类型数据给后台以及后台java接收操作
- AngularJs中$http发送post或者get请求,SpringMVC后台接收不到参数值的解决办法