Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

小程序请求有时会出现 Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ #359

Closed
ghs0223 opened this issue Oct 30, 2017 · 41 comments

Comments

@ghs0223
Copy link

ghs0223 commented Oct 30, 2017

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
at com.google.gson.Gson.fromJson(Gson.java:887)
at com.google.gson.Gson.fromJson(Gson.java:852)
at com.google.gson.Gson.fromJson(Gson.java:801)
at com.google.gson.Gson.fromJson(Gson.java:773)
at cn.binarywang.wx.miniapp.bean.WxMaUserInfo.fromJson(WxMaUserInfo.java:23)
at cn.binarywang.wx.miniapp.api.impl.WxMaUserServiceImpl.getUserInfo(WxMaUserServiceImpl.java:41)

@binarywang

This comment has been minimized.

@ghs0223

This comment has been minimized.

@jinriyang

This comment has been minimized.

@Tigerioo

This comment has been minimized.

@guoyangyang

This comment has been minimized.

@guoyangyang

This comment has been minimized.

@binarywang binarywang reopened this Apr 19, 2018
@binarywang
Copy link
Member

https://www.cnblogs.com/guansixu/articles/6484872.html 楼上遇到问题的各位请参考此文,不知是否有帮助

@guoyangyang
Copy link

@binarywang 感谢回复。我这边遇到的问题和你分享的文章相似。

回头翻了一下小程序开发手册,发现开发过程中忽略了下面这段注意事项。
getphonenumber

修改了调用wx.login顺序后,问题解决。

@binarywang binarywang changed the title 小程序解密用户信息是,经常会出现com.google.gson.JsonSyntaxException: java.lang.IllegalStateException 小程序解密用户信息经常会出现com.google.gson.JsonSyntaxException May 15, 2018
@Wechat-Group Wechat-Group deleted a comment from yiyi910 May 15, 2018
@Wechat-Group Wechat-Group deleted a comment from jinriyang Jun 11, 2018
@binarywang binarywang reopened this Jun 27, 2018
@binarywang binarywang changed the title 小程序解密用户信息经常会出现com.google.gson.JsonSyntaxException 小程序解密用户信息经常会出现JsonSyntaxException Jun 28, 2018
@7400108

This comment has been minimized.

@hyede

This comment has been minimized.

@binarywang

This comment has been minimized.

@hyede

This comment has been minimized.

@binarywang binarywang pinned this issue Dec 28, 2018
@chwuling
Copy link

chwuling commented Apr 2, 2020

解密手机号的时候,遇到了相同的问题,原因是用固定的 session_key + encryptedData+ iv 解密,但是encryptedData 或者 iv 可能是一次性的,解密完之后就不能再用了

@spiritelf

This comment has been minimized.

@binarywang binarywang changed the title 小程序解密相关信息有时会出现JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT 小程序请求有时会出现 Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ Jul 7, 2020
@luzhaoren
Copy link

luzhaoren commented Jul 7, 2020

确认下前后端传递的参数有没有做UrlEncode/UrlDecode,因为encryptedData里会包含特殊字符在传递参数时被转义,可能服务器端实际拿到的参数encryptedData并不是前端实际获取到的值,导致SDK调用微信相应接口时无法解密而报错,只要保证前端实际获取到的encryptedData和服务器端调用SDK时传入的encryptedData一致就不会报错的,SDK中方法并无问题;建议让前后台都打印下日志,看下服务端最终使用的参数值是否还是前端获取到的原始值呢。

重要:有朋友反映按照以上描述处理后还是会偶尔出现这个解密问题,那么可能就是前后端没有协同好了,忽略了每次调用wx.login时微信都会刷新sessionkey,可能造成后台使用了旧的/过期的sessionkey去解密而失败,一般开发小程序时有一个原则,前端只要调用wx.login就必须通知后台使用最新的code刷新sessionkey!所以正确的做法应该是:

  1. 前端调用wx.checkSession,检查session是否过期
  2. 如果session过期,则前端调用wx.login并通知后台使用auth.code2Session刷新sessionkey
  3. 前端调用wx.getShareInfo,获取微信返回的encryptedData和iv
  4. 前端调用后台接口,后台使用encryptedData解密用户信息

PS:wx.request对GET/POST传递字符串参数时会自动做encodeURIComponent,SpringBoot某些场景下form表单参数是会自动做UrlDecode的...

注意事项官方说明

wx.request官方API文档
获取用户信息
获取用户手机号码
服务端解密开放数据

@makehkx
Copy link

makehkx commented Jul 7, 2020

确认下前后端传递的参数有没有做UrlEncode/UrlDecode,因为encryptedData里会包含特殊字符在传递参数时被转义,可能服务器端实际拿到的参数encryptedData并不是前端实际获取到的值,导致SDK调用微信相应接口时无法解密而报错,只要保证前端实际获取到的encryptedData和服务器端调用SDK时传入的encryptedData一致就不会报错的,SDK中方法并无问题;建议让前后台都打印下日志,看下服务端最终使用的参数值是否还是前端获取到的原始值呢。PS:SpringBoot某些场景下form表单参数是会自动做UrlDecode的...

多谢大佬,就是特殊字符被转义了

@93Laer
Copy link

93Laer commented Jul 7, 2020

确认下前后端传递的参数有没有做UrlEncode/UrlDecode,因为encryptedData里会包含特殊字符在传递参数时被转义,可能服务器端实际拿到的参数encryptedData并不是前端实际获取到的值,导致SDK调用微信相应接口时无法解密而报错,只要保证前端实际获取到的encryptedData和服务器端调用SDK时传入的encryptedData一致就不会报错的,SDK中方法并无问题;建议让前后台都打印下日志,看下服务端最终使用的参数值是否还是前端获取到的原始值呢。PS:SpringBoot某些场景下form表单参数是会自动做UrlDecode的...

多谢大佬,就是特殊字符被转义了

多谢大佬,我懂了

@SwpuEsine

This comment has been minimized.

@binarywang

This comment has been minimized.

@qmdx

This comment has been minimized.

@binarywang

This comment has been minimized.

@longzhiwuing

This comment has been minimized.

@RmanzzZ

This comment has been minimized.

@tianyahaijiaowxp

This comment has been minimized.

@RmanzzZ
Copy link

RmanzzZ commented Nov 12, 2020

怎么这个问题感觉都没有特别明确的回答啊
下面代码报错
WxMaPhoneNumberInfo phoneNoInfo = this.wxMaService.getUserService().getPhoneNoInfo(session.getSessionKey(), encryptedData, iv);
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $

都没有个实质的回答

已解决 还是顺序的问题
image

@weiqilong
Copy link

weiqilong commented Jan 30, 2021 via email

@sav7ng
Copy link

sav7ng commented Feb 27, 2021

@weiqilong 可以爬一下楼,问题解决方案都在上面,可以一步一步排查。

@KaimingLuo
Copy link

KaimingLuo commented Mar 24, 2021

确认下前后端传递的参数有没有做UrlEncode/UrlDecode,因为encryptedData里会包含特殊字符在传递参数时被转义,可能服务器端实际拿到的参数encryptedData并不是前端实际获取到的值,导致SDK调用微信相应接口时无法解密而报错,只要保证前端实际获取到的encryptedData和服务器端调用SDK时传入的encryptedData一致就不会报错的,SDK中方法并无问题;建议让前后台都打印下日志,看下服务端最终使用的参数值是否还是前端获取到的原始值呢。

重要:有朋友反映按照以上描述处理后还是会偶尔出现这个解密问题,那么可能就是前后端没有协同好了,忽略了每次调用wx.login时微信都会刷新sessionkey,可能造成后台使用了旧的/过期的sessionkey去解密而失败,一般开发小程序时有一个原则,前端只要调用wx.login就必须通知后台使用最新的code刷新sessionkey!所以正确的做法应该是:

  1. 前端调用wx.checkSession,检查session是否过期
  2. 如果session过期,则前端调用wx.login并通知后台使用auth.code2Session刷新sessionkey
  3. 前端调用wx.getShareInfo,获取微信返回的encryptedData和iv
  4. 前端调用后台接口,后台使用encryptedData解密用户信息

PS:wx.request对GET/POST传递字符串参数时会自动做encodeURIComponent,SpringBoot某些场景下form表单参数是会自动做UrlDecode的...

注意事项官方说明

wx.request官方API文档
获取用户信息
获取用户手机号码
服务端解密开放数据

我也遇到偶尔解密失败的问题,看完大佬们的回答,调查后发现是顺序问题。前端先调用了getUserInfo,再调用wx.login,拿着旧的加密信息和新的session去解密了。。
不过,现在直接从session中拿openid、unionid,用户信息用getUserProfile拿明文,不用再去解密了0.0?

@HeyChiang
Copy link

解密手机号的时候,遇到了相同的问题,原因是用固定的 session_key + encryptedData+ iv 解密,但是encryptedData 或者 iv 可能是一次性的,解密完之后就不能再用了

我亲自测试了, session_key + encryptedData+ iv 可以重复使用postman拿到手机号码,并不是你说的一次性。

@q127981
Copy link

q127981 commented Oct 31, 2021

image
简单粗暴的一个解决方法,既然拿到的sessionKey是过期的,那么就再拿一次

@IllusionOops
Copy link

IllusionOops commented Nov 25, 2021

前端获取到用户手机号信息,然后打印,接着使用postman调用后端接口,由后端进行用户手机号信息解密。
偶尔会出现这种情况:成功、失败交替进行;大部分情况:多次失败,偶尔成功。
这个错误到底是什么原因?
我现在是测试阶段,仅仅通过前端打印数据,然后通过postman发起post请求进行接口调用,完全不存在前端重复调用登录接口导致sessionkey失效问题,也没有调用其他接口。
当出现失败报错的时候,我使用文本对比工具对比过前端打印的数据和后端打印的数据,完全一致!!!

每个人的回答我都看了,但是依然没懂这个错误到底是什么原因···能否告知下

@liuguofeng-java

This comment was marked as spam.

@liuguofeng-java
Copy link

找到问题了先调用login在调用getphonenumber

image

@longtimeGo
Copy link

我这边遇到了线下可以获取到用户信息,到线上就报错,错误信息提示中如下列:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
at com.google.gson.Gson.fromJson(Gson.java:888)
at com.google.gson.Gson.fromJson(Gson.java:853)
at com.google.gson.Gson.fromJson(Gson.java:802)
at com.google.gson.Gson.fromJson(Gson.java:774)
at cn.binarywang.wx.miniapp.bean.WxMaUserInfo.fromJson(WxMaUserInfo.java:29)
at cn.binarywang.wx.miniapp.api.impl.WxMaUserServiceImpl.getUserInfo(WxMaUserServiceImpl.java:38)

代码层面:(getPhoneNoInfo不报错,getUserInfo会报上述的错)
wxPhoneInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, request.getMobileEncryptedData(), request.getMobileIvStr());
wxUserInfo = wxMaService.getUserService().getUserInfo(sessionKey, request.getUserInfoEncryptedData(), request.getUserInfoIvStr());

@binarywang binarywang unpinned this issue Jun 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests