微信小程序踩坑记-Java基于SSM下的post请求

前言

最近在持续踩微信小程序的坑,canvas和WebSocket的暂时还没找到相关的解决方案,暂时先将post请求无法获取data参数的坑填上。直接附上解决方案,已通过真机检测~之后的解决历程有兴趣的可以看看,没兴趣就可以直接跳过了,附录里是一些遇到的知识延伸以及参考资料地址。本文的环境为:微信小程序+Java+SpringMCV,由于暂时没用到数据库,就不写ssm了。以下内容仅适用于微信小程序,普通页面中暂不负责~(就酱霸气~~)

高危预警

用的久了,发现之前说的那些原因所在了。一切都是Content-Type问题,之前分析的确实有点错误,Content-Type为‘application/json’时,后端需要用@RequestBody ,Content-Type为‘application/x-www-form-urlencoded’或者‘multipart/form-data’时可以用不加注解或者@RequestParam。详情原因可转至最近发布的文章:RequestParam与RequestBod等参数注解简析

-2017-12-16

内容原因等可能存在误区,暂时没时间深究,请慎重参考。

-2017-08-01

解决方案

java后台

方案一与方案二唯一不同之处就是@RequestBody注解的参数类型不同。没错,就是用@RequestBody来获取微信小程序 wx.request中data参数。

方案一:参数为自定义类

该方式主要可用于前端传递自定义对象参数时

    @ResponseBody
    @RequestMapping("nihao2.do")
    public String nihao2(HttpServletRequest request, HttpServletResponse response, @RequestBody User j){
        response.setHeader("Access-Control-Allow-Origin", "*");
        System.out.println("uid:"+j.getUid()+" uname:"+j.getUname());
        JSONObject js = new JSONObject(j);
        return js.toString();
    }

方案二:参数为MAP

该方法可以自定义前面的传参,原本是想找个能直接传递int、String这种的,最后无奈放弃选用这种了。

 params" > @ResponseBody
    @RequestMapping("nihao4.do")
    public String nihao4(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> params){
        response.setHeader("Access-Control-Allow-Origin", "*");
        JSONObject j = new JSONObject(params);
        System.out.println("uid:"+j.get("uid")+" uname:"+j.get("uname"));
        return j.toString();
    }

前端

    wx.request({
      url: 'action地址',
      data:  {
        'uid':1,
        'uname':"哈哈"
      },
      method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      // header: {}, // 设置请求的 header
      success: function(res){
        // success
        console.log("toRed success:"+res.data.uid+' '+res.data.uname)
      },
      fail: function(res) {
        // fail
        console.log("toRed fail:"+res);
      },
      complete: function(res) {
        // complete
        console.log("toRed complete:"+res);
      }
    })

什么?head怎么没了?data数据转换怎么没了?因为那些都不需要,不论换不换head,最后微信请求时都是'Content-Type': 'application/json',不信的话你可以去开发者工具那看看= =。

解决历程

在网上寻找解决过程时,看到好多说要将head中的'Content-Type': 'application/json'改为"Content-Type": "application/x-www-form-urlencoded",也有说即使改成上面格式也依旧获取不到data的,然后又将datay由Json改为“uid=1&uname=哈哈”类似字符串,同时字符串要经过encodeURIComponent转码,并给出相应转码util的。然而以上这些都没说后台是什么环境,自然也没找到基于ssm的java后台的相关解决方案了。

偶然转换了下思路,同样的代码为何在普通的html中可以使用,在小程序里就报空指针异常(由于参数中包含int类型)了呢。

常用的SpringMVC接受参数与传递数据的方法

    @ResponseBody
    @RequestMapping("nihao.do")
    public String nihao(HttpServletRequest request, HttpServletResponse response, int uid,String uname){
        response.setHeader("Access-Control-Allow-Origin", "*");
        JSONObject j = new JSONObject();
        System.out.println("uid:"+uid+" uname:"+uname);
        j.put("uid",uid);
        j.put("uname",uname);
        return j.toString();
    }

之后打开前端的开发者工具,发现平常使用ajax传递时,参数数据都在form data中,如图

而微信小程序中的post请求参数是在request payload中,如图:

至于这两者有什么区别,能找到的解释会放在附录中。现在问题就从如何解决微信小程序中post的问题转为用什么方法获取request payload

经过大量搜索筛选后,@RequestBody这个注解项进入到视野。

@RequestBody 将HTTP请求正文转换为适合的HttpMessageConverter对象。 POST模式下,使用@RequestBody绑定请求对象,Spring会帮你进行协议转换,将Json、Xml协议转换成你需要的对象。

目前能搜到的就是这个了,至于深层的@RequestBody为何能获取到request payload的数据,暂时只能寻求这方面的大神去解答了。在实验过程中,发现它可以用在Map,自定义对象如User(自定义实体类)等上,直接加载JSONobjet发现始终是错误提示415。

附录

HTTP请求中的form data和request payload的区别

整理一下再放送

JSON转Key=val模板

虽然这里用不到,留个备份,没准什么时候用到了呢。

放置在util.js中即可

function json2Form(json) {  
    var str = [];  
    for(var p in json){  
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(json[p]));  
    }  
    return str.join("&");  
}  
module.exports = {  
  json2Form:json2Form,  
}</span>

使用方式:

使用方式

//获取应用实例  
var app = getApp()  
Page( {  
  data: {  
    toastHidden: true,  
    city_name: '',  
  },  
  onLoad: function() {  
    var that = this;  
    wx.request( {  
      url: "http://op.juhe.cn/onebox/weather/query",  
      header: {  
        "Content-Type": "application/x-www-form-urlencoded"  
      },  
      method: "POST",  
     //data: { cityname: "上海", key: "1430ec127e097e1113259c5e1be1ba70" }, 
     //此处引用 
      data: Util.json2Form( { cityname: "上海", key: "1430ec127e097e1113259c5e1be1ba70" }),  
      complete: function( res ) {  
        that.setData( {  
          toastHidden: false,  
          toastText: res.data.reason,  
          city_name: res.data.result.data.realtime.city_name,  
          date: res.data.result.data.realtime.date,  
          info: res.data.result.data.realtime.weather.info,  
        });  
        if( res == null || res.data == null ) {  
          console.error( '网络请求失败' );  
          return;  
        }  
      }  
    })  
  },  
  onToastChanged: function() {  
    that.setData( { toastHidden: true });  
  }  
})  
var Util = require( '../../utils/util.js' );

参考资料

微信小程序开发之网络请求(POST请求)(放个最全的,基本涵盖了目前网上全部微信小程序post解决方案,毕竟翻来覆去就那两项= =)

Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable

angular的post请求,SpringMVC后台接收不到参数值的解决方案(最开始使用了这个的,又是JSON.stringify,又是将给@RequestBodyJSONObjet,然后就报415了。。之后新建了个User实体类并替换了JSONObject后就success了,瞬间幸福感爆棚~)

SpringMVC使用Map或MultiValueMap接收前端提交的Form Data或Query String(找到VO类的解决方案后,想要不需要创建VO类就能获取到信息的方法,然后就遇上了这个,并最终选择了这个用map接收前端参数的方案)

@RequestBody-------springMVC(介个。。我也记不清仔细看了没,看到浏览器打开没关,暂且放着吧)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

开源BUG跟踪平台JIRA目录遍历漏洞分析

作者 Taskiller 最近,一则新发布的公告报告了一个影响Jira 5.0.11和6.0.3版本的目录遍历漏洞,该漏洞在去年7月份被验证,并在接下来的几个月...

46260
来自专栏老码农专栏

原 荐 一场版本升级引发的性能血案 - 之数

24430
来自专栏BeJavaGod

省市区 - 三级联动通用化模块组件

都说我们要做模块化设计,而不要做功能化设计 什么是模块化设计,就是可插拔性高,组件化,想要就用,不要用拉倒,直接删除就行 什么是功能化设计,就是一个简单的功能,...

58850
来自专栏Java架构师历程

solr

Solr它是一种开放源码的、基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中。Solr 提供了层面搜索(就是统计)、命中醒目显示并且支...

52120
来自专栏程序猿DD

Jenkins Pipeline插件十大最佳实践!

Jenkins Pipeline 插件对于 Jenkins 用户来说可以让用户能够改变游戏规则。基于 Groovy 中的领域特定语言(DSL),Pipeline...

595100
来自专栏desperate633

深入理解Spring框架的作用(Spring in action 学习笔记)激发POJO的潜能依赖注入应用切面使用模板消除样板式代码

纵览Spring , 读者会发现Spring 可以做非常多的事情。 但归根结底, 支撑Spring的仅仅是少许的基本理念, 所有的理念都可以追溯到Spring最...

28330
来自专栏编舟记

一步步编写SonarQube Plugin

插件确实不好写,因为插件是插入庞大的系统当中工作的,那也就意味着写插件需要具备一定的领域知识,包括系统架构、扩展点、业务共性及差异、API及其业务模型对应、安装...

99030
来自专栏吉浦迅科技

DAY71:阅读Device-side Launch from PTX

我们正带领大家开始阅读英文的《CUDA C Programming Guide》,今天是第71天,我们正在讲解CUDA 动态并行,希望在接下来的30天里,您可以...

14020
来自专栏小灰灰

Java & PhantomJs 实现html输出图片

Java & PhantomJs 实现html输出图片 借助phantomJs来实现将html网页输出为图片 I. 背景 如何在小程序里面生成一张图,分享到朋...

83580
来自专栏向治洪

android获取设备唯一标示

概述 有时需要对用户设备进行标识,所以希望能够得到一个稳定可靠并且唯一的识别码。虽然Android系统中提供了这样设备识别码,但是由于Android系统版本、...

2K70

扫码关注云+社区

领取腾讯云代金券