微信小程序踩坑记-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 条评论
登录 后参与评论

相关文章

来自专栏有刻

Java 小记 — RabbitMQ 的实践与思考

38010
来自专栏老码农专栏

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

2203
来自专栏编舟记

一步步编写SonarQube Plugin

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

4932
来自专栏JavaEdge

Redis实践(八)-Sentinal12 主从复制高可用?3 Redis Sentinel 架构4 安装与配置5 安装与演示6 客户端11 三个定时任务12 主观下线和客观下线13 领导者选举14

由于Redis Sentinel只会对主节点进行故障转移,对从节点采取主观的下线,所以需要自定义一个客户端来监控对应的事件

1651
来自专栏Java架构师历程

solr

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

2802
来自专栏向治洪

android获取设备唯一标示

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

1.5K7
来自专栏吉浦迅科技

DAY71:阅读Device-side Launch from PTX

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

1132
来自专栏老码农专栏

TodoBackend展示应用以及ActFramework的实现

1225
来自专栏desperate633

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

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

2003
来自专栏coolblog.xyz技术专栏

Spring IOC 容器源码分析系列文章导读

Spring 是一个轻量级的企业级应用开发框架,于 2004 年由 Rod Johnson 发布了 1.0 版本。经过十几年的迭代,现在的 Spring 框架已...

1393

扫码关注云+社区