├── .gitignore ├── README.md ├── eclipse-java-google-style.xml ├── pom.xml └── src ├── main └── java │ └── com │ └── belerweb │ └── social │ ├── API.java │ ├── SDK.java │ ├── bean │ ├── Error.java │ ├── Gender.java │ ├── JsonBean.java │ ├── OnlineStatus.java │ └── Result.java │ ├── captcha │ ├── api │ │ └── Yundama.java │ └── bean │ │ └── YundamaType.java │ ├── exception │ └── SocialException.java │ ├── http │ ├── Http.java │ └── HttpException.java │ ├── mail │ └── api │ │ └── POP3.java │ ├── qq │ ├── connect │ │ ├── api │ │ │ ├── OAuth2.java │ │ │ ├── QQConnect.java │ │ │ ├── QZone.java │ │ │ ├── User.java │ │ │ └── Weibo.java │ │ └── bean │ │ │ ├── AccessToken.java │ │ │ ├── Album.java │ │ │ ├── AlbumPrivilege.java │ │ │ ├── Company.java │ │ │ ├── Display.java │ │ │ ├── Education.java │ │ │ ├── FanList.java │ │ │ ├── Gut.java │ │ │ ├── IdolList.java │ │ │ ├── Image.java │ │ │ ├── Music.java │ │ │ ├── NewT.java │ │ │ ├── OpenID.java │ │ │ ├── Photo.java │ │ │ ├── PicUploadResult.java │ │ │ ├── RepostList.java │ │ │ ├── Scope.java │ │ │ ├── SendPrivate.java │ │ │ ├── Tag.java │ │ │ ├── TenpayAddress.java │ │ │ ├── TweetInfo.java │ │ │ ├── User.java │ │ │ ├── Video.java │ │ │ └── WeiboUser.java │ ├── mail │ │ ├── api │ │ │ └── Contact.java │ │ └── bean │ │ │ ├── Address.java │ │ │ ├── Email.java │ │ │ ├── Group.java │ │ │ ├── Org.java │ │ │ ├── Tel.java │ │ │ ├── User.java │ │ │ └── ValidationCode.java │ ├── qzone │ │ └── api │ │ │ └── Visitor.java │ └── t │ │ └── api │ │ ├── OAuth2.java │ │ └── QQT.java │ ├── weibo │ ├── api │ │ ├── OAuth2.java │ │ ├── User.java │ │ └── Weibo.java │ └── bean │ │ ├── AccessToken.java │ │ ├── Comment.java │ │ ├── Display.java │ │ ├── Geo.java │ │ ├── Privacy.java │ │ ├── Remind.java │ │ ├── Scope.java │ │ ├── Status.java │ │ ├── TokenInfo.java │ │ ├── UrlShort.java │ │ ├── User.java │ │ ├── UserCounts.java │ │ └── Visible.java │ └── weixin │ ├── api │ ├── Group.java │ ├── Media.java │ ├── Menu.java │ ├── OAuth2.java │ ├── User.java │ └── Weixin.java │ └── bean │ ├── AccessToken.java │ ├── ApiTicket.java │ ├── Article.java │ ├── EventType.java │ ├── GetFollowersResult.java │ ├── Group.java │ ├── JSApiTicket.java │ ├── Media.java │ ├── MediaType.java │ ├── Menu.java │ ├── MenuType.java │ ├── Message.java │ ├── MsgType.java │ ├── QRCreation.java │ ├── QRTicket.java │ ├── QRType.java │ ├── Scope.java │ ├── User.java │ ├── Variable.java │ └── VoiceType.java └── test ├── java └── com │ └── belerweb │ └── social │ ├── SDKTest.java │ ├── TestConfig.java │ ├── captcha │ └── api │ │ └── YundamaTest.java │ ├── mail │ └── api │ │ └── POP3Test.java │ ├── qq │ └── connect │ │ └── api │ │ ├── OAuth2Test.java │ │ └── UserTest.java │ ├── weibo │ └── api │ │ ├── OAuth2Test.java │ │ └── UserTest.java │ └── weixin │ └── api │ ├── GroupTest.java │ ├── MediaTest.java │ ├── MenuTest.java │ ├── OAuth2Test.java │ ├── UserTest.java │ └── WeixinTest.java └── resources └── logback.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | .externalToolBuilders/ 3 | .settings/ 4 | bin/ 5 | tmp/ 6 | .metadata 7 | .gradle 8 | *.tmp 9 | *.bak 10 | *.swp 11 | *~.nib 12 | local.properties 13 | .loadpath 14 | .project 15 | .classpath 16 | 17 | # IntelliJ IDES 18 | .idea/ 19 | out/ 20 | .idea_modules/ 21 | *.iml 22 | *.ipr 23 | *.ids 24 | *.iws 25 | 26 | # OSX 27 | # Icon must end with two \r 28 | Icon 29 | 30 | 31 | ._* 32 | .DS_Store 33 | .AppleDouble 34 | .LSOverride 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | .AppleDB 42 | .AppleDesktop 43 | Network Trash Folder 44 | Temporary Items 45 | .apdisk 46 | 47 | # Windows 48 | $RECYCLE.BIN/ 49 | Thumbs.db 50 | ehthumbs.db 51 | Desktop.ini 52 | *.lnk 53 | 54 | # Linux 55 | *~ 56 | .directory 57 | .Trash-* 58 | 59 | # Maven 60 | target/ 61 | pom.xml.tag 62 | pom.xml.releaseBackup 63 | pom.xml.versionsBackup 64 | pom.xml.next 65 | release.properties 66 | dependency-reduced-pom.xml 67 | buildNumber.properties 68 | .mvn/timing.properties 69 | 70 | # frontend-maven-plugin 71 | node 72 | bower_components 73 | node_modules 74 | etc 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | social-sdk 2 | ========== 3 | 4 | social-sdk是一个集成[新浪微博开放平台][1]、[QQ互联][2]、[腾讯微博开发平台][3]、[微信公众平台][4]等社交平台的接口的Java库。 5 | 6 | 7 | 8 | 其实在开始这个项目之前,各个平台都已经提供相应的Java 9 | SDK,有官方的、也有非官方的开源项目,如如新浪微博开放平台有[weibo4j][5]。我也一直在使用这些项目。但是在使用过程中越到的问题越来越多,越来越麻烦,如: 10 | 11 | - 这些SDK都是提供一个ZIP包,不适合Maven或Ivy管理的项目。 12 | 13 | - 各个SDK都引入了开源公共类库,确改了包名,造成类库过多、混乱。 14 | 15 | - SDK更新超级慢,跟不上平台上接口的变更。 16 | 17 | - 没有交流环境,遇到BUG找不到资料,找不到沟通的地方,需要自己去琢磨源代码。 18 | 19 | - ...... 20 | 21 | 因此,自己开发一个,尝试尽可能多的集成社交平台。 22 | 23 | 24 | 25 | **因为我并没有在项目中使用到那么多社交平台,所以有的社交平台没有可供测试的应用信息(通常叫做AppKey和AppSecret)。所以非常希望有资源的朋友共享测试帐号。** 26 | 27 | 28 | 29 | 已实现 30 | --- 31 | 32 | - QQ相关 33 | - 通过QQ邮箱获取联系人,支持验证码自动登录 34 | - 获取QZone访客记录,支持验证码自动登录 35 | - 新浪微博 36 | - 新浪微博登录 37 | - 获取新浪微博用户信息 38 | - QQ帐号/QQ互联 39 | - 支持http://wiki.connect.qq.com 列出的API 40 | - 腾讯微博(未测试) 41 | - 腾讯微博登录(未测试) 42 | - 获取腾讯微博用户信息(未测试) 43 | - [微信帐号](../../wiki/微信API) 44 | - [获取access_token](../../wiki/微信API#获取access token) 45 | - [获取jsapi_ticket](../../wiki/微信API#获取jsapi_ticket) 46 | - jsapi签名 47 | - 上传下载多媒体文件 48 | - 接受消息/事件推送/位置信息 49 | - 验证消息真实性 50 | - 发送被动响应信息 51 | - 发送客服消息 52 | - 发送模板消息 53 | - 分组管理 54 | - 获取用户基本信息 55 | - 获取关注者列表 56 | - 网页授权获取用户基本信息 57 | - 自定义菜单 58 | - 生成带参数的二维码接口 59 | 60 | 61 | 62 | 计划开发 63 | ---- 64 | 65 | - 更多的接口 66 | 67 | - 支持更多的平台 68 | 69 | 70 | 71 | 下载 72 | -- 73 | 74 | 推荐使用Maven下载。social-sdk已发布到Maven中央库。 75 | 76 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 77 | 78 | com.belerweb 79 | social-sdk 80 | 0.0.5 81 | 82 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 83 | 84 | 85 | 86 | 参与 87 | -- 88 | 89 | 交流:GitHub上留言或加入QQ群(328171904) 90 | 91 | 共享代码:Fork项目并提交Pull Requests 92 | 93 | 提交BUG:直接在GitHub上提交 94 | 95 | 其他:欢迎任何形式的贡献,文档、经验、意见... 96 | 97 | 98 | 99 | 链接 100 | -- 101 | 102 | [1]: 103 | [2]: 104 | [3]: 105 | [4]: 106 | [5]: 107 | [6]: 108 | [7]: 109 | [8]: 110 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | org.sonatype.oss 6 | oss-parent 7 | 7 8 | 9 | 10 | com.belerweb 11 | social-sdk 12 | 0.0.6-SNAPSHOT 13 | jar 14 | 15 | social-sdk 16 | All in one sdk, include weibo, qq connect, t.qq.com ... 17 | https://github.com/belerweb/social-sdk 18 | 19 | 20 | 21 | BSD 22 | http://opensource.org/licenses/bsd-license.html 23 | repo 24 | 25 | 26 | 27 | 28 | scm:git:https://github.com/belerweb/social-sdk.git 29 | scm:git:https://github.com/belerweb/social-sdk.git 30 | https://github.com/belerweb/social-sdk.git 31 | 32 | 33 | Github Issue 34 | https://github.com/belerweb/social-sdk/issues 35 | 36 | 37 | 38 | belerweb 39 | Tangjun He 40 | belerweb@gmail.com 41 | https://github.com/belerweb 42 | 43 | 44 | 45 | 46 | UTF-8 47 | 1.5 48 | ${maven.compiler.source} 49 | 2.6 50 | 51 | 52 | 53 | 54 | org.json 55 | json 56 | 20131018 57 | 58 | 59 | org.apache.httpcomponents 60 | httpmime 61 | 4.3.1 62 | 63 | 64 | commons-lang 65 | commons-lang 66 | 2.6 67 | 68 | 69 | commons-io 70 | commons-io 71 | 2.4 72 | 73 | 74 | commons-net 75 | commons-net 76 | 3.3 77 | 78 | 79 | org.jsoup 80 | jsoup 81 | 1.7.3 82 | 83 | 84 | org.slf4j 85 | slf4j-api 86 | 1.7.5 87 | 88 | 89 | ch.qos.logback 90 | logback-classic 91 | 1.0.13 92 | test 93 | 94 | 95 | junit 96 | junit 97 | 4.11 98 | test 99 | 100 | 101 | 102 | 103 | 104 | 105 | com.googlecode.maven-java-formatter-plugin 106 | maven-java-formatter-plugin 107 | 0.4 108 | 109 | ${maven.compiler.source} 110 | ${maven.compiler.source} 111 | ${maven.compiler.source} 112 | ${project.basedir}/eclipse-java-google-style.xml 113 | LF 114 | 115 | 116 | 117 | 118 | format 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | org.eclipse.m2e 128 | lifecycle-mapping 129 | 1.0.0 130 | 131 | 132 | 133 | 134 | 135 | com.googlecode.maven-java-formatter-plugin 136 | maven-java-formatter-plugin 137 | [0.4] 138 | 139 | format 140 | 141 | 142 | 143 | 144 | true 145 | 146 | 147 | 148 | 149 | 150 | org.apache.maven.plugins 151 | maven-enforcer-plugin 152 | [1.0,) 153 | 154 | enforce 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/API.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social; 2 | 3 | import com.belerweb.social.qq.connect.api.QQConnect; 4 | import com.belerweb.social.qq.t.api.QQT; 5 | import com.belerweb.social.weibo.api.Weibo; 6 | import com.belerweb.social.weixin.api.Weixin; 7 | 8 | 9 | public abstract class API { 10 | 11 | protected Weibo weibo; 12 | protected Weixin weixin; 13 | protected QQConnect connect; 14 | protected QQT t; 15 | 16 | protected API(Weibo weibo) { 17 | this.weibo = weibo; 18 | } 19 | 20 | protected API(Weixin weixin) { 21 | this.weixin = weixin; 22 | } 23 | 24 | protected API(QQConnect connect) { 25 | this.connect = connect; 26 | } 27 | 28 | protected API(QQT t) { 29 | this.t = t; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/SDK.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social; 2 | 3 | import java.nio.charset.Charset; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import org.apache.commons.lang.StringUtils; 8 | import org.apache.http.HttpEntity; 9 | import org.apache.http.NameValuePair; 10 | import org.apache.http.message.BasicNameValuePair; 11 | import org.json.JSONArray; 12 | import org.json.JSONObject; 13 | 14 | import com.belerweb.social.bean.Error; 15 | import com.belerweb.social.bean.Result; 16 | import com.belerweb.social.exception.SocialException; 17 | import com.belerweb.social.http.Http; 18 | import com.belerweb.social.http.HttpException; 19 | 20 | public abstract class SDK { 21 | 22 | private final Charset defaultCharset; 23 | 24 | public SDK() { 25 | this(null); 26 | } 27 | 28 | public SDK(Charset defaultCharset) { 29 | this.defaultCharset = defaultCharset; 30 | } 31 | 32 | public String get(String url, List params) { 33 | try { 34 | Http.setDefaultCharset(defaultCharset); 35 | return Http.get(url, params); 36 | } catch (HttpException e) { 37 | throw new SocialException(e); 38 | } 39 | } 40 | 41 | public String get(String url) { 42 | return get(url, null); 43 | } 44 | 45 | public String post(String url, HttpEntity postBody) { 46 | try { 47 | Http.setDefaultCharset(defaultCharset); 48 | return Http.post(url, postBody); 49 | } catch (HttpException e) { 50 | throw new SocialException(e); 51 | } 52 | } 53 | 54 | public String post(String url, List params) { 55 | try { 56 | Http.setDefaultCharset(defaultCharset); 57 | return Http.post(url, params, "UTF-8"); 58 | } catch (HttpException e) { 59 | throw new SocialException(e); 60 | } 61 | } 62 | 63 | public String post(String url) { 64 | return post(url, (HttpEntity) null); 65 | } 66 | 67 | public void addParameter(List params, String name, Object value) { 68 | if (value == null) { 69 | throw new SocialException("Parameter " + name + " must not be null."); 70 | } 71 | params.add(new BasicNameValuePair(name, value.toString())); 72 | } 73 | 74 | public void addNotNullParameter(List params, String name, Object value) { 75 | if (value != null) { 76 | params.add(new BasicNameValuePair(name, value.toString())); 77 | } 78 | } 79 | 80 | public void addTrueParameter(List params, String name, Boolean value) { 81 | if (Boolean.TRUE.equals(value)) { 82 | params.add(new BasicNameValuePair(name, value.toString())); 83 | } 84 | } 85 | 86 | /** 87 | * 经纬度转换为地址 88 | * 89 | * @param lon 经度 90 | * @param lat 纬度 91 | */ 92 | public Result lonLatToAddress(Double lon, Double lat) { 93 | List params = new ArrayList(); 94 | addParameter(params, "sensor", "false"); 95 | addParameter(params, "language", "zh"); 96 | addParameter(params, "latlng", lat + "," + lon); 97 | String json = get("https://maps.googleapis.com/maps/api/geocode/json", params); 98 | JSONObject jsonObject = new JSONObject(json); 99 | if (!"OK".equals(jsonObject.getString("status"))) { 100 | Error error = new Error(); 101 | error.setErrorCode(jsonObject.getString("status")); 102 | error.setError(jsonObject.optString("error_message")); 103 | return new Result(error); 104 | } 105 | 106 | JSONArray results = jsonObject.getJSONArray("results"); 107 | if (results.length() == 0) { 108 | return new Result(StringUtils.EMPTY); 109 | } 110 | return new Result(results.getJSONObject(0).getString("formatted_address")); 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/bean/Error.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | public final class Error extends JsonBean { 6 | 7 | private String request; 8 | private String errorCode; 9 | private String error; 10 | 11 | public Error() {} 12 | 13 | public Error(String code, String message) { 14 | this.errorCode = code; 15 | this.error = message; 16 | } 17 | 18 | private Error(JSONObject jsonObject) { 19 | super(jsonObject); 20 | } 21 | 22 | public String getRequest() { 23 | return request; 24 | } 25 | 26 | public void setRequest(String request) { 27 | this.request = request; 28 | } 29 | 30 | public String getErrorCode() { 31 | return errorCode; 32 | } 33 | 34 | public void setErrorCode(String errorCode) { 35 | this.errorCode = errorCode; 36 | } 37 | 38 | public String getError() { 39 | return error; 40 | } 41 | 42 | public void setError(String error) { 43 | this.error = error; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return errorCode + ":" + error + "(" + request + ")"; 49 | } 50 | 51 | public static Error parse(JSONObject jsonObject) { 52 | String errorCode = jsonObject.optString("error_code", null); 53 | if (errorCode != null) {// 微博 54 | String request = jsonObject.optString("request", null); 55 | String error = jsonObject.optString("error", null); 56 | Error er = new Error(jsonObject); 57 | er.setRequest(request); 58 | er.setErrorCode(errorCode); 59 | er.setError(error); 60 | return er; 61 | } 62 | 63 | errorCode = jsonObject.optString("error", null); 64 | if (errorCode != null) {// QQ互联 65 | String error = jsonObject.optString("error_description", null); 66 | Error er = new Error(jsonObject); 67 | er.setErrorCode(errorCode); 68 | er.setError(error); 69 | return er; 70 | } 71 | 72 | Integer ret = Result.parseInteger(jsonObject.opt("ret")); 73 | if (ret != null && ret != 0) {// QQ互联 74 | String msg = jsonObject.optString("msg", null); 75 | Error er = new Error(jsonObject); 76 | er.setErrorCode(ret.toString()); 77 | er.setError(msg); 78 | return er; 79 | } 80 | 81 | ret = Result.parseInteger(jsonObject.opt("errcode")); 82 | if (ret != null && ret != 0) {// 微信 83 | String error = jsonObject.optString("errmsg", null); 84 | Error er = new Error(jsonObject); 85 | er.setErrorCode(ret.toString()); 86 | er.setError(error); 87 | return er; 88 | } 89 | 90 | return null; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/bean/Gender.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.bean; 2 | 3 | public enum Gender { 4 | 5 | MALE(1, "m", "男", "Male"), FEMALE(0, "f", "女", "Female"), UNKNOWN(-1, "n", "未知", "Unknown"); 6 | 7 | int intValue; 8 | String code; 9 | String zhValue; 10 | String enValue; 11 | 12 | private Gender(int intValue, String code, String zhValue, String enValue) { 13 | this.intValue = intValue; 14 | this.code = code; 15 | this.zhValue = zhValue; 16 | this.enValue = zhValue; 17 | } 18 | 19 | public int value() { 20 | return intValue; 21 | } 22 | 23 | public String code() { 24 | return code; 25 | } 26 | 27 | public String text() { 28 | return zhValue; 29 | } 30 | 31 | public String enText() { 32 | return enValue; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return zhValue; 38 | } 39 | 40 | public static Gender parse(Integer val) { 41 | if (val == null) { 42 | return null; 43 | } 44 | if (new Integer(1).equals(val)) { 45 | return MALE; 46 | } 47 | if (new Integer(0).equals(val) || new Integer(2).equals(val)) { 48 | // FIXME 微信2代表女性,0表示未知。暂且把微信的未知看作女性,如同新浪微博用户没有设置性别的时候会返回男性一样 49 | return FEMALE; 50 | } 51 | return UNKNOWN; 52 | } 53 | 54 | public static Gender parse(String val) { 55 | if (val == null) { 56 | return null; 57 | } 58 | if ("男".equals(val) || "m".equalsIgnoreCase(val) || "male".equalsIgnoreCase(val) 59 | || "b".equalsIgnoreCase(val) || "boy".equalsIgnoreCase(val)) { 60 | return MALE; 61 | } 62 | if ("女".equals(val) || "f".equalsIgnoreCase(val) || "female".equalsIgnoreCase(val) 63 | || "g".equalsIgnoreCase(val) || "girl".equalsIgnoreCase(val)) { 64 | return FEMALE; 65 | } 66 | return UNKNOWN; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/bean/JsonBean.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | public abstract class JsonBean { 6 | 7 | private JSONObject jsonObject; 8 | 9 | protected JsonBean() {} 10 | 11 | protected JsonBean(JSONObject jsonObject) { 12 | this.jsonObject = jsonObject; 13 | } 14 | 15 | public JSONObject getJsonObject() { 16 | return jsonObject; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/bean/OnlineStatus.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.bean; 2 | 3 | public enum OnlineStatus { 4 | 5 | ONLINE(1, "在线", "online"), OFFLINE(0, "不在线", "offline"); 6 | 7 | private int status; 8 | private String text; 9 | private String enText; 10 | 11 | private OnlineStatus(int status, String text, String enText) { 12 | this.status = status; 13 | this.text = text; 14 | this.enText = enText; 15 | } 16 | 17 | public boolean online() { 18 | return status == 1; 19 | } 20 | 21 | public int status() { 22 | return status; 23 | } 24 | 25 | public String text() { 26 | return text; 27 | } 28 | 29 | public String enText() { 30 | return enText; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return super.toString(); 36 | } 37 | 38 | public static OnlineStatus parse(Integer val) { 39 | if (val == null) { 40 | return null; 41 | } 42 | if (new Integer(1).equals(val)) { 43 | return ONLINE; 44 | } 45 | return OFFLINE; 46 | } 47 | 48 | public static OnlineStatus parse(String val) { 49 | if (val == null) { 50 | return null; 51 | } 52 | if ("在线".equals(val) || "online".equalsIgnoreCase(val)) { 53 | return ONLINE; 54 | } 55 | return OFFLINE; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/bean/Result.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.bean; 2 | 3 | import java.lang.reflect.Method; 4 | import java.text.ParseException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.ArrayList; 7 | import java.util.Date; 8 | import java.util.List; 9 | import java.util.Locale; 10 | 11 | import org.json.JSONArray; 12 | import org.json.JSONObject; 13 | 14 | import com.belerweb.social.exception.SocialException; 15 | 16 | public class Result { 17 | 18 | private Error error; 19 | private T result; 20 | private List results; 21 | 22 | public Result(Error error) { 23 | this.error = error; 24 | } 25 | 26 | public Result(T result) { 27 | this.result = result; 28 | } 29 | 30 | public Result(List results) { 31 | this.results = results; 32 | } 33 | 34 | public boolean success() { 35 | return error == null; 36 | } 37 | 38 | public Error getError() { 39 | return error; 40 | } 41 | 42 | public T getResult() { 43 | return result; 44 | } 45 | 46 | public List getResults() { 47 | return results; 48 | } 49 | 50 | public static Result parse(String json, Class resultType) { 51 | try { 52 | if (json.matches("^\\s*\\[.*$")) { 53 | return new Result(parse(new JSONArray(json), resultType)); 54 | } else { 55 | return parse(new JSONObject(json), resultType); 56 | } 57 | } catch (Exception e) { 58 | throw new SocialException(e); 59 | } 60 | } 61 | 62 | @SuppressWarnings("unchecked") 63 | public static Result parse(JSONObject jsonObject, Class resultType) { 64 | try { 65 | Error error = Error.parse(jsonObject); 66 | if (error == null) { 67 | Method parse = resultType.getMethod("parse", JSONObject.class); 68 | T obj = (T) parse.invoke(null, jsonObject); 69 | return new Result(obj); 70 | } 71 | return new Result(error); 72 | } catch (Exception e) { 73 | throw new SocialException(e); 74 | } 75 | } 76 | 77 | @SuppressWarnings("unchecked") 78 | public static List parse(JSONArray jsonArray, Class resultType) { 79 | List list = new ArrayList(); 80 | if (jsonArray == null) { 81 | return list; 82 | } 83 | try { 84 | for (int i = 0; i < jsonArray.length(); i++) { 85 | if (resultType.isAssignableFrom(String.class)) { 86 | list.add((T) toString(jsonArray.get(i))); 87 | } else if (resultType.isAssignableFrom(Integer.class)) { 88 | list.add((T) parseInteger(jsonArray.get(i))); 89 | } else if (resultType.isAssignableFrom(Long.class)) { 90 | list.add((T) parseLong(jsonArray.get(i))); 91 | } else if (resultType.isAssignableFrom(Double.class)) { 92 | list.add((T) parseDouble(jsonArray.get(i))); 93 | } else { 94 | Method parse = resultType.getMethod("parse", JSONObject.class); 95 | list.add((T) parse.invoke(null, jsonArray.getJSONObject(i))); 96 | } 97 | } 98 | return list; 99 | } catch (Exception e) { 100 | throw new SocialException(e); 101 | } 102 | } 103 | 104 | public static String toString(Object obj) { 105 | if (obj == null) { 106 | return null; 107 | } 108 | 109 | return obj.toString(); 110 | } 111 | 112 | public static Long parseLong(Object obj) { 113 | if (obj == null) { 114 | return null; 115 | } 116 | 117 | Long result = null; 118 | if (obj instanceof Number) { 119 | result = ((Number) obj).longValue(); 120 | } else if (obj instanceof String) { 121 | result = Long.valueOf((String) obj); 122 | } 123 | 124 | return result; 125 | } 126 | 127 | public static Integer parseInteger(Object obj) { 128 | if (obj == null) { 129 | return null; 130 | } 131 | 132 | Integer result = null; 133 | if (obj instanceof Number) { 134 | result = ((Number) obj).intValue(); 135 | } else if (obj instanceof String) { 136 | result = Integer.valueOf((String) obj); 137 | } 138 | 139 | return result; 140 | } 141 | 142 | public static Double parseDouble(Object obj) { 143 | if (obj == null) { 144 | return null; 145 | } 146 | 147 | Double result = null; 148 | if (obj instanceof Number) { 149 | result = ((Number) obj).doubleValue(); 150 | } else if (obj instanceof String) { 151 | result = Double.valueOf((String) obj); 152 | } 153 | 154 | return result; 155 | } 156 | 157 | public static Boolean parseBoolean(Object obj) { 158 | if (obj == null) { 159 | return null; 160 | } 161 | 162 | Boolean result = null; 163 | if (obj instanceof Boolean) { 164 | result = (Boolean) obj; 165 | } else if (obj instanceof Integer) { 166 | result = ((Integer) obj).intValue() == 1; 167 | } else if (obj instanceof String) { 168 | result = Boolean.valueOf(obj.toString()); 169 | } 170 | 171 | return result; 172 | } 173 | 174 | public static Date parseDate(Object obj, String pattern, Locale locale) { 175 | if (obj == null) { 176 | return null; 177 | } 178 | 179 | Date result = null; 180 | if (obj instanceof Date) { 181 | result = new Date(((Date) obj).getTime()); 182 | } else if (obj instanceof String) { 183 | try { 184 | SimpleDateFormat format = new SimpleDateFormat(pattern, locale); 185 | result = format.parse((String) obj); 186 | } catch (ParseException e) { 187 | throw new SocialException(e); 188 | } 189 | } 190 | 191 | return result; 192 | } 193 | 194 | public static Date parseTimeSeconds(Object obj) { 195 | Integer seconds = Result.parseInteger(obj); 196 | if (seconds == null || seconds == 0) { 197 | return null; 198 | } 199 | return new Date(seconds * 1000); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/captcha/api/Yundama.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.captcha.api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.commons.io.IOUtils; 6 | import org.apache.http.HttpResponse; 7 | import org.apache.http.client.ClientProtocolException; 8 | import org.apache.http.client.methods.HttpPost; 9 | import org.apache.http.entity.ContentType; 10 | import org.apache.http.entity.mime.MultipartEntityBuilder; 11 | import org.json.JSONObject; 12 | 13 | import com.belerweb.social.bean.Error; 14 | import com.belerweb.social.bean.Result; 15 | import com.belerweb.social.captcha.bean.YundamaType; 16 | import com.belerweb.social.exception.SocialException; 17 | import com.belerweb.social.http.Http; 18 | import com.belerweb.social.http.HttpException; 19 | 20 | public class Yundama { 21 | 22 | private String appId = "85"; 23 | private String appKey = "19fcd07d8de9c03b8cebec5d8bfe7d8e"; 24 | private String username; 25 | private String password; 26 | 27 | public Yundama(String username, String password) { 28 | this.username = username; 29 | this.password = password; 30 | } 31 | 32 | public Result decode(byte[] img, YundamaType type) { 33 | HttpPost request = new HttpPost("http://api.yundama.com/api.php?method=upload"); 34 | MultipartEntityBuilder builder = 35 | MultipartEntityBuilder.create() 36 | .addBinaryBody("file", img, ContentType.create("image/png"), "code.png") 37 | .addTextBody("username", username).addTextBody("password", password) 38 | .addTextBody("codetype", type.getType().toString()).addTextBody("appid", appId) 39 | .addTextBody("appkey", appKey).addTextBody("timeout", "60"); 40 | request.setEntity(builder.build()); 41 | try { 42 | HttpResponse response = Http.CLIENT.execute(request); 43 | String json = IOUtils.toString(response.getEntity().getContent()); 44 | request.releaseConnection(); 45 | JSONObject jsonObject = new JSONObject(json); 46 | Integer ret = Result.parseInteger(jsonObject.get("ret")); 47 | if (ret == 0) { 48 | String url = 49 | "http://api.yundama.com/api.php?method=result&cid=" 50 | + Result.toString(jsonObject.get("cid")); 51 | long start = System.currentTimeMillis(); 52 | while (true) { 53 | jsonObject = new JSONObject(Http.get(url)); 54 | if (Result.parseInteger(jsonObject.get("ret")) == 0) { 55 | return new Result(Result.toString(jsonObject.get("text"))); 56 | } 57 | if (System.currentTimeMillis() - start > 10000) { 58 | return new Result(new Error("TIMEOUT", "验证码识别超时。")); 59 | } 60 | try { 61 | Thread.sleep(300); 62 | } catch (InterruptedException e) { 63 | e.printStackTrace(); 64 | } 65 | } 66 | } 67 | Error error = new Error(); 68 | error.setErrorCode(ret.toString()); 69 | return new Result(error); 70 | } catch (ClientProtocolException e) { 71 | throw new SocialException(e); 72 | } catch (HttpException e) { 73 | throw new SocialException(e); 74 | } catch (IOException e) { 75 | throw new SocialException(e); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/captcha/bean/YundamaType.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.captcha.bean; 2 | 3 | 4 | public enum YundamaType { 5 | /** 6 | * 不定长英文数字 2.5题分一个字符(按文本长度收费) 7 | */ 8 | ALPHANUMERIC(1000), 9 | /** 10 | * 1位英文数字 7题分 11 | */ 12 | ALPHANUMERIC1(1001), 13 | /** 14 | * 2位英文数字 8题分 15 | */ 16 | ALPHANUMERIC2(1002), 17 | /** 18 | * 3位英文数字 9题分 19 | */ 20 | ALPHANUMERIC3(1003), 21 | /** 22 | * 4位英文数字 10题分 23 | */ 24 | ALPHANUMERIC4(1004), 25 | /** 26 | * 5位英文数字 12题分 27 | */ 28 | ALPHANUMERIC5(1005), 29 | /** 30 | * 6位英文数字 15题分 31 | */ 32 | ALPHANUMERIC6(1006), 33 | /** 34 | * 7位英文数字 17题分 35 | */ 36 | ALPHANUMERIC7(1007), 37 | /** 38 | * 8位英文数字 20题分 39 | */ 40 | ALPHANUMERIC8(1008), 41 | /** 42 | * 9位英文数字 22题分 43 | */ 44 | ALPHANUMERIC9(1009), 45 | /** 46 | * 10位英文数字 25题分 47 | */ 48 | ALPHANUMERIC10(1010), 49 | /** 50 | * 11位英文数字 27题分 51 | */ 52 | ALPHANUMERIC11(1011), 53 | /** 54 | * 12位英文数字 30题分 55 | */ 56 | ALPHANUMERIC12(1012), 57 | /** 58 | * 13位英文数字 32题分 59 | */ 60 | ALPHANUMERIC13(1013), 61 | /** 62 | * 14位英文数字 35题分 63 | */ 64 | ALPHANUMERIC14(1014), 65 | /** 66 | * 15位英文数字 37题分 67 | */ 68 | ALPHANUMERIC15(1015), 69 | /** 70 | * 16位英文数字 40题分 71 | */ 72 | ALPHANUMERIC16(1016), 73 | /** 74 | * 17位英文数字 42题分 75 | */ 76 | ALPHANUMERIC17(1017), 77 | /** 78 | * 18位英文数字 45题分 79 | */ 80 | ALPHANUMERIC18(1018), 81 | /** 82 | * 19位英文数字 47题分 83 | */ 84 | ALPHANUMERIC19(1019), 85 | /** 86 | * 20位英文数字 50题分 87 | */ 88 | ALPHANUMERIC20(1020), 89 | /** 90 | * 2位纯汉字 20题分 91 | */ 92 | CHINESE2(2002), 93 | /** 94 | * 4位纯汉字 40题分 95 | */ 96 | CHINESE4(2004), 97 | /** 98 | * 4位纯英文 10题分 99 | */ 100 | ALPHABETIC4(3004), 101 | /** 102 | * 5位纯英文 12题分 103 | */ 104 | ALPHABETIC5(3005), 105 | /** 106 | * 6位纯英文 15题分 107 | */ 108 | ALPHABETIC6(3006), 109 | /** 110 | * 4位纯数字 10题分 111 | */ 112 | NUMERIC4(4004), 113 | /** 114 | * 5位纯数字 12题分 115 | */ 116 | NUMERIC5(4005); 117 | 118 | Integer type; 119 | 120 | YundamaType(Integer type) { 121 | this.type = type; 122 | } 123 | 124 | public Integer getType() { 125 | return type; 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/exception/SocialException.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.exception; 2 | 3 | public class SocialException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 3536584215181288508L; 6 | 7 | public SocialException(Exception exception) { 8 | super(exception); 9 | } 10 | 11 | public SocialException(String message) { 12 | super(message); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/http/HttpException.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.http; 2 | 3 | 4 | 5 | public class HttpException extends Exception { 6 | 7 | private static final long serialVersionUID = -7528165403129614352L; 8 | 9 | public HttpException(Exception exception) { 10 | super(exception); 11 | } 12 | 13 | public HttpException(String message) { 14 | super(message); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/mail/api/POP3.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.mail.api; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.io.Reader; 7 | import java.net.SocketException; 8 | 9 | import org.apache.commons.io.FileUtils; 10 | import org.apache.commons.io.IOUtils; 11 | import org.apache.commons.net.pop3.POP3Client; 12 | import org.apache.commons.net.pop3.POP3MessageInfo; 13 | import org.apache.commons.net.pop3.POP3SClient; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | 17 | import com.belerweb.social.exception.SocialException; 18 | 19 | /** 20 | * POP3 邮件工具 21 | */ 22 | public class POP3 { 23 | 24 | private static final Logger LOGGER = LoggerFactory.getLogger(POP3.class); 25 | 26 | private String username; 27 | private String password; 28 | private String host; 29 | private int port; 30 | 31 | private POP3Client client; 32 | 33 | public POP3(String username, String password, String host) { 34 | this(username, password, host, org.apache.commons.net.pop3.POP3.DEFAULT_PORT, false); 35 | } 36 | 37 | public POP3(String username, String password, String host, int port, boolean ssl) { 38 | this.username = username; 39 | this.password = password; 40 | this.host = host; 41 | this.port = port; 42 | if (ssl) { 43 | this.client = new POP3SClient("SSL", true); 44 | } else { 45 | this.client = new POP3Client(); 46 | } 47 | this.client.setDefaultTimeout(300000); 48 | } 49 | 50 | private boolean login() throws SocketException, IOException { 51 | client.connect(host, port); 52 | return client.login(username, password); 53 | } 54 | 55 | /** 56 | * 检查用户信息是否正确 57 | */ 58 | public boolean test() throws SocialException { 59 | try { 60 | return login(); 61 | } catch (SocketException e) { 62 | e.printStackTrace(); 63 | throw new SocialException(e); 64 | } catch (IOException e) { 65 | e.printStackTrace(); 66 | throw new SocialException(e); 67 | } finally { 68 | try { 69 | this.client.disconnect(); 70 | } catch (IOException e) { 71 | e.printStackTrace(); 72 | } 73 | } 74 | } 75 | 76 | /** 77 | * 下载所有电子邮件到指定目录 78 | */ 79 | public void download(File dir) throws SocialException { 80 | if (!dir.isDirectory() || !dir.canWrite()) { 81 | throw new SocialException("The specified directory is unavailable."); 82 | } 83 | 84 | try { 85 | if (login()) { 86 | POP3MessageInfo[] messages = client.listUniqueIdentifiers(); 87 | if (messages == null) { 88 | LOGGER.debug("Could not retrieve message list."); 89 | throw new SocialException("Could not retrieve message list."); 90 | 91 | } else { 92 | for (POP3MessageInfo message : messages) { 93 | File eml = new File(dir, username + "@" + host + "/" + message.identifier + ".eml"); 94 | try { 95 | Reader reader = client.retrieveMessage(message.number); 96 | if (reader == null) { 97 | LOGGER.debug("Could not retrieve message."); 98 | continue; 99 | } 100 | if (eml.exists() 101 | && ((message.size > 0 && eml.length() == message.size) || eml.length() > 1000)) { 102 | LOGGER.debug("Message {} exist, skip download.", message.identifier); 103 | continue; 104 | } 105 | eml.getParentFile().mkdirs(); 106 | LOGGER.debug("Downloading {} ...", message.identifier); 107 | IOUtils.copy(reader, new FileOutputStream(eml));; 108 | LOGGER.debug("Downloaded {} ...", message.identifier); 109 | } catch (Exception e) { 110 | try { 111 | FileUtils.forceDelete(eml); 112 | } catch (Exception exception) { 113 | e.printStackTrace(); 114 | } 115 | } 116 | } 117 | } 118 | } 119 | } catch (SocketException e) { 120 | e.printStackTrace(); 121 | } catch (IOException e) { 122 | e.printStackTrace(); 123 | } finally { 124 | try { 125 | client.disconnect(); 126 | } catch (IOException e) { 127 | e.printStackTrace(); 128 | } 129 | } 130 | 131 | } 132 | 133 | /** 134 | * 下载所有电子邮件到指定目录 135 | */ 136 | public void download(String dir) { 137 | download(new File(dir)); 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/api/User.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.api; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.http.NameValuePair; 7 | 8 | import com.belerweb.social.API; 9 | import com.belerweb.social.bean.Result; 10 | 11 | /** 12 | * 访问用户资料 13 | */ 14 | public final class User extends API { 15 | 16 | protected User(QQConnect connect) { 17 | super(connect); 18 | } 19 | 20 | /** 21 | * 获取登录用户在QQ空间的信息,包括昵称、头像、性别及黄钻信息(包括黄钻等级、是否年费黄钻等)。此接口仅支持网站调用 22 | * 23 | * 文档地址:http://wiki.connect.qq.com/get_user_info 24 | * 25 | * @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。 26 | * @param openid 用户的ID,与QQ号码一一对应。 27 | * 可通过调用https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN 来获取。 28 | */ 29 | public Result getUserInfo(String accessToken, 30 | String openid) { 31 | return getUserInfo(accessToken, connect.getClientId(), openid); 32 | } 33 | 34 | /** 35 | * 获取登录用户在QQ空间的信息,包括昵称、头像、性别及黄钻信息(包括黄钻等级、是否年费黄钻等)。此接口仅支持网站调用 36 | * 37 | * 文档地址:http://wiki.connect.qq.com/get_user_info 38 | * 39 | * @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。 40 | * @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid 41 | * @param openid 用户的ID,与QQ号码一一对应。 42 | * 可通过调用https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN 来获取。 43 | */ 44 | public Result getUserInfo(String accessToken, 45 | String oAuthConsumerKey, String openid) { 46 | List params = new ArrayList(); 47 | connect.addParameter(params, "access_token", accessToken); 48 | connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey); 49 | connect.addParameter(params, "openid", openid); 50 | connect.addNotNullParameter(params, "format", "json"); 51 | String json = connect.get("https://graph.qq.com/user/get_user_info", params); 52 | return Result.parse(json, com.belerweb.social.qq.connect.bean.User.class); 53 | } 54 | 55 | /** 56 | * 获取移动端应用的登录用户在QQ空间的简单个人信息,包括昵称、头像和黄钻信息(包括黄钻等级、是否年费黄钻等),以及用户的QQ头像。 此接口仅支持移动端应用调用 57 | * 58 | * 文档地址:http://wiki.connect.qq.com/get_simple_userinfo 59 | * 60 | * @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。 61 | * @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid 62 | * @param openid 用户的ID,与QQ号码一一对应。 63 | * 可通过调用https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN 来获取。 64 | */ 65 | public Result getSimpleUserInfo(String accessToken, 66 | String oAuthConsumerKey, String openid) { 67 | List params = new ArrayList(); 68 | connect.addParameter(params, "access_token", accessToken); 69 | connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey); 70 | connect.addParameter(params, "openid", openid); 71 | connect.addNotNullParameter(params, "format", "json"); 72 | String json = connect.get("https://openmobile.qq.com/user/get_simple_userinfo", params); 73 | return Result.parse(json, com.belerweb.social.qq.connect.bean.User.class); 74 | } 75 | 76 | /** 77 | * 获取已登录用户的关于QQ会员业务的基本资料。 78 | * 79 | * 基本资料包括以下信息:是否为“普通包月会员”,是否为“年费会员”,QQ会员等级信息,是否为“豪华版QQ会员”,是否为“钻皇会员”,是否为“SVIP”。 80 | * 81 | * 文档地址:http://wiki.connect.qq.com/get_vip_info 82 | * 83 | * @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。 84 | * @param openid 用户的ID,与QQ号码一一对应。 85 | */ 86 | public Result getVipInfo(String accessToken, 87 | String openid) { 88 | return getVipInfo(accessToken, connect.getClientId(), openid); 89 | } 90 | 91 | /** 92 | * 获取已登录用户的关于QQ会员业务的基本资料。 93 | * 94 | * 基本资料包括以下信息:是否为“普通包月会员”,是否为“年费会员”,QQ会员等级信息,是否为“豪华版QQ会员”,是否为“钻皇会员”,是否为“SVIP”。 95 | * 96 | * 文档地址:http://wiki.connect.qq.com/get_vip_info 97 | * 98 | * @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。 99 | * @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid 100 | * @param openid 用户的ID,与QQ号码一一对应。 101 | */ 102 | public Result getVipInfo(String accessToken, 103 | String oAuthConsumerKey, String openid) { 104 | List params = new ArrayList(); 105 | connect.addParameter(params, "access_token", accessToken); 106 | connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey); 107 | connect.addParameter(params, "openid", openid); 108 | connect.addParameter(params, "format", "json"); 109 | String json = connect.get("https://graph.qq.com/user/get_vip_info", params); 110 | return Result.parse(json, com.belerweb.social.qq.connect.bean.User.class); 111 | } 112 | 113 | /** 114 | * 获取已登录用户的关于QQ会员业务的详细资料。 115 | * 116 | * 详细资料包括:用户会员的历史属性,用户会员特权的到期时间,用户最后一次充值会员业务的支付渠道,用户开通会员的主要驱动因素。 117 | * 118 | * 文档地址:http://wiki.connect.qq.com/get_vip_rich_info 119 | * 120 | * @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。 121 | * @param openid 用户的ID,与QQ号码一一对应。 122 | */ 123 | public Result getVipRichInfo(String accessToken, 124 | String openid) { 125 | return getVipRichInfo(connect.getClientId(), accessToken, openid); 126 | } 127 | 128 | /** 129 | * 获取已登录用户的关于QQ会员业务的详细资料。 130 | * 131 | * 详细资料包括:用户会员的历史属性,用户会员特权的到期时间,用户最后一次充值会员业务的支付渠道,用户开通会员的主要驱动因素。 132 | * 133 | * 文档地址:http://wiki.connect.qq.com/get_vip_rich_info 134 | * 135 | * @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid 136 | * @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。 137 | * @param openid 用户的ID,与QQ号码一一对应。 138 | */ 139 | public Result getVipRichInfo(String oAuthConsumerKey, 140 | String accessToken, String openid) { 141 | List params = new ArrayList(); 142 | connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey); 143 | connect.addParameter(params, "access_token", accessToken); 144 | connect.addParameter(params, "openid", openid); 145 | connect.addParameter(params, "format", "json"); 146 | String json = connect.get("https://graph.qq.com/user/get_vip_rich_info", params); 147 | return Result.parse(json, com.belerweb.social.qq.connect.bean.User.class); 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/AccessToken.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class AccessToken extends JsonBean { 9 | 10 | public AccessToken() {} 11 | 12 | private AccessToken(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String token;// 授权令牌,Access_Token。 17 | private Long expiresIn;// 该access token的有效期,单位为秒。 18 | private String refreshToken;// 在授权自动续期步骤中,获取新的Access_Token时需要提供的参数。 19 | 20 | /** 21 | * 授权令牌,Access_Token。 22 | */ 23 | public String getToken() { 24 | return token; 25 | } 26 | 27 | public void setToken(String token) { 28 | this.token = token; 29 | } 30 | 31 | 32 | /** 33 | * 该access token的有效期,单位为秒。 34 | */ 35 | public Long getExpiresIn() { 36 | return expiresIn; 37 | } 38 | 39 | public void setExpiresIn(Long expiresIn) { 40 | this.expiresIn = expiresIn; 41 | } 42 | 43 | /** 44 | * 在授权自动续期步骤中,获取新的Access_Token时需要提供的参数。 45 | */ 46 | public String getRefreshToken() { 47 | return refreshToken; 48 | } 49 | 50 | public void setRefreshToken(String refreshToken) { 51 | this.refreshToken = refreshToken; 52 | } 53 | 54 | public static AccessToken parse(JSONObject jsonObject) { 55 | if (jsonObject == null) { 56 | return null; 57 | } 58 | AccessToken obj = new AccessToken(jsonObject); 59 | obj.token = jsonObject.getString("access_token"); 60 | obj.expiresIn = Result.parseLong(jsonObject.opt("expires_in")); 61 | obj.refreshToken = Result.toString(jsonObject.opt("refresh_token")); 62 | return obj; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Album.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import java.util.Date; 4 | 5 | import org.json.JSONObject; 6 | 7 | import com.belerweb.social.bean.JsonBean; 8 | import com.belerweb.social.bean.Result; 9 | 10 | public class Album extends JsonBean { 11 | 12 | public Album() {} 13 | 14 | private Album(JSONObject jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | private String albumId; 19 | private String classId; 20 | private Date createTime; 21 | private String name; 22 | private String description; 23 | private String cover; 24 | private Integer picNum; 25 | 26 | public String getAlbumId() { 27 | return albumId; 28 | } 29 | 30 | public void setAlbumId(String albumId) { 31 | this.albumId = albumId; 32 | } 33 | 34 | public String getClassId() { 35 | return classId; 36 | } 37 | 38 | public void setClassId(String classId) { 39 | this.classId = classId; 40 | } 41 | 42 | public Date getCreateTime() { 43 | return createTime; 44 | } 45 | 46 | public void setCreateTime(Date createTime) { 47 | this.createTime = createTime; 48 | } 49 | 50 | public String getName() { 51 | return name; 52 | } 53 | 54 | public void setName(String name) { 55 | this.name = name; 56 | } 57 | 58 | public String getDescription() { 59 | return description; 60 | } 61 | 62 | public void setDescription(String description) { 63 | this.description = description; 64 | } 65 | 66 | public String getCover() { 67 | return cover; 68 | } 69 | 70 | public void setCover(String cover) { 71 | this.cover = cover; 72 | } 73 | 74 | public Integer getPicNum() { 75 | return picNum; 76 | } 77 | 78 | public void setPicNum(Integer picNum) { 79 | this.picNum = picNum; 80 | } 81 | 82 | public static Album parse(JSONObject jsonObject) { 83 | if (jsonObject == null) { 84 | return null; 85 | } 86 | Album obj = new Album(jsonObject); 87 | obj.albumId = Result.toString(jsonObject.get("albumid")); 88 | obj.classId = Result.toString(jsonObject.opt("classid")); 89 | obj.createTime = Result.parseTimeSeconds(jsonObject.opt("createtime")); 90 | obj.name = Result.toString(jsonObject.opt("name")); 91 | obj.description = Result.toString(jsonObject.opt("desc")); 92 | obj.cover = Result.toString(jsonObject.opt("coverurl")); 93 | obj.picNum = Result.parseInteger(jsonObject.opt("picnum")); 94 | return obj; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/AlbumPrivilege.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | public enum AlbumPrivilege { 4 | PUBLIC(1), PRIVATE(3), FRIEND(4), QUESTION(5); 5 | 6 | private Integer value; 7 | 8 | private AlbumPrivilege(Integer value) { 9 | this.value = value; 10 | } 11 | 12 | public Integer value() { 13 | return value; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return value.toString(); 19 | } 20 | 21 | public static AlbumPrivilege parse(Integer value) { 22 | if (value == null) { 23 | return null; 24 | } 25 | if (value == 1) { 26 | return PUBLIC; 27 | } 28 | if (value == 3) { 29 | return PRIVATE; 30 | } 31 | if (value == 4) { 32 | return FRIEND; 33 | } 34 | if (value == 5) { 35 | return QUESTION; 36 | } 37 | return null; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Company.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class Company extends JsonBean { 9 | 10 | public Company() {} 11 | 12 | private Company(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String id;// 公司id。 17 | private String companyName;// 公司名称。 18 | private String departmentName;// 部门名称。 19 | private Integer beginYear;// 开始年。 20 | private Integer endYear;// 结束年。 21 | 22 | public String getId() { 23 | return id; 24 | } 25 | 26 | public void setId(String id) { 27 | this.id = id; 28 | } 29 | 30 | public String getCompanyName() { 31 | return companyName; 32 | } 33 | 34 | public void setCompanyName(String companyName) { 35 | this.companyName = companyName; 36 | } 37 | 38 | public String getDepartmentName() { 39 | return departmentName; 40 | } 41 | 42 | public void setDepartmentName(String departmentName) { 43 | this.departmentName = departmentName; 44 | } 45 | 46 | public Integer getBeginYear() { 47 | return beginYear; 48 | } 49 | 50 | public void setBeginYear(Integer beginYear) { 51 | this.beginYear = beginYear; 52 | } 53 | 54 | public Integer getEndYear() { 55 | return endYear; 56 | } 57 | 58 | public void setEndYear(Integer endYear) { 59 | this.endYear = endYear; 60 | } 61 | 62 | public static Company parse(JSONObject jsonObject) { 63 | if (jsonObject == null) { 64 | return null; 65 | } 66 | Company obj = new Company(jsonObject); 67 | obj.id = Result.toString(jsonObject.get("id")); 68 | obj.companyName = Result.toString(jsonObject.opt("company_name")); 69 | obj.departmentName = Result.toString(jsonObject.opt("department_name")); 70 | obj.beginYear = Result.parseInteger(jsonObject.opt("begin_year")); 71 | obj.endYear = Result.parseInteger(jsonObject.opt("end_year")); 72 | return obj; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Display.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | public enum Display { 4 | 5 | DEFAULT, 6 | 7 | MOBILE; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Education.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class Education extends JsonBean { 9 | 10 | public Education() {} 11 | 12 | private Education(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String id;// 教育信息记录ID。 17 | private Integer year;// 入学年。 18 | private String schoolId;// 学校ID。学校ID与学校具体信息的对应关系请参见教育信息数据库。 19 | private String departmentId;// 院系ID。院系ID与院系具体信息的对应关系请参见教育信息数据库。 20 | private Integer level;// 学历级别。 21 | 22 | public String getId() { 23 | return id; 24 | } 25 | 26 | public void setId(String id) { 27 | this.id = id; 28 | } 29 | 30 | public Integer getYear() { 31 | return year; 32 | } 33 | 34 | public void setYear(Integer year) { 35 | this.year = year; 36 | } 37 | 38 | public String getSchoolId() { 39 | return schoolId; 40 | } 41 | 42 | public void setSchoolId(String schoolId) { 43 | this.schoolId = schoolId; 44 | } 45 | 46 | public String getDepartmentId() { 47 | return departmentId; 48 | } 49 | 50 | public void setDepartmentId(String departmentId) { 51 | this.departmentId = departmentId; 52 | } 53 | 54 | public Integer getLevel() { 55 | return level; 56 | } 57 | 58 | public void setLevel(Integer level) { 59 | this.level = level; 60 | } 61 | 62 | public static Education parse(JSONObject jsonObject) { 63 | if (jsonObject == null) { 64 | return null; 65 | } 66 | Education obj = new Education(jsonObject); 67 | obj.id = Result.toString(jsonObject.get("id")); 68 | obj.schoolId = Result.toString(jsonObject.opt("company_name")); 69 | obj.departmentId = Result.toString(jsonObject.opt("department_name")); 70 | obj.year = Result.parseInteger(jsonObject.opt("begin_year")); 71 | obj.level = Result.parseInteger(jsonObject.opt("end_year")); 72 | return obj; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/FanList.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | import org.json.JSONObject; 7 | 8 | import com.belerweb.social.bean.JsonBean; 9 | import com.belerweb.social.bean.Result; 10 | 11 | public class FanList extends JsonBean { 12 | 13 | public FanList() {} 14 | 15 | private FanList(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private Date timestamp; 20 | private Boolean hasNext; 21 | private List fans; 22 | 23 | public Date getTimestamp() { 24 | return timestamp; 25 | } 26 | 27 | public void setTimestamp(Date timestamp) { 28 | this.timestamp = timestamp; 29 | } 30 | 31 | public Boolean getHasNext() { 32 | return hasNext; 33 | } 34 | 35 | public void setHasNext(Boolean hasNext) { 36 | this.hasNext = hasNext; 37 | } 38 | 39 | public List getFans() { 40 | return fans; 41 | } 42 | 43 | public void setFans(List fans) { 44 | this.fans = fans; 45 | } 46 | 47 | public static FanList parse(JSONObject jsonObject) { 48 | if (jsonObject == null) { 49 | return null; 50 | } 51 | FanList obj = new FanList(jsonObject); 52 | obj.timestamp = Result.parseTimeSeconds(jsonObject.get("timestamp")); 53 | obj.hasNext = Result.parseBoolean(jsonObject.get("hasnext")); 54 | obj.fans = Result.parse(jsonObject.optJSONArray("info"), WeiboUser.class); 55 | return obj; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Gut.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | /** 4 | * QQ登录页面版本 5 | */ 6 | public enum Gut { 7 | 8 | WML(1), 9 | 10 | XHTML(2); 11 | 12 | private int value; 13 | 14 | private Gut(int value) { 15 | this.value = value; 16 | } 17 | 18 | public int value() { 19 | return value; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return String.valueOf(value); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/IdolList.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | import org.json.JSONObject; 7 | 8 | import com.belerweb.social.bean.JsonBean; 9 | import com.belerweb.social.bean.Result; 10 | 11 | public class IdolList extends JsonBean { 12 | 13 | public IdolList() {} 14 | 15 | private IdolList(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private Date timestamp; 20 | private Boolean hasNext; 21 | private List fans; 22 | 23 | public Date getTimestamp() { 24 | return timestamp; 25 | } 26 | 27 | public void setTimestamp(Date timestamp) { 28 | this.timestamp = timestamp; 29 | } 30 | 31 | public Boolean getHasNext() { 32 | return hasNext; 33 | } 34 | 35 | public void setHasNext(Boolean hasNext) { 36 | this.hasNext = hasNext; 37 | } 38 | 39 | public List getFans() { 40 | return fans; 41 | } 42 | 43 | public void setFans(List fans) { 44 | this.fans = fans; 45 | } 46 | 47 | public static IdolList parse(JSONObject jsonObject) { 48 | if (jsonObject == null) { 49 | return null; 50 | } 51 | IdolList obj = new IdolList(jsonObject); 52 | obj.timestamp = Result.parseTimeSeconds(jsonObject.get("timestamp")); 53 | obj.hasNext = Result.parseBoolean(jsonObject.get("hasnext")); 54 | obj.fans = Result.parse(jsonObject.optJSONArray("info"), WeiboUser.class); 55 | return obj; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Image.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class Image extends JsonBean { 9 | 10 | public Image() {} 11 | 12 | private Image(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String url; 17 | private Integer width; 18 | private Integer height; 19 | 20 | public String getUrl() { 21 | return url; 22 | } 23 | 24 | public void setUrl(String url) { 25 | this.url = url; 26 | } 27 | 28 | public Integer getWidth() { 29 | return width; 30 | } 31 | 32 | public void setWidth(Integer width) { 33 | this.width = width; 34 | } 35 | 36 | public Integer getHeight() { 37 | return height; 38 | } 39 | 40 | public void setHeight(Integer height) { 41 | this.height = height; 42 | } 43 | 44 | public static Image parse(JSONObject jsonObject) { 45 | if (jsonObject == null) { 46 | return null; 47 | } 48 | Image obj = new Image(jsonObject); 49 | obj.url = Result.toString(jsonObject.opt("url")); 50 | obj.width = Result.parseInteger(jsonObject.opt("width")); 51 | obj.height = Result.parseInteger(jsonObject.opt("height")); 52 | return obj; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Music.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class Music extends JsonBean { 9 | 10 | public Music() {} 11 | 12 | private Music(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String author;// 演唱者。 17 | private String url;// 音频地址。 18 | private String title;// 音频名字,歌名。 19 | 20 | 21 | public String getAuthor() { 22 | return author; 23 | } 24 | 25 | public void setAuthor(String author) { 26 | this.author = author; 27 | } 28 | 29 | public String getUrl() { 30 | return url; 31 | } 32 | 33 | public void setUrl(String url) { 34 | this.url = url; 35 | } 36 | 37 | public String getTitle() { 38 | return title; 39 | } 40 | 41 | public void setTitle(String title) { 42 | this.title = title; 43 | } 44 | 45 | public static Music parse(JSONObject jsonObject) { 46 | if (jsonObject == null) { 47 | return null; 48 | } 49 | Music obj = new Music(jsonObject); 50 | obj.author = Result.toString(jsonObject.opt("author")); 51 | obj.url = Result.toString(jsonObject.opt("url")); 52 | obj.title = Result.toString(jsonObject.opt("title")); 53 | return obj; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/NewT.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import java.util.Date; 4 | 5 | import org.json.JSONObject; 6 | 7 | import com.belerweb.social.bean.JsonBean; 8 | import com.belerweb.social.bean.Result; 9 | 10 | /** 11 | * 新发布的微博的返回信息 12 | */ 13 | public class NewT extends JsonBean { 14 | 15 | public NewT() {} 16 | 17 | private NewT(JSONObject jsonObject) { 18 | super(jsonObject); 19 | } 20 | 21 | private Long id;// 微博的ID,用来唯一标识一条微博。 22 | private Date time;// 微博的发表时间。 23 | private String imgUrl;// 图片分享后的url地址。 24 | 25 | public Long getId() { 26 | return id; 27 | } 28 | 29 | public void setId(Long id) { 30 | this.id = id; 31 | } 32 | 33 | public Date getTime() { 34 | return time; 35 | } 36 | 37 | public void setTime(Date time) { 38 | this.time = time; 39 | } 40 | 41 | public String getImgUrl() { 42 | return imgUrl; 43 | } 44 | 45 | public void setImgUrl(String imgUrl) { 46 | this.imgUrl = imgUrl; 47 | } 48 | 49 | public static NewT parse(JSONObject jsonObject) { 50 | if (jsonObject == null) { 51 | return null; 52 | } 53 | NewT obj = new NewT(jsonObject); 54 | obj.id = Result.parseLong(jsonObject.get("id")); 55 | obj.time = new Date(Result.parseLong(jsonObject.get("time")) * 1000); 56 | obj.imgUrl = jsonObject.optString("imgurl"); 57 | return obj; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/OpenID.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | 7 | public class OpenID extends JsonBean { 8 | 9 | public OpenID() {} 10 | 11 | private OpenID(JSONObject jsonObject) { 12 | super(jsonObject); 13 | } 14 | 15 | private String clientId; 16 | private String openId; // openid是此网站上唯一对应用户身份的标识,网站可将此ID进行存储便于用户下次登录时辨识其身份,或将其与用户在网站上的原有账号进行绑定。 17 | 18 | /** 19 | * openid是此网站上唯一对应用户身份的标识,网站可将此ID进行存储便于用户下次登录时辨识其身份,或将其与用户在网站上的原有账号进行绑定。 20 | */ 21 | public String getClientId() { 22 | return clientId; 23 | } 24 | 25 | public void setClientId(String clientId) { 26 | this.clientId = clientId; 27 | } 28 | 29 | public String getOpenId() { 30 | return openId; 31 | } 32 | 33 | public void setOpenId(String openId) { 34 | this.openId = openId; 35 | } 36 | 37 | public static OpenID parse(JSONObject jsonObject) { 38 | if (jsonObject == null) { 39 | return null; 40 | } 41 | OpenID obj = new OpenID(jsonObject); 42 | obj.clientId = jsonObject.getString("client_id"); 43 | obj.openId = jsonObject.getString("openid"); 44 | return obj; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Photo.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import java.util.Date; 4 | import java.util.Locale; 5 | 6 | import org.json.JSONObject; 7 | 8 | import com.belerweb.social.bean.JsonBean; 9 | import com.belerweb.social.bean.Result; 10 | 11 | public class Photo extends JsonBean { 12 | 13 | public Photo() {} 14 | 15 | private Photo(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private String sLoc; 20 | private String lLoc; 21 | private String name; 22 | private String description; 23 | private Date updatedTime; 24 | private Date uploadedTime; 25 | private String smallUrl; 26 | private Image largeImage; 27 | 28 | public String getsLoc() { 29 | return sLoc; 30 | } 31 | 32 | public void setsLoc(String sLoc) { 33 | this.sLoc = sLoc; 34 | } 35 | 36 | public String getlLoc() { 37 | return lLoc; 38 | } 39 | 40 | public void setlLoc(String lLoc) { 41 | this.lLoc = lLoc; 42 | } 43 | 44 | public String getName() { 45 | return name; 46 | } 47 | 48 | public void setName(String name) { 49 | this.name = name; 50 | } 51 | 52 | public String getDescription() { 53 | return description; 54 | } 55 | 56 | public void setDescription(String description) { 57 | this.description = description; 58 | } 59 | 60 | public Date getUpdatedTime() { 61 | return updatedTime; 62 | } 63 | 64 | public void setUpdatedTime(Date updatedTime) { 65 | this.updatedTime = updatedTime; 66 | } 67 | 68 | public Date getUploadedTime() { 69 | return uploadedTime; 70 | } 71 | 72 | public void setUploadedTime(Date uploadedTime) { 73 | this.uploadedTime = uploadedTime; 74 | } 75 | 76 | public String getSmallUrl() { 77 | return smallUrl; 78 | } 79 | 80 | public void setSmallUrl(String smallUrl) { 81 | this.smallUrl = smallUrl; 82 | } 83 | 84 | public Image getLargeImage() { 85 | return largeImage; 86 | } 87 | 88 | public void setLargeImage(Image largeImage) { 89 | this.largeImage = largeImage; 90 | } 91 | 92 | public static Photo parse(JSONObject jsonObject) { 93 | if (jsonObject == null) { 94 | return null; 95 | } 96 | Photo obj = new Photo(jsonObject); 97 | obj.sLoc = Result.toString(jsonObject.opt("sloc")); 98 | obj.lLoc = Result.toString(jsonObject.opt("lloc")); 99 | obj.name = Result.toString(jsonObject.opt("name")); 100 | obj.description = Result.toString(jsonObject.opt("desc")); 101 | obj.updatedTime = Result.parseTimeSeconds(jsonObject.opt("updated_time")); 102 | obj.uploadedTime = 103 | Result.parseDate(jsonObject.opt("uploaded_time"), "yyyy-MM-dd HH:mm:ss", Locale.CHINA); 104 | obj.smallUrl = Result.toString(jsonObject.opt("small_url")); 105 | obj.largeImage = Image.parse(jsonObject.optJSONObject("large_image")); 106 | return obj; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/PicUploadResult.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class PicUploadResult extends JsonBean { 9 | 10 | public PicUploadResult() {} 11 | 12 | private PicUploadResult(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String albumId; 17 | private String lLoc; 18 | private String sLoc; 19 | private String largeUrl; 20 | private String smallUrl; 21 | private Integer width; 22 | private Integer height; 23 | 24 | public String getAlbumId() { 25 | return albumId; 26 | } 27 | 28 | public void setAlbumId(String albumId) { 29 | this.albumId = albumId; 30 | } 31 | 32 | public String getlLoc() { 33 | return lLoc; 34 | } 35 | 36 | public void setlLoc(String lLoc) { 37 | this.lLoc = lLoc; 38 | } 39 | 40 | public String getsLoc() { 41 | return sLoc; 42 | } 43 | 44 | public void setsLoc(String sLoc) { 45 | this.sLoc = sLoc; 46 | } 47 | 48 | public String getLargeUrl() { 49 | return largeUrl; 50 | } 51 | 52 | public void setLargeUrl(String largeUrl) { 53 | this.largeUrl = largeUrl; 54 | } 55 | 56 | public String getSmallUrl() { 57 | return smallUrl; 58 | } 59 | 60 | public void setSmallUrl(String smallUrl) { 61 | this.smallUrl = smallUrl; 62 | } 63 | 64 | public Integer getWidth() { 65 | return width; 66 | } 67 | 68 | public void setWidth(Integer width) { 69 | this.width = width; 70 | } 71 | 72 | public Integer getHeight() { 73 | return height; 74 | } 75 | 76 | public void setHeight(Integer height) { 77 | this.height = height; 78 | } 79 | 80 | public static PicUploadResult parse(JSONObject jsonObject) { 81 | if (jsonObject == null) { 82 | return null; 83 | } 84 | PicUploadResult obj = new PicUploadResult(jsonObject); 85 | obj.albumId = Result.toString(jsonObject.opt("albumid")); 86 | obj.lLoc = Result.toString(jsonObject.opt("lloc")); 87 | obj.sLoc = Result.toString(jsonObject.opt("sloc")); 88 | obj.largeUrl = Result.toString(jsonObject.opt("large_url")); 89 | obj.smallUrl = Result.toString(jsonObject.opt("small_url")); 90 | obj.width = Result.parseInteger(jsonObject.opt("width")); 91 | obj.height = Result.parseInteger(jsonObject.opt("height")); 92 | return obj; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/RepostList.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import java.util.Date; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import org.json.JSONObject; 10 | 11 | import com.belerweb.social.bean.JsonBean; 12 | import com.belerweb.social.bean.Result; 13 | 14 | public class RepostList extends JsonBean { 15 | 16 | public RepostList() {} 17 | 18 | private RepostList(JSONObject jsonObject) { 19 | super(jsonObject); 20 | } 21 | 22 | private Date timestamp; 23 | private Boolean hasNext; 24 | private Integer totalNum; 25 | private List tweets; 26 | private Map nameNickMap = new HashMap(); 27 | 28 | public Date getTimestamp() { 29 | return timestamp; 30 | } 31 | 32 | public void setTimestamp(Date timestamp) { 33 | this.timestamp = timestamp; 34 | } 35 | 36 | public Boolean getHasNext() { 37 | return hasNext; 38 | } 39 | 40 | public void setHasNext(Boolean hasNext) { 41 | this.hasNext = hasNext; 42 | } 43 | 44 | public Integer getTotalNum() { 45 | return totalNum; 46 | } 47 | 48 | public void setTotalNum(Integer totalNum) { 49 | this.totalNum = totalNum; 50 | } 51 | 52 | public List getTweets() { 53 | return tweets; 54 | } 55 | 56 | public void setTweets(List tweets) { 57 | this.tweets = tweets; 58 | } 59 | 60 | public static RepostList parse(JSONObject jsonObject) { 61 | if (jsonObject == null) { 62 | return null; 63 | } 64 | RepostList obj = new RepostList(jsonObject); 65 | obj.timestamp = Result.parseTimeSeconds(jsonObject.get("timestamp")); 66 | obj.hasNext = Result.parseBoolean(jsonObject.get("hasnext")); 67 | obj.totalNum = Result.parseInteger(jsonObject.get("totalnum")); 68 | obj.tweets = Result.parse(jsonObject.optJSONArray("info"), TweetInfo.class); 69 | JSONObject map = jsonObject.optJSONObject("user"); 70 | if (map != null) { 71 | Iterator keys = map.keys(); 72 | while (keys.hasNext()) { 73 | String key = keys.next().toString(); 74 | obj.nameNickMap.put(key, map.get(key).toString()); 75 | } 76 | } 77 | return obj; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Scope.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | /** 4 | * 请求用户授权时向用户显示的可进行授权的列表。 5 | */ 6 | public enum Scope { 7 | 8 | /** 9 | * do_like 10 | */ 11 | DO_LIKE("do_like"), 12 | 13 | /** 14 | * 获取登录用户的昵称、头像、性别 15 | */ 16 | GET_USER_INFO("get_user_info"), 17 | 18 | /** 19 | * 获取登录用户的昵称、头像、性别 20 | */ 21 | GET_SIMPLE_USERINFO("get_simple_userinfo"), 22 | 23 | /** 24 | * 获取QQ会员的基本信息 25 | */ 26 | GET_VIP_INFO("get_vip_info"), 27 | 28 | /** 29 | * 获取QQ会员的高级信息 30 | */ 31 | GET_VIP_RICH_INFO("get_vip_rich_info"), 32 | 33 | /** 34 | * 发表日志到QQ空间 35 | */ 36 | ADD_ONE_BLOG("add_one_blog"), 37 | 38 | /** 39 | * 获取用户QQ空间相册列表 40 | */ 41 | LIST_ALBUM("list_album"), 42 | 43 | /** 44 | * 上传一张照片到QQ空间相册 45 | */ 46 | UPLOAD_PIC("upload_pic"), 47 | 48 | /** 49 | * 在用户的空间相册里,创建一个新的个人相册 50 | */ 51 | ADD_ALBUM("add_album"), 52 | 53 | /** 54 | * 获取用户QQ空间相册中的照片列表 55 | */ 56 | LIST_PHOTO("list_photo"), 57 | 58 | /** 59 | * 获取登录用户在腾讯微博详细资料 60 | */ 61 | GET_INFO("get_info"), 62 | 63 | /** 64 | * 发表一条微博 65 | */ 66 | ADD_T("add_t"), 67 | 68 | /** 69 | * 删除一条微博 70 | */ 71 | DEL_T("del_t"), 72 | 73 | /** 74 | * 发表一条带图片的微博 75 | */ 76 | ADD_PIC_T("add_pic_t"), 77 | 78 | /** 79 | * 获取单条微博的转发或点评列表 80 | */ 81 | GET_REPOST_LIST("get_repost_list"), 82 | 83 | /** 84 | * 获取他人微博资料 85 | */ 86 | GET_OTHER_INFO("get_other_info"), 87 | 88 | /** 89 | * 我的微博粉丝列表 90 | */ 91 | GET_FANSLIST("get_fanslist"), 92 | 93 | /** 94 | * 我的微博偶像列表 95 | */ 96 | GET_IDOLLIST("get_idollist"), 97 | 98 | /** 99 | * 收听某个微博用户 100 | */ 101 | ADD_IDOL("add_idol"), 102 | 103 | /** 104 | * 取消收听某个微博用户 105 | */ 106 | DEL_IDOL("del_idol"), 107 | 108 | /** 109 | * 在这个网站上将展现您财付通登记的收货地址 110 | */ 111 | GET_TENPAY_ADDR("get_tenpay_addr"); 112 | 113 | private String scope; 114 | 115 | private Scope(String scope) { 116 | this.scope = scope; 117 | } 118 | 119 | public String value() { 120 | return scope; 121 | } 122 | 123 | @Override 124 | public String toString() { 125 | return scope; 126 | } 127 | 128 | public static final Scope[] ALL = new Scope[] {Scope.DO_LIKE, Scope.GET_USER_INFO, 129 | Scope.GET_SIMPLE_USERINFO, Scope.GET_VIP_INFO, Scope.GET_VIP_RICH_INFO, Scope.ADD_ONE_BLOG, 130 | Scope.LIST_ALBUM, Scope.UPLOAD_PIC, Scope.ADD_ALBUM, Scope.LIST_PHOTO, Scope.GET_INFO, 131 | Scope.ADD_T, Scope.DEL_T, Scope.ADD_PIC_T, Scope.GET_REPOST_LIST, Scope.GET_OTHER_INFO, 132 | Scope.GET_FANSLIST, Scope.GET_IDOLLIST, Scope.ADD_IDOL, Scope.DEL_IDOL, 133 | Scope.GET_TENPAY_ADDR,}; 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/SendPrivate.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | public enum SendPrivate { 4 | IDOL(0), FRIEND(1), PUBLIC(2); 5 | 6 | private Integer value; 7 | 8 | private SendPrivate(Integer value) { 9 | this.value = value; 10 | } 11 | 12 | public Integer value() { 13 | return value; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return value.toString(); 19 | } 20 | 21 | public static SendPrivate parse(Integer value) { 22 | if (value == null) { 23 | return null; 24 | } 25 | if (value == 0) { 26 | return IDOL; 27 | } 28 | if (value == 1) { 29 | return FRIEND; 30 | } 31 | if (value == 2) { 32 | return PUBLIC; 33 | } 34 | return null; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Tag.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class Tag extends JsonBean { 9 | 10 | public Tag() {} 11 | 12 | private Tag(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String id;// 个人标签id。 17 | private String name;// 标签名。 18 | 19 | 20 | public String getId() { 21 | return id; 22 | } 23 | 24 | public void setId(String id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(String name) { 33 | this.name = name; 34 | } 35 | 36 | public static Tag parse(JSONObject jsonObject) { 37 | if (jsonObject == null) { 38 | return null; 39 | } 40 | Tag obj = new Tag(jsonObject); 41 | obj.id = Result.toString(jsonObject.get("id")); 42 | obj.name = Result.toString(jsonObject.opt("name")); 43 | return obj; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/TenpayAddress.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * 财付通收货地址 7 | */ 8 | public class TenpayAddress { 9 | 10 | private Integer index;// 收货信息的索引编号 11 | private Integer regionId;// 收货信息的地区编号 12 | private String street;// 收货信息的收货地址 13 | private String zipcode;// 收货信息的邮编 14 | private String mobile;// 收货信息的收货人移动电话 15 | private String tel;// 收货信息的收货人固定电话 16 | private String name;// 收货信息的收货人姓名 17 | private Date created;// 收货信息的创建时间 18 | private Date modified;// 收货信息上一次被修改的时间 19 | private Date lastUsed;// 收货信息上一次被使用的时间 20 | private Integer usedCount;// 收货信息被使用过的次数 21 | private Integer total;// 该用户财付通收货地址的个数 22 | 23 | public Integer getIndex() { 24 | return index; 25 | } 26 | 27 | public void setIndex(Integer index) { 28 | this.index = index; 29 | } 30 | 31 | public Integer getRegionId() { 32 | return regionId; 33 | } 34 | 35 | public void setRegionId(Integer regionId) { 36 | this.regionId = regionId; 37 | } 38 | 39 | public String getStreet() { 40 | return street; 41 | } 42 | 43 | public void setStreet(String street) { 44 | this.street = street; 45 | } 46 | 47 | public String getZipcode() { 48 | return zipcode; 49 | } 50 | 51 | public void setZipcode(String zipcode) { 52 | this.zipcode = zipcode; 53 | } 54 | 55 | public String getMobile() { 56 | return mobile; 57 | } 58 | 59 | public void setMobile(String mobile) { 60 | this.mobile = mobile; 61 | } 62 | 63 | public String getTel() { 64 | return tel; 65 | } 66 | 67 | public void setTel(String tel) { 68 | this.tel = tel; 69 | } 70 | 71 | public String getName() { 72 | return name; 73 | } 74 | 75 | public void setName(String name) { 76 | this.name = name; 77 | } 78 | 79 | public Date getCreated() { 80 | return created; 81 | } 82 | 83 | public void setCreated(Date created) { 84 | this.created = created; 85 | } 86 | 87 | public Date getModified() { 88 | return modified; 89 | } 90 | 91 | public void setModified(Date modified) { 92 | this.modified = modified; 93 | } 94 | 95 | public Date getLastUsed() { 96 | return lastUsed; 97 | } 98 | 99 | public void setLastUsed(Date lastUsed) { 100 | this.lastUsed = lastUsed; 101 | } 102 | 103 | public Integer getUsedCount() { 104 | return usedCount; 105 | } 106 | 107 | public void setUsedCount(Integer usedCount) { 108 | this.usedCount = usedCount; 109 | } 110 | 111 | public Integer getTotal() { 112 | return total; 113 | } 114 | 115 | public void setTotal(Integer total) { 116 | this.total = total; 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/TweetInfo.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import java.util.Date; 4 | 5 | import org.json.JSONObject; 6 | 7 | import com.belerweb.social.bean.JsonBean; 8 | import com.belerweb.social.bean.Result; 9 | 10 | public class TweetInfo extends JsonBean { 11 | 12 | public TweetInfo() {} 13 | 14 | private TweetInfo(JSONObject jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | private String id;// 微博唯一id。 19 | private String countryCode;// 发表微博时所作的国家代码。 20 | private String provinceCode;// 发表微博时所作的省份代码。 21 | private String cityCode;// 发表微博时所作的城市代码。 22 | private String emotionType;// 心情类型。 23 | private String emotionUrl;// 心情图片url。 24 | private String from;// 来源。 25 | private String fromUrl;// 来源url。 26 | private String image;// 图片url。 27 | private String geo;// 地理位置信息。 28 | private String location;// 发表者所在地。 29 | private Double longitude;// 经度。 30 | private Double latitude;// 纬度。 31 | private Music music; 32 | private String origText;// 微博原始内容。 33 | private Boolean self;// 是否自已发的的微博 34 | private Integer status;// 表示微博的状态。0:正常;1:微博被系统删除;2:审核中;3;微博被用户删除;4:源微博被系统审核删除。 35 | private String text;// 微博内容。 36 | private Date timestamp;// 服务器时间戳,不能用于翻页。 37 | private Integer type;// 表示微博的类型。1:原创发表;2:转播;3:私信;4:回复;5:没有内容的回复;6:提及;7:评论。 38 | private Video video;// 视频信息。 39 | private Integer count;// 转播次数。 40 | private Integer mCount;// 评论数。 41 | private Boolean isVip;// 用户是否为微博认证用户 42 | 43 | public String getId() { 44 | return id; 45 | } 46 | 47 | public void setId(String id) { 48 | this.id = id; 49 | } 50 | 51 | public String getCountryCode() { 52 | return countryCode; 53 | } 54 | 55 | public void setCountryCode(String countryCode) { 56 | this.countryCode = countryCode; 57 | } 58 | 59 | public String getProvinceCode() { 60 | return provinceCode; 61 | } 62 | 63 | public void setProvinceCode(String provinceCode) { 64 | this.provinceCode = provinceCode; 65 | } 66 | 67 | public String getCityCode() { 68 | return cityCode; 69 | } 70 | 71 | public void setCityCode(String cityCode) { 72 | this.cityCode = cityCode; 73 | } 74 | 75 | public String getEmotionType() { 76 | return emotionType; 77 | } 78 | 79 | public void setEmotionType(String emotionType) { 80 | this.emotionType = emotionType; 81 | } 82 | 83 | public String getEmotionUrl() { 84 | return emotionUrl; 85 | } 86 | 87 | public void setEmotionUrl(String emotionUrl) { 88 | this.emotionUrl = emotionUrl; 89 | } 90 | 91 | public String getFrom() { 92 | return from; 93 | } 94 | 95 | public void setFrom(String from) { 96 | this.from = from; 97 | } 98 | 99 | public String getFromUrl() { 100 | return fromUrl; 101 | } 102 | 103 | public void setFromUrl(String fromUrl) { 104 | this.fromUrl = fromUrl; 105 | } 106 | 107 | public String getImage() { 108 | return image; 109 | } 110 | 111 | public void setImage(String image) { 112 | this.image = image; 113 | } 114 | 115 | public String getGeo() { 116 | return geo; 117 | } 118 | 119 | public void setGeo(String geo) { 120 | this.geo = geo; 121 | } 122 | 123 | public String getLocation() { 124 | return location; 125 | } 126 | 127 | public void setLocation(String location) { 128 | this.location = location; 129 | } 130 | 131 | public Double getLongitude() { 132 | return longitude; 133 | } 134 | 135 | public void setLongitude(Double longitude) { 136 | this.longitude = longitude; 137 | } 138 | 139 | public Double getLatitude() { 140 | return latitude; 141 | } 142 | 143 | public void setLatitude(Double latitude) { 144 | this.latitude = latitude; 145 | } 146 | 147 | public Music getMusic() { 148 | return music; 149 | } 150 | 151 | public void setMusic(Music music) { 152 | this.music = music; 153 | } 154 | 155 | public String getOrigText() { 156 | return origText; 157 | } 158 | 159 | public void setOrigText(String origText) { 160 | this.origText = origText; 161 | } 162 | 163 | public Boolean getSelf() { 164 | return self; 165 | } 166 | 167 | public void setSelf(Boolean self) { 168 | this.self = self; 169 | } 170 | 171 | public Integer getStatus() { 172 | return status; 173 | } 174 | 175 | public void setStatus(Integer status) { 176 | this.status = status; 177 | } 178 | 179 | public String getText() { 180 | return text; 181 | } 182 | 183 | public void setText(String text) { 184 | this.text = text; 185 | } 186 | 187 | public Date getTimestamp() { 188 | return timestamp; 189 | } 190 | 191 | public void setTimestamp(Date timestamp) { 192 | this.timestamp = timestamp; 193 | } 194 | 195 | public Integer getType() { 196 | return type; 197 | } 198 | 199 | public void setType(Integer type) { 200 | this.type = type; 201 | } 202 | 203 | public Video getVideo() { 204 | return video; 205 | } 206 | 207 | public void setVideo(Video video) { 208 | this.video = video; 209 | } 210 | 211 | public Integer getCount() { 212 | return count; 213 | } 214 | 215 | public void setCount(Integer count) { 216 | this.count = count; 217 | } 218 | 219 | public Integer getmCount() { 220 | return mCount; 221 | } 222 | 223 | public void setmCount(Integer mCount) { 224 | this.mCount = mCount; 225 | } 226 | 227 | public Boolean getIsVip() { 228 | return isVip; 229 | } 230 | 231 | public void setIsVip(Boolean isVip) { 232 | this.isVip = isVip; 233 | } 234 | 235 | public static TweetInfo parse(JSONObject jsonObject) { 236 | if (jsonObject == null) { 237 | return null; 238 | } 239 | TweetInfo obj = new TweetInfo(jsonObject); 240 | obj.id = Result.toString(jsonObject.get("id")); 241 | obj.countryCode = Result.toString(jsonObject.opt("country_code")); 242 | obj.provinceCode = Result.toString(jsonObject.opt("province_code")); 243 | obj.cityCode = Result.toString(jsonObject.opt("city_code")); 244 | obj.emotionType = Result.toString(jsonObject.opt("emotiontype")); 245 | obj.emotionUrl = Result.toString(jsonObject.opt("emotionurl")); 246 | obj.from = Result.toString(jsonObject.opt("from")); 247 | obj.fromUrl = Result.toString(jsonObject.opt("fromurl")); 248 | obj.image = Result.toString(jsonObject.opt("image")); 249 | obj.geo = Result.toString(jsonObject.opt("geo")); 250 | obj.location = Result.toString(jsonObject.opt("location")); 251 | obj.longitude = Result.parseDouble(jsonObject.opt("longitude")); 252 | obj.latitude = Result.parseDouble(jsonObject.opt("latitude")); 253 | obj.music = Music.parse(jsonObject.optJSONObject("music")); 254 | obj.origText = Result.toString(jsonObject.opt("origtext")); 255 | obj.self = Result.parseBoolean(jsonObject.opt("self")); 256 | obj.status = Result.parseInteger(jsonObject.opt("status")); 257 | obj.text = Result.toString(jsonObject.opt("text")); 258 | obj.timestamp = Result.parseTimeSeconds(jsonObject.opt("timestamp")); 259 | obj.type = Result.parseInteger(jsonObject.opt("type")); 260 | obj.video = Video.parse(jsonObject.optJSONObject("video")); 261 | obj.count = Result.parseInteger(jsonObject.opt("count")); 262 | obj.mCount = Result.parseInteger(jsonObject.opt("mcount")); 263 | obj.isVip = Result.parseBoolean(jsonObject.opt("isvip")); 264 | return obj; 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/connect/bean/Video.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class Video extends JsonBean { 9 | 10 | public Video() {} 11 | 12 | private Video(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String picUrl;// 缩略图。 17 | private String player;// 播放器地址。 18 | private String realUrl;// 视频原地址。 19 | private String shortUrl;// 视频的短url。 20 | private String title;// 视频标题。 21 | 22 | public String getPicUrl() { 23 | return picUrl; 24 | } 25 | 26 | public void setPicUrl(String picUrl) { 27 | this.picUrl = picUrl; 28 | } 29 | 30 | public String getPlayer() { 31 | return player; 32 | } 33 | 34 | public void setPlayer(String player) { 35 | this.player = player; 36 | } 37 | 38 | public String getRealUrl() { 39 | return realUrl; 40 | } 41 | 42 | public void setRealUrl(String realUrl) { 43 | this.realUrl = realUrl; 44 | } 45 | 46 | public String getShortUrl() { 47 | return shortUrl; 48 | } 49 | 50 | public void setShortUrl(String shortUrl) { 51 | this.shortUrl = shortUrl; 52 | } 53 | 54 | public String getTitle() { 55 | return title; 56 | } 57 | 58 | public void setTitle(String title) { 59 | this.title = title; 60 | } 61 | 62 | public static Video parse(JSONObject jsonObject) { 63 | if (jsonObject == null) { 64 | return null; 65 | } 66 | Video obj = new Video(jsonObject); 67 | obj.picUrl = Result.toString(jsonObject.opt("picurl")); 68 | obj.player = Result.toString(jsonObject.opt("player")); 69 | obj.realUrl = Result.toString(jsonObject.opt("realurl")); 70 | obj.shortUrl = Result.toString(jsonObject.opt("shorturl")); 71 | obj.title = Result.toString(jsonObject.opt("title")); 72 | return obj; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/mail/bean/Address.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.mail.bean; 2 | 3 | public class Address { 4 | 5 | private String label; 6 | private String type; 7 | private String country; 8 | private String province; 9 | private String city; 10 | private String street; 11 | private String postcode; 12 | 13 | public String getLabel() { 14 | return label; 15 | } 16 | 17 | public void setLabel(String label) { 18 | this.label = label; 19 | } 20 | 21 | public String getType() { 22 | return type; 23 | } 24 | 25 | public void setType(String type) { 26 | this.type = type; 27 | } 28 | 29 | public String getCountry() { 30 | return country; 31 | } 32 | 33 | public void setCountry(String country) { 34 | this.country = country; 35 | } 36 | 37 | public String getProvince() { 38 | return province; 39 | } 40 | 41 | public void setProvince(String province) { 42 | this.province = province; 43 | } 44 | 45 | public String getCity() { 46 | return city; 47 | } 48 | 49 | public void setCity(String city) { 50 | this.city = city; 51 | } 52 | 53 | public String getStreet() { 54 | return street; 55 | } 56 | 57 | public void setStreet(String street) { 58 | this.street = street; 59 | } 60 | 61 | public String getPostcode() { 62 | return postcode; 63 | } 64 | 65 | public void setPostcode(String postcode) { 66 | this.postcode = postcode; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/mail/bean/Email.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.mail.bean; 2 | 3 | public class Email { 4 | 5 | private String label; 6 | private String type; 7 | private String email; 8 | 9 | public String getLabel() { 10 | return label; 11 | } 12 | 13 | public void setLabel(String label) { 14 | this.label = label; 15 | } 16 | 17 | public String getType() { 18 | return type; 19 | } 20 | 21 | public void setType(String type) { 22 | this.type = type; 23 | } 24 | 25 | public String getEmail() { 26 | return email; 27 | } 28 | 29 | public void setEmail(String email) { 30 | this.email = email; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/mail/bean/Group.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.mail.bean; 2 | 3 | import java.util.List; 4 | 5 | public class Group { 6 | 7 | private String id; 8 | private String type; 9 | private String name; 10 | private List users; 11 | private String owner; 12 | 13 | public String getId() { 14 | return id; 15 | } 16 | 17 | public void setId(String id) { 18 | this.id = id; 19 | } 20 | 21 | public String getType() { 22 | return type; 23 | } 24 | 25 | public void setType(String type) { 26 | this.type = type; 27 | } 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public List getUsers() { 38 | return users; 39 | } 40 | 41 | public void setUsers(List users) { 42 | this.users = users; 43 | } 44 | 45 | public String getOwner() { 46 | return owner; 47 | } 48 | 49 | public void setOwner(String owner) { 50 | this.owner = owner; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/mail/bean/Org.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.mail.bean; 2 | 3 | public class Org { 4 | 5 | private String org1; 6 | private String org2; 7 | private String title; 8 | 9 | public String getOrg1() { 10 | return org1; 11 | } 12 | 13 | public void setOrg1(String org1) { 14 | this.org1 = org1; 15 | } 16 | 17 | public String getOrg2() { 18 | return org2; 19 | } 20 | 21 | public void setOrg2(String org2) { 22 | this.org2 = org2; 23 | } 24 | 25 | public String getTitle() { 26 | return title; 27 | } 28 | 29 | public void setTitle(String title) { 30 | this.title = title; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/mail/bean/Tel.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.mail.bean; 2 | 3 | public class Tel { 4 | 5 | private String label; 6 | private String type; 7 | private String num; 8 | 9 | public String getLabel() { 10 | return label; 11 | } 12 | 13 | public void setLabel(String label) { 14 | this.label = label; 15 | } 16 | 17 | public String getType() { 18 | return type; 19 | } 20 | 21 | public void setType(String type) { 22 | this.type = type; 23 | } 24 | 25 | public String getNum() { 26 | return num; 27 | } 28 | 29 | public void setNum(String num) { 30 | this.num = num; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/mail/bean/User.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.mail.bean; 2 | 3 | import java.util.List; 4 | 5 | public class User { 6 | 7 | private String id; 8 | private String level; 9 | private String type; 10 | private String name; 11 | private String nickName; 12 | private String familyName; 13 | private String givenName; 14 | private String relate; 15 | private String url; 16 | private String date; 17 | private String birthday; 18 | private String im; 19 | private String custom; 20 | private String note; 21 | private Address address; 22 | private Org org; 23 | private List emails; 24 | private List tels; 25 | 26 | public String getId() { 27 | return id; 28 | } 29 | 30 | public void setId(String id) { 31 | this.id = id; 32 | } 33 | 34 | public String getLevel() { 35 | return level; 36 | } 37 | 38 | public void setLevel(String level) { 39 | this.level = level; 40 | } 41 | 42 | public String getType() { 43 | return type; 44 | } 45 | 46 | public void setType(String type) { 47 | this.type = type; 48 | } 49 | 50 | public String getName() { 51 | return name; 52 | } 53 | 54 | public void setName(String name) { 55 | this.name = name; 56 | } 57 | 58 | public String getNickName() { 59 | return nickName; 60 | } 61 | 62 | public void setNickName(String nickName) { 63 | this.nickName = nickName; 64 | } 65 | 66 | public String getFamilyName() { 67 | return familyName; 68 | } 69 | 70 | public void setFamilyName(String familyName) { 71 | this.familyName = familyName; 72 | } 73 | 74 | public String getGivenName() { 75 | return givenName; 76 | } 77 | 78 | public void setGivenName(String givenName) { 79 | this.givenName = givenName; 80 | } 81 | 82 | public String getRelate() { 83 | return relate; 84 | } 85 | 86 | public void setRelate(String relate) { 87 | this.relate = relate; 88 | } 89 | 90 | public String getUrl() { 91 | return url; 92 | } 93 | 94 | public void setUrl(String url) { 95 | this.url = url; 96 | } 97 | 98 | public String getDate() { 99 | return date; 100 | } 101 | 102 | public void setDate(String date) { 103 | this.date = date; 104 | } 105 | 106 | public String getBirthday() { 107 | return birthday; 108 | } 109 | 110 | public void setBirthday(String birthday) { 111 | this.birthday = birthday; 112 | } 113 | 114 | public String getIm() { 115 | return im; 116 | } 117 | 118 | public void setIm(String im) { 119 | this.im = im; 120 | } 121 | 122 | public String getCustom() { 123 | return custom; 124 | } 125 | 126 | public void setCustom(String custom) { 127 | this.custom = custom; 128 | } 129 | 130 | public String getNote() { 131 | return note; 132 | } 133 | 134 | public void setNote(String note) { 135 | this.note = note; 136 | } 137 | 138 | public Address getAddress() { 139 | return address; 140 | } 141 | 142 | public void setAddress(Address address) { 143 | this.address = address; 144 | } 145 | 146 | public Org getOrg() { 147 | return org; 148 | } 149 | 150 | public void setOrg(Org org) { 151 | this.org = org; 152 | } 153 | 154 | public List getEmails() { 155 | return emails; 156 | } 157 | 158 | public void setEmails(List emails) { 159 | this.emails = emails; 160 | } 161 | 162 | public List getTels() { 163 | return tels; 164 | } 165 | 166 | public void setTels(List tels) { 167 | this.tels = tels; 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/mail/bean/ValidationCode.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.mail.bean; 2 | 3 | public class ValidationCode { 4 | 5 | private String status; 6 | private String code; 7 | private String uid; 8 | 9 | public ValidationCode() {} 10 | 11 | public ValidationCode(String response) { 12 | String[] str = response.substring(13, response.length() - 2).split(","); 13 | status = str[0].trim().substring(1, str[0].length() - 1); 14 | code = str[1].trim().substring(1, str[1].length() - 1); 15 | uid = str[2].trim().substring(1, str[2].length() - 1).replaceAll("\\\\x", ""); 16 | } 17 | 18 | public String getStatus() { 19 | return status; 20 | } 21 | 22 | public void setStatus(String status) { 23 | this.status = status; 24 | } 25 | 26 | public String getCode() { 27 | return code; 28 | } 29 | 30 | public void setCode(String code) { 31 | this.code = code; 32 | } 33 | 34 | public String getUid() { 35 | return uid; 36 | } 37 | 38 | public void setUid(String uid) { 39 | this.uid = uid; 40 | } 41 | 42 | public boolean need() { 43 | return !"0".equals(status); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/t/api/OAuth2.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.t.api; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.commons.lang.StringUtils; 7 | import org.apache.http.NameValuePair; 8 | 9 | import com.belerweb.social.API; 10 | 11 | public final class OAuth2 extends API { 12 | 13 | OAuth2(QQT t) { 14 | super(t); 15 | } 16 | 17 | /** 18 | * 获取Authorization Code 19 | * 20 | * 从 {@link QQT} 从获取clientId,redirectUri,responseType为code ,其余参数默认 21 | * 22 | * @see OAuth2#authorize(String, String, String, String, String, Boolean) 23 | */ 24 | public String authorize() { 25 | return authorize(t.getRedirectUri()); 26 | } 27 | 28 | 29 | /** 30 | * 获取Authorization Code 31 | * 32 | * 从 {@link QQT} 从获取clientId,responseType为code ,其余参数默认 33 | * 34 | * @see OAuth2#authorize(String, String, String, String, String, Boolean) 35 | */ 36 | public String authorize(String redirectUri) { 37 | return authorize(t.getClientId(), redirectUri, "code", null, null, null); 38 | } 39 | 40 | /** 41 | * 获取Authorization Code 42 | * 43 | * 文档地址:http://wiki.t.qq.com/使用authorization_code获取access_token 44 | * 45 | * @param clientId 必须,申请应用时分配的app_key 46 | * @param redirectUri 必须,授权回调地址,必须和应用注册的地址一致(地址长度上限为256个字节) 47 | * @param responseType 必须,授权类型,为code 48 | * @param wap 49 | * 主要用于指定手机授权页的版本,无此参数默认显示pc授权页面。wap=1时,跳转到wap1.0的授权页。wap=2时,跳转到wap2.0的授权页。不带本参数时,手机访问默认跳到wap2 50 | * .0的授权页 51 | * @param state 52 | * 用于保持请求和回调的状态,授权请求成功后原样带回给第三方。该参数用于防止csrf攻击(跨站请求伪造攻击),强烈建议第三方带上该参数。参数设置建议为简单随机数+session的方式 53 | * @param forceLogin 针对pc授权页。forcelogin=true,强制弹出登录授权页面 54 | * forcelogin=false,用户已经登录并且已经授权第三方应用,则不再弹出授权页面 默认为forcelogin=true 55 | */ 56 | public String authorize(String clientId, String redirectUri, String responseType, String wap, 57 | String state, Boolean forceLogin) { 58 | List params = new ArrayList(); 59 | t.addParameter(params, "client_id", clientId); 60 | t.addParameter(params, "redirect_uri", redirectUri); 61 | t.addParameter(params, "response_type", responseType); 62 | t.addNotNullParameter(params, "wap", wap); 63 | t.addNotNullParameter(params, "state", state); 64 | t.addTrueParameter(params, "forcelogin", forceLogin); 65 | return "https://open.t.qq.com/cgi-bin/oauth2/authorize?" + StringUtils.join(params, "&"); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/qq/t/api/QQT.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.t.api; 2 | 3 | import com.belerweb.social.SDK; 4 | 5 | public final class QQT extends SDK { 6 | 7 | private String clientId; 8 | private String clientSecret; 9 | private String redirectUri; 10 | 11 | public QQT(String clientId, String clientSecret) { 12 | this.clientId = clientId; 13 | this.clientSecret = clientSecret; 14 | } 15 | 16 | public QQT(String clientId, String clientSecret, String redirectUri) { 17 | this(clientId, clientSecret); 18 | this.redirectUri = redirectUri; 19 | } 20 | 21 | public String getClientId() { 22 | return clientId; 23 | } 24 | 25 | public void setClientId(String clientId) { 26 | this.clientId = clientId; 27 | } 28 | 29 | public String getClientSecret() { 30 | return clientSecret; 31 | } 32 | 33 | public void setClientSecret(String clientSecret) { 34 | this.clientSecret = clientSecret; 35 | } 36 | 37 | public String getRedirectUri() { 38 | return redirectUri; 39 | } 40 | 41 | public void setRedirectUri(String redirectUri) { 42 | this.redirectUri = redirectUri; 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/api/OAuth2.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.api; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.commons.lang.StringUtils; 7 | import org.apache.http.NameValuePair; 8 | import org.json.JSONObject; 9 | 10 | import com.belerweb.social.API; 11 | import com.belerweb.social.bean.Error; 12 | import com.belerweb.social.bean.Result; 13 | import com.belerweb.social.exception.SocialException; 14 | import com.belerweb.social.weibo.bean.AccessToken; 15 | import com.belerweb.social.weibo.bean.Display; 16 | import com.belerweb.social.weibo.bean.Scope; 17 | import com.belerweb.social.weibo.bean.TokenInfo; 18 | 19 | public final class OAuth2 extends API { 20 | 21 | OAuth2(Weibo weibo) { 22 | super(weibo); 23 | } 24 | 25 | 26 | /** 27 | * OAuth2的authorize接口 28 | * 29 | * 从 {@link Weibo} 从获取clientId,redirectUri,scope 使用 {@link Scope#ALL},其余参数默认 30 | * 31 | * @see OAuth2#authorize(String, String, Scope[], String, Display, Boolean, String) 32 | */ 33 | public String authorize() { 34 | return authorize(weibo.getRedirectUri()); 35 | } 36 | 37 | 38 | /** 39 | * OAuth2的authorize接口 40 | * 41 | * 从 {@link Weibo} 从获取clientId,scope 使用 {@link Scope#ALL},其余参数默认 42 | * 43 | * @see OAuth2#authorize(String, String, Scope[], String, Display, Boolean, String) 44 | * 45 | * @param redirectUri 授权回调地址,站外应用需与设置的回调地址一致,站内应用需填写canvas page的地址。 46 | */ 47 | public String authorize(String redirectUri) { 48 | return authorize(weibo.getClientId(), redirectUri, new Scope[] {Scope.ALL}, null, null, null, 49 | null); 50 | } 51 | 52 | /** 53 | * OAuth2的authorize接口 54 | * 55 | * 文档地址:http://open.weibo.com/wiki/Oauth2/authorize 56 | * 57 | * @param clientId 申请应用时分配的AppKey。 58 | * @param redirectUri 授权回调地址,站外应用需与设置的回调地址一致,站内应用需填写canvas page的地址。 59 | * @param scope 申请scope权限所需参数,可一次申请多个scope权限,用逗号分隔。使用文档 61 | * @param state 用于保持请求和回调的状态,在回调时,会在Query 62 | * Parameter中回传该参数。开发者可以用这个参数验证请求有效性,也可以记录用户请求授权页前的位置。这个参数可用于防止跨站请求伪造(CSRF)攻击 63 | * @param display 授权页面的终端类型,取值见下面的说明。 64 | * @param forceLogin 是否强制用户重新登录,true:是,false:否。默认false。 65 | * @param language 授权页语言,缺省为中文简体版,en为英文版。 66 | */ 67 | public String authorize(String clientId, String redirectUri, Scope[] scope, String state, 68 | Display display, Boolean forceLogin, String language) { 69 | List params = new ArrayList(); 70 | weibo.addParameter(params, "client_id", clientId); 71 | weibo.addParameter(params, "redirect_uri", redirectUri); 72 | if (scope != null) { 73 | weibo.addParameter(params, "scope", StringUtils.join(scope, ",")); 74 | } 75 | weibo.addNotNullParameter(params, "state", state); 76 | weibo.addNotNullParameter(params, "display", display); 77 | weibo.addTrueParameter(params, "forcelogin", forceLogin); 78 | weibo.addNotNullParameter(params, "language", language); 79 | 80 | return "https://api.weibo.com/oauth2/authorize?" + StringUtils.join(params, "&"); 81 | } 82 | 83 | /** 84 | * 从 {@link Weibo} 从获取clientId,clientSecret,grantType,redirectUri 使用 authorization_code 85 | * 86 | * @see OAuth2#accessToken(String, String, String, String, String) 87 | */ 88 | public Result accessToken(String code) { 89 | return accessToken(code, weibo.getRedirectUri()); 90 | } 91 | 92 | /** 93 | * 从 {@link Weibo} 从获取clientId,clientSecret,grantType 使用 authorization_code 94 | * 95 | * @see OAuth2#accessToken(String, String, String, String, String) 96 | */ 97 | public Result accessToken(String code, String redirectUri) { 98 | return accessToken(weibo.getClientId(), weibo.getClientSecret(), "authorization_code", code, 99 | redirectUri); 100 | } 101 | 102 | /** 103 | * OAuth2的access_token接口 104 | * 105 | * 文档地址:http://open.weibo.com/wiki/OAuth2/access_token 106 | * 107 | * @param clientId 申请应用时分配的AppKey。 108 | * @param clientSecret 申请应用时分配的AppSecret。 109 | * @param grantType 请求的类型,填写authorization_code 110 | * @param code grant_type为authorization_code时,调用authorize获得的code值。 111 | * @param redirectUri grant_type为authorization_code时,回调地址,需需与注册应用里的回调地址一致。 112 | */ 113 | public Result accessToken(String clientId, String clientSecret, String grantType, 114 | String code, String redirectUri) { 115 | List params = new ArrayList(); 116 | weibo.addParameter(params, "client_id", clientId); 117 | weibo.addParameter(params, "client_secret", clientSecret); 118 | weibo.addParameter(params, "grant_type", grantType); 119 | if ("authorization_code".equals(grantType)) { 120 | weibo.addParameter(params, "code", code); 121 | weibo.addParameter(params, "redirect_uri", redirectUri); 122 | } 123 | String result = weibo.post("https://api.weibo.com/oauth2/access_token", params); 124 | return Result.parse(result, AccessToken.class); 125 | } 126 | 127 | /** 128 | * 查询用户access_token的授权相关信息,包括授权时间,过期时间和scope权限。 129 | * 130 | * 文档地址:http://open.weibo.com/wiki/Oauth2/get_token_info 131 | * 132 | * @param accessToken 用户授权时生成的access_token。 133 | */ 134 | public Result getTokenInfo(String accessToken) { 135 | List params = new ArrayList(); 136 | weibo.addParameter(params, "access_token", accessToken); 137 | String result = weibo.post("https://api.weibo.com/oauth2/get_token_info", params); 138 | return Result.parse(result, TokenInfo.class); 139 | } 140 | 141 | /** 142 | * 用于OAuth1.0 access token 更换至 OAuth2.0 access 143 | * token,帮助开发者使用新版接口和OAuth2.0时平滑迁移用户。详细的OAuth1.0调用方式和SDK资源参见:http://open.weibo.com/wiki/Oauth 145 | * 146 | * 文档地址:http://open.weibo.com/wiki/Oauth2/get_oauth2_token 147 | * 148 | * @param oauthConsumerKey 创建应用时生成的APP KEY。 149 | * @param oauthToken oauth的token。 150 | * @param oauthSignatureMethod 签名方法,建议使用“HMAC-SHA1”。 151 | * @param oauthTimestamp 生成Base String时的时间戳。 152 | * @param oauthNonce 单次值,一个随机字符串,防止重复攻击。该参数只支持ASCII码的字符串。 153 | * @param oauthVersion OAuth协议版本。填写“1.0”。 154 | * @param oauthSignature 签名值,是由根据上面的几个参数生成的 Base String经HMAC-SHA1算法计算得出。 155 | */ 156 | public void getOAuth2Token(String oauthConsumerKey, String oauthToken, 157 | String oauthSignatureMethod, Long oauthTimestamp, String oauthNonce, String oauthVersion, 158 | String oauthSignature) { 159 | throw new SocialException("方法还未实现..."); 160 | } 161 | 162 | /** 163 | * 授权回收接口,帮助开发者主动取消用户的授权。 164 | * 165 | * 文档地址:http://open.weibo.com/wiki/Oauth2/revokeoauth2 166 | * 167 | * @param accessToken 用户授权应用的access_token 168 | */ 169 | public Result revokeOAuth2(String accessToken) { 170 | List params = new ArrayList(); 171 | weibo.addParameter(params, "access_token", accessToken); 172 | String json = weibo.post("https://api.weibo.com/oauth2/revokeoauth2", params); 173 | JSONObject jsonObject = new JSONObject(json); 174 | Error error = Error.parse(jsonObject); 175 | if (error == null) { 176 | return new Result(Result.parseBoolean(jsonObject.get("result"))); 177 | } 178 | 179 | return new Result(error); 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/api/User.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.api; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.commons.lang.StringUtils; 7 | import org.apache.http.NameValuePair; 8 | 9 | import com.belerweb.social.API; 10 | import com.belerweb.social.bean.Result; 11 | import com.belerweb.social.exception.SocialException; 12 | import com.belerweb.social.weibo.bean.UserCounts; 13 | 14 | /** 15 | * 读取用户信息接口 16 | */ 17 | public final class User extends API { 18 | 19 | protected User(Weibo weibo) { 20 | super(weibo); 21 | } 22 | 23 | /** 24 | * 获取用户信息/根据用户ID获取用户信息 25 | * 26 | * 访问级别:普通接口 27 | * 28 | * 频次限制:是 29 | * 30 | * 文档地址:https://api.weibo.com/2/users/show.json 31 | * 32 | * @param source 采用OAuth授权方式不需要此参数,其他授权方式为必填参数,数值为应用的AppKey。 33 | * @param accessToken 采用OAuth授权方式为必填参数,其他授权方式不需要此参数,OAuth授权后获得。 34 | * @param uid 需要查询的用户ID。 35 | * @param screename 需要查询的用户昵称。 36 | * 37 | * 参数uid与screen_name二者必选其一,且只能选其一 38 | */ 39 | public Result show(String source, String accessToken, 40 | String uid, String screenName) { 41 | List params = new ArrayList(); 42 | weibo.addNotNullParameter(params, "source", source); 43 | weibo.addNotNullParameter(params, "access_token", accessToken); 44 | weibo.addNotNullParameter(params, "uid", uid); 45 | weibo.addNotNullParameter(params, "screen_name", screenName); 46 | String json = weibo.get("https://api.weibo.com/2/users/show.json", params); 47 | return Result.parse(json, com.belerweb.social.weibo.bean.User.class); 48 | } 49 | 50 | /** 51 | * 通过个性域名获取用户信息/通过个性化域名获取用户资料以及用户最新的一条微博 52 | * 53 | * 访问级别:普通接口 54 | * 55 | * 频次限制:是 56 | * 57 | * 文档地址:https://api.weibo.com/2/users/domain_show.json 58 | * 59 | * @param source 采用OAuth授权方式不需要此参数,其他授权方式为必填参数,数值为应用的AppKey。 60 | * @param accessToken 采用OAuth授权方式为必填参数,其他授权方式不需要此参数,OAuth授权后获得。 61 | * @param domain 需要查询的个性化域名。 62 | */ 63 | public Result domainShow(String source, String accessToken, 64 | String domain) { 65 | List params = new ArrayList(); 66 | weibo.addNotNullParameter(params, "source", source); 67 | weibo.addNotNullParameter(params, "access_token", accessToken); 68 | weibo.addParameter(params, "domain", domain); 69 | String json = weibo.get("https://api.weibo.com/2/users/domain_show.json", params); 70 | return Result.parse(json, com.belerweb.social.weibo.bean.User.class); 71 | } 72 | 73 | /** 74 | * 批量获取用户的粉丝数、关注数、微博数 75 | * 76 | * 访问级别:普通接口 77 | * 78 | * 频次限制:是 79 | * 80 | * 文档地址:https://api.weibo.com/2/users/counts.json 81 | * 82 | * @param source 采用OAuth授权方式不需要此参数,其他授权方式为必填参数,数值为应用的AppKey。 83 | * @param accessToken 采用OAuth授权方式为必填参数,其他授权方式不需要此参数,OAuth授权后获得。 84 | * @param uids 需要获取数据的用户UID,最多不超过100个。 85 | */ 86 | public Result counts(String source, String accessToken, List uids) { 87 | if (uids == null || uids.size() > 100) { 88 | throw new SocialException("需要获取数据的用户UID,必须且最多不超过100个"); 89 | } 90 | 91 | List params = new ArrayList(); 92 | weibo.addNotNullParameter(params, "source", source); 93 | weibo.addNotNullParameter(params, "access_token", accessToken); 94 | weibo.addParameter(params, "uids", StringUtils.join(uids, ",")); 95 | String result = weibo.get("https://api.weibo.com/2/users/counts.json", params); 96 | return Result.parse(result, UserCounts.class); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/api/Weibo.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.api; 2 | 3 | import com.belerweb.social.SDK; 4 | 5 | public final class Weibo extends SDK { 6 | 7 | private String clientId; 8 | private String clientSecret; 9 | private String redirectUri; 10 | 11 | private OAuth2 oAuth2; 12 | private User user; 13 | 14 | public Weibo(String clientId, String clientSecret) { 15 | this.clientId = clientId; 16 | this.clientSecret = clientSecret; 17 | } 18 | 19 | 20 | public Weibo(String clientId, String clientSecret, String redirectUri) { 21 | this(clientId, clientSecret); 22 | this.redirectUri = redirectUri; 23 | } 24 | 25 | 26 | public OAuth2 getOAuth2() { 27 | if (oAuth2 == null) { 28 | oAuth2 = new OAuth2(this); 29 | } 30 | 31 | return oAuth2; 32 | } 33 | 34 | public User getUser() { 35 | if (user == null) { 36 | user = new User(this); 37 | } 38 | 39 | return user; 40 | } 41 | 42 | public String getClientId() { 43 | return clientId; 44 | } 45 | 46 | public void setClientId(String clientId) { 47 | this.clientId = clientId; 48 | } 49 | 50 | public String getClientSecret() { 51 | return clientSecret; 52 | } 53 | 54 | public void setClientSecret(String clientSecret) { 55 | this.clientSecret = clientSecret; 56 | } 57 | 58 | public String getRedirectUri() { 59 | return redirectUri; 60 | } 61 | 62 | public void setRedirectUri(String redirectUri) { 63 | this.redirectUri = redirectUri; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/AccessToken.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class AccessToken extends JsonBean { 9 | 10 | public AccessToken() {} 11 | 12 | private AccessToken(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String token;// 用于调用access_token,接口获取授权后的access token。 17 | private Long expiresIn;// access_token的生命周期,单位是秒数。 18 | private Long remindIn;// access_token的生命周期(该参数即将废弃,开发者请使用expires_in)。 19 | private String uid;// 当前授权用户的UID。 20 | 21 | /** 22 | * 用于调用access_token,接口获取授权后的access token。 23 | */ 24 | public String getToken() { 25 | return token; 26 | } 27 | 28 | public void setToken(String token) { 29 | this.token = token; 30 | } 31 | 32 | /** 33 | * access_token的生命周期,单位是秒数。 34 | */ 35 | public Long getExpiresIn() { 36 | return expiresIn; 37 | } 38 | 39 | public void setExpiresIn(Long expiresIn) { 40 | this.expiresIn = expiresIn; 41 | } 42 | 43 | /** 44 | * access_token的生命周期(该参数即将废弃,开发者请使用expires_in)。 45 | */ 46 | public Long getRemindIn() { 47 | return remindIn; 48 | } 49 | 50 | public void setRemindIn(Long remindIn) { 51 | this.remindIn = remindIn; 52 | } 53 | 54 | /** 55 | * 当前授权用户的UID。 56 | */ 57 | public String getUid() { 58 | return uid; 59 | } 60 | 61 | public void setUid(String uid) { 62 | this.uid = uid; 63 | } 64 | 65 | public static AccessToken parse(JSONObject jsonObject) { 66 | if (jsonObject == null) { 67 | return null; 68 | } 69 | AccessToken obj = new AccessToken(jsonObject); 70 | obj.token = jsonObject.getString("access_token"); 71 | obj.expiresIn = Result.parseLong(jsonObject.opt("expires_in")); 72 | obj.remindIn = Result.parseLong(jsonObject.opt("remind_in")); 73 | obj.uid = Result.toString(jsonObject.get("uid")); 74 | return obj; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/Comment.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | import java.util.Date; 4 | import java.util.Locale; 5 | 6 | import org.json.JSONObject; 7 | 8 | import com.belerweb.social.bean.JsonBean; 9 | import com.belerweb.social.bean.Result; 10 | 11 | /** 12 | * 评论 13 | * 14 | * 文档地址:http://open.weibo.com/wiki/常见返回对象数据结构#.E8.AF.84.E8.AE.BA.EF.BC.88comment.EF.BC.89 15 | */ 16 | public class Comment extends JsonBean { 17 | 18 | public Comment() {} 19 | 20 | private Comment(JSONObject jsonObject) { 21 | super(jsonObject); 22 | } 23 | 24 | private String id;// 评论的ID 25 | private String mid;// 评论的MID 26 | private String idstr;// 字符串型的评论ID 27 | private Date createdAt;// 评论创建时间 28 | private String text;// 评论的内容 29 | private String source;// 评论的来源 30 | private User user;// 评论作者的用户信息字段 31 | private Status status;// 评论的微博信息字段 32 | private Comment replyComment;// 评论来源评论,当本评论属于对另一评论的回复时返回此字段 33 | 34 | /** 35 | * 评论的ID 36 | */ 37 | public String getId() { 38 | return id; 39 | } 40 | 41 | public void setId(String id) { 42 | this.id = id; 43 | } 44 | 45 | /** 46 | * 评论的MID 47 | */ 48 | public String getMid() { 49 | return mid; 50 | } 51 | 52 | public void setMid(String mid) { 53 | this.mid = mid; 54 | } 55 | 56 | /** 57 | * 字符串型的评论ID 58 | */ 59 | public String getIdstr() { 60 | return idstr; 61 | } 62 | 63 | public void setIdstr(String idstr) { 64 | this.idstr = idstr; 65 | } 66 | 67 | /** 68 | * 评论创建时间 69 | */ 70 | public Date getCreatedAt() { 71 | return createdAt; 72 | } 73 | 74 | public void setCreatedAt(Date createdAt) { 75 | this.createdAt = createdAt; 76 | } 77 | 78 | /** 79 | * 评论的内容 80 | */ 81 | public String getText() { 82 | return text; 83 | } 84 | 85 | public void setText(String text) { 86 | this.text = text; 87 | } 88 | 89 | /** 90 | * 评论的来源 91 | */ 92 | public String getSource() { 93 | return source; 94 | } 95 | 96 | public void setSource(String source) { 97 | this.source = source; 98 | } 99 | 100 | /** 101 | * 评论作者的用户信息字段 102 | */ 103 | public User getUser() { 104 | return user; 105 | } 106 | 107 | public void setUser(User user) { 108 | this.user = user; 109 | } 110 | 111 | /** 112 | * 评论的微博信息字段 113 | */ 114 | public Status getStatus() { 115 | return status; 116 | } 117 | 118 | public void setStatus(Status status) { 119 | this.status = status; 120 | } 121 | 122 | /** 123 | * 评论来源评论,当本评论属于对另一评论的回复时返回此字段 124 | */ 125 | public Comment getReplyComment() { 126 | return replyComment; 127 | } 128 | 129 | public void setReplyComment(Comment replyComment) { 130 | this.replyComment = replyComment; 131 | } 132 | 133 | public static Comment parse(JSONObject jsonObject) { 134 | if (jsonObject == null) { 135 | return null; 136 | } 137 | Comment obj = new Comment(jsonObject); 138 | obj.id = Result.toString(jsonObject.get("id")); 139 | obj.mid = Result.toString(jsonObject.opt("mid")); 140 | obj.idstr = Result.toString(jsonObject.opt("idstr")); 141 | obj.createdAt = 142 | Result 143 | .parseDate(jsonObject.opt("created_at"), "EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH); 144 | 145 | obj.text = Result.toString(jsonObject.get("text")); 146 | obj.source = Result.toString(jsonObject.opt("source")); 147 | 148 | obj.user = User.parse(jsonObject.optJSONObject("user")); 149 | obj.status = Status.parse(jsonObject); 150 | obj.replyComment = Comment.parse(jsonObject.optJSONObject("reply_comment")); 151 | return obj; 152 | } 153 | 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/Display.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | /** 4 | * 授权页面的终端类型 5 | */ 6 | public enum Display { 7 | 8 | /** 9 | * 默认的授权页面,适用于web浏览器。 10 | */ 11 | DEFAULT("default"), 12 | 13 | /** 14 | * 移动终端的授权页面,适用于支持html5的手机。注:使用此版授权页请用 https://open.weibo.cn/oauth2/authorize 授权接口 15 | */ 16 | MOBILE("mobile"), 17 | 18 | /** 19 | * wap版授权页面,适用于非智能手机。 20 | */ 21 | WAP("wap"), 22 | 23 | /** 24 | * 客户端版本授权页面,适用于PC桌面应用。 25 | */ 26 | CLIENT("client"), 27 | 28 | /** 29 | * 默认的站内应用授权页,授权后不返回access_token,只刷新站内应用父框架。 30 | */ 31 | APPONWEIBO("apponweibo"); 32 | 33 | private String display; 34 | 35 | private Display(String display) { 36 | this.display = display; 37 | } 38 | 39 | public String value() { 40 | return display; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return display; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/Geo.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * 地理信息 10 | * 11 | * 文档地址:http://open.weibo.com/wiki/常见返回对象数据结构#.E5.9C.B0.E7.90.86.E4.BF.A1.E6.81.AF.EF.BC.88geo.EF.BC 12 | * .89 13 | */ 14 | public class Geo extends JsonBean { 15 | 16 | public Geo() {} 17 | 18 | private Geo(JSONObject jsonObject) { 19 | super(jsonObject); 20 | } 21 | 22 | private Double longitude;// 经度坐标 23 | private Double latitude;// 维度坐标 24 | private String city;// 所在城市的城市代码 25 | private String province;// 所在省份的省份代码 26 | private String cityName;// 所在城市的城市名称 27 | private String provinceName;// 所在省份的省份名称 28 | private String address;// 所在的实际地址,可以为空 29 | private String pinyin;// 地址的汉语拼音,不是所有情况都会返回该字段 30 | private String more;// 更多信息,不是所有情况都会返回该字段 31 | 32 | /** 33 | * 经度坐标 34 | */ 35 | public Double getLongitude() { 36 | return longitude; 37 | } 38 | 39 | public void setLongitude(Double longitude) { 40 | this.longitude = longitude; 41 | } 42 | 43 | /** 44 | * 维度坐标 45 | */ 46 | public Double getLatitude() { 47 | return latitude; 48 | } 49 | 50 | public void setLatitude(Double latitude) { 51 | this.latitude = latitude; 52 | } 53 | 54 | /** 55 | * 所在城市的城市代码 56 | */ 57 | public String getCity() { 58 | return city; 59 | } 60 | 61 | public void setCity(String city) { 62 | this.city = city; 63 | } 64 | 65 | /** 66 | * 所在省份的省份代码 67 | */ 68 | public String getProvince() { 69 | return province; 70 | } 71 | 72 | public void setProvince(String province) { 73 | this.province = province; 74 | } 75 | 76 | /** 77 | * 所在城市的城市名称 78 | */ 79 | public String getCityName() { 80 | return cityName; 81 | } 82 | 83 | public void setCityName(String cityName) { 84 | this.cityName = cityName; 85 | } 86 | 87 | /** 88 | * 所在省份的省份名称 89 | */ 90 | public String getProvinceName() { 91 | return provinceName; 92 | } 93 | 94 | public void setProvinceName(String provinceName) { 95 | this.provinceName = provinceName; 96 | } 97 | 98 | /** 99 | * 所在的实际地址,可以为空 100 | */ 101 | public String getAddress() { 102 | return address; 103 | } 104 | 105 | public void setAddress(String address) { 106 | this.address = address; 107 | } 108 | 109 | /** 110 | * 地址的汉语拼音,不是所有情况都会返回该字段 111 | */ 112 | public String getPinyin() { 113 | return pinyin; 114 | } 115 | 116 | public void setPinyin(String pinyin) { 117 | this.pinyin = pinyin; 118 | } 119 | 120 | /** 121 | * 更多信息,不是所有情况都会返回该字段 122 | */ 123 | public String getMore() { 124 | return more; 125 | } 126 | 127 | public void setMore(String more) { 128 | this.more = more; 129 | } 130 | 131 | public static Geo parse(JSONObject jsonObject) { 132 | if (jsonObject == null) { 133 | return null; 134 | } 135 | Geo obj = new Geo(jsonObject); 136 | obj.longitude = Result.parseDouble(jsonObject.get("longitude")); 137 | obj.latitude = Result.parseDouble(jsonObject.get("latitude")); 138 | obj.city = Result.toString(jsonObject.opt("city")); 139 | obj.province = Result.toString(jsonObject.opt("province")); 140 | obj.cityName = Result.toString(jsonObject.opt("city_name")); 141 | obj.provinceName = Result.toString(jsonObject.opt("province_name")); 142 | obj.address = Result.toString(jsonObject.opt("address")); 143 | obj.pinyin = Result.toString(jsonObject.opt("pinyin")); 144 | obj.more = Result.toString(jsonObject.opt("more")); 145 | return obj; 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/Privacy.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * 隐私设置 10 | */ 11 | public class Privacy extends JsonBean { 12 | 13 | public Privacy() {} 14 | 15 | private Privacy(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private Integer comment;// 是否可以评论我的微博,0:所有人、1:关注的人、2:可信用户 20 | private Integer geo;// 是否开启地理信息,0:不开启、1:开启 21 | private Integer message;// 是否可以给我发私信,0:所有人、1:我关注的人、2:可信用户 22 | private Integer realname;// 是否可以通过真名搜索到我,0:不可以、1:可以 23 | private Integer badge;// 勋章是否可见,0:不可见、1:可见 24 | private Integer mobile;// 是否可以通过手机号码搜索到我,0:不可以、1:可以 25 | private Integer webim;// 是否开启webim, 0:不开启、1:开启 26 | 27 | /** 28 | * 是否可以评论我的微博,0:所有人、1:关注的人、2:可信用户 29 | */ 30 | public Integer getComment() { 31 | return comment; 32 | } 33 | 34 | public void setComment(Integer comment) { 35 | this.comment = comment; 36 | } 37 | 38 | /** 39 | * 是否开启地理信息,0:不开启、1:开启 40 | */ 41 | public Integer getGeo() { 42 | return geo; 43 | } 44 | 45 | public void setGeo(Integer geo) { 46 | this.geo = geo; 47 | } 48 | 49 | /** 50 | * 是否可以给我发私信,0:所有人、1:我关注的人、2:可信用户 51 | */ 52 | public Integer getMessage() { 53 | return message; 54 | } 55 | 56 | public void setMessage(Integer message) { 57 | this.message = message; 58 | } 59 | 60 | /** 61 | * 是否可以通过真名搜索到我,0:不可以、1:可以 62 | */ 63 | public Integer getRealname() { 64 | return realname; 65 | } 66 | 67 | public void setRealname(Integer realname) { 68 | this.realname = realname; 69 | } 70 | 71 | /** 72 | * 勋章是否可见,0:不可见、1:可见 73 | */ 74 | public Integer getBadge() { 75 | return badge; 76 | } 77 | 78 | public void setBadge(Integer badge) { 79 | this.badge = badge; 80 | } 81 | 82 | /** 83 | * 是否可以通过手机号码搜索到我,0:不可以、1:可以 84 | */ 85 | public Integer getMobile() { 86 | return mobile; 87 | } 88 | 89 | public void setMobile(Integer mobile) { 90 | this.mobile = mobile; 91 | } 92 | 93 | /** 94 | * 是否开启webim, 0:不开启、1:开启 95 | */ 96 | public Integer getWebim() { 97 | return webim; 98 | } 99 | 100 | public void setWebim(Integer webim) { 101 | this.webim = webim; 102 | } 103 | 104 | public static Privacy parse(JSONObject jsonObject) { 105 | if (jsonObject == null) { 106 | return null; 107 | } 108 | Privacy obj = new Privacy(jsonObject); 109 | obj.comment = Result.parseInteger(jsonObject.opt("comment")); 110 | obj.geo = Result.parseInteger(jsonObject.opt("geo")); 111 | obj.message = Result.parseInteger(jsonObject.opt("message")); 112 | obj.realname = Result.parseInteger(jsonObject.opt("realname")); 113 | obj.badge = Result.parseInteger(jsonObject.opt("badge")); 114 | obj.mobile = Result.parseInteger(jsonObject.opt("mobile")); 115 | obj.webim = Result.parseInteger(jsonObject.opt("webim")); 116 | return obj; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/Remind.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * 消息未读数 10 | */ 11 | public class Remind extends JsonBean { 12 | 13 | public Remind() {} 14 | 15 | private Remind(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private Integer status;// 新微博未读数 20 | private Integer follower;// 新粉丝数 21 | private Integer cmt;// 新评论数 22 | private Integer dm;// 新私信数 23 | private Integer mentionStatus;// 新提及我的微博数 24 | private Integer mentionCmt;// 新提及我的评论数 25 | private Integer group;// 微群消息未读数 26 | private Integer privateGroup;// 私有微群消息未读数 27 | private Integer notice;// 新通知未读数 28 | private Integer invite;// 新邀请未读数 29 | private Integer badge;// 新勋章数 30 | private Integer photo;// 相册消息未读数 31 | private Integer msgbox;// 消息未读数 32 | 33 | /** 34 | * 新微博未读数 35 | */ 36 | public Integer getStatus() { 37 | return status; 38 | } 39 | 40 | public void setStatus(Integer status) { 41 | this.status = status; 42 | } 43 | 44 | /** 45 | * 新粉丝数 46 | */ 47 | public Integer getFollower() { 48 | return follower; 49 | } 50 | 51 | public void setFollower(Integer follower) { 52 | this.follower = follower; 53 | } 54 | 55 | /** 56 | * 新评论数 57 | */ 58 | public Integer getCmt() { 59 | return cmt; 60 | } 61 | 62 | public void setCmt(Integer cmt) { 63 | this.cmt = cmt; 64 | } 65 | 66 | /** 67 | * 新私信数 68 | */ 69 | public Integer getDm() { 70 | return dm; 71 | } 72 | 73 | public void setDm(Integer dm) { 74 | this.dm = dm; 75 | } 76 | 77 | /** 78 | * 新提及我的微博数 79 | */ 80 | public Integer getMentionStatus() { 81 | return mentionStatus; 82 | } 83 | 84 | public void setMentionStatus(Integer mentionStatus) { 85 | this.mentionStatus = mentionStatus; 86 | } 87 | 88 | /** 89 | * 新提及我的评论数 90 | */ 91 | public Integer getMentionCmt() { 92 | return mentionCmt; 93 | } 94 | 95 | public void setMentionCmt(Integer mentionCmt) { 96 | this.mentionCmt = mentionCmt; 97 | } 98 | 99 | /** 100 | * 微群消息未读数 101 | */ 102 | public Integer getGroup() { 103 | return group; 104 | } 105 | 106 | public void setGroup(Integer group) { 107 | this.group = group; 108 | } 109 | 110 | /** 111 | * 私有微群消息未读数 112 | */ 113 | public Integer getPrivateGroup() { 114 | return privateGroup; 115 | } 116 | 117 | public void setPrivateGroup(Integer privateGroup) { 118 | this.privateGroup = privateGroup; 119 | } 120 | 121 | /** 122 | * 新通知未读数 123 | */ 124 | public Integer getNotice() { 125 | return notice; 126 | } 127 | 128 | public void setNotice(Integer notice) { 129 | this.notice = notice; 130 | } 131 | 132 | /** 133 | * 新邀请未读数 134 | */ 135 | public Integer getInvite() { 136 | return invite; 137 | } 138 | 139 | public void setInvite(Integer invite) { 140 | this.invite = invite; 141 | } 142 | 143 | /** 144 | * 新勋章数 145 | */ 146 | public Integer getBadge() { 147 | return badge; 148 | } 149 | 150 | public void setBadge(Integer badge) { 151 | this.badge = badge; 152 | } 153 | 154 | /** 155 | * 相册消息未读数 156 | */ 157 | public Integer getPhoto() { 158 | return photo; 159 | } 160 | 161 | public void setPhoto(Integer photo) { 162 | this.photo = photo; 163 | } 164 | 165 | /** 166 | * 消息未读数 167 | */ 168 | public Integer getMsgbox() { 169 | return msgbox; 170 | } 171 | 172 | public void setMsgbox(Integer msgbox) { 173 | this.msgbox = msgbox; 174 | } 175 | 176 | public static Remind parse(JSONObject jsonObject) { 177 | if (jsonObject == null) { 178 | return null; 179 | } 180 | Remind obj = new Remind(jsonObject); 181 | obj.status = Result.parseInteger(jsonObject.opt("status")); 182 | obj.follower = Result.parseInteger(jsonObject.opt("follower")); 183 | obj.cmt = Result.parseInteger(jsonObject.opt("cmt")); 184 | obj.dm = Result.parseInteger(jsonObject.opt("dm")); 185 | obj.mentionStatus = Result.parseInteger(jsonObject.opt("mention_status")); 186 | obj.mentionCmt = Result.parseInteger(jsonObject.opt("mention_cmt")); 187 | obj.group = Result.parseInteger(jsonObject.opt("group")); 188 | obj.privateGroup = Result.parseInteger(jsonObject.opt("private_group")); 189 | obj.notice = Result.parseInteger(jsonObject.opt("notice")); 190 | obj.invite = Result.parseInteger(jsonObject.opt("invite")); 191 | obj.badge = Result.parseInteger(jsonObject.opt("badge")); 192 | obj.photo = Result.parseInteger(jsonObject.opt("photo")); 193 | obj.msgbox = Result.parseInteger(jsonObject.opt("msgbox")); 194 | return obj; 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/Scope.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | /** 4 | * scope是OAuth2.0授权机制中authorize接口的一个参数 5 | * 6 | * 通过scope,平台将开放更多的微博核心功能给开发者,同时也加强用户隐私保护,提升了用户体验,用户在新OAuth2.0授权页中有权利选择赋予应用的功能。 7 | */ 8 | public enum Scope { 9 | 10 | /** 11 | * 请求下列所有scope权限 12 | */ 13 | ALL("all"), 14 | 15 | /** 16 | * 用户的联系邮箱 17 | */ 18 | EMAIL("email"), 19 | 20 | /** 21 | * 私信发送接口 22 | */ 23 | DIRECT_MESSAGES_WRITE("direct_messages_write"), 24 | 25 | /** 26 | * 私信读取接口 27 | */ 28 | DIRECT_MESSAGES_READ("direct_messages_read"), 29 | 30 | /** 31 | * 邀请发送接口 32 | */ 33 | INVITATION_WRITE("invitation_write"), 34 | 35 | /** 36 | * 好友分组读取接口组 37 | */ 38 | FRIENDSHIPS_GROUPS_READ("friendships_groups_read"), 39 | 40 | /** 41 | * 好友分组写入接口组 42 | */ 43 | FRIENDSHIPS_GROUPS_WRITE("friendships_groups_write"), 44 | 45 | /** 46 | * 定向微博读取接口组 47 | */ 48 | STATUSES_TO_ME_READ("statuses_to_me_read"), 49 | 50 | /** 51 | * 关注应用官方微博,该参数不对应具体接口,只需在应用控制台填写官方帐号即可(默认值是应用开发者帐号) 52 | */ 53 | FOLLOW_APP_OFFICIAL_MICROBLOG("follow_app_official_microblog"); 54 | 55 | private String scope; 56 | 57 | private Scope(String scope) { 58 | this.scope = scope; 59 | } 60 | 61 | public String value() { 62 | return scope; 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return scope; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/TokenInfo.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | public class TokenInfo extends JsonBean { 9 | 10 | public TokenInfo() {} 11 | 12 | private TokenInfo(JSONObject jsonObject) { 13 | super(jsonObject); 14 | } 15 | 16 | private String uid; 17 | private String appkey;// access_token所属的应用appkey。 18 | private String scope;// 用户授权的scope权限。 19 | private Long createAt;// access_token的创建时间,从1970年到创建时间的秒数。 20 | private Long expireIn;// access_token的剩余时间,单位是秒数。 21 | 22 | /** 23 | * 授权用户的uid。 24 | */ 25 | public String getUid() { 26 | return uid; 27 | } 28 | 29 | public void setUid(String uid) { 30 | this.uid = uid; 31 | } 32 | 33 | /** 34 | * access_token所属的应用appkey。 35 | */ 36 | public String getAppkey() { 37 | return appkey; 38 | } 39 | 40 | public void setAppkey(String appkey) { 41 | this.appkey = appkey; 42 | } 43 | 44 | /** 45 | * 用户授权的scope权限。 46 | */ 47 | public String getScope() { 48 | return scope; 49 | } 50 | 51 | public void setScope(String scope) { 52 | this.scope = scope; 53 | } 54 | 55 | /** 56 | * access_token的创建时间,从1970年到创建时间的秒数。 57 | */ 58 | public Long getCreateAt() { 59 | return createAt; 60 | } 61 | 62 | public void setCreateAt(Long createAt) { 63 | this.createAt = createAt; 64 | } 65 | 66 | 67 | /** 68 | * access_token的剩余时间,单位是秒数。 69 | */ 70 | public Long getExpireIn() { 71 | return expireIn; 72 | } 73 | 74 | public void setExpireIn(Long expireIn) { 75 | this.expireIn = expireIn; 76 | } 77 | 78 | public static TokenInfo parse(JSONObject jsonObject) { 79 | TokenInfo obj = new TokenInfo(jsonObject); 80 | obj.uid = Result.toString(jsonObject.get("uid")); 81 | obj.appkey = Result.toString(jsonObject.opt("appkey")); 82 | obj.scope = Result.toString(jsonObject.opt("scope")); 83 | obj.createAt = Result.parseLong(jsonObject.opt("create_at")); 84 | obj.expireIn = Result.parseLong(jsonObject.opt("expire_in")); 85 | return obj; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/UrlShort.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * 短链 10 | */ 11 | public class UrlShort extends JsonBean { 12 | 13 | public UrlShort() {} 14 | 15 | private UrlShort(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private String urlShort;// 短链接 20 | private String urlLong;// 原始长链接 21 | private Integer type;// 链接的类型,0:普通网页、1:视频、2:音乐、3:活动、5、投票 22 | private Boolean result;// 短链的可用状态,true:可用、false:不可用。 23 | 24 | /** 25 | * 短链接 26 | */ 27 | public String getUrlShort() { 28 | return urlShort; 29 | } 30 | 31 | public void setUrlShort(String urlShort) { 32 | this.urlShort = urlShort; 33 | } 34 | 35 | /** 36 | * 原始长链接 37 | */ 38 | public String getUrlLong() { 39 | return urlLong; 40 | } 41 | 42 | public void setUrlLong(String urlLong) { 43 | this.urlLong = urlLong; 44 | } 45 | 46 | /** 47 | * 链接的类型,0:普通网页、1:视频、2:音乐、3:活动、5、投票 48 | */ 49 | public Integer getType() { 50 | return type; 51 | } 52 | 53 | public void setType(Integer type) { 54 | this.type = type; 55 | } 56 | 57 | /** 58 | * 短链的可用状态,true:可用、false:不可用。 59 | */ 60 | public Boolean getResult() { 61 | return result; 62 | } 63 | 64 | public void setResult(Boolean result) { 65 | this.result = result; 66 | } 67 | 68 | public static UrlShort parse(JSONObject jsonObject) { 69 | if (jsonObject == null) { 70 | return null; 71 | } 72 | UrlShort obj = new UrlShort(jsonObject); 73 | obj.urlShort = Result.toString(jsonObject.opt("url_short")); 74 | obj.urlLong = Result.toString(jsonObject.opt("url_long")); 75 | obj.type = Result.parseInteger(jsonObject.opt("type")); 76 | obj.result = Result.parseBoolean(jsonObject.opt("result")); 77 | return obj; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/UserCounts.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * 用户的粉丝数、关注数、微博数 10 | */ 11 | public class UserCounts extends JsonBean { 12 | 13 | public UserCounts() {} 14 | 15 | private UserCounts(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private String id;// 微博ID 20 | private Integer followersCount;// 粉丝数 21 | private Integer friendsCount;// 关注数 22 | private Integer statusesCount;// 微博数 23 | private Integer privateFriendsCount;// 暂未支持 24 | 25 | /** 26 | * 微博ID 27 | */ 28 | public String getId() { 29 | return id; 30 | } 31 | 32 | public void setId(String id) { 33 | this.id = id; 34 | } 35 | 36 | /** 37 | * 粉丝数 38 | */ 39 | public Integer getFollowersCount() { 40 | return followersCount; 41 | } 42 | 43 | public void setFollowersCount(Integer followersCount) { 44 | this.followersCount = followersCount; 45 | } 46 | 47 | /** 48 | * 关注数 49 | */ 50 | public Integer getFriendsCount() { 51 | return friendsCount; 52 | } 53 | 54 | public void setFriendsCount(Integer friendsCount) { 55 | this.friendsCount = friendsCount; 56 | } 57 | 58 | /** 59 | * 微博数 60 | */ 61 | public Integer getStatusesCount() { 62 | return statusesCount; 63 | } 64 | 65 | public void setStatusesCount(Integer statusesCount) { 66 | this.statusesCount = statusesCount; 67 | } 68 | 69 | /** 70 | * 暂未支持 71 | */ 72 | public Integer getPrivateFriendsCount() { 73 | return privateFriendsCount; 74 | } 75 | 76 | public void setPrivateFriendsCount(Integer privateFriendsCount) { 77 | this.privateFriendsCount = privateFriendsCount; 78 | } 79 | 80 | 81 | public static UserCounts parse(JSONObject jsonObject) { 82 | UserCounts obj = new UserCounts(jsonObject); 83 | obj.id = Result.toString(jsonObject.get("id")); 84 | obj.followersCount = Result.parseInteger(jsonObject.opt("followers_count")); 85 | obj.friendsCount = Result.parseInteger(jsonObject.opt("friends_count")); 86 | obj.statusesCount = Result.parseInteger(jsonObject.opt("statuses_count")); 87 | obj.privateFriendsCount = Result.parseInteger(jsonObject.opt("private_friends_count")); 88 | return obj; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weibo/bean/Visible.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * 微博的可见性及指定可见分组信息 10 | */ 11 | public class Visible extends JsonBean { 12 | 13 | public Visible() {} 14 | 15 | private Visible(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private Integer type;// 0:普通微博,1:私密微博,3:指定分组微博,4:密友微博 20 | private Integer listId;// 分组的组号 21 | 22 | /** 23 | * 0:普通微博,1:私密微博,3:指定分组微博,4:密友微博 24 | */ 25 | public Integer getType() { 26 | return type; 27 | } 28 | 29 | public void setType(Integer type) { 30 | this.type = type; 31 | } 32 | 33 | /** 34 | * 分组的组号 35 | */ 36 | public Integer getListId() { 37 | return listId; 38 | } 39 | 40 | public void setListId(Integer listId) { 41 | this.listId = listId; 42 | } 43 | 44 | public static Visible parse(JSONObject jsonObject) { 45 | if (jsonObject == null) { 46 | return null; 47 | } 48 | Visible obj = new Visible(jsonObject); 49 | obj.type = Result.parseInteger(jsonObject.opt("type")); 50 | obj.listId = Result.parseInteger(jsonObject.opt("list_id")); 51 | return obj; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/api/Group.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import org.apache.http.NameValuePair; 8 | import org.apache.http.entity.StringEntity; 9 | import org.json.JSONObject; 10 | 11 | import com.belerweb.social.API; 12 | import com.belerweb.social.bean.Error; 13 | import com.belerweb.social.bean.Result; 14 | import com.belerweb.social.exception.SocialException; 15 | 16 | /** 17 | * 分组管理接口 18 | * 19 | * 文档地址:http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口 20 | */ 21 | public class Group extends API { 22 | 23 | protected Group(Weixin weixin) { 24 | super(weixin); 25 | } 26 | 27 | /** 28 | * 查询分组 29 | */ 30 | public Result> get() { 31 | return get(weixin.getAccessToken().getToken()); 32 | } 33 | 34 | /** 35 | * 查询分组 36 | * 37 | * @param accessToken 调用接口凭证 38 | */ 39 | public Result> get(String accessToken) { 40 | List params = new ArrayList(); 41 | weixin.addParameter(params, "access_token", accessToken); 42 | String json = weixin.get("https://api.weixin.qq.com/cgi-bin/groups/get", params); 43 | JSONObject jsonObject = new JSONObject(json); 44 | Error error = Error.parse(jsonObject); 45 | if (error == null) { 46 | List groups = 47 | Result.parse(jsonObject.getJSONArray("groups"), 48 | com.belerweb.social.weixin.bean.Group.class); 49 | return new Result>(groups); 50 | } 51 | return new Result>(error); 52 | } 53 | 54 | /** 55 | * 创建分组 56 | * 57 | * @param name 分组名字(30个字符以内) 58 | */ 59 | public Result create(String name) { 60 | return create(weixin.getAccessToken().getToken(), name); 61 | } 62 | 63 | /** 64 | * 创建分组 65 | * 66 | * 一个公众账号,最多支持创建500个分组。 67 | * 68 | * @param accessToken 调用接口凭证 69 | * @param name 分组名字(30个字符以内) 70 | */ 71 | public Result create(String accessToken, String name) { 72 | JSONObject request = new JSONObject(); 73 | JSONObject group = new JSONObject(); 74 | group.put("name", name); 75 | request.put("group", group); 76 | try { 77 | String json = 78 | weixin.post( 79 | "https://api.weixin.qq.com/cgi-bin/groups/create?access_token=" + accessToken, 80 | new StringEntity(request.toString())); 81 | JSONObject jsonObject = new JSONObject(json); 82 | Error error = Error.parse(jsonObject); 83 | if (error != null) { 84 | return new Result(error); 85 | } 86 | return new Result( 87 | com.belerweb.social.weixin.bean.Group.parse(jsonObject.getJSONObject("group"))); 88 | } catch (UnsupportedEncodingException e) { 89 | throw new SocialException(e); 90 | } 91 | } 92 | 93 | /** 94 | * 修改分组名 95 | * 96 | * @param id 分组id,由微信分配 97 | * @param name 分组名字(30个字符以内) 98 | */ 99 | public Result update(String id, String name) { 100 | return update(weixin.getAccessToken().getToken(), id, name); 101 | } 102 | 103 | /** 104 | * 修改分组名 105 | * 106 | * @param accessToken 调用接口凭证 107 | * @param id 分组id,由微信分配 108 | * @param name 分组名字(30个字符以内) 109 | */ 110 | public Result update(String accessToken, String id, String name) { 111 | JSONObject request = new JSONObject(); 112 | JSONObject group = new JSONObject(); 113 | group.put("id", id); 114 | group.put("name", name); 115 | request.put("group", group); 116 | try { 117 | String json = 118 | weixin.post( 119 | "https://api.weixin.qq.com/cgi-bin/groups/update?access_token=" + accessToken, 120 | new StringEntity(request.toString())); 121 | return Result.parse(json, Error.class); 122 | } catch (UnsupportedEncodingException e) { 123 | throw new SocialException(e); 124 | } 125 | } 126 | 127 | /** 128 | * 移动用户分组 129 | * 130 | * @param openId 用户唯一标识符 131 | * @param groupId 分组id 132 | */ 133 | public Result move(String openId, String groupId) { 134 | return move(weixin.getAccessToken().getToken(), openId, groupId); 135 | } 136 | 137 | /** 138 | * 移动用户分组 139 | * 140 | * @param accessToken 调用接口凭证 141 | * @param openId 用户唯一标识符 142 | * @param groupId 分组id 143 | */ 144 | public Result move(String accessToken, String openId, String groupId) { 145 | JSONObject request = new JSONObject(); 146 | request.put("openid", openId); 147 | request.put("to_groupid", groupId); 148 | try { 149 | String json = 150 | weixin.post("https://api.weixin.qq.com/cgi-bin/groups/members/update?access_token=" 151 | + accessToken, new StringEntity(request.toString())); 152 | return Result.parse(json, Error.class); 153 | } catch (UnsupportedEncodingException e) { 154 | throw new SocialException(e); 155 | } 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/api/Media.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.commons.io.IOUtils; 6 | import org.apache.http.Header; 7 | import org.apache.http.HttpEntity; 8 | import org.apache.http.HttpResponse; 9 | import org.apache.http.client.ClientProtocolException; 10 | import org.apache.http.client.methods.HttpGet; 11 | import org.apache.http.client.methods.HttpPost; 12 | import org.apache.http.entity.ContentType; 13 | import org.apache.http.entity.mime.MultipartEntityBuilder; 14 | import org.json.JSONObject; 15 | 16 | import com.belerweb.social.API; 17 | import com.belerweb.social.bean.Error; 18 | import com.belerweb.social.bean.Result; 19 | import com.belerweb.social.exception.SocialException; 20 | import com.belerweb.social.http.Http; 21 | import com.belerweb.social.weixin.bean.MediaType; 22 | 23 | /** 24 | * 上传下载多媒体文件 25 | * 26 | * 文档地址:http://mp.weixin.qq.com/wiki/index.php?title=上传下载多媒体文件 27 | * 28 | * 公众号在使用接口时,对多媒体文件、多媒体消息的获取和调用等操作,是通过media_id来进行的。通过本接口,公众号可以上传或下载多媒体文件。但请注意,每个多媒体文件(media_id)会在上传、 29 | * 用户发送到微信服务器3天后自动删除,以节省服务器资源。 30 | * 31 | */ 32 | public class Media extends API { 33 | 34 | protected Media(Weixin weixin) { 35 | super(weixin); 36 | } 37 | 38 | /** 39 | * 上传多媒体文件,将把上传成功后的mediaId设置回传入的media中 40 | * 41 | * @param type 媒体文件类型 42 | * @param media form-data中媒体文件标识,有filename、filelength、content-type等信息 43 | */ 44 | public Result upload(MediaType type, 45 | com.belerweb.social.weixin.bean.Media media) { 46 | return upload(weixin.getAccessToken().getToken(), type, media); 47 | } 48 | 49 | /** 50 | * 上传多媒体文件,将把上传成功后的mediaId设置回传入的media中 51 | * 52 | * 图片(image): 256K,支持JPG格式 53 | * 54 | * 语音(voice):256K,播放长度不超过60s,支持AMR与MP3格式 55 | * 56 | * 视频(video):2MB,支持MP4格式 57 | * 58 | * 缩略图(thumb):64KB,支持JPG格式 59 | * 60 | * @param accessToken 调用接口凭证 61 | * @param type 媒体文件类型 62 | * @param media form-data中媒体文件标识,有filename、filelength、content-type等信息 63 | */ 64 | public Result upload(String accessToken, MediaType type, 65 | com.belerweb.social.weixin.bean.Media media) { 66 | String url = 67 | "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=" + accessToken + "&type=" 68 | + type.value(); 69 | HttpPost request = new HttpPost(url); 70 | MultipartEntityBuilder builder = 71 | MultipartEntityBuilder.create().addBinaryBody("media", media.getContent(), 72 | ContentType.create(media.getContentType()), media.getName()); 73 | request.setEntity(builder.build()); 74 | try { 75 | HttpResponse response = Http.CLIENT.execute(request); 76 | String json = IOUtils.toString(response.getEntity().getContent()); 77 | JSONObject jsonObject = new JSONObject(json); 78 | Error error = Error.parse(jsonObject); 79 | if (error != null) { 80 | return new Result(error); 81 | } 82 | media.setId(jsonObject.getString("media_id")); 83 | return new Result(media); 84 | } catch (ClientProtocolException e) { 85 | throw new SocialException(e); 86 | } catch (IOException e) { 87 | throw new SocialException(e); 88 | } 89 | } 90 | 91 | /** 92 | * 下载多媒体文件 93 | * 94 | * @param mediaId 媒体文件ID 95 | */ 96 | public Result get(String mediaId) { 97 | return get(weixin.getAccessToken().getToken(), mediaId); 98 | } 99 | 100 | /** 101 | * 下载多媒体文件 102 | * 103 | * 公众号可调用本接口来获取多媒体文件。请注意,调用该接口需http协议。 104 | * 105 | * @param accessToken 调用接口凭证 106 | * @param mediaId 媒体文件ID 107 | */ 108 | public Result get(String accessToken, String mediaId) { 109 | String url = 110 | "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=" + accessToken 111 | + "&media_id=" + mediaId; 112 | try { 113 | HttpResponse response = Http.CLIENT.execute(new HttpGet(url)); 114 | Header disposition = response.getFirstHeader("Content-disposition"); 115 | HttpEntity entity = response.getEntity(); 116 | if (disposition == null) { 117 | return new Result(Error.parse(new JSONObject(IOUtils 118 | .toString(entity.getContent())))); 119 | } 120 | 121 | String fileName = disposition.getValue(); 122 | fileName = fileName.substring(fileName.indexOf("\"") + 1, fileName.lastIndexOf("\"")); 123 | com.belerweb.social.weixin.bean.Media media = new com.belerweb.social.weixin.bean.Media(); 124 | media.setId(mediaId); 125 | media.setName(fileName); 126 | media.setContentType(entity.getContentType().getValue()); 127 | media.setContent(IOUtils.toByteArray(entity.getContent())); 128 | return new Result(media); 129 | } catch (ClientProtocolException e) { 130 | throw new SocialException(e); 131 | } catch (IOException e) { 132 | throw new SocialException(e); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/api/Menu.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import org.apache.http.NameValuePair; 8 | import org.apache.http.entity.StringEntity; 9 | import org.json.JSONArray; 10 | import org.json.JSONObject; 11 | 12 | import com.belerweb.social.API; 13 | import com.belerweb.social.bean.Error; 14 | import com.belerweb.social.bean.Result; 15 | import com.belerweb.social.exception.SocialException; 16 | import com.belerweb.social.weixin.bean.MenuType; 17 | 18 | /** 19 | * 自定义菜单接口 20 | * 21 | * 文档地址:http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单创建接口 22 | */ 23 | public class Menu extends API { 24 | 25 | protected Menu(Weixin weixin) { 26 | super(weixin); 27 | } 28 | 29 | /** 30 | * 自定义菜单创建接口 31 | * 32 | * @param menus 菜单 33 | */ 34 | public Result create(List menus) { 35 | return create(weixin.getAccessToken().getToken(), menus); 36 | } 37 | 38 | /** 39 | * 自定义菜单创建接口 40 | *

41 | * 注意:只有菜单类型为 MenuType.VIEW 时才需要url属性,其它情况都是使用key 42 | *

43 | * 44 | * @param accessToken 调用接口凭证 45 | * @param menus 菜单 46 | */ 47 | public Result create(String accessToken, List menus) { 48 | JSONArray menuArray = new JSONArray(); 49 | for (com.belerweb.social.weixin.bean.Menu menu : menus) { 50 | JSONObject obj = new JSONObject(); 51 | MenuType type = menu.getType(); 52 | obj.put("name", menu.getName()); 53 | if (type != null) { 54 | obj.put("type", type.value()); 55 | if (type == MenuType.VIEW) { 56 | obj.put("url", menu.getUrl()); 57 | } else { 58 | obj.put("key", menu.getKey()); 59 | } 60 | } 61 | List subs = menu.getSubs(); 62 | if (subs != null) { 63 | JSONArray _menuArray = new JSONArray(); 64 | for (com.belerweb.social.weixin.bean.Menu _menu : subs) { 65 | JSONObject _obj = new JSONObject(); 66 | MenuType _type = _menu.getType(); 67 | _obj.put("name", _menu.getName()); 68 | if (_type != null) { 69 | _obj.put("type", _type.value()); 70 | if (_type == MenuType.VIEW) { 71 | _obj.put("url", _menu.getUrl()); 72 | } else { 73 | _obj.put("key", _menu.getKey()); 74 | } 75 | } 76 | _menuArray.put(_obj); 77 | } 78 | obj.put("sub_button", _menuArray); 79 | } 80 | menuArray.put(obj); 81 | } 82 | JSONObject request = new JSONObject(); 83 | request.put("button", menuArray); 84 | try { 85 | String json = 86 | weixin.post("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + accessToken, 87 | new StringEntity(request.toString(), "UTF-8")); 88 | return Result.parse(json, Error.class); 89 | } catch (UnsupportedEncodingException e) { 90 | throw new SocialException(e); 91 | } 92 | } 93 | 94 | /** 95 | * 自定义菜单查询接口 96 | */ 97 | public Result> get() { 98 | return get(weixin.getAccessToken().getToken()); 99 | } 100 | 101 | /** 102 | * 自定义菜单查询接口 103 | * 104 | * @param accessToken 调用接口凭证 105 | */ 106 | public Result> get(String accessToken) { 107 | List params = new ArrayList(); 108 | weixin.addParameter(params, "access_token", accessToken); 109 | String json = weixin.get("https://api.weixin.qq.com/cgi-bin/menu/get", params); 110 | JSONObject jsonObject = new JSONObject(json); 111 | Error error = Error.parse(jsonObject); 112 | if (error != null) { 113 | return new Result>(error); 114 | } 115 | List menus = 116 | new ArrayList(); 117 | JSONObject menu = jsonObject.optJSONObject("menu"); 118 | if (menu != null) { 119 | menus = Result.parse(menu.optJSONArray("button"), com.belerweb.social.weixin.bean.Menu.class); 120 | } 121 | return new Result>(menus); 122 | } 123 | 124 | /** 125 | * 自定义菜单删除接口 126 | */ 127 | public Result delete() { 128 | return delete(weixin.getAccessToken().getToken()); 129 | } 130 | 131 | /** 132 | * 自定义菜单删除接口 133 | * 134 | * @param accessToken 调用接口凭证 135 | */ 136 | public Result delete(String accessToken) { 137 | List params = new ArrayList(); 138 | weixin.addParameter(params, "access_token", accessToken); 139 | String json = weixin.get("https://api.weixin.qq.com/cgi-bin/menu/delete", params); 140 | return Result.parse(json, Error.class); 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/api/User.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.commons.lang.StringUtils; 7 | import org.apache.http.NameValuePair; 8 | 9 | import com.belerweb.social.API; 10 | import com.belerweb.social.bean.Result; 11 | import com.belerweb.social.weixin.bean.GetFollowersResult; 12 | 13 | /** 14 | * 网页授权获取用户基本信息 15 | * 16 | * 如果用户在微信中(Web微信除外)访问公众号的第三方网页,公众号开发者可以通过此接口获取当前用户基本信息(包括昵称、性别、城市、国家)。利用用户信息,可以实现体验优化、用户来源统计、帐号绑定、 17 | * 用户身份鉴权等功能 18 | * 。请注意,“获取用户基本信息接口是在用户和公众号产生消息交互时,才能根据用户OpenID获取用户基本信息,而网页授权的方式获取用户基本信息,则无需消息交互,只是用户进入到公众号的网页 19 | * ,就可弹出请求用户授权的界面,用户授权后,就可获得其基本信息(此过程甚至不需要用户已经关注公众号。)” 20 | * 21 | * 本接口是通过OAuth2.0来完成网页授权的,是安全可靠的,关于OAuth2.0的详细介绍,可以参考OAuth2.0协议标准。在微信公众号请求用户网页授权之前, 22 | * 开发者需要先到公众平台网站中配置授权回调域名。 23 | */ 24 | public class User extends API { 25 | 26 | protected User(Weixin weixin) { 27 | super(weixin); 28 | } 29 | 30 | /** 31 | * 拉取用户信息(需scope为 snsapi_userinfo)。适用于网页授权的用户。 32 | * 33 | * 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。 34 | * 35 | * @param accessToken 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 36 | * @param openId 用户的唯一标识 37 | */ 38 | public Result snsapiUserInfo(String accessToken, 39 | String openId) { 40 | List params = new ArrayList(); 41 | weixin.addParameter(params, "access_token", accessToken); 42 | weixin.addParameter(params, "openid", openId); 43 | String json = weixin.get("https://api.weixin.qq.com/sns/userinfo", params); 44 | return Result.parse(json, com.belerweb.social.weixin.bean.User.class); 45 | } 46 | 47 | /** 48 | * 获取用户基本信息,适用于已关注公众帐号的用户。 49 | * 50 | * 在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。 51 | * 公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。 52 | * 53 | * @param accessToken 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 54 | * @param openId 用户的唯一标识 55 | */ 56 | public Result userInfo(String accessToken, String openId) { 57 | List params = new ArrayList(); 58 | weixin.addParameter(params, "access_token", accessToken); 59 | weixin.addParameter(params, "openid", openId); 60 | String json = weixin.get("https://api.weixin.qq.com/cgi-bin/user/info", params); 61 | return Result.parse(json, com.belerweb.social.weixin.bean.User.class); 62 | } 63 | 64 | /** 65 | * 获取所欲关注者列表,包含用户详细信息,该接口采用循环多次获取用户详细信息的方式。如果关注者太多可能会很慢。还会超过微信API调用次数限制。请谨慎调用。建议只在第一次同步关注着信息时调用。 66 | */ 67 | public Result> getFollowUsers() { 68 | return getFollowUsers(weixin.getAccessToken().getToken()); 69 | } 70 | 71 | /** 72 | * 获取所欲关注者列表,包含用户详细信息,该接口采用循环多次获取用户详细信息的方式。如果关注者太多可能会很慢。还会超过微信API调用次数限制。请谨慎调用。建议只在第一次同步关注着信息时调用。 73 | * 74 | * @param accessToken 调用接口凭证 75 | */ 76 | public Result> getFollowUsers(String accessToken) { 77 | List users = 78 | new ArrayList(); 79 | Result followersResult = getFollowers(accessToken); 80 | if (followersResult.success()) { 81 | for (String openId : followersResult.getResult().getOpenIds()) { 82 | Result userResult = userInfo(accessToken, openId); 83 | if (userResult.success()) { 84 | users.add(userResult.getResult()); 85 | } else { 86 | return new Result>(userResult.getError()); 87 | } 88 | } 89 | 90 | return new Result>(users); 91 | } 92 | return new Result>(followersResult.getError()); 93 | } 94 | 95 | /** 96 | * 获取所欲关注者列表 97 | */ 98 | public Result getFollowers() { 99 | return getFollowers(weixin.getAccessToken().getToken()); 100 | } 101 | 102 | /** 103 | * 获取所欲关注者列表 104 | * 105 | * @param accessToken 调用接口凭证 106 | */ 107 | public Result getFollowers(String accessToken) { 108 | GetFollowersResult result = new GetFollowersResult(); 109 | List openIds = new ArrayList(); 110 | Result followers = getFollowers(accessToken, null); 111 | while (followers.success()) { 112 | for (String openId : followers.getResult().getOpenIds()) { 113 | openIds.add(openId); 114 | } 115 | String nextOpenid = followers.getResult().getNextOpenid(); 116 | if (StringUtils.isBlank(nextOpenid) || followers.getResult().getTotal() == openIds.size()) { 117 | break; 118 | } 119 | followers = getFollowers(accessToken, nextOpenid); 120 | } 121 | if (!followers.success()) { 122 | return new Result(followers.getError()); 123 | } 124 | result.setTotal(openIds.size()); 125 | result.setCount(openIds.size()); 126 | result.setOpenIds(openIds); 127 | return new Result(result); 128 | } 129 | 130 | /** 131 | * 获取关注者列表 132 | * 133 | * 公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID 134 | * ,可以通过多次拉取的方式来满足需求。 135 | * 136 | * 文档地址:http://mp.weixin.qq.com/wiki/index.php?title=获取关注者列表 137 | * 138 | * @param accessToken 调用接口凭证 139 | * @param openId 第一个拉取的OPENID,不填默认从头开始拉取 140 | */ 141 | public Result getFollowers(String accessToken, String openId) { 142 | List params = new ArrayList(); 143 | weixin.addParameter(params, "access_token", accessToken); 144 | weixin.addNotNullParameter(params, "next_openid", openId); 145 | String json = weixin.get("https://api.weixin.qq.com/cgi-bin/user/get", params); 146 | return Result.parse(json, GetFollowersResult.class); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/AccessToken.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * 网页授权接口调用凭证 10 | */ 11 | public class AccessToken extends JsonBean { 12 | 13 | public AccessToken() {} 14 | 15 | private AccessToken(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private String token;// 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 20 | private Long expiresIn;// access_token接口调用凭证超时时间,单位(秒) 21 | private String refreshToken;// 用户刷新access_token 22 | private String openId;// 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID 23 | private Scope scope;// 用户授权的作用域,使用逗号(,)分隔 24 | private String unionid;// 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段 25 | 26 | /** 27 | * 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 28 | */ 29 | public String getToken() { 30 | return token; 31 | } 32 | 33 | public void setToken(String token) { 34 | this.token = token; 35 | } 36 | 37 | /** 38 | * access_token接口调用凭证超时时间,单位(秒) 39 | */ 40 | public Long getExpiresIn() { 41 | return expiresIn; 42 | } 43 | 44 | public void setExpiresIn(Long expiresIn) { 45 | this.expiresIn = expiresIn; 46 | } 47 | 48 | /** 49 | * 用户刷新access_token 50 | */ 51 | public String getRefreshToken() { 52 | return refreshToken; 53 | } 54 | 55 | public void setRefreshToken(String refreshToken) { 56 | this.refreshToken = refreshToken; 57 | } 58 | 59 | /** 60 | * 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID 61 | */ 62 | public String getOpenId() { 63 | return openId; 64 | } 65 | 66 | public void setOpenId(String openId) { 67 | this.openId = openId; 68 | } 69 | 70 | /** 71 | * 用户授权的作用域,使用逗号(,)分隔 72 | */ 73 | public Scope getScope() { 74 | return scope; 75 | } 76 | 77 | public void setScope(Scope scope) { 78 | this.scope = scope; 79 | } 80 | 81 | public String getUnionid() { 82 | return unionid; 83 | } 84 | 85 | public void setUnionid(String unionid) { 86 | this.unionid = unionid; 87 | } 88 | 89 | public static AccessToken parse(JSONObject jsonObject) { 90 | if (jsonObject == null) { 91 | return null; 92 | } 93 | AccessToken obj = new AccessToken(jsonObject); 94 | obj.token = jsonObject.getString("access_token"); 95 | obj.openId = Result.toString(jsonObject.opt("openid")); 96 | obj.expiresIn = Result.parseLong(jsonObject.opt("expires_in")); 97 | obj.refreshToken = Result.toString(jsonObject.opt("refresh_token")); 98 | obj.scope = Scope.parse(jsonObject.opt("scope")); 99 | obj.unionid = Result.toString(jsonObject.opt("unionid")); 100 | return obj; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/ApiTicket.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * api_ticket 是用于调用微信卡券JS API的临时票据,有效期为7200 秒,通过access_token 来获取。 10 | */ 11 | public class ApiTicket extends JsonBean { 12 | 13 | public ApiTicket() {} 14 | 15 | private ApiTicket(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private String ticket;// ticket是公众号用于调用微信卡券JS API的临时票据 20 | private Long expiresIn;// api_ticket接口调用凭证超时时间,单位(秒) 21 | 22 | public String getTicket() { 23 | return ticket; 24 | } 25 | 26 | public void setTicket(String ticket) { 27 | this.ticket = ticket; 28 | } 29 | 30 | public Long getExpiresIn() { 31 | return expiresIn; 32 | } 33 | 34 | public void setExpiresIn(Long expiresIn) { 35 | this.expiresIn = expiresIn; 36 | } 37 | 38 | public static ApiTicket parse(JSONObject jsonObject) { 39 | if (jsonObject == null) { 40 | return null; 41 | } 42 | ApiTicket obj = new ApiTicket(jsonObject); 43 | obj.ticket = jsonObject.getString("ticket"); 44 | obj.expiresIn = Result.parseLong(jsonObject.opt("expires_in")); 45 | return obj; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/Article.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | /** 4 | * 图文 5 | */ 6 | public class Article { 7 | 8 | private String title;// 图文消息标题 9 | private String description;// 图文消息描述 10 | private String picUrl;// 图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200 11 | private String url;// 点击图文消息跳转链接 12 | 13 | /** 14 | * 图文消息标题 15 | */ 16 | public String getTitle() { 17 | return title; 18 | } 19 | 20 | public void setTitle(String title) { 21 | this.title = title; 22 | } 23 | 24 | /** 25 | * 图文消息描述 26 | */ 27 | public String getDescription() { 28 | return description; 29 | } 30 | 31 | public void setDescription(String description) { 32 | this.description = description; 33 | } 34 | 35 | /** 36 | * 图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200 37 | */ 38 | public String getPicUrl() { 39 | return picUrl; 40 | } 41 | 42 | public void setPicUrl(String picUrl) { 43 | this.picUrl = picUrl; 44 | } 45 | 46 | /** 47 | * 点击图文消息跳转链接 48 | */ 49 | public String getUrl() { 50 | return url; 51 | } 52 | 53 | public void setUrl(String url) { 54 | this.url = url; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/EventType.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | 4 | /** 5 | * 事件类型 6 | */ 7 | public enum EventType { 8 | 9 | /** 10 | * 订阅 11 | */ 12 | SUBSCRIBE("subscribe"), 13 | 14 | /** 15 | * 取消订阅 16 | */ 17 | UNSUBSCRIBE("unsubscribe"), 18 | 19 | /** 20 | * 扫描二维码:用户已关注时的事件推送 21 | */ 22 | SCAN("SCAN"), 23 | 24 | /** 25 | * 上报地理位置事件 26 | */ 27 | LOCATION("LOCATION"), 28 | 29 | /** 30 | * 点击链接事件 31 | */ 32 | VIEW("VIEW"), 33 | 34 | /** 35 | * 自定义菜单事件 36 | */ 37 | CLICK("CLICK"); 38 | 39 | private String type; 40 | 41 | private EventType(String type) { 42 | this.type = type; 43 | } 44 | 45 | public String value() { 46 | return type; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return type; 52 | } 53 | 54 | public static EventType parse(Object val) { 55 | if (SUBSCRIBE.type.equals(val)) { 56 | return SUBSCRIBE; 57 | } 58 | if (UNSUBSCRIBE.type.equals(val)) { 59 | return UNSUBSCRIBE; 60 | } 61 | if (SCAN.type.equals(val)) { 62 | return SCAN; 63 | } 64 | if (LOCATION.type.equals(val)) { 65 | return LOCATION; 66 | } 67 | if (CLICK.type.equals(val)) { 68 | return CLICK; 69 | } 70 | if (VIEW.type.equals(val)) { 71 | return VIEW; 72 | } 73 | return null; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/GetFollowersResult.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.json.JSONArray; 7 | import org.json.JSONObject; 8 | 9 | import com.belerweb.social.bean.JsonBean; 10 | import com.belerweb.social.bean.Result; 11 | 12 | /** 13 | * 获取关注者列表结果 14 | */ 15 | public class GetFollowersResult extends JsonBean { 16 | 17 | public GetFollowersResult() {} 18 | 19 | private GetFollowersResult(JSONObject jsonObject) { 20 | super(jsonObject); 21 | } 22 | 23 | private Integer total;// 关注该公众账号的总用户数 24 | private Integer count;// 拉取的OPENID个数,最大值为10000 25 | private List openIds;// OPENID的列表 26 | private String nextOpenid;// 拉取列表的后一个用户的OPENID 27 | 28 | /** 29 | * 关注该公众账号的总用户数 30 | */ 31 | public Integer getTotal() { 32 | return total; 33 | } 34 | 35 | public void setTotal(Integer total) { 36 | this.total = total; 37 | } 38 | 39 | /** 40 | * 拉取的OPENID个数,最大值为10000 41 | */ 42 | public Integer getCount() { 43 | return count; 44 | } 45 | 46 | public void setCount(Integer count) { 47 | this.count = count; 48 | } 49 | 50 | /** 51 | * OPENID的列表 52 | */ 53 | public List getOpenIds() { 54 | return openIds; 55 | } 56 | 57 | public void setOpenIds(List openIds) { 58 | this.openIds = openIds; 59 | } 60 | 61 | /** 62 | * 拉取列表的后一个用户的OPENID 63 | */ 64 | public String getNextOpenid() { 65 | return nextOpenid; 66 | } 67 | 68 | public void setNextOpenid(String nextOpenid) { 69 | this.nextOpenid = nextOpenid; 70 | } 71 | 72 | public static GetFollowersResult parse(JSONObject jsonObject) { 73 | if (jsonObject == null) { 74 | return null; 75 | } 76 | GetFollowersResult obj = new GetFollowersResult(jsonObject); 77 | obj.total = Result.parseInteger(jsonObject.get("total")); 78 | obj.count = Result.parseInteger(jsonObject.get("count")); 79 | obj.nextOpenid = Result.toString(jsonObject.opt("next_openid")); 80 | JSONArray openIdArray = jsonObject.getJSONObject("data").getJSONArray("openid"); 81 | List openIds = new ArrayList(); 82 | for (int i = 0; i < openIdArray.length(); i++) { 83 | openIds.add(openIdArray.getString(i)); 84 | } 85 | obj.openIds = openIds; 86 | return obj; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/Group.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * 分组 10 | */ 11 | public class Group extends JsonBean { 12 | 13 | public Group() {} 14 | 15 | private Group(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private String id;// 分组id,由微信分配 20 | private String name;// 分组名字,UTF8编码 21 | private Integer count;// 分组内用户数量 22 | 23 | /** 24 | * 分组id,由微信分配 25 | */ 26 | public String getId() { 27 | return id; 28 | } 29 | 30 | public void setId(String id) { 31 | this.id = id; 32 | } 33 | 34 | /** 35 | * 分组名字,UTF8编码 36 | */ 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public void setName(String name) { 42 | this.name = name; 43 | } 44 | 45 | /** 46 | * 分组内用户数量 47 | */ 48 | public Integer getCount() { 49 | return count; 50 | } 51 | 52 | public void setCount(Integer count) { 53 | this.count = count; 54 | } 55 | 56 | public static Group parse(JSONObject jsonObject) { 57 | if (jsonObject == null) { 58 | return null; 59 | } 60 | Group obj = new Group(jsonObject); 61 | obj.id = Result.toString(jsonObject.get("id")); 62 | obj.name = Result.toString(jsonObject.get("name")); 63 | obj.count = Result.parseInteger(jsonObject.opt("count")); 64 | return obj; 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/JSApiTicket.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。 10 | */ 11 | public class JSApiTicket extends JsonBean { 12 | 13 | public JSApiTicket() {} 14 | 15 | private JSApiTicket(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private String ticket;// ticket是公众号用于调用微信JS接口的临时票据 20 | private Long expiresIn;// jsapi_ticket接口调用凭证超时时间,单位(秒) 21 | 22 | public String getTicket() { 23 | return ticket; 24 | } 25 | 26 | public void setTicket(String ticket) { 27 | this.ticket = ticket; 28 | } 29 | 30 | public Long getExpiresIn() { 31 | return expiresIn; 32 | } 33 | 34 | public void setExpiresIn(Long expiresIn) { 35 | this.expiresIn = expiresIn; 36 | } 37 | 38 | public static JSApiTicket parse(JSONObject jsonObject) { 39 | if (jsonObject == null) { 40 | return null; 41 | } 42 | JSApiTicket obj = new JSApiTicket(jsonObject); 43 | obj.ticket = jsonObject.getString("ticket"); 44 | obj.expiresIn = Result.parseLong(jsonObject.opt("expires_in")); 45 | return obj; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/Media.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | 4 | /** 5 | * 媒体文件 6 | */ 7 | public class Media { 8 | 9 | private String id; 10 | private String name; 11 | private String contentType; 12 | private byte[] content; 13 | 14 | public String getId() { 15 | return id; 16 | } 17 | 18 | public void setId(String id) { 19 | this.id = id; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public String getContentType() { 31 | return contentType; 32 | } 33 | 34 | public void setContentType(String contentType) { 35 | this.contentType = contentType; 36 | } 37 | 38 | public byte[] getContent() { 39 | return content; 40 | } 41 | 42 | public void setContent(byte[] content) { 43 | this.content = content; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/MediaType.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | 4 | /** 5 | * 媒体文件类型 6 | */ 7 | public enum MediaType { 8 | 9 | /** 10 | * 图片 11 | */ 12 | IMAGE("image"), 13 | 14 | /** 15 | * 语音 16 | */ 17 | VOICE("voice"), 18 | 19 | /** 20 | * 语音 21 | */ 22 | VOICE_AMR("voice"), 23 | 24 | /** 25 | * 语音 26 | */ 27 | VOICE_MP3("voice"), 28 | 29 | /** 30 | * 视频 31 | */ 32 | VIDEO("video"), 33 | 34 | /** 35 | * 缩略图 36 | */ 37 | THUMB("thumb"); 38 | 39 | private String type; 40 | 41 | private MediaType(String type) { 42 | this.type = type; 43 | } 44 | 45 | public String value() { 46 | return type; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return type; 52 | } 53 | 54 | public String contentType() { 55 | if (this == IMAGE || this == THUMB) { 56 | return "image/jpeg"; 57 | } 58 | if (this == VOICE || this == VOICE_AMR) { 59 | return "audio/amr"; 60 | } 61 | if (this == VOICE_MP3) { 62 | return "audio/mp3"; 63 | } 64 | if (this == VIDEO) { 65 | return "audio/mp4"; 66 | } 67 | return null; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/Menu.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | import java.util.List; 4 | 5 | import org.json.JSONObject; 6 | 7 | import com.belerweb.social.bean.JsonBean; 8 | import com.belerweb.social.bean.Result; 9 | 10 | 11 | /** 12 | * 自定义菜单 13 | */ 14 | public class Menu extends JsonBean { 15 | 16 | public Menu() {} 17 | 18 | private Menu(JSONObject jsonObject) { 19 | super(jsonObject); 20 | } 21 | 22 | private MenuType type; 23 | private String key; 24 | private String url; 25 | private String name; 26 | private List subs; 27 | 28 | public MenuType getType() { 29 | return type; 30 | } 31 | 32 | public void setType(MenuType type) { 33 | this.type = type; 34 | } 35 | 36 | public String getKey() { 37 | return key; 38 | } 39 | 40 | public void setKey(String key) { 41 | this.key = key; 42 | } 43 | 44 | public String getUrl() { 45 | return url; 46 | } 47 | 48 | public void setUrl(String url) { 49 | this.url = url; 50 | } 51 | 52 | public String getName() { 53 | return name; 54 | } 55 | 56 | public void setName(String name) { 57 | this.name = name; 58 | } 59 | 60 | public List getSubs() { 61 | return subs; 62 | } 63 | 64 | public void setSubs(List subs) { 65 | this.subs = subs; 66 | } 67 | 68 | public static Menu parse(JSONObject jsonObject) { 69 | if (jsonObject == null) { 70 | return null; 71 | } 72 | Menu obj = new Menu(jsonObject); 73 | obj.name = Result.toString(jsonObject.get("name")); 74 | obj.key = Result.toString(jsonObject.opt("key")); 75 | obj.url = Result.toString(jsonObject.opt("url")); 76 | obj.type = MenuType.parse(jsonObject.opt("type")); 77 | obj.subs = Result.parse(jsonObject.optJSONArray("sub_button"), Menu.class); 78 | return obj; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/MenuType.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | 4 | /** 5 | * 自定义菜单类型 6 | */ 7 | public enum MenuType { 8 | 9 | /** 10 | * 用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值, 11 | * 开发者可以通过自定义的key值与用户进行交互; 12 | */ 13 | CLICK("click"), 14 | 15 | /** 16 | * 用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的url值 (即网页链接),达到打开网页的目的,建议与网页授权获取用户基本信息接口结合,获得用户的登入个人信息。 17 | */ 18 | VIEW("view"), 19 | 20 | /** 21 | * 扫码推事件,用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后显示扫描结果(如果是URL,将进入URL),且会将扫码的结果传给开发者,开发者可以下发消息。 22 | */ 23 | SCANCODE_PUSH("scancode_push"), 24 | 25 | /** 26 | * 扫码推事件且弹出“消息接收中”提示框,用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具, 27 | * 然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。 28 | */ 29 | SCANCODE_WAITMSG("scancode_waitmsg"), 30 | 31 | /** 32 | * 弹出系统拍照发图,用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。 33 | */ 34 | PIC_SYSPHOTO("pic_sysphoto"), 35 | 36 | /** 37 | * 弹出拍照或者相册发图,用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。 38 | */ 39 | PIC_PHOTO_OR_ALBUM("pic_photo_or_album"), 40 | 41 | /** 42 | * 弹出微信相册发图器,用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器, 并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。 43 | */ 44 | PIC_WEIXIN("pic_weixin"), 45 | 46 | /** 47 | * 弹出地理位置选择器,用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器, 同时收起位置选择工具,随后可能会收到开发者下发的消息。 48 | */ 49 | LOCATION_SELECT("location_select"), ; 50 | 51 | private String type; 52 | 53 | private MenuType(String type) { 54 | this.type = type; 55 | } 56 | 57 | public String value() { 58 | return type; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return type; 64 | } 65 | 66 | public static MenuType parse(Object val) { 67 | if (CLICK.type.equals(val)) { 68 | return CLICK; 69 | } 70 | if (VIEW.type.equals(val)) { 71 | return VIEW; 72 | } 73 | return null; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/MsgType.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | 4 | /** 5 | * 普通消息 6 | */ 7 | public enum MsgType { 8 | 9 | /** 10 | * 文本消息 11 | */ 12 | TEXT("text"), 13 | 14 | /** 15 | * 图片消息 16 | */ 17 | IMAGE("image"), 18 | 19 | /** 20 | * 语音消息 21 | */ 22 | VOICE("voice"), 23 | 24 | /** 25 | * 视频消息 26 | */ 27 | VIDEO("video"), 28 | 29 | /** 30 | * 视频消息 31 | */ 32 | SHORTVIDEO("shortvideo"), 33 | 34 | /** 35 | * 音乐消息 36 | */ 37 | MUSIC("music"), 38 | 39 | /** 40 | * 地理位置消息 41 | */ 42 | LOCATION("location"), 43 | 44 | /** 45 | * 链接消息 46 | */ 47 | LINK("link"), 48 | 49 | /** 50 | * 事件 51 | */ 52 | EVENT("event"), 53 | 54 | /** 55 | * 图文消息 56 | */ 57 | NEWS("news"), 58 | 59 | /** 60 | * 模板消息 61 | */ 62 | TEMPLATE("template"), 63 | 64 | /** 65 | * 多客服接入 66 | */ 67 | TRANSFER_CUSTOMER_SERVICE("transfer_customer_service"); 68 | 69 | private String type; 70 | 71 | private MsgType(String type) { 72 | this.type = type; 73 | } 74 | 75 | public String value() { 76 | return type; 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return type; 82 | } 83 | 84 | public static MsgType parse(Object val) { 85 | if (TEXT.type.equals(val)) { 86 | return TEXT; 87 | } 88 | if (IMAGE.type.equals(val)) { 89 | return IMAGE; 90 | } 91 | if (VOICE.type.equals(val)) { 92 | return VOICE; 93 | } 94 | if (VIDEO.type.equals(val)) { 95 | return VIDEO; 96 | } 97 | if (MUSIC.type.equals(val)) { 98 | return MUSIC; 99 | } 100 | if (LOCATION.type.equals(val)) { 101 | return LOCATION; 102 | } 103 | if (LINK.type.equals(val)) { 104 | return LINK; 105 | } 106 | if (EVENT.type.equals(val)) { 107 | return EVENT; 108 | } 109 | if (NEWS.type.equals(val)) { 110 | return NEWS; 111 | } 112 | if (TEMPLATE.type.equals(val)) { 113 | return TEMPLATE; 114 | } 115 | if (TRANSFER_CUSTOMER_SERVICE.type.equals(val)) { 116 | return TRANSFER_CUSTOMER_SERVICE; 117 | } 118 | return null; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/QRCreation.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | public class QRCreation { 6 | 7 | private QRType type;// 二维码类型,QR_SCENE为临时,QR_LIMIT_SCENE为永久 8 | private Integer expireSeconds = 1800;// 该二维码有效时间,以秒为单位。 最大不超过1800。 9 | private Integer sceneId;// 场景值ID,临时二维码时为32位整型,永久二维码时最大值为1000 10 | 11 | public QRType getType() { 12 | return type; 13 | } 14 | 15 | public void setType(QRType type) { 16 | this.type = type; 17 | } 18 | 19 | public Integer getExpireSeconds() { 20 | return expireSeconds; 21 | } 22 | 23 | public void setExpireSeconds(Integer expireSeconds) { 24 | this.expireSeconds = expireSeconds; 25 | } 26 | 27 | public Integer getSceneId() { 28 | return sceneId; 29 | } 30 | 31 | public void setSceneId(Integer sceneId) { 32 | this.sceneId = sceneId; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | JSONObject obj = new JSONObject(); 38 | if (type == QRType.QR_SCENE) { 39 | obj.put("expire_seconds", expireSeconds); 40 | } 41 | 42 | obj.put("action_name", type.value()); 43 | JSONObject actionInfo = new JSONObject(); 44 | JSONObject scene = new JSONObject(); 45 | scene.put("scene_id", sceneId); 46 | actionInfo.put("scene", scene); 47 | obj.put("action_info", actionInfo); 48 | return obj.toString(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/QRTicket.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.belerweb.social.bean.JsonBean; 6 | import com.belerweb.social.bean.Result; 7 | 8 | /** 9 | * 二维码 Ticket 10 | */ 11 | public class QRTicket extends JsonBean { 12 | 13 | public QRTicket() {} 14 | 15 | private QRTicket(JSONObject jsonObject) { 16 | super(jsonObject); 17 | } 18 | 19 | private String ticket;// 获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码。 20 | private Integer expireSeconds = 604800;// 该二维码有效时间,以秒为单位。 最大不超过1800。 21 | 22 | /** 23 | * 获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码。 24 | */ 25 | public String getTicket() { 26 | return ticket; 27 | } 28 | 29 | public void setTicket(String ticket) { 30 | this.ticket = ticket; 31 | } 32 | 33 | /** 34 | * 获取二维码ticket后,开发者可用ticket换取二维码图片。请注意,本接口无须登录态即可调用。 35 | */ 36 | public String getQRUrl() { 37 | return "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket; 38 | } 39 | 40 | /** 41 | * 该二维码有效时间,以秒为单位。 最大不超过1800。 42 | */ 43 | public Integer getExpireSeconds() { 44 | return expireSeconds; 45 | } 46 | 47 | public void setExpireSeconds(Integer expireSeconds) { 48 | this.expireSeconds = expireSeconds; 49 | } 50 | 51 | public static QRTicket parse(JSONObject jsonObject) { 52 | if (jsonObject == null) { 53 | return null; 54 | } 55 | QRTicket obj = new QRTicket(jsonObject); 56 | obj.ticket = jsonObject.getString("ticket"); 57 | obj.expireSeconds = Result.parseInteger(jsonObject.opt("expire_seconds")); 58 | return obj; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/QRType.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | 4 | /** 5 | * 带参数的二维码类型 6 | */ 7 | public enum QRType { 8 | 9 | /** 10 | * 临时二维码 11 | */ 12 | QR_SCENE("QR_SCENE"), 13 | 14 | /** 15 | * 永久二维码 16 | */ 17 | QR_LIMIT_SCENE("QR_LIMIT_SCENE"); 18 | 19 | private String type; 20 | 21 | private QRType(String type) { 22 | this.type = type; 23 | } 24 | 25 | public String value() { 26 | return type; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return type; 32 | } 33 | 34 | public static QRType parse(Object val) { 35 | if (QR_LIMIT_SCENE.type.equals(val)) { 36 | return QR_LIMIT_SCENE; 37 | } 38 | if (QR_SCENE.type.equals(val)) { 39 | return QR_SCENE; 40 | } 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/Scope.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | 4 | /** 5 | * 应用授权作用域 6 | */ 7 | public enum Scope { 8 | 9 | /** 10 | * 不弹出授权页面,直接跳转,只能获取用户openid 11 | */ 12 | SNSAPI_BASE("snsapi_base"), 13 | 14 | /** 15 | * 网页应用目前仅填写snsapi_login即可 16 | */ 17 | SNSAPI_LOGIN("snsapi_login"), 18 | 19 | /** 20 | * 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 21 | */ 22 | SNSAPI_USERINFO("snsapi_userinfo"); 23 | 24 | private String scope; 25 | 26 | private Scope(String scope) { 27 | this.scope = scope; 28 | } 29 | 30 | public String value() { 31 | return scope; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return scope; 37 | } 38 | 39 | public static Scope parse(Object val) { 40 | if (SNSAPI_BASE.scope.equals(val)) { 41 | return SNSAPI_BASE; 42 | } 43 | if (SNSAPI_USERINFO.scope.equals(val)) { 44 | return SNSAPI_USERINFO; 45 | } 46 | if (SNSAPI_LOGIN.scope.equals(val)) { 47 | return SNSAPI_LOGIN; 48 | } 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/User.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | import org.json.JSONObject; 7 | 8 | import com.belerweb.social.bean.Gender; 9 | import com.belerweb.social.bean.JsonBean; 10 | import com.belerweb.social.bean.Result; 11 | 12 | /** 13 | * 微信用户信息 14 | */ 15 | public class User extends JsonBean { 16 | 17 | public User() {} 18 | 19 | private User(JSONObject jsonObject) { 20 | super(jsonObject); 21 | } 22 | 23 | private String openId;// 用户的唯一标识 24 | private String unionID;// 同一用户,对同一个微信开放平台帐号下的不同应用,UnionID是相同的 25 | private String nickname;// 用户昵称 26 | private Gender gender;// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 27 | private String province;// 用户个人资料填写的省份 28 | private String city;// 普通用户个人资料填写的城市 29 | private String country;// 国家,如中国为CN 30 | private List privilege; // 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom) 31 | private String language;// 用户的语言,简体中文为zh_CN 32 | private String headImgUrl;// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 33 | private Boolean subscribe;// 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 34 | private Date subscribeTime;// 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间 35 | 36 | /** 37 | * 用户的唯一标识 38 | */ 39 | public String getOpenId() { 40 | return openId; 41 | } 42 | 43 | public void setOpenId(String openId) { 44 | this.openId = openId; 45 | } 46 | 47 | /** 48 | * 用户昵称 49 | */ 50 | public String getNickname() { 51 | return nickname; 52 | } 53 | 54 | public void setNickname(String nickname) { 55 | this.nickname = nickname; 56 | } 57 | 58 | /** 59 | * 用户的性别 60 | */ 61 | public Gender getGender() { 62 | return gender; 63 | } 64 | 65 | public void setGender(Gender gender) { 66 | this.gender = gender; 67 | } 68 | 69 | /** 70 | * 用户个人资料填写的省份 71 | */ 72 | public String getProvince() { 73 | return province; 74 | } 75 | 76 | public void setProvince(String province) { 77 | this.province = province; 78 | } 79 | 80 | /** 81 | * 普通用户个人资料填写的城市 82 | */ 83 | public String getCity() { 84 | return city; 85 | } 86 | 87 | public void setCity(String city) { 88 | this.city = city; 89 | } 90 | 91 | /** 92 | * 国家,如中国为CN 93 | */ 94 | public String getCountry() { 95 | return country; 96 | } 97 | 98 | public void setCountry(String country) { 99 | this.country = country; 100 | } 101 | 102 | /** 103 | * 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom) 104 | */ 105 | public List getPrivilege() { 106 | return privilege; 107 | } 108 | 109 | public void setPrivilege(List privilege) { 110 | this.privilege = privilege; 111 | } 112 | 113 | /** 114 | * 用户的语言,简体中文为zh_CN 115 | */ 116 | public String getLanguage() { 117 | return language; 118 | } 119 | 120 | public void setLanguage(String language) { 121 | this.language = language; 122 | } 123 | 124 | /** 125 | * 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 126 | */ 127 | public String getHeadImgUrl() { 128 | return headImgUrl; 129 | } 130 | 131 | public void setHeadImgUrl(String headImgUrl) { 132 | this.headImgUrl = headImgUrl; 133 | } 134 | 135 | /** 136 | * 用户是否订阅该公众号标识,false 表此用户没有关注该公众号,拉取不到其余信息。 137 | */ 138 | public Boolean getSubscribe() { 139 | return subscribe; 140 | } 141 | 142 | public void setSubscribe(Boolean subscribe) { 143 | this.subscribe = subscribe; 144 | } 145 | 146 | /** 147 | * 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间 148 | */ 149 | public Date getSubscribeTime() { 150 | return subscribeTime; 151 | } 152 | 153 | public void setSubscribeTime(Date subscribeTime) { 154 | this.subscribeTime = subscribeTime; 155 | } 156 | 157 | /** 158 | * 公众号只有在被绑定到微信开放平台帐号下后,才会获取UnionID。只要是同一个微信开放平台帐号下的公众号,用户的UnionID是唯一的 159 | * 160 | * @return the unionId 161 | */ 162 | public String getUnionID() { 163 | return unionID; 164 | } 165 | 166 | public void setUnionID(String unionID) { 167 | this.unionID = unionID; 168 | } 169 | 170 | public static User parse(JSONObject jsonObject) { 171 | if (jsonObject == null) { 172 | return null; 173 | } 174 | User obj = new User(jsonObject); 175 | obj.openId = Result.toString(jsonObject.get("openid")); 176 | if (jsonObject.has("unionid")) { 177 | obj.unionID = Result.toString(jsonObject.get("unionid")); 178 | } 179 | obj.nickname = Result.toString(jsonObject.opt("nickname")); 180 | obj.gender = Gender.parse(Result.parseInteger(jsonObject.opt("sex"))); 181 | obj.province = Result.toString(jsonObject.opt("province")); 182 | obj.city = Result.toString(jsonObject.opt("city")); 183 | obj.country = Result.toString(jsonObject.opt("country")); 184 | obj.language = Result.toString(jsonObject.opt("language")); 185 | obj.headImgUrl = Result.toString(jsonObject.opt("headimgurl")); 186 | obj.subscribe = Result.parseBoolean(jsonObject.opt("subscribe")); 187 | Long subscribeTime = Result.parseLong(jsonObject.opt("subscribe_time")); 188 | if (subscribeTime != null) { 189 | obj.subscribeTime = new Date(subscribeTime * 1000); 190 | } 191 | obj.privilege = Result.parse(jsonObject.optJSONArray("privilege"), String.class); 192 | return obj; 193 | } 194 | 195 | } 196 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/Variable.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | /** 4 | * 模板消息中的变量 5 | * 6 | * @date Aug 28, 2014 7 | */ 8 | public class Variable { 9 | 10 | private String name;// 变量名称 11 | private String value;// 变量值 12 | private String color;// 变量颜色值 eg:#FF0000 13 | 14 | public Variable() {} 15 | 16 | public Variable(String name, String value) { 17 | this.name = name; 18 | this.value = value; 19 | } 20 | 21 | public Variable(String name, String value, String color) { 22 | this.name = name; 23 | this.value = value; 24 | this.color = color; 25 | } 26 | 27 | /** 28 | * 变量名称 29 | */ 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | /** 39 | * 变量值 40 | */ 41 | public String getValue() { 42 | return value; 43 | } 44 | 45 | public void setValue(String value) { 46 | this.value = value; 47 | } 48 | 49 | /** 50 | * 变量颜色值 eg:#FF0000 51 | */ 52 | public String getColor() { 53 | return color; 54 | } 55 | 56 | public void setColor(String color) { 57 | this.color = color; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/belerweb/social/weixin/bean/VoiceType.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.bean; 2 | 3 | 4 | /** 5 | * 语音格式 6 | */ 7 | public enum VoiceType { 8 | 9 | /** 10 | * amr 11 | */ 12 | AMR("amr"), 13 | 14 | /** 15 | * speex 16 | */ 17 | SPEEX("speex"); 18 | 19 | private String type; 20 | 21 | private VoiceType(String type) { 22 | this.type = type; 23 | } 24 | 25 | public String value() { 26 | return type; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return type; 32 | } 33 | 34 | public static VoiceType parse(Object val) { 35 | if (AMR.type.equals(val)) { 36 | return AMR; 37 | } 38 | if (SPEEX.type.equals(val)) { 39 | return SPEEX; 40 | } 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/SDKTest.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import com.belerweb.social.bean.Result; 9 | 10 | public class SDKTest extends TestConfig { 11 | 12 | final static Logger logger = LoggerFactory.getLogger(SDKTest.class); 13 | 14 | @Test 15 | public void testLonLatToAddress() { 16 | Result result = weibo.lonLatToAddress(118.839485, 31.954561); 17 | Assert.assertTrue(result.success()); 18 | logger.info(result.getResult()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/TestConfig.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social; 2 | 3 | import org.junit.Before; 4 | 5 | import com.belerweb.social.qq.connect.api.QQConnect; 6 | import com.belerweb.social.weibo.api.Weibo; 7 | import com.belerweb.social.weixin.api.Weixin; 8 | 9 | public class TestConfig { 10 | 11 | protected Weibo weibo; 12 | protected QQConnect connect; 13 | protected Weixin weixin; 14 | 15 | @Before 16 | public void initialize() { 17 | String redirectUri = System.getProperty("redirect"); 18 | weibo = 19 | new Weibo(System.getProperty("weibo.id"), System.getProperty("weibo.secret"), redirectUri); 20 | connect = 21 | new QQConnect(System.getProperty("connect.id"), System.getProperty("connect.secret"), 22 | redirectUri); 23 | weixin = 24 | new Weixin(System.getProperty("weixin.id"), System.getProperty("weixin.secret"), 25 | redirectUri, System.getProperty("weixin.token")); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/mail/api/POP3Test.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.mail.api; 2 | 3 | import org.junit.Test; 4 | 5 | import com.belerweb.social.mail.api.POP3; 6 | 7 | public class POP3Test { 8 | 9 | @Test 10 | public void testDownload() { 11 | String username = System.getProperty("pop3.username"); 12 | String password = System.getProperty("pop3.password"); 13 | String host = System.getProperty("pop3.host"); 14 | POP3 pop3 = new POP3(username, password, host, 995, true); 15 | pop3.download(System.getProperty("java.io.tmpdir")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/qq/connect/api/OAuth2Test.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.api; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import com.belerweb.social.TestConfig; 9 | import com.belerweb.social.bean.Result; 10 | import com.belerweb.social.qq.connect.bean.AccessToken; 11 | import com.belerweb.social.qq.connect.bean.OpenID; 12 | 13 | public class OAuth2Test extends TestConfig { 14 | 15 | final static Logger logger = LoggerFactory.getLogger(OAuth2Test.class); 16 | 17 | @Test 18 | public void testAuthorize() { 19 | String url = connect.getOAuth2().authorize(); 20 | // 浏览器打开URL获取code用于下一步测试 21 | logger.info(url); 22 | } 23 | 24 | @Test 25 | public void testAuthorizeWap() { 26 | String url = connect.getOAuth2().authorize(true); 27 | // 浏览器打开URL获取code用于下一步测试 28 | logger.info(url); 29 | } 30 | 31 | @Test 32 | public void testAccessToken() { 33 | Result tokenResult = connect.getOAuth2().accessToken("code"); 34 | Assert.assertTrue(!tokenResult.success()); 35 | logger.info(tokenResult.getError().toString()); 36 | 37 | String code = System.getProperty("connect.code"); 38 | tokenResult = connect.getOAuth2().accessToken(code); 39 | Assert.assertTrue(tokenResult.success()); 40 | logger.info(tokenResult.getResult().getJsonObject().toString()); 41 | } 42 | 43 | @Test 44 | public void testAccessTokenWap() { 45 | Result tokenResult = connect.getOAuth2().accessToken("code", true); 46 | Assert.assertTrue(!tokenResult.success()); 47 | logger.info(tokenResult.getError().toString()); 48 | 49 | String code = System.getProperty("connect.code"); 50 | tokenResult = connect.getOAuth2().accessToken(code, true); 51 | Assert.assertTrue(tokenResult.success()); 52 | logger.info(tokenResult.getResult().getJsonObject().toString()); 53 | } 54 | 55 | @Test 56 | public void testOpenId() { 57 | String accessToken = System.getProperty("connect.token"); 58 | Result result = connect.getOAuth2().openId(accessToken); 59 | Assert.assertTrue(result.success()); 60 | logger.info(result.getResult().getJsonObject().toString()); 61 | } 62 | 63 | @Test 64 | public void testOpenIdWap() { 65 | String accessToken = System.getProperty("connect.token"); 66 | Result result = connect.getOAuth2().openId(accessToken, true); 67 | Assert.assertTrue(result.success()); 68 | logger.info(result.getResult().getJsonObject().toString()); 69 | } 70 | 71 | @Test 72 | public void testRefreshAccessToken() { 73 | String refreshToken = System.getProperty("connect.rtoken"); 74 | Result result = connect.getOAuth2().refreshAccessToken(refreshToken); 75 | Assert.assertTrue(result.success()); 76 | logger.info(result.getResult().getJsonObject().toString()); 77 | } 78 | 79 | @Test 80 | public void testRefreshAccessTokenWap() { 81 | String refreshToken = System.getProperty("connect.rtoken"); 82 | Result result = connect.getOAuth2().refreshAccessToken(refreshToken, true); 83 | Assert.assertTrue(result.success()); 84 | logger.info(result.getResult().getJsonObject().toString()); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/qq/connect/api/UserTest.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.qq.connect.api; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import com.belerweb.social.TestConfig; 9 | import com.belerweb.social.bean.Result; 10 | 11 | public class UserTest extends TestConfig { 12 | final static Logger logger = LoggerFactory.getLogger(UserTest.class); 13 | 14 | @Test 15 | public void testGetUserInfo() { 16 | String openId = System.getProperty("connect.openid"); 17 | String accessToken = System.getProperty("connect.token"); 18 | 19 | Result result = 20 | connect.getUser().getUserInfo(accessToken, openId); 21 | Assert.assertTrue(result.success()); 22 | logger.info(result.getResult().getJsonObject().toString()); 23 | } 24 | 25 | @Test 26 | public void testGetSimpleUserInfo() { 27 | String openId = System.getProperty("connect.openid"); 28 | String accessToken = System.getProperty("connect.token"); 29 | 30 | Result result = 31 | connect.getUser().getSimpleUserInfo(accessToken, connect.getClientId(), openId); 32 | Assert.assertTrue(result.success()); 33 | logger.info(result.getResult().getJsonObject().toString()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/weibo/api/OAuth2Test.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.api; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import com.belerweb.social.TestConfig; 9 | import com.belerweb.social.bean.Result; 10 | import com.belerweb.social.weibo.bean.AccessToken; 11 | import com.belerweb.social.weibo.bean.TokenInfo; 12 | 13 | public class OAuth2Test extends TestConfig { 14 | 15 | final static Logger logger = LoggerFactory.getLogger(OAuth2Test.class); 16 | 17 | /** 18 | * 获取用于获取accessToken的code,此方法需要单独测试 19 | */ 20 | @Test 21 | public void testAuthorize() { 22 | String url = weibo.getOAuth2().authorize(); 23 | // 浏览器打开URL获取code用于下一步测试 24 | logger.info(url); 25 | } 26 | 27 | /** 28 | * 获取accessToken,此方法需要单独测试 29 | */ 30 | @Test 31 | public void testAccessToken() { 32 | Result tokenResult = weibo.getOAuth2().accessToken("code"); 33 | Assert.assertTrue(!tokenResult.success()); 34 | logger.info(tokenResult.getError().toString()); 35 | 36 | String code = System.getProperty("weibo.code"); 37 | tokenResult = weibo.getOAuth2().accessToken(code); 38 | Assert.assertTrue(tokenResult.success()); 39 | logger.info(tokenResult.getResult().getJsonObject().toString()); 40 | } 41 | 42 | @Test 43 | public void testGetTokenInfo() { 44 | String accessToken = System.getProperty("weibo.token"); 45 | Result tokenResult = weibo.getOAuth2().getTokenInfo(accessToken); 46 | Assert.assertTrue(tokenResult.success()); 47 | logger.info(tokenResult.getResult().getJsonObject().toString()); 48 | } 49 | 50 | @Test 51 | public void testRevokeOAuth2() { 52 | String accessToken = System.getProperty("weibo.token"); 53 | Result tokenResult = weibo.getOAuth2().revokeOAuth2(accessToken); 54 | Assert.assertTrue(tokenResult.success()); 55 | Assert.assertTrue(tokenResult.getResult()); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/weibo/api/UserTest.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weibo.api; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.belerweb.social.TestConfig; 12 | import com.belerweb.social.bean.Result; 13 | import com.belerweb.social.weibo.bean.UserCounts; 14 | 15 | public class UserTest extends TestConfig { 16 | 17 | final static Logger logger = LoggerFactory.getLogger(UserTest.class); 18 | 19 | @Test 20 | public void testShow() { 21 | String uid = System.getProperty("weibo.uid"); 22 | Result result = 23 | weibo.getUser().show(weibo.getClientId(), null, uid, null); 24 | Assert.assertTrue(result.success()); 25 | logger.info(result.getResult().getJsonObject().toString()); 26 | } 27 | 28 | @Test 29 | public void testDomainShow() { 30 | Result result = 31 | weibo.getUser().domainShow(weibo.getClientId(), null, "cqlybest"); 32 | Assert.assertTrue(result.success()); 33 | logger.info(result.getResult().getJsonObject().toString()); 34 | } 35 | 36 | @Test 37 | public void testCounts() { 38 | String accessToken = System.getProperty("weibo.token"); 39 | String uid = System.getProperty("weibo.uid"); 40 | List uids = new ArrayList(); 41 | uids.add(uid); 42 | Result result = weibo.getUser().counts(null, accessToken, uids); 43 | Assert.assertTrue(result.success()); 44 | List results = result.getResults(); 45 | for (UserCounts userCounts : results) { 46 | logger.info(userCounts.getJsonObject().toString()); 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/weixin/api/GroupTest.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.lang.RandomStringUtils; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.belerweb.social.TestConfig; 12 | import com.belerweb.social.bean.Error; 13 | import com.belerweb.social.bean.Result; 14 | import com.belerweb.social.weixin.bean.Group; 15 | 16 | public class GroupTest extends TestConfig { 17 | final static Logger logger = LoggerFactory.getLogger(GroupTest.class); 18 | 19 | @Test 20 | public void testCreate() { 21 | Result result = weixin.getGroup().create(RandomStringUtils.randomAlphabetic(6)); 22 | Assert.assertTrue(result.success()); 23 | logger.info(result.getResult().getJsonObject().toString()); 24 | } 25 | 26 | @Test 27 | public void testGet() { 28 | Result> result = weixin.getGroup().get(); 29 | Assert.assertTrue(result.success()); 30 | for (Group group : result.getResult()) { 31 | logger.info(group.getJsonObject().toString()); 32 | } 33 | } 34 | 35 | @Test 36 | public void testUpdate() { 37 | String id = System.getProperty("weixin.groupid"); 38 | Result result = weixin.getGroup().update(id, RandomStringUtils.randomAlphabetic(6)); 39 | Assert.assertTrue(result.success()); 40 | } 41 | 42 | @Test 43 | public void testMove() { 44 | String openId = System.getProperty("weixin.openid"); 45 | String groupId = System.getProperty("weixin.groupid"); 46 | Result result = weixin.getGroup().move(openId, groupId); 47 | Assert.assertTrue(result.success()); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/weixin/api/MediaTest.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import java.io.File; 4 | 5 | import org.apache.commons.io.FileUtils; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.belerweb.social.TestConfig; 12 | import com.belerweb.social.bean.Result; 13 | import com.belerweb.social.weixin.bean.Media; 14 | import com.belerweb.social.weixin.bean.MediaType; 15 | 16 | public class MediaTest extends TestConfig { 17 | final static Logger logger = LoggerFactory.getLogger(MediaTest.class); 18 | 19 | @Test 20 | public void testUpload() throws Exception { 21 | File file = new File(System.getProperty("weixin.file")); 22 | Media media = new Media(); 23 | media.setName(file.getName()); 24 | media.setContentType(MediaType.VOICE_AMR.contentType()); 25 | media.setContent(FileUtils.readFileToByteArray(file)); 26 | Result result = 27 | weixin.getMedia().upload(MediaType.VOICE_AMR, media); 28 | Assert.assertTrue(result.success()); 29 | logger.info(result.getResult().getId()); 30 | } 31 | 32 | @Test 33 | public void testGet() throws Exception { 34 | String mediaId = System.getProperty("weixin.mediaid"); 35 | Result result = weixin.getMedia().get(mediaId); 36 | Assert.assertTrue(result.success()); 37 | logger.info(result.getResult().getContentType()); 38 | logger.info(result.getResult().getName()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/weixin/api/MenuTest.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.commons.lang.RandomStringUtils; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | import com.belerweb.social.TestConfig; 11 | import com.belerweb.social.bean.Error; 12 | import com.belerweb.social.bean.Result; 13 | import com.belerweb.social.weixin.bean.Menu; 14 | import com.belerweb.social.weixin.bean.MenuType; 15 | 16 | public class MenuTest extends TestConfig { 17 | 18 | @Test 19 | public void testGet() { 20 | Result> result = weixin.getMenu().get(); 21 | Assert.assertTrue(result.success()); 22 | } 23 | 24 | @Test 25 | public void testDelete() { 26 | Result result = weixin.getMenu().delete(); 27 | Assert.assertTrue(result.success()); 28 | } 29 | 30 | @Test 31 | public void testCreate() { 32 | List menus = new ArrayList(); 33 | Menu menu1 = new Menu(); 34 | menu1.setName(RandomStringUtils.randomAlphabetic(4)); 35 | List subs = new ArrayList(); 36 | Menu menu11 = new Menu(); 37 | menu11.setName(RandomStringUtils.randomAlphabetic(4)); 38 | menu11.setType(MenuType.CLICK); 39 | menu11.setKey(RandomStringUtils.randomAlphabetic(4)); 40 | subs.add(menu11); 41 | Menu menu22 = new Menu(); 42 | menu22.setName(RandomStringUtils.randomAlphabetic(4)); 43 | menu22.setType(MenuType.VIEW); 44 | menu22.setUrl("https://github.com/belerweb/"); 45 | subs.add(menu22); 46 | menu1.setSubs(subs); 47 | menus.add(menu1); 48 | Result result = weixin.getMenu().create(menus); 49 | Assert.assertTrue(result.success()); 50 | } 51 | 52 | @Test 53 | public void testCreate1() throws Exception { 54 | List menus = new ArrayList(); 55 | Menu menu1 = new Menu(); 56 | menu1.setName("普通菜单"); 57 | List subs1 = new ArrayList(); 58 | Menu menu11 = new Menu(); 59 | menu11.setName("点击事件"); 60 | menu11.setType(MenuType.CLICK); 61 | menu11.setKey("menu-click"); 62 | subs1.add(menu11); 63 | Menu menu12 = new Menu(); 64 | menu12.setName("跳转URL"); 65 | menu12.setType(MenuType.VIEW); 66 | menu12.setUrl("https://github.com/jdkcn"); 67 | subs1.add(menu12); 68 | menu1.setSubs(subs1); 69 | menus.add(menu1); 70 | 71 | Menu menu2 = new Menu(); 72 | menu2.setName("扫码"); 73 | List subs2 = new ArrayList(); 74 | Menu menu21 = new Menu(); 75 | menu21.setName("扫码推事件"); 76 | menu21.setType(MenuType.SCANCODE_PUSH); 77 | menu21.setKey("scancode_push"); 78 | subs2.add(menu21); 79 | Menu menu22 = new Menu(); 80 | menu22.setName("扫码带提示"); 81 | menu22.setType(MenuType.SCANCODE_WAITMSG); 82 | menu22.setKey("scancode_waitmsg"); 83 | subs2.add(menu22); 84 | Menu menu23 = new Menu(); 85 | menu23.setName("发送位置"); 86 | menu23.setType(MenuType.LOCATION_SELECT); 87 | menu23.setKey("location_select"); 88 | subs2.add(menu23); 89 | menu2.setSubs(subs2); 90 | menus.add(menu2); 91 | 92 | Menu menu3 = new Menu(); 93 | menu3.setName("发图"); 94 | List subs3 = new ArrayList(); 95 | Menu menu31 = new Menu(); 96 | menu31.setName("系统拍照发图"); 97 | menu31.setType(MenuType.PIC_SYSPHOTO); 98 | menu31.setKey("pic_sysphoto"); 99 | subs3.add(menu31); 100 | Menu menu32 = new Menu(); 101 | menu32.setName("拍照或者相册发图"); 102 | menu32.setType(MenuType.PIC_PHOTO_OR_ALBUM); 103 | menu32.setKey("pic_photo_or_album"); 104 | subs3.add(menu32); 105 | Menu menu33 = new Menu(); 106 | menu33.setName("微信相册发图"); 107 | menu33.setType(MenuType.PIC_WEIXIN); 108 | menu33.setKey("pic_weixin"); 109 | subs3.add(menu33); 110 | menu3.setSubs(subs3); 111 | menus.add(menu3); 112 | Result result = weixin.getMenu().create(menus); 113 | Assert.assertTrue(result.success()); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/weixin/api/OAuth2Test.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import com.belerweb.social.TestConfig; 9 | import com.belerweb.social.bean.Result; 10 | import com.belerweb.social.weixin.bean.AccessToken; 11 | 12 | public class OAuth2Test extends TestConfig { 13 | final static Logger logger = LoggerFactory.getLogger(OAuth2Test.class); 14 | 15 | @Test 16 | public void testAuthorize() { 17 | String url = weixin.getOAuth2().authorize(); 18 | // 浏览器不能访问,只能在微信客户端中访问 19 | logger.info(url); 20 | } 21 | 22 | @Test 23 | public void testAccessToken() { 24 | Result tokenResult = weixin.getOAuth2().accessToken("code"); 25 | Assert.assertTrue(!tokenResult.success()); 26 | logger.info(tokenResult.getError().toString()); 27 | 28 | String code = System.getProperty("weixin.code"); 29 | tokenResult = weixin.getOAuth2().accessToken(code); 30 | Assert.assertTrue(tokenResult.success()); 31 | logger.info(tokenResult.getResult().getJsonObject().toString()); 32 | } 33 | 34 | @Test 35 | public void testRefreshAccessToken() { 36 | String refreshToken = System.getProperty("weixin.rtoken"); 37 | Result tokenResult = weixin.getOAuth2().refreshAccessToken(refreshToken); 38 | Assert.assertTrue(tokenResult.success()); 39 | System.out.print(tokenResult.getResult().getJsonObject()); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/weixin/api/UserTest.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import java.util.List; 4 | 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import com.belerweb.social.TestConfig; 11 | import com.belerweb.social.bean.Result; 12 | 13 | public class UserTest extends TestConfig { 14 | 15 | final static Logger logger = LoggerFactory.getLogger(UserTest.class); 16 | 17 | @Test 18 | public void testSnsapiUserInfo() { 19 | String accessToken = System.getProperty("weixin.atoken"); 20 | String openId = System.getProperty("weixin.openid"); 21 | Result result = 22 | weixin.getUser().snsapiUserInfo(accessToken, openId); 23 | Assert.assertTrue(result.success()); 24 | logger.info(result.getResult().getJsonObject().toString()); 25 | } 26 | 27 | @Test 28 | public void testUserInfo() { 29 | String openId = System.getProperty("weixin.openid"); 30 | Result result = 31 | weixin.getUser().userInfo(weixin.getAccessToken().getToken(), openId); 32 | Assert.assertTrue(result.success()); 33 | logger.info(result.getResult().getJsonObject().toString()); 34 | } 35 | 36 | @Test 37 | public void testGetFollowUsers() { 38 | Result> result = weixin.getUser().getFollowUsers(); 39 | Assert.assertTrue(result.success()); 40 | for (com.belerweb.social.weixin.bean.User user : result.getResult()) { 41 | logger.info(user.getJsonObject().toString()); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/com/belerweb/social/weixin/api/WeixinTest.java: -------------------------------------------------------------------------------- 1 | package com.belerweb.social.weixin.api; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.Date; 6 | 7 | import org.apache.commons.lang.RandomStringUtils; 8 | import org.apache.commons.lang.time.DateFormatUtils; 9 | import org.junit.Assert; 10 | import org.junit.Test; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import com.belerweb.social.TestConfig; 15 | import com.belerweb.social.bean.Result; 16 | import com.belerweb.social.weixin.bean.AccessToken; 17 | import com.belerweb.social.weixin.bean.ApiTicket; 18 | import com.belerweb.social.weixin.bean.JSApiTicket; 19 | import com.belerweb.social.weixin.bean.Message; 20 | import com.belerweb.social.weixin.bean.MsgType; 21 | import com.belerweb.social.weixin.bean.QRTicket; 22 | import com.belerweb.social.weixin.bean.QRType; 23 | import com.belerweb.social.weixin.bean.Variable; 24 | 25 | public class WeixinTest extends TestConfig { 26 | final static Logger logger = LoggerFactory.getLogger(WeixinTest.class); 27 | 28 | @Test 29 | public void testGetAccessToken() { 30 | AccessToken result = weixin.getAccessToken(); 31 | Assert.assertNotNull(result); 32 | logger.info(result.getJsonObject().toString()); 33 | } 34 | 35 | @Test 36 | public void testGetJSApiTicket() { 37 | JSApiTicket result = weixin.getJsApiTicket(); 38 | Assert.assertNotNull(result); 39 | logger.info(result.getJsonObject().toString()); 40 | } 41 | 42 | @Test 43 | public void testGetApiTicket() { 44 | ApiTicket result = weixin.getApiTicket(); 45 | Assert.assertNotNull(result); 46 | logger.info(result.getJsonObject().toString()); 47 | } 48 | 49 | @Test 50 | public void testSignature() throws Exception { 51 | Weixin wx = new Weixin(null); 52 | assertEquals("def42db04eb64f66c47a4e14fcc736156a704d8e", wx.signature("sduhi123", 53 | "wxd0f84fbc9396d6ae", "GROUPON", 54 | "E0o2-at6NcC2OsJiQTlwlKQmnidi_i9qnUG6I8wOFOOnPaK_fcjapbiBA15AUBXvkux2vvNsjYomRcbxXolfMw", 55 | "14300000000", "134234235235235")); 56 | } 57 | 58 | @Test 59 | public void testJsApiSignature() { 60 | String signature = 61 | weixin.jsapiSignature("http://openlaw.cn", new Date().getTime(), 62 | RandomStringUtils.randomAlphanumeric(16)); 63 | Assert.assertNotNull(signature); 64 | logger.info(signature); 65 | } 66 | 67 | @Test 68 | public void testCreateQR() { 69 | Result result = weixin.createQR(QRType.QR_SCENE, 0); 70 | Assert.assertTrue(result.success()); 71 | logger.info(result.getResult().getJsonObject().toString()); 72 | } 73 | 74 | @Test 75 | public void testCreateQR2() { 76 | Result result = weixin.createQR(QRType.QR_LIMIT_SCENE, 0); 77 | Assert.assertTrue(result.success()); 78 | logger.info(result.getResult().getJsonObject().toString()); 79 | logger.info(result.getResult().getQRUrl()); 80 | } 81 | 82 | @Test 83 | public void testSendCustomMessage() { 84 | Message message = new Message(MsgType.TEXT); 85 | message.setToUser(System.getProperty("weixin.openid")); 86 | message.setContent(new Date().toString()); 87 | Result result = weixin.sendCustomMessage(message); 88 | Assert.assertTrue(result.success()); 89 | } 90 | 91 | @Test 92 | public void testSendTemplateMessage() throws Exception { 93 | Message message = new Message(MsgType.TEMPLATE); 94 | message.setToUser(System.getProperty("weixin.openid")); 95 | message.setUrl("https://github.com/belerweb/social-sdk"); 96 | message.setTopColor("#459ae9"); 97 | message.setTemplateId(System.getProperty("weixin.templateid")); 98 | Variable var1 = new Variable("first", "您好,这是一个模板消息的测试"); 99 | Variable var2 = new Variable("schedule", "这是一个新的事件"); 100 | Variable var3 = new Variable("time", DateFormatUtils.format(new Date(), "yyyy年MM月dd日 HH:mm")); 101 | message.addVariable(var1).addVariable(var2).addVariable(var3); 102 | Result result = weixin.sendTemplateMessage(message); 103 | Assert.assertTrue(result.success()); 104 | } 105 | 106 | @Test 107 | public void testSendTemplateMessage1() throws Exception { 108 | Message message = new Message(MsgType.TEMPLATE); 109 | message.setToUser(System.getProperty("weixin.openid")); 110 | message.setUrl("http://openlaw.cn/judgement/4b47137610264874a4e41f3635b3fd83"); 111 | message.setTopColor("#459ae9"); 112 | message.setTemplateId(System.getProperty("weixin.templateid")); 113 | Variable var1 = 114 | new Variable("first", "高圆圆,您好!您关注的判决文书:\n龚喜琴与上海诺盛企业发展有限公司劳动合同纠纷一审民事判决书\n有新的回复。"); 115 | Variable var2 = new Variable("keyword1", "happyboy_1688"); 116 | Variable var3 = 117 | new Variable("keyword2", DateFormatUtils.format(new Date(), "yyyy年MM月dd日 HH:mm")); 118 | Variable var4 = 119 | new Variable( 120 | "keyword3", 121 | "本人参与庭审,有权发表意见:\n原告负责的项目她没本事拿下来,本人花了几个月把这项目做下来,老板为显示公平,却把一半提成给了原告,本人只拿一半帮原告挣钱但毫无怨言,这事大家都同意了,现在原告在法庭上反悔要本人的那一半,还好法官有眼,没给她.正义战胜邪恶! ", 122 | "#32a3cb"); 123 | message.addVariable(var1).addVariable(var2).addVariable(var3).addVariable(var4); 124 | Result result = weixin.sendTemplateMessage(message); 125 | Assert.assertTrue(result.success()); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | --------------------------------------------------------------------------------