Repository: belerweb/social-sdk
Branch: master
Commit: 797b15bd70f0
Files: 114
Total size: 384.3 KB
Directory structure:
gitextract_ctatj41d/
├── .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
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Eclipse
.externalToolBuilders/
.settings/
bin/
tmp/
.metadata
.gradle
*.tmp
*.bak
*.swp
*~.nib
local.properties
.loadpath
.project
.classpath
# IntelliJ IDES
.idea/
out/
.idea_modules/
*.iml
*.ipr
*.ids
*.iws
# OSX
# Icon must end with two \r
Icon
._*
.DS_Store
.AppleDouble
.LSOverride
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows
$RECYCLE.BIN/
Thumbs.db
ehthumbs.db
Desktop.ini
*.lnk
# Linux
*~
.directory
.Trash-*
# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# frontend-maven-plugin
node
bower_components
node_modules
etc
================================================
FILE: README.md
================================================
social-sdk
==========
social-sdk是一个集成[新浪微博开放平台][1]、[QQ互联][2]、[腾讯微博开发平台][3]、[微信公众平台][4]等社交平台的接口的Java库。
其实在开始这个项目之前,各个平台都已经提供相应的Java
SDK,有官方的、也有非官方的开源项目,如如新浪微博开放平台有[weibo4j][5]。我也一直在使用这些项目。但是在使用过程中越到的问题越来越多,越来越麻烦,如:
- 这些SDK都是提供一个ZIP包,不适合Maven或Ivy管理的项目。
- 各个SDK都引入了开源公共类库,确改了包名,造成类库过多、混乱。
- SDK更新超级慢,跟不上平台上接口的变更。
- 没有交流环境,遇到BUG找不到资料,找不到沟通的地方,需要自己去琢磨源代码。
- ......
因此,自己开发一个,尝试尽可能多的集成社交平台。
**因为我并没有在项目中使用到那么多社交平台,所以有的社交平台没有可供测试的应用信息(通常叫做AppKey和AppSecret)。所以非常希望有资源的朋友共享测试帐号。**
已实现
---
- QQ相关
- 通过QQ邮箱获取联系人,支持验证码自动登录
- 获取QZone访客记录,支持验证码自动登录
- 新浪微博
- 新浪微博登录
- 获取新浪微博用户信息
- QQ帐号/QQ互联
- 支持http://wiki.connect.qq.com 列出的API
- 腾讯微博(未测试)
- 腾讯微博登录(未测试)
- 获取腾讯微博用户信息(未测试)
- [微信帐号](../../wiki/微信API)
- [获取access_token](../../wiki/微信API#获取access token)
- [获取jsapi_ticket](../../wiki/微信API#获取jsapi_ticket)
- jsapi签名
- 上传下载多媒体文件
- 接受消息/事件推送/位置信息
- 验证消息真实性
- 发送被动响应信息
- 发送客服消息
- 发送模板消息
- 分组管理
- 获取用户基本信息
- 获取关注者列表
- 网页授权获取用户基本信息
- 自定义菜单
- 生成带参数的二维码接口
计划开发
----
- 更多的接口
- 支持更多的平台
下载
--
推荐使用Maven下载。social-sdk已发布到Maven中央库。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
com.belerweb
social-sdk
0.0.5
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
参与
--
交流:GitHub上留言或加入QQ群(328171904)
共享代码:Fork项目并提交Pull Requests
提交BUG:直接在GitHub上提交
其他:欢迎任何形式的贡献,文档、经验、意见...
链接
--
[1]:
[2]:
[3]:
[4]:
[5]:
[6]:
[7]:
[8]:
================================================
FILE: eclipse-java-google-style.xml
================================================
================================================
FILE: pom.xml
================================================
4.0.0
org.sonatype.oss
oss-parent
7
com.belerweb
social-sdk
0.0.6-SNAPSHOT
jar
social-sdk
All in one sdk, include weibo, qq connect, t.qq.com ...
https://github.com/belerweb/social-sdk
BSD
http://opensource.org/licenses/bsd-license.html
repo
scm:git:https://github.com/belerweb/social-sdk.git
scm:git:https://github.com/belerweb/social-sdk.git
https://github.com/belerweb/social-sdk.git
Github Issue
https://github.com/belerweb/social-sdk/issues
belerweb
Tangjun He
belerweb@gmail.com
https://github.com/belerweb
UTF-8
1.5
${maven.compiler.source}
2.6
org.json
json
20131018
org.apache.httpcomponents
httpmime
4.3.1
commons-lang
commons-lang
2.6
commons-io
commons-io
2.4
commons-net
commons-net
3.3
org.jsoup
jsoup
1.7.3
org.slf4j
slf4j-api
1.7.5
ch.qos.logback
logback-classic
1.0.13
test
junit
junit
4.11
test
com.googlecode.maven-java-formatter-plugin
maven-java-formatter-plugin
0.4
${maven.compiler.source}
${maven.compiler.source}
${maven.compiler.source}
${project.basedir}/eclipse-java-google-style.xml
LF
format
org.eclipse.m2e
lifecycle-mapping
1.0.0
com.googlecode.maven-java-formatter-plugin
maven-java-formatter-plugin
[0.4]
format
true
org.apache.maven.plugins
maven-enforcer-plugin
[1.0,)
enforce
================================================
FILE: src/main/java/com/belerweb/social/API.java
================================================
package com.belerweb.social;
import com.belerweb.social.qq.connect.api.QQConnect;
import com.belerweb.social.qq.t.api.QQT;
import com.belerweb.social.weibo.api.Weibo;
import com.belerweb.social.weixin.api.Weixin;
public abstract class API {
protected Weibo weibo;
protected Weixin weixin;
protected QQConnect connect;
protected QQT t;
protected API(Weibo weibo) {
this.weibo = weibo;
}
protected API(Weixin weixin) {
this.weixin = weixin;
}
protected API(QQConnect connect) {
this.connect = connect;
}
protected API(QQT t) {
this.t = t;
}
}
================================================
FILE: src/main/java/com/belerweb/social/SDK.java
================================================
package com.belerweb.social;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;
import com.belerweb.social.bean.Error;
import com.belerweb.social.bean.Result;
import com.belerweb.social.exception.SocialException;
import com.belerweb.social.http.Http;
import com.belerweb.social.http.HttpException;
public abstract class SDK {
private final Charset defaultCharset;
public SDK() {
this(null);
}
public SDK(Charset defaultCharset) {
this.defaultCharset = defaultCharset;
}
public String get(String url, List params) {
try {
Http.setDefaultCharset(defaultCharset);
return Http.get(url, params);
} catch (HttpException e) {
throw new SocialException(e);
}
}
public String get(String url) {
return get(url, null);
}
public String post(String url, HttpEntity postBody) {
try {
Http.setDefaultCharset(defaultCharset);
return Http.post(url, postBody);
} catch (HttpException e) {
throw new SocialException(e);
}
}
public String post(String url, List params) {
try {
Http.setDefaultCharset(defaultCharset);
return Http.post(url, params, "UTF-8");
} catch (HttpException e) {
throw new SocialException(e);
}
}
public String post(String url) {
return post(url, (HttpEntity) null);
}
public void addParameter(List params, String name, Object value) {
if (value == null) {
throw new SocialException("Parameter " + name + " must not be null.");
}
params.add(new BasicNameValuePair(name, value.toString()));
}
public void addNotNullParameter(List params, String name, Object value) {
if (value != null) {
params.add(new BasicNameValuePair(name, value.toString()));
}
}
public void addTrueParameter(List params, String name, Boolean value) {
if (Boolean.TRUE.equals(value)) {
params.add(new BasicNameValuePair(name, value.toString()));
}
}
/**
* 经纬度转换为地址
*
* @param lon 经度
* @param lat 纬度
*/
public Result lonLatToAddress(Double lon, Double lat) {
List params = new ArrayList();
addParameter(params, "sensor", "false");
addParameter(params, "language", "zh");
addParameter(params, "latlng", lat + "," + lon);
String json = get("https://maps.googleapis.com/maps/api/geocode/json", params);
JSONObject jsonObject = new JSONObject(json);
if (!"OK".equals(jsonObject.getString("status"))) {
Error error = new Error();
error.setErrorCode(jsonObject.getString("status"));
error.setError(jsonObject.optString("error_message"));
return new Result(error);
}
JSONArray results = jsonObject.getJSONArray("results");
if (results.length() == 0) {
return new Result(StringUtils.EMPTY);
}
return new Result(results.getJSONObject(0).getString("formatted_address"));
}
}
================================================
FILE: src/main/java/com/belerweb/social/bean/Error.java
================================================
package com.belerweb.social.bean;
import org.json.JSONObject;
public final class Error extends JsonBean {
private String request;
private String errorCode;
private String error;
public Error() {}
public Error(String code, String message) {
this.errorCode = code;
this.error = message;
}
private Error(JSONObject jsonObject) {
super(jsonObject);
}
public String getRequest() {
return request;
}
public void setRequest(String request) {
this.request = request;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
@Override
public String toString() {
return errorCode + ":" + error + "(" + request + ")";
}
public static Error parse(JSONObject jsonObject) {
String errorCode = jsonObject.optString("error_code", null);
if (errorCode != null) {// 微博
String request = jsonObject.optString("request", null);
String error = jsonObject.optString("error", null);
Error er = new Error(jsonObject);
er.setRequest(request);
er.setErrorCode(errorCode);
er.setError(error);
return er;
}
errorCode = jsonObject.optString("error", null);
if (errorCode != null) {// QQ互联
String error = jsonObject.optString("error_description", null);
Error er = new Error(jsonObject);
er.setErrorCode(errorCode);
er.setError(error);
return er;
}
Integer ret = Result.parseInteger(jsonObject.opt("ret"));
if (ret != null && ret != 0) {// QQ互联
String msg = jsonObject.optString("msg", null);
Error er = new Error(jsonObject);
er.setErrorCode(ret.toString());
er.setError(msg);
return er;
}
ret = Result.parseInteger(jsonObject.opt("errcode"));
if (ret != null && ret != 0) {// 微信
String error = jsonObject.optString("errmsg", null);
Error er = new Error(jsonObject);
er.setErrorCode(ret.toString());
er.setError(error);
return er;
}
return null;
}
}
================================================
FILE: src/main/java/com/belerweb/social/bean/Gender.java
================================================
package com.belerweb.social.bean;
public enum Gender {
MALE(1, "m", "男", "Male"), FEMALE(0, "f", "女", "Female"), UNKNOWN(-1, "n", "未知", "Unknown");
int intValue;
String code;
String zhValue;
String enValue;
private Gender(int intValue, String code, String zhValue, String enValue) {
this.intValue = intValue;
this.code = code;
this.zhValue = zhValue;
this.enValue = zhValue;
}
public int value() {
return intValue;
}
public String code() {
return code;
}
public String text() {
return zhValue;
}
public String enText() {
return enValue;
}
@Override
public String toString() {
return zhValue;
}
public static Gender parse(Integer val) {
if (val == null) {
return null;
}
if (new Integer(1).equals(val)) {
return MALE;
}
if (new Integer(0).equals(val) || new Integer(2).equals(val)) {
// FIXME 微信2代表女性,0表示未知。暂且把微信的未知看作女性,如同新浪微博用户没有设置性别的时候会返回男性一样
return FEMALE;
}
return UNKNOWN;
}
public static Gender parse(String val) {
if (val == null) {
return null;
}
if ("男".equals(val) || "m".equalsIgnoreCase(val) || "male".equalsIgnoreCase(val)
|| "b".equalsIgnoreCase(val) || "boy".equalsIgnoreCase(val)) {
return MALE;
}
if ("女".equals(val) || "f".equalsIgnoreCase(val) || "female".equalsIgnoreCase(val)
|| "g".equalsIgnoreCase(val) || "girl".equalsIgnoreCase(val)) {
return FEMALE;
}
return UNKNOWN;
}
}
================================================
FILE: src/main/java/com/belerweb/social/bean/JsonBean.java
================================================
package com.belerweb.social.bean;
import org.json.JSONObject;
public abstract class JsonBean {
private JSONObject jsonObject;
protected JsonBean() {}
protected JsonBean(JSONObject jsonObject) {
this.jsonObject = jsonObject;
}
public JSONObject getJsonObject() {
return jsonObject;
}
}
================================================
FILE: src/main/java/com/belerweb/social/bean/OnlineStatus.java
================================================
package com.belerweb.social.bean;
public enum OnlineStatus {
ONLINE(1, "在线", "online"), OFFLINE(0, "不在线", "offline");
private int status;
private String text;
private String enText;
private OnlineStatus(int status, String text, String enText) {
this.status = status;
this.text = text;
this.enText = enText;
}
public boolean online() {
return status == 1;
}
public int status() {
return status;
}
public String text() {
return text;
}
public String enText() {
return enText;
}
@Override
public String toString() {
return super.toString();
}
public static OnlineStatus parse(Integer val) {
if (val == null) {
return null;
}
if (new Integer(1).equals(val)) {
return ONLINE;
}
return OFFLINE;
}
public static OnlineStatus parse(String val) {
if (val == null) {
return null;
}
if ("在线".equals(val) || "online".equalsIgnoreCase(val)) {
return ONLINE;
}
return OFFLINE;
}
}
================================================
FILE: src/main/java/com/belerweb/social/bean/Result.java
================================================
package com.belerweb.social.bean;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.json.JSONArray;
import org.json.JSONObject;
import com.belerweb.social.exception.SocialException;
public class Result {
private Error error;
private T result;
private List results;
public Result(Error error) {
this.error = error;
}
public Result(T result) {
this.result = result;
}
public Result(List results) {
this.results = results;
}
public boolean success() {
return error == null;
}
public Error getError() {
return error;
}
public T getResult() {
return result;
}
public List getResults() {
return results;
}
public static Result parse(String json, Class resultType) {
try {
if (json.matches("^\\s*\\[.*$")) {
return new Result(parse(new JSONArray(json), resultType));
} else {
return parse(new JSONObject(json), resultType);
}
} catch (Exception e) {
throw new SocialException(e);
}
}
@SuppressWarnings("unchecked")
public static Result parse(JSONObject jsonObject, Class resultType) {
try {
Error error = Error.parse(jsonObject);
if (error == null) {
Method parse = resultType.getMethod("parse", JSONObject.class);
T obj = (T) parse.invoke(null, jsonObject);
return new Result(obj);
}
return new Result(error);
} catch (Exception e) {
throw new SocialException(e);
}
}
@SuppressWarnings("unchecked")
public static List parse(JSONArray jsonArray, Class resultType) {
List list = new ArrayList();
if (jsonArray == null) {
return list;
}
try {
for (int i = 0; i < jsonArray.length(); i++) {
if (resultType.isAssignableFrom(String.class)) {
list.add((T) toString(jsonArray.get(i)));
} else if (resultType.isAssignableFrom(Integer.class)) {
list.add((T) parseInteger(jsonArray.get(i)));
} else if (resultType.isAssignableFrom(Long.class)) {
list.add((T) parseLong(jsonArray.get(i)));
} else if (resultType.isAssignableFrom(Double.class)) {
list.add((T) parseDouble(jsonArray.get(i)));
} else {
Method parse = resultType.getMethod("parse", JSONObject.class);
list.add((T) parse.invoke(null, jsonArray.getJSONObject(i)));
}
}
return list;
} catch (Exception e) {
throw new SocialException(e);
}
}
public static String toString(Object obj) {
if (obj == null) {
return null;
}
return obj.toString();
}
public static Long parseLong(Object obj) {
if (obj == null) {
return null;
}
Long result = null;
if (obj instanceof Number) {
result = ((Number) obj).longValue();
} else if (obj instanceof String) {
result = Long.valueOf((String) obj);
}
return result;
}
public static Integer parseInteger(Object obj) {
if (obj == null) {
return null;
}
Integer result = null;
if (obj instanceof Number) {
result = ((Number) obj).intValue();
} else if (obj instanceof String) {
result = Integer.valueOf((String) obj);
}
return result;
}
public static Double parseDouble(Object obj) {
if (obj == null) {
return null;
}
Double result = null;
if (obj instanceof Number) {
result = ((Number) obj).doubleValue();
} else if (obj instanceof String) {
result = Double.valueOf((String) obj);
}
return result;
}
public static Boolean parseBoolean(Object obj) {
if (obj == null) {
return null;
}
Boolean result = null;
if (obj instanceof Boolean) {
result = (Boolean) obj;
} else if (obj instanceof Integer) {
result = ((Integer) obj).intValue() == 1;
} else if (obj instanceof String) {
result = Boolean.valueOf(obj.toString());
}
return result;
}
public static Date parseDate(Object obj, String pattern, Locale locale) {
if (obj == null) {
return null;
}
Date result = null;
if (obj instanceof Date) {
result = new Date(((Date) obj).getTime());
} else if (obj instanceof String) {
try {
SimpleDateFormat format = new SimpleDateFormat(pattern, locale);
result = format.parse((String) obj);
} catch (ParseException e) {
throw new SocialException(e);
}
}
return result;
}
public static Date parseTimeSeconds(Object obj) {
Integer seconds = Result.parseInteger(obj);
if (seconds == null || seconds == 0) {
return null;
}
return new Date(seconds * 1000);
}
}
================================================
FILE: src/main/java/com/belerweb/social/captcha/api/Yundama.java
================================================
package com.belerweb.social.captcha.api;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.json.JSONObject;
import com.belerweb.social.bean.Error;
import com.belerweb.social.bean.Result;
import com.belerweb.social.captcha.bean.YundamaType;
import com.belerweb.social.exception.SocialException;
import com.belerweb.social.http.Http;
import com.belerweb.social.http.HttpException;
public class Yundama {
private String appId = "85";
private String appKey = "19fcd07d8de9c03b8cebec5d8bfe7d8e";
private String username;
private String password;
public Yundama(String username, String password) {
this.username = username;
this.password = password;
}
public Result decode(byte[] img, YundamaType type) {
HttpPost request = new HttpPost("http://api.yundama.com/api.php?method=upload");
MultipartEntityBuilder builder =
MultipartEntityBuilder.create()
.addBinaryBody("file", img, ContentType.create("image/png"), "code.png")
.addTextBody("username", username).addTextBody("password", password)
.addTextBody("codetype", type.getType().toString()).addTextBody("appid", appId)
.addTextBody("appkey", appKey).addTextBody("timeout", "60");
request.setEntity(builder.build());
try {
HttpResponse response = Http.CLIENT.execute(request);
String json = IOUtils.toString(response.getEntity().getContent());
request.releaseConnection();
JSONObject jsonObject = new JSONObject(json);
Integer ret = Result.parseInteger(jsonObject.get("ret"));
if (ret == 0) {
String url =
"http://api.yundama.com/api.php?method=result&cid="
+ Result.toString(jsonObject.get("cid"));
long start = System.currentTimeMillis();
while (true) {
jsonObject = new JSONObject(Http.get(url));
if (Result.parseInteger(jsonObject.get("ret")) == 0) {
return new Result(Result.toString(jsonObject.get("text")));
}
if (System.currentTimeMillis() - start > 10000) {
return new Result(new Error("TIMEOUT", "验证码识别超时。"));
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Error error = new Error();
error.setErrorCode(ret.toString());
return new Result(error);
} catch (ClientProtocolException e) {
throw new SocialException(e);
} catch (HttpException e) {
throw new SocialException(e);
} catch (IOException e) {
throw new SocialException(e);
}
}
}
================================================
FILE: src/main/java/com/belerweb/social/captcha/bean/YundamaType.java
================================================
package com.belerweb.social.captcha.bean;
public enum YundamaType {
/**
* 不定长英文数字 2.5题分一个字符(按文本长度收费)
*/
ALPHANUMERIC(1000),
/**
* 1位英文数字 7题分
*/
ALPHANUMERIC1(1001),
/**
* 2位英文数字 8题分
*/
ALPHANUMERIC2(1002),
/**
* 3位英文数字 9题分
*/
ALPHANUMERIC3(1003),
/**
* 4位英文数字 10题分
*/
ALPHANUMERIC4(1004),
/**
* 5位英文数字 12题分
*/
ALPHANUMERIC5(1005),
/**
* 6位英文数字 15题分
*/
ALPHANUMERIC6(1006),
/**
* 7位英文数字 17题分
*/
ALPHANUMERIC7(1007),
/**
* 8位英文数字 20题分
*/
ALPHANUMERIC8(1008),
/**
* 9位英文数字 22题分
*/
ALPHANUMERIC9(1009),
/**
* 10位英文数字 25题分
*/
ALPHANUMERIC10(1010),
/**
* 11位英文数字 27题分
*/
ALPHANUMERIC11(1011),
/**
* 12位英文数字 30题分
*/
ALPHANUMERIC12(1012),
/**
* 13位英文数字 32题分
*/
ALPHANUMERIC13(1013),
/**
* 14位英文数字 35题分
*/
ALPHANUMERIC14(1014),
/**
* 15位英文数字 37题分
*/
ALPHANUMERIC15(1015),
/**
* 16位英文数字 40题分
*/
ALPHANUMERIC16(1016),
/**
* 17位英文数字 42题分
*/
ALPHANUMERIC17(1017),
/**
* 18位英文数字 45题分
*/
ALPHANUMERIC18(1018),
/**
* 19位英文数字 47题分
*/
ALPHANUMERIC19(1019),
/**
* 20位英文数字 50题分
*/
ALPHANUMERIC20(1020),
/**
* 2位纯汉字 20题分
*/
CHINESE2(2002),
/**
* 4位纯汉字 40题分
*/
CHINESE4(2004),
/**
* 4位纯英文 10题分
*/
ALPHABETIC4(3004),
/**
* 5位纯英文 12题分
*/
ALPHABETIC5(3005),
/**
* 6位纯英文 15题分
*/
ALPHABETIC6(3006),
/**
* 4位纯数字 10题分
*/
NUMERIC4(4004),
/**
* 5位纯数字 12题分
*/
NUMERIC5(4005);
Integer type;
YundamaType(Integer type) {
this.type = type;
}
public Integer getType() {
return type;
}
}
================================================
FILE: src/main/java/com/belerweb/social/exception/SocialException.java
================================================
package com.belerweb.social.exception;
public class SocialException extends RuntimeException {
private static final long serialVersionUID = 3536584215181288508L;
public SocialException(Exception exception) {
super(exception);
}
public SocialException(String message) {
super(message);
}
}
================================================
FILE: src/main/java/com/belerweb/social/http/Http.java
================================================
package com.belerweb.social.http;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLContext;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.HttpClientBuilder;
public final class Http {
private static final String[] AGENTS =
new String[] {
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1664.3 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; Media Center PC 5.0; .NET CLR 3.5.21022; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.30729; InfoPath.2; .NET CLR 3.0.30729; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; GTB6; .NET CLR 2.0.50727; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; GTB6; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; GTB6.3; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; GTB0.0; InfoPath.1; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 4.0.20506; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322; InfoPath.2; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.04506.30; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; .NET CLR 2.0.50727; InfoPath.1; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322; GreenBrowser)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 1.1.4322; GreenBrowser)",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36"};
public static final HttpClient CLIENT = newClient();
private static final ThreadLocal defaultCharset = new ThreadLocal();
private static Charset getDefaultCharset() {
return defaultCharset.get();
}
/**
* Sets the default charset for reading the response, which is used while the server side does not
* provided the encoding or charset. If {@code null} is set, the {@link Charset#defaultCharset()}
* will be used to read the response. Note, this is a {@link ThreadLocal} variable.
*
* @param charset the charset.
* @see #responseToString(HttpResponse)
*/
public static void setDefaultCharset(Charset charset) {
defaultCharset.set(charset);
}
public static String get(String uri, List params) throws HttpException {
String url = uri;
if (params != null) {
String param = StringUtils.join(params, "&");
if (url.contains("?")) {
url = url + "&" + param;
} else {
url = url + "?" + param;
}
}
return get(url);
}
public static String get(String uri, Header... headers) throws HttpException {
HttpGet request = new HttpGet(uri);
if (headers != null) {
for (Header header : headers) {
request.addHeader(header);
}
}
return execute(request);
}
public static String post(String uri, HttpEntity postBody, Header... headers)
throws HttpException {
HttpPost request = new HttpPost(uri);
if (postBody != null) {
request.setEntity(postBody);
}
if (headers != null) {
for (Header header : headers) {
request.addHeader(header);
}
}
return execute(request);
}
public static String post(String uri, List params, String charset,
Header... headers) throws HttpException {
HttpPost request = new HttpPost(uri);
if (params != null) {
List parameters = new ArrayList();
parameters.addAll(params);
try {
HttpEntity entity = new UrlEncodedFormEntity(parameters, charset);
request.setEntity(entity);
} catch (UnsupportedEncodingException e) {
throw new HttpException(e);
}
}
if (headers != null) {
for (Header header : headers) {
request.addHeader(header);
}
}
return execute(request);
}
public static String post(String uri) throws HttpException {
return post(uri, (HttpEntity) null);
}
private static String execute(HttpRequestBase request) throws HttpException {
try {
HttpResponse response = CLIENT.execute(request);
// StatusLine status = response.getStatusLine();
return responseToString(response);
// if (status.getStatusCode() != HttpStatus.SC_OK) {
// throw new HttpException(status.getStatusCode() + ":" + status.getReasonPhrase() + "\r\n"
// + result);
// }
} catch (ClientProtocolException e) {
throw new HttpException(e);
} catch (IOException e) {
throw new HttpException(e);
} finally {
request.releaseConnection();
}
}
public static boolean isRequestSuccess(HttpResponse response) throws HttpException {
return response.getStatusLine() != null
&& response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
}
public static String responseToString(HttpResponse response) throws HttpException {
HttpEntity entity = response.getEntity();
String result = null;
if (entity != null) {
Charset charset = null;
Header encoding = entity.getContentEncoding();
if (encoding == null) {
ContentType contentType = ContentType.get(entity);
if (contentType != null) {
charset = contentType.getCharset();
}
} else {
charset = Charset.forName(encoding.getValue());
}
if (charset == null) {
charset = getDefaultCharset();
}
try {
result = IOUtils.toString(entity.getContent(), charset);
} catch (Exception e) {
throw new HttpException(e);
}
return result;
} else {
throw new HttpException("No response entity.");
}
}
public static String randomAgent() {
return AGENTS[RandomUtils.nextInt(AGENTS.length)];
}
public static HttpClient newClient() {
SSLContext sslContext = SSLContexts.createDefault();
try {
sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
return true;
}
}).build();
} catch (Exception e) {
e.printStackTrace();
}
return HttpClientBuilder
.create()
.setSslcontext(sslContext)
.setMaxConnPerRoute(50)
.setMaxConnTotal(200)
.setUserAgent(Http.randomAgent())
.setDefaultRequestConfig(
RequestConfig.custom().setConnectTimeout(30000).setSocketTimeout(30000)
.setConnectionRequestTimeout(30000).build()).build();
}
}
================================================
FILE: src/main/java/com/belerweb/social/http/HttpException.java
================================================
package com.belerweb.social.http;
public class HttpException extends Exception {
private static final long serialVersionUID = -7528165403129614352L;
public HttpException(Exception exception) {
super(exception);
}
public HttpException(String message) {
super(message);
}
}
================================================
FILE: src/main/java/com/belerweb/social/mail/api/POP3.java
================================================
package com.belerweb.social.mail.api;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.net.SocketException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.pop3.POP3Client;
import org.apache.commons.net.pop3.POP3MessageInfo;
import org.apache.commons.net.pop3.POP3SClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.belerweb.social.exception.SocialException;
/**
* POP3 邮件工具
*/
public class POP3 {
private static final Logger LOGGER = LoggerFactory.getLogger(POP3.class);
private String username;
private String password;
private String host;
private int port;
private POP3Client client;
public POP3(String username, String password, String host) {
this(username, password, host, org.apache.commons.net.pop3.POP3.DEFAULT_PORT, false);
}
public POP3(String username, String password, String host, int port, boolean ssl) {
this.username = username;
this.password = password;
this.host = host;
this.port = port;
if (ssl) {
this.client = new POP3SClient("SSL", true);
} else {
this.client = new POP3Client();
}
this.client.setDefaultTimeout(300000);
}
private boolean login() throws SocketException, IOException {
client.connect(host, port);
return client.login(username, password);
}
/**
* 检查用户信息是否正确
*/
public boolean test() throws SocialException {
try {
return login();
} catch (SocketException e) {
e.printStackTrace();
throw new SocialException(e);
} catch (IOException e) {
e.printStackTrace();
throw new SocialException(e);
} finally {
try {
this.client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 下载所有电子邮件到指定目录
*/
public void download(File dir) throws SocialException {
if (!dir.isDirectory() || !dir.canWrite()) {
throw new SocialException("The specified directory is unavailable.");
}
try {
if (login()) {
POP3MessageInfo[] messages = client.listUniqueIdentifiers();
if (messages == null) {
LOGGER.debug("Could not retrieve message list.");
throw new SocialException("Could not retrieve message list.");
} else {
for (POP3MessageInfo message : messages) {
File eml = new File(dir, username + "@" + host + "/" + message.identifier + ".eml");
try {
Reader reader = client.retrieveMessage(message.number);
if (reader == null) {
LOGGER.debug("Could not retrieve message.");
continue;
}
if (eml.exists()
&& ((message.size > 0 && eml.length() == message.size) || eml.length() > 1000)) {
LOGGER.debug("Message {} exist, skip download.", message.identifier);
continue;
}
eml.getParentFile().mkdirs();
LOGGER.debug("Downloading {} ...", message.identifier);
IOUtils.copy(reader, new FileOutputStream(eml));;
LOGGER.debug("Downloaded {} ...", message.identifier);
} catch (Exception e) {
try {
FileUtils.forceDelete(eml);
} catch (Exception exception) {
e.printStackTrace();
}
}
}
}
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 下载所有电子邮件到指定目录
*/
public void download(String dir) {
download(new File(dir));
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/api/OAuth2.java
================================================
package com.belerweb.social.qq.connect.api;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import org.json.JSONObject;
import com.belerweb.social.API;
import com.belerweb.social.bean.Result;
import com.belerweb.social.qq.connect.bean.AccessToken;
import com.belerweb.social.qq.connect.bean.Display;
import com.belerweb.social.qq.connect.bean.Gut;
import com.belerweb.social.qq.connect.bean.OpenID;
import com.belerweb.social.qq.connect.bean.Scope;
public final class OAuth2 extends API {
OAuth2(QQConnect connect) {
super(connect);
}
/**
* 获取Authorization Code
*
* @see OAuth2#authorize(Boolean)
*/
public String authorize() {
return authorize(false);
}
/**
* 获取Authorization Code
*
* @see OAuth2#authorize(String, Boolean)
*/
public String authorize(String redirectUri) {
return authorize(redirectUri, false);
}
/**
* 获取Authorization Code
*
* 从 {@link QQConnect} 从获取clientId,redirectUri,responseType为code,state使用authorize,scope使用
* {@link Scope#ALL},其余参数默认
*
* @see OAuth2#authorize(String, String, String, String, Scope[], Display, Gut, Boolean)
*/
public String authorize(Boolean wap) {
return authorize(connect.getRedirectUri(), wap);
}
/**
* 获取Authorization Code
*
* 从 {@link QQConnect} 从获取clientId,responseType为code,state使用authorize,scope使用 {@link Scope#ALL}
* ,其余参数默认
*
* @see OAuth2#authorize(String, String, String, String, Scope[], Display, Gut, Boolean)
*/
public String authorize(String redirectUri, Boolean wap) {
return authorize(connect.getClientId(), redirectUri, "code", "authorize", Scope.ALL, null,
null, wap);
}
/**
* 获取Authorization Code
*
* 文档地址:http://wiki.connect.qq.com/使用authorization_code获取access_token
*
* @param clientId 必须,申请QQ登录成功后,分配给应用的appid。
* @param redirectUri 必须,成功授权后的回调地址,必须是注册appid时填写的主域名下的地址,建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
* @param responseType 必须,授权类型,此值固定为“code”。
* @param state 必须,client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
* @param scope 可选,请求用户授权时向用户显示的可进行授权的列表
* @param display 可选,仅PC网站接入时使用。用于展示的样式。不传则默认展示为PC下的样式。如果传入“mobile”,则展示为mobile端下的样式。
* @param gut 仅WAP网站接入时使用。QQ登录页面版本(1:wml版本; 2:xhtml版本),默认值为1。
* @param wap 是否使wap版,默认为false
*/
public String authorize(String clientId, String redirectUri, String responseType, String state,
Scope[] scope, Display display, Gut gut, Boolean wap) {
List params = new ArrayList();
connect.addParameter(params, "response_type", responseType);
connect.addParameter(params, "client_id", clientId);
connect.addParameter(params, "redirect_uri", redirectUri);
connect.addParameter(params, "state", state);
if (scope != null) {
connect.addParameter(params, "scope", StringUtils.join(scope, ","));
}
if (Display.MOBILE.equals(display)) {
connect.addParameter(params, "display", "mobile");
}
if (Gut.XHTML.equals(gut)) {
connect.addParameter(params, "g_ut", gut.toString());
}
String url = "https://graph.qq.com/oauth2.0/authorize?";
if (Boolean.TRUE.equals(wap)) {
url = "https://graph.z.qq.com/moc2/authorize?";
}
return url + StringUtils.join(params, "&");
}
/**
* 通过Authorization Code获取Access Token,此接口适用于PC网站。
*
* 从 {@link QQConnect} 从获取clientId,clientSecret,redirectUri,grantType为authorization_code
*
* @see OAuth2#accessToken(String, String, String, String, String, Boolean)
*/
public Result accessToken(String code) {
return accessToken(code, connect.getRedirectUri());
}
/**
* 通过Authorization Code获取Access Token,此接口适用于PC网站。
*
* 从 {@link QQConnect} 从获取clientId,clientSecret,grantType为authorization_code
*
* @see OAuth2#accessToken(String, String, String, String, String, Boolean)
*/
public Result accessToken(String code, String redirectUri) {
return accessToken(code, redirectUri, null);
}
/**
* 通过Authorization Code获取Access Token
*
* 从 {@link QQConnect} 从获取clientId,clientSecret,redirectUri,grantType为authorization_code
*
* @see OAuth2#accessToken(String, String, String, String, String, Boolean)
*/
public Result accessToken(String code, Boolean wap) {
return accessToken(code, connect.getRedirectUri(), wap);
}
/**
* 通过Authorization Code获取Access Token
*
* 从 {@link QQConnect} 从获取clientId,clientSecret,grantType为authorization_code
*
* @see OAuth2#accessToken(String, String, String, String, String, Boolean)
*/
public Result accessToken(String code, String redirectUri, Boolean wap) {
return accessToken(connect.getClientId(), connect.getClientSecret(), "authorization_code",
code, redirectUri, wap);
}
/**
* 通过Authorization Code获取Access Token
*
* 文档地址:http://wiki.connect.qq.com/使用authorization_code获取access_token
*
* @param clientId 申请QQ登录成功后,分配给网站的appid。
* @param clientSecret 申请QQ登录成功后,分配给网站的appkey。
* @param grantType 授权类型,在本步骤中,此值为“authorization_code”。
* @param code 上一步返回的authorization code。如果用户成功登录并授权,则会跳转到指定的回调地址,并在URL中带上Authorization
* Code。注意此code会在10分钟内过期。
* @param redirectUri 与上面一步中传入的redirect_uri保持一致。
* @param wap 是否使wap版,默认为false
*/
public Result accessToken(String clientId, String clientSecret, String grantType,
String code, String redirectUri, Boolean wap) {
List params = new ArrayList();
connect.addParameter(params, "client_id", clientId);
connect.addParameter(params, "client_secret", clientSecret);
connect.addParameter(params, "grant_type", grantType);
connect.addParameter(params, "code", code);
connect.addParameter(params, "redirect_uri", redirectUri);
String url = "https://graph.qq.com/oauth2.0/token";
if (Boolean.TRUE.equals(wap)) {
url = "https://graph.z.qq.com/moc2/token";
}
String result = connect.get(url, params).trim();
return parseAccessTokenResult(result);
}
/**
* 权限自动续期,获取Access Token,此方法适用于PC网站。
*
* 从 {@link QQConnect}中获取 clientId, clientSecret
*
* @see OAuth2#refreshAccessToken(String, String, String, String, Boolean)
* @param refreshToken {@link AccessToken}中的refresToken。
*/
public Result refreshAccessToken(String refreshToken) {
return refreshAccessToken(connect.getClientId(), connect.getClientSecret(), refreshToken);
}
/**
* 权限自动续期,获取Access Token,此方法适用于PC网站。
*
* @see OAuth2#refreshAccessToken(String, String, String, String, Boolean)
* @param refreshToken {@link AccessToken}中的refresToken。
*/
public Result refreshAccessToken(String clientId, String clientSecret,
String refreshToken) {
return refreshAccessToken(clientId, clientSecret, "refresh_token", refreshToken, null);
}
/**
* 权限自动续期,获取Access Token
*
* 从 {@link QQConnect}中获取 clientId, clientSecret
*
* @see OAuth2#refreshAccessToken(String, String, String, String, Boolean)
* @param refreshToken {@link AccessToken}中的refresToken。
* @param wap 是否使wap版,默认为false
*/
public Result refreshAccessToken(String refreshToken, Boolean wap) {
return refreshAccessToken(connect.getClientId(), connect.getClientSecret(), refreshToken, wap);
}
/**
* 权限自动续期,获取Access Token
*
* @see OAuth2#refreshAccessToken(String, String, String, String, Boolean)
* @param refreshToken {@link AccessToken}中的refresToken。
* @param wap 是否使wap版,默认为false
*/
public Result refreshAccessToken(String clientId, String clientSecret,
String refreshToken, Boolean wap) {
return refreshAccessToken(clientId, clientSecret, "refresh_token", refreshToken, wap);
}
/**
* 权限自动续期,获取Access Token
*
* 文档地址:http://wiki.connect.qq.com/使用authorization_code获取access_token
*
* @param clientId 申请QQ登录成功后,分配给网站的appid。
* @param clientSecret 申请QQ登录成功后,分配给网站的appkey。
* @param grantType 授权类型,在本步骤中,此值为“refresh_token”。
* @param refresToken {@link AccessToken}中的refresToken。
* @param wap 是否使wap版,默认为false
*/
public Result refreshAccessToken(String clientId, String clientSecret,
String grantType, String refreshToken, Boolean wap) {
List params = new ArrayList();
connect.addParameter(params, "client_id", clientId);
connect.addParameter(params, "client_secret", clientSecret);
connect.addParameter(params, "grant_type", grantType);
connect.addParameter(params, "refresh_token", refreshToken);
String url = "https://graph.qq.com/oauth2.0/token";
if (Boolean.TRUE.equals(wap)) {
url = "https://graph.z.qq.com/moc2/token";
}
String result = connect.get(url, params);
return parseAccessTokenResult(result);
}
/**
* 获取用户OpenID,此接口适用于PC网站访问
*
* 文档地址:http://wiki.connect.qq.com/获取用户openid_oauth2-0
*
* @param accessToken 授权令牌
*/
public Result openId(String accessToken) {
return openId(accessToken, null);
}
/**
* 获取用户OpenID
*
* 文档地址:http://wiki.connect.qq.com/获取用户openid_oauth2-0
*
* @param accessToken 授权令牌
* @param wap 是否使wap网站访问
*/
public Result openId(String accessToken, Boolean wap) {
List params = new ArrayList();
connect.addParameter(params, "access_token", accessToken);
String url = "https://graph.qq.com/oauth2.0/me";
if (Boolean.TRUE.equals(wap)) {
url = "https://graph.z.qq.com/moc2/me";
}
String result = connect.get(url, params).trim();
JSONObject jsonObject;
if (result.startsWith("callback")) {// PC网站的正确返回结果
jsonObject =
new JSONObject(result.substring(result.indexOf("{"), result.lastIndexOf("}") + 1));
} else {// WAP网站返回结果或错误信息
jsonObject = new JSONObject();
String[] results = result.split("\\&");
for (String param : results) {
String[] keyValue = param.split("\\=");
jsonObject.put(keyValue[0], keyValue.length > 0 ? keyValue[1] : null);
}
String errorCode = jsonObject.optString("code", null);
if (errorCode != null) {
jsonObject.put("ret", errorCode);// To match Error.parse()
}
}
return Result.parse(jsonObject, OpenID.class);
}
private Result parseAccessTokenResult(String result) {
JSONObject jsonObject;
if (result.startsWith("callback")) {// 错误信息
// callback({"error":100021,"error_description":"get access token error"});
jsonObject =
new JSONObject(result.substring(result.indexOf("{"), result.lastIndexOf("}") + 1));
return Result.parse(jsonObject, AccessToken.class);
} else {// 正确结果
jsonObject = new JSONObject();
String[] results = result.split("\\&");
for (String param : results) {
String[] keyValue = param.split("\\=");
jsonObject.put(keyValue[0], keyValue.length > 0 ? keyValue[1] : null);
}
String errorCode = jsonObject.optString("code", null);
if (errorCode != null) {
jsonObject.put("ret", errorCode);// To match Error.parse()
}
}
return Result.parse(jsonObject, AccessToken.class);
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/api/QQConnect.java
================================================
package com.belerweb.social.qq.connect.api;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.json.JSONObject;
import com.belerweb.social.SDK;
import com.belerweb.social.bean.Error;
import com.belerweb.social.bean.Result;
import com.belerweb.social.exception.SocialException;
import com.belerweb.social.http.Http;
import com.belerweb.social.qq.connect.bean.NewT;
import com.belerweb.social.qq.connect.bean.TenpayAddress;
public final class QQConnect extends SDK {
private String clientId;
private String clientSecret;
private String redirectUri;
private OAuth2 oAuth2;
private User user;
public QQConnect(String clientId, String clientSecret) {
this.clientId = clientId;
this.clientSecret = clientSecret;
}
public QQConnect(String clientId, String clientSecret, String redirectUri) {
this(clientId, clientSecret);
this.redirectUri = redirectUri;
}
/**
* 收听腾讯微博上的用户。
*
* 文档地址:http://wiki.connect.qq.com/add_idol
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
* @param name 要收听的用户的账户名列表。最多30个。
*/
public Result addIdol(String accessToken, String openId, List name) {
return addIdol(accessToken, openId, name, null);
}
/**
* 收听腾讯微博上的用户。
*
* 文档地址:http://wiki.connect.qq.com/add_idol
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
* @param name 要收听的用户的账户名列表。最多30个。
* @param fopenids 要收听的用户的openid列表。最多30个。 name和fopenids至少选一个,若同时存在则以name值为主。
*/
public Result addIdol(String accessToken, String openId, List name,
List fopenids) {
return addIdol(accessToken, getClientId(), openId, name, fopenids);
}
/**
* 收听腾讯微博上的用户。
*
* 文档地址:http://wiki.connect.qq.com/add_idol
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oauthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openId 用户的ID,与QQ号码一一对应。
* @param name 要收听的用户的账户名列表。最多30个。
* @param fopenids 要收听的用户的openid列表。最多30个。 name和fopenids至少选一个,若同时存在则以name值为主。
*/
public Result addIdol(String accessToken, String oauthConsumerKey, String openId,
List name, List fopenids) {
List params = new ArrayList();
addParameter(params, "access_token", accessToken);
addParameter(params, "oauth_consumer_key", oauthConsumerKey);
addParameter(params, "openid", openId);
if (name != null && !name.isEmpty()) {
addParameter(params, "name", StringUtils.join(name, ","));
}
if (fopenids != null && !fopenids.isEmpty()) {
addParameter(params, "fopenids", StringUtils.join(fopenids, "_"));
}
addParameter(params, "format", "json");
return Result.parse(post("https://graph.qq.com/relation/add_idol", params), Error.class);
}
/**
* 取消收听腾讯微博上的用户。
*
* 文档地址:http://wiki.connect.qq.com/del_idol
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
* @param name 要取消收听的用户的账户名。 可选,name和fopenid至少选一个,若同时存在则以name值为主。
*/
public Result delIdol(String accessToken, String openId, String name) {
return delIdol(accessToken, openId, name, null);
}
/**
* 取消收听腾讯微博上的用户。
*
* 文档地址:http://wiki.connect.qq.com/del_idol
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
* @param name 要取消收听的用户的账户名。 可选,name和fopenid至少选一个,若同时存在则以name值为主。
* @param fopenid 要取消收听的用户的openid。可选,name和fopenid至少选一个,若同时存在则以name值为主。
*/
public Result delIdol(String accessToken, String openId, String name, String fopenid) {
return delIdol(accessToken, getClientId(), openId, name, fopenid);
}
/**
* 取消收听腾讯微博上的用户。
*
* 文档地址:http://wiki.connect.qq.com/del_idol
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oauthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openId 用户的ID,与QQ号码一一对应。
* @param name 要取消收听的用户的账户名。 可选,name和fopenid至少选一个,若同时存在则以name值为主。
* @param fopenid 要取消收听的用户的openid。可选,name和fopenid至少选一个,若同时存在则以name值为主。
*/
public Result delIdol(String accessToken, String oauthConsumerKey, String openId,
String name, String fopenid) {
List params = new ArrayList();
addParameter(params, "access_token", accessToken);
addParameter(params, "oauth_consumer_key", oauthConsumerKey);
addParameter(params, "openid", openId);
addNotNullParameter(params, "name", name);
addNotNullParameter(params, "fopenid", fopenid);
addParameter(params, "format", "json");
return Result.parse(post("https://graph.qq.com/relation/del_idol", params), Error.class);
}
/**
* 登录用户发表一篇新日志。
*
* 文档地址:http://wiki.connect.qq.com/add_one_blog
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
* @param title 日志标题(纯文本,最大长度128个字节,utf-8编码)。
* @param content 文章内容(html数据,最大长度100*1024个字节,utf-8编码).
*/
public Result addOneBlog(String accessToken, String openId, String title, String content) {
return addOneBlog(accessToken, getClientId(), openId, title, content);
}
/**
* 登录用户发表一篇新日志。
*
* 文档地址:http://wiki.connect.qq.com/add_one_blog
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oauthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openId 用户的ID,与QQ号码一一对应。
* @param title 日志标题(纯文本,最大长度128个字节,utf-8编码)。
* @param content 文章内容(html数据,最大长度100*1024个字节,utf-8编码).
*/
public Result addOneBlog(String accessToken, String oauthConsumerKey, String openId,
String title, String content) {
List params = new ArrayList();
addParameter(params, "access_token", accessToken);
addParameter(params, "oauth_consumer_key", oauthConsumerKey);
addParameter(params, "openid", openId);
addParameter(params, "title", title);
addParameter(params, "content", content);
addParameter(params, "format", "json");
return Result.parse(post("https://graph.qq.com/blog/add_one_blog", params), Error.class);
}
/**
* 发表一条微博信息(纯文本)到腾讯微博平台上。注意连续两次发布的微博内容不可以重复。
*
* 文档地址:http://wiki.connect.qq.com/add_t
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
* @param content
* 表示要发表的微博内容。必须为UTF-8编码,最长为140个汉字,也就是420字节。如果微博内容中有URL,后台会自动将该URL转换为短URL,每个URL折算成11个字节。
* 若在此处@好友,需正确填写好友的微博账号,而非昵称。
*/
public Result addT(String accessToken, String openId, String content) {
return addT(accessToken, getClientId(), openId, content);
}
/**
* 发表一条微博信息(纯文本)到腾讯微博平台上。注意连续两次发布的微博内容不可以重复。
*
* 文档地址:http://wiki.connect.qq.com/add_t
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oauthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openId 用户的ID,与QQ号码一一对应。
* @param content
* 表示要发表的微博内容。必须为UTF-8编码,最长为140个汉字,也就是420字节。如果微博内容中有URL,后台会自动将该URL转换为短URL,每个URL折算成11个字节。
* 若在此处@好友,需正确填写好友的微博账号,而非昵称。
*/
public Result addT(String accessToken, String oauthConsumerKey, String openId,
String content) {
return addT(accessToken, oauthConsumerKey, openId, content, null, null, null, true, true);
}
/**
* 发表一条微博信息(纯文本)到腾讯微博平台上。注意连续两次发布的微博内容不可以重复。
*
* 文档地址:http://wiki.connect.qq.com/add_t
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oauthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openId 用户的ID,与QQ号码一一对应。
* @param content
* 表示要发表的微博内容。必须为UTF-8编码,最长为140个汉字,也就是420字节。如果微博内容中有URL,后台会自动将该URL转换为短URL,每个URL折算成11个字节。
* 若在此处@好友,需正确填写好友的微博账号,而非昵称。
* @param clientIp 用户ip。必须正确填写用户侧真实ip,不能为内网ip及以127或255开头的ip,以分析用户所在地。
* @param lon 用户所在地理位置的经度。为实数,最多支持10位有效数字。有效范围:-180.0到+180.0,+表示东经,默认为0.0。
* @param lat 用户所在地理位置的纬度。为实数,最多支持10位有效数字。有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
* @param sync 标识是否将发布的微博同步到QQ空间(0:同步; 1:不同步;),默认为0。该参数只支持OAuth1.0,OAuth2.0暂不支持。
* @param compatible 容错标志,支持按位操作,默认为0。0x20:微博内容长度超过140字则报错;0:以上错误均做容错处理,即发表普通微博。
*/
public Result addT(String accessToken, String oauthConsumerKey, String openId,
String content, String clientIp, Double lon, Double lat, Boolean sync, Boolean compatible) {
List params = new ArrayList();
addParameter(params, "access_token", accessToken);
addParameter(params, "oauth_consumer_key", oauthConsumerKey);
addParameter(params, "openid", openId);
addParameter(params, "content", content);
addNotNullParameter(params, "clientip", clientIp);
addNotNullParameter(params, "lon", lon);
addNotNullParameter(params, "lat", lat);
if (sync != null) {
addParameter(params, "syncflag", sync ? "0" : "1");
}
if (compatible != null) {
addParameter(params, "compatibleflag", compatible ? "0" : "0x20");
}
addParameter(params, "format", "json");
JSONObject jsonObject = new JSONObject(post("https://graph.qq.com/t/add_t", params));
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result(error);
}
return Result.parse(jsonObject.getJSONObject("data"), NewT.class);
}
/**
* 根据微博ID删除指定微博。
*
* 文档地址:http://wiki.connect.qq.com/del_t
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
* @param id 微博消息的ID,用来唯一标识一条微博消息。
*/
public Result delT(String accessToken, String openId, String id) {
return delT(accessToken, getClientId(), openId, id);
}
/**
* 上传一张图片,并发布一条消息到腾讯微博平台上。
*
* 文档地址:http://wiki.connect.qq.com/add_pic_t
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
* @param content
* 表示要发表的微博内容。必须为UTF-8编码,最长为140个汉字,也就是420字节。如果微博内容中有URL,后台会自动将该URL转换为短URL,每个URL折算成11个字节。
* 若在此处@好友,需正确填写好友的微博账号,而非昵称。
* @param pic
* 要上传的图片的文件名以及图片的内容(在发送请求时,图片内容以二进制数据流的形式发送,见下面的请求示例)。图片仅支持gif、jpeg、jpg、png、bmp及ico格式(所有图片都会重新压缩
* ,gif被重新压缩后不会再有动画效果),图片size小于4M。
*/
public Result addPicT(String accessToken, String openId, String content, byte[] pic) {
return addPicT(accessToken, getClientId(), openId, content, pic);
}
/**
* 上传一张图片,并发布一条消息到腾讯微博平台上。
*
* 文档地址:http://wiki.connect.qq.com/add_pic_t
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oauthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openId 用户的ID,与QQ号码一一对应。
* @param content
* 表示要发表的微博内容。必须为UTF-8编码,最长为140个汉字,也就是420字节。如果微博内容中有URL,后台会自动将该URL转换为短URL,每个URL折算成11个字节。
* 若在此处@好友,需正确填写好友的微博账号,而非昵称。
* @param pic
* 要上传的图片的文件名以及图片的内容(在发送请求时,图片内容以二进制数据流的形式发送,见下面的请求示例)。图片仅支持gif、jpeg、jpg、png、bmp及ico格式(所有图片都会重新压缩
* ,gif被重新压缩后不会再有动画效果),图片size小于4M。
*/
public Result addPicT(String accessToken, String oauthConsumerKey, String openId,
String content, byte[] pic) {
return addPicT(accessToken, oauthConsumerKey, openId, content, pic, null, null, null, true,
true);
}
/**
* 上传一张图片,并发布一条消息到腾讯微博平台上。
*
* 文档地址:http://wiki.connect.qq.com/add_pic_t
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oauthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openId 用户的ID,与QQ号码一一对应。
* @param content
* 表示要发表的微博内容。必须为UTF-8编码,最长为140个汉字,也就是420字节。如果微博内容中有URL,后台会自动将该URL转换为短URL,每个URL折算成11个字节。
* 若在此处@好友,需正确填写好友的微博账号,而非昵称。
* @param pic
* 要上传的图片的文件名以及图片的内容(在发送请求时,图片内容以二进制数据流的形式发送,见下面的请求示例)。图片仅支持gif、jpeg、jpg、png、bmp及ico格式(所有图片都会重新压缩
* ,gif被重新压缩后不会再有动画效果),图片size小于4M。
* @param clientIp 用户ip。必须正确填写用户侧真实ip,不能为内网ip及以127或255开头的ip,以分析用户所在地。
* @param lon 用户所在地理位置的经度。为实数,最多支持10位有效数字。有效范围:-180.0到+180.0,+表示东经,默认为0.0。
* @param lat 用户所在地理位置的纬度。为实数,最多支持10位有效数字。有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
* @param sync 标识是否将发布的微博同步到QQ空间(0:同步; 1:不同步;),默认为0。该参数只支持OAuth1.0,OAuth2.0暂不支持。
* @param compatible 容错标志,支持按位操作,默认为0。0x20:微博内容长度超过140字则报错;0:以上错误均做容错处理,即发表普通微博。
*/
public Result addPicT(String accessToken, String oauthConsumerKey, String openId,
String content, byte[] pic, String clientIp, Double lon, Double lat, Boolean sync,
Boolean compatible) {
HttpPost request = new HttpPost("https://graph.qq.com/t/add_pic_t");
MultipartEntityBuilder builder = MultipartEntityBuilder.create().addBinaryBody("pic", pic);
List params = new ArrayList();
addParameter(params, "access_token", accessToken);
addParameter(params, "oauth_consumer_key", oauthConsumerKey);
addParameter(params, "openid", openId);
addParameter(params, "content", content);
addNotNullParameter(params, "clientip", clientIp);
addNotNullParameter(params, "lon", lon);
addNotNullParameter(params, "lat", lat);
if (sync != null) {
addParameter(params, "syncflag", sync ? "0" : "1");
}
if (compatible != null) {
addParameter(params, "compatibleflag", compatible ? "0" : "0x20");
}
addParameter(params, "format", "json");
for (NameValuePair nameValuePair : params) {
builder.addTextBody(nameValuePair.getName(), nameValuePair.getValue());
}
request.setEntity(builder.build());
try {
HttpResponse response = Http.CLIENT.execute(request);
String json = IOUtils.toString(response.getEntity().getContent());
JSONObject jsonObject = new JSONObject(json);
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result(error);
}
return Result.parse(jsonObject.getJSONObject("data"), NewT.class);
} catch (ClientProtocolException e) {
throw new SocialException(e);
} catch (IOException e) {
throw new SocialException(e);
} finally {
request.releaseConnection();
}
}
/**
* 根据微博ID删除指定微博。
*
* 文档地址:http://wiki.connect.qq.com/del_t
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oauthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openId 用户的ID,与QQ号码一一对应。
* @param id 微博消息的ID,用来唯一标识一条微博消息。
*/
public Result delT(String accessToken, String oauthConsumerKey, String openId, String id) {
List params = new ArrayList();
addParameter(params, "access_token", accessToken);
addParameter(params, "oauth_consumer_key", oauthConsumerKey);
addParameter(params, "openid", openId);
addParameter(params, "id", id);
addParameter(params, "format", "json");
return Result.parse(post("https://graph.qq.com/t/del_t", params), Error.class);
}
/**
* 获取财付通用户的收货地址。一个用户可能设置了多条收货地址信息。查询的用户必须为财付通用户,否则查询将返回失败。
*
* 文档地址:http://wiki.connect.qq.com/get_tenpay_addr
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
*/
public Result> getTenpayAddr(String accessToken, String openId) {
return getTenpayAddr(accessToken, getClientId(), openId, 0, Integer.MAX_VALUE);
}
/**
* 获取财付通用户的收货地址。一个用户可能设置了多条收货地址信息。查询的用户必须为财付通用户,否则查询将返回失败。
*
* 文档地址:http://wiki.connect.qq.com/get_tenpay_addr
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openId 用户的ID,与QQ号码一一对应。
* @param offset
* 表示查询收货地址的偏移量,一般情况下offset可以不传值或传入0,表示从第一条开始读取。offset参数是为一种特殊情况准备的,即该收货人有很多条收获地址,需要分页展示,
* 则offset可设置为该页显示的条数。例如如果offset为10,则会跳过第10条收货地址,从第11条收货地址开始读取。
* @param limit 表示查询收货地址的返回限制数(即最多期望返回几个收货地址)。limit不传默认按照5来处理。
*/
public Result> getTenpayAddr(String accessToken, String openId,
Integer offset, Integer limit) {
return getTenpayAddr(accessToken, getClientId(), openId, offset, limit);
}
/**
* 获取财付通用户的收货地址。一个用户可能设置了多条收货地址信息。查询的用户必须为财付通用户,否则查询将返回失败。
*
* 文档地址:http://wiki.connect.qq.com/get_tenpay_addr
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oauthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openId 用户的ID,与QQ号码一一对应。
* @param offset
* 表示查询收货地址的偏移量,一般情况下offset可以不传值或传入0,表示从第一条开始读取。offset参数是为一种特殊情况准备的,即该收货人有很多条收获地址,需要分页展示,
* 则offset可设置为该页显示的条数。例如如果offset为10,则会跳过第10条收货地址,从第11条收货地址开始读取。
* @param limit 表示查询收货地址的返回限制数(即最多期望返回几个收货地址)。limit不传默认按照5来处理。
*/
public Result> getTenpayAddr(String accessToken, String oauthConsumerKey,
String openId, Integer offset, Integer limit) {
List params = new ArrayList();
addParameter(params, "access_token", accessToken);
addParameter(params, "oauth_consumer_key", oauthConsumerKey);
addParameter(params, "openid", openId);
addParameter(params, "offset", offset == null ? "0" : offset);
addParameter(params, "limit", limit == null ? "5" : limit);
addParameter(params, "ver", "1");
addParameter(params, "format", "json");
JSONObject jsonObject =
new JSONObject(post("https://graph.qq.com/cft_info/get_tenpay_addr", params));
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result>(error);
}
List addresses = new ArrayList();
Integer total = Result.parseInteger(jsonObject.get("ret_num"));
for (int i = 0; i < total; i++) {
Integer index = Result.parseInteger(jsonObject.opt("Findex_" + i));
if (index == null) {
break;
}
TenpayAddress address = new TenpayAddress();
address.setTotal(total);
address.setIndex(index);
address.setRegionId(Result.parseInteger(jsonObject.opt("FRegionId_" + i)));
address.setStreet(jsonObject.optString("Faddrstreet_" + i));
address.setZipcode(Result.toString(jsonObject.opt("Fzipcode_" + i)));
address.setMobile(Result.toString(jsonObject.opt("Fmobile_" + i)));
address.setTel(Result.toString(jsonObject.opt("Ftel_" + i)));
address.setName(Result.toString(jsonObject.opt("Fname_" + i)));
address.setCreated(Result.parseDate(jsonObject.opt("Fcreate_time_" + i),
"yyyy-MM-dd HH:mm:ss", Locale.CHINA));
address.setModified(Result.parseDate(jsonObject.opt("Fmod_time_" + i), "yyyy-MM-dd HH:mm:ss",
Locale.CHINA));
address.setLastUsed(Result.parseDate(jsonObject.opt("Flastuse_time_" + i),
"yyyy-MM-dd HH:mm:ss", Locale.CHINA));
address.setUsedCount(Result.parseInteger(jsonObject.opt("FUsedCount_" + i)));
}
return new Result>(addresses);
}
public OAuth2 getOAuth2() {
if (oAuth2 == null) {
oAuth2 = new OAuth2(this);
}
return oAuth2;
}
public User getUser() {
if (user == null) {
user = new User(this);
}
return user;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getRedirectUri() {
return redirectUri;
}
public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/api/QZone.java
================================================
package com.belerweb.social.qq.connect.api;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.json.JSONArray;
import org.json.JSONObject;
import com.belerweb.social.API;
import com.belerweb.social.bean.Error;
import com.belerweb.social.bean.Result;
import com.belerweb.social.exception.SocialException;
import com.belerweb.social.http.Http;
import com.belerweb.social.qq.connect.bean.Album;
import com.belerweb.social.qq.connect.bean.AlbumPrivilege;
import com.belerweb.social.qq.connect.bean.Photo;
import com.belerweb.social.qq.connect.bean.PicUploadResult;
/**
* QZone API,相册,日志...
*/
public final class QZone extends API {
protected QZone(QQConnect connect) {
super(connect);
}
/**
* 获取登录用户的相册列表。
*
* 文档地址:http://wiki.connect.qq.com/list_album
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
*/
public Result listAlbum(String accessToken, String openid) {
return listAlbum(connect.getClientId(), accessToken, openid);
}
/**
* 获取登录用户的相册列表。
*
* 文档地址:http://wiki.connect.qq.com/list_album
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
*/
public Result listAlbum(String oAuthConsumerKey, String accessToken, String openid) {
List params = new ArrayList();
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
String json = connect.get("https://graph.qq.com/photo/list_album", params);
JSONObject jsonObject = new JSONObject(json);
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result(error);
}
List results = new ArrayList();
JSONArray jsonArray = jsonObject.getJSONArray("album");
for (int i = 0; i < jsonArray.length(); i++) {
results.add(Album.parse(jsonArray.getJSONObject(i)));
}
return new Result(results);
}
/**
* 登录用户创建一个公共相册。注:每个用户最多可创建10个相册。
*
* 文档地址:http://wiki.connect.qq.com/add_album
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param albumName 相册名,不能超过30个字符。
*/
public Result addAlbum(String accessToken, String openid, String albumName) {
return addAlbum(connect.getClientId(), accessToken, openid, albumName, null, null, null, null);
}
/**
* 登录用户创建相册。注:每个用户最多可创建10个相册。
*
* 文档地址:http://wiki.connect.qq.com/add_album
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param albumName 相册名,不能超过30个字符。
* @param albumDesc 相册描述,不能超过200个字符。
* @param privilege 用户的ID,与QQ号码一一对应。 相册权限,
*
* 其取值含义为: 1=公开;3=只主人可见; 4=QQ好友可见; 5=问答加密。
*
* 不传则相册默认为公开权限。
*
* 如果priv取值为5,即相册是问答加密的,则必须包含问题和答案两个参数:
*
* -question: 问题,不能超过30个字符。
*
* -answer: 答案,不能超过30个字符。
*/
public Result addAlbum(String oAuthConsumerKey, String accessToken, String openid,
String albumName, String albumDesc, AlbumPrivilege privilege, String question, String answer) {
List params = new ArrayList();
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
connect.addParameter(params, "albumname", albumName);
connect.addNotNullParameter(params, "albumdesc", albumDesc);
connect.addNotNullParameter(params, "priv", privilege);
if (privilege == AlbumPrivilege.QUESTION) {
connect.addParameter(params, "question", question);
connect.addParameter(params, "answer", answer);
}
String json = connect.post("https://graph.qq.com/photo/add_album", params);
return Result.parse(json, Album.class);
}
/**
* 登录用户上传照片,支持单张上传和批量上传。
*
* 文档地址:http://wiki.connect.qq.com/upload_pic
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param title 照片的命名,必须以.jpg, .gif, .png, .jpeg, .bmp此类后缀结尾。
* @param picture
* @param photoDesc 照片描述,注意照片描述不能超过200个字符。
* @param albumId 相册id。可不填,不填时则根据“mobile”标识选择默认上传的相册。
* @param mobile
* 标志位,0表示PC,1表示手机。用于当不传相册id时(即albumid为空时)控制是否传到手机相册。(1)如果传1,则当albumid为空时,图片会上传到手机相册;(2)
* 如果不传或传0,则当albumid为空时,图片会上传到贴图相册;
* @param lon 照片拍摄时的地理位置的经度。请使用原始数据(纯经纬度,0-360)。
* @param lat 照片拍摄时的地理位置的纬度。请使用原始数据(纯经纬度,0-360)。
* @param needFeed 标识上传照片时是否要发feed(0:不发feed; 1:发feed)。如果不填则默认为发feed。
* @param successNum 批量上传照片时,已成功上传的张数,指明上传完成情况。单张上传时可以不填,不填则默认为0。
* @param picNum
* 批量上传照片的总张数,如果不填则默认为1。如果picnum=1,为单张上传,发送单张上传feed;如果picnum>1,为批量上传,发送批量上传feed。批量上传方式:
* picnum为一次上传照片的张数
* ,successnum初始值为0,每调用一次照片上传接口后递增其值。信息中心中的feed表现形式:批量上传时最新的7张在feed中展示。其中最新上传的一张图片展示为大图
* ,剩下的六张按从新到旧的顺序展示为小图,其他图片不在feed中展示。
*/
public Result uploadPic(String oAuthConsumerKey, String accessToken,
String openid, String title, byte[] picture, String photoDesc, String albumId,
Boolean mobile, Double lon, Double lat, Boolean needFeed, Integer successNum, Integer picNum) {
HttpPost request = new HttpPost("https://graph.qq.com/photo/upload_pic");
MultipartEntityBuilder builder =
MultipartEntityBuilder.create().addBinaryBody("picture", picture,
ContentType.create("image/" + title.substring(title.lastIndexOf(".") + 1)), title);
builder.addTextBody("oauth_consumer_key", oAuthConsumerKey);
builder.addTextBody("access_token", accessToken);
builder.addTextBody("openid", openid);
builder.addTextBody("format", "json");
builder.addTextBody("title", title);
if (photoDesc != null) {
builder.addTextBody("photodesc", photoDesc);
}
if (albumId != null) {
builder.addTextBody("albumid", albumId);
}
if (Boolean.TRUE.equals(mobile)) {
builder.addTextBody("mobile", "1");
}
if (lon != null) {
builder.addTextBody("x", lon.toString());
}
if (lat != null) {
builder.addTextBody("y", lat.toString());
}
if (Boolean.FALSE.equals(needFeed)) {
builder.addTextBody("needfeed", "0");
}
if (successNum != null) {
builder.addTextBody("successnum", successNum.toString());
}
if (picNum != null) {
builder.addTextBody("picnum", picNum.toString());
}
request.setEntity(builder.build());
try {
HttpResponse response = Http.CLIENT.execute(request);
String json = IOUtils.toString(response.getEntity().getContent());
return Result.parse(json, PicUploadResult.class);
} catch (ClientProtocolException e) {
throw new SocialException(e);
} catch (IOException e) {
throw new SocialException(e);
} finally {
request.releaseConnection();
}
}
/**
* 获取登录用户的照片列表。
*
* 文档地址:http://wiki.connect.qq.com/list_photo
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param albumId 表示要获取的照片列表所在的相册ID。
*/
public Result listPhoto(String accessToken, String openid, String albumId) {
return listPhoto(connect.getClientId(), accessToken, openid, albumId);
}
/**
* 获取登录用户的照片列表。
*
* 文档地址:http://wiki.connect.qq.com/list_photo
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param albumId 表示要获取的照片列表所在的相册ID。
*/
public Result listPhoto(String oAuthConsumerKey, String accessToken, String openid,
String albumId) {
List params = new ArrayList();
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
connect.addParameter(params, "albumid", albumId);
String json = connect.get("https://graph.qq.com/photo/list_photo", params);
JSONObject jsonObject = new JSONObject(json);
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result(error);
}
List results = new ArrayList();
JSONArray jsonArray = jsonObject.getJSONArray("photos");
for (int i = 0; i < jsonArray.length(); i++) {
results.add(Photo.parse(jsonArray.getJSONObject(i)));
}
return new Result(results);
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/api/User.java
================================================
package com.belerweb.social.qq.connect.api;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import com.belerweb.social.API;
import com.belerweb.social.bean.Result;
/**
* 访问用户资料
*/
public final class User extends API {
protected User(QQConnect connect) {
super(connect);
}
/**
* 获取登录用户在QQ空间的信息,包括昵称、头像、性别及黄钻信息(包括黄钻等级、是否年费黄钻等)。此接口仅支持网站调用
*
* 文档地址:http://wiki.connect.qq.com/get_user_info
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* 可通过调用https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN 来获取。
*/
public Result getUserInfo(String accessToken,
String openid) {
return getUserInfo(accessToken, connect.getClientId(), openid);
}
/**
* 获取登录用户在QQ空间的信息,包括昵称、头像、性别及黄钻信息(包括黄钻等级、是否年费黄钻等)。此接口仅支持网站调用
*
* 文档地址:http://wiki.connect.qq.com/get_user_info
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openid 用户的ID,与QQ号码一一对应。
* 可通过调用https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN 来获取。
*/
public Result getUserInfo(String accessToken,
String oAuthConsumerKey, String openid) {
List params = new ArrayList();
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "openid", openid);
connect.addNotNullParameter(params, "format", "json");
String json = connect.get("https://graph.qq.com/user/get_user_info", params);
return Result.parse(json, com.belerweb.social.qq.connect.bean.User.class);
}
/**
* 获取移动端应用的登录用户在QQ空间的简单个人信息,包括昵称、头像和黄钻信息(包括黄钻等级、是否年费黄钻等),以及用户的QQ头像。 此接口仅支持移动端应用调用
*
* 文档地址:http://wiki.connect.qq.com/get_simple_userinfo
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openid 用户的ID,与QQ号码一一对应。
* 可通过调用https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN 来获取。
*/
public Result getSimpleUserInfo(String accessToken,
String oAuthConsumerKey, String openid) {
List params = new ArrayList();
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "openid", openid);
connect.addNotNullParameter(params, "format", "json");
String json = connect.get("https://openmobile.qq.com/user/get_simple_userinfo", params);
return Result.parse(json, com.belerweb.social.qq.connect.bean.User.class);
}
/**
* 获取已登录用户的关于QQ会员业务的基本资料。
*
* 基本资料包括以下信息:是否为“普通包月会员”,是否为“年费会员”,QQ会员等级信息,是否为“豪华版QQ会员”,是否为“钻皇会员”,是否为“SVIP”。
*
* 文档地址:http://wiki.connect.qq.com/get_vip_info
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
*/
public Result getVipInfo(String accessToken,
String openid) {
return getVipInfo(accessToken, connect.getClientId(), openid);
}
/**
* 获取已登录用户的关于QQ会员业务的基本资料。
*
* 基本资料包括以下信息:是否为“普通包月会员”,是否为“年费会员”,QQ会员等级信息,是否为“豪华版QQ会员”,是否为“钻皇会员”,是否为“SVIP”。
*
* 文档地址:http://wiki.connect.qq.com/get_vip_info
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param openid 用户的ID,与QQ号码一一对应。
*/
public Result getVipInfo(String accessToken,
String oAuthConsumerKey, String openid) {
List params = new ArrayList();
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
String json = connect.get("https://graph.qq.com/user/get_vip_info", params);
return Result.parse(json, com.belerweb.social.qq.connect.bean.User.class);
}
/**
* 获取已登录用户的关于QQ会员业务的详细资料。
*
* 详细资料包括:用户会员的历史属性,用户会员特权的到期时间,用户最后一次充值会员业务的支付渠道,用户开通会员的主要驱动因素。
*
* 文档地址:http://wiki.connect.qq.com/get_vip_rich_info
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
*/
public Result getVipRichInfo(String accessToken,
String openid) {
return getVipRichInfo(connect.getClientId(), accessToken, openid);
}
/**
* 获取已登录用户的关于QQ会员业务的详细资料。
*
* 详细资料包括:用户会员的历史属性,用户会员特权的到期时间,用户最后一次充值会员业务的支付渠道,用户开通会员的主要驱动因素。
*
* 文档地址:http://wiki.connect.qq.com/get_vip_rich_info
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
*/
public Result getVipRichInfo(String oAuthConsumerKey,
String accessToken, String openid) {
List params = new ArrayList();
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
String json = connect.get("https://graph.qq.com/user/get_vip_rich_info", params);
return Result.parse(json, com.belerweb.social.qq.connect.bean.User.class);
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/api/Weibo.java
================================================
package com.belerweb.social.qq.connect.api;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.json.JSONObject;
import com.belerweb.social.API;
import com.belerweb.social.bean.Error;
import com.belerweb.social.bean.Result;
import com.belerweb.social.qq.connect.bean.FanList;
import com.belerweb.social.qq.connect.bean.IdolList;
import com.belerweb.social.qq.connect.bean.RepostList;
import com.belerweb.social.qq.connect.bean.WeiboUser;
/**
* 腾讯微博API
*/
public final class Weibo extends API {
protected Weibo(QQConnect connect) {
super(connect);
}
/**
* 获取腾讯微博登录用户的用户资料。
*
* 文档地址:http://wiki.connect.qq.com/get_info
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
*/
public Result getInfo(String accessToken, String openid) {
return getInfo(connect.getClientId(), accessToken, openid);
}
/**
* 获取腾讯微博登录用户的用户资料。
*
* 文档地址:http://wiki.connect.qq.com/get_info
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
*/
public Result getInfo(String oAuthConsumerKey, String accessToken, String openid) {
List params = new ArrayList();
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
String json = connect.get("https://graph.qq.com/user/get_info", params);
JSONObject jsonObject = new JSONObject(json);
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result(error);
}
return Result.parse(jsonObject.getJSONObject("data"), WeiboUser.class);
}
/**
* 获取腾讯微博其他用户详细信息。
*
* 文档地址:http://wiki.connect.qq.com/get_other_info
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param name 其他用户的账户名。可选,name和fopenid至少选一个,若同时存在则以name值为主。
*/
public Result getOtherInfo(String accessToken, String openid, String name) {
return getOtherInfo(connect.getClientId(), accessToken, openid, name, null);
}
/**
* 获取腾讯微博其他用户详细信息。
*
* 文档地址:http://wiki.connect.qq.com/get_other_info
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param name 其他用户的账户名。可选,name和fopenid至少选一个,若同时存在则以name值为主。
* @param fopenid 其他用户的账户名。可选,name和fopenid至少选一个,若同时存在则以name值为主。
*/
public Result getOtherInfo(String oAuthConsumerKey, String accessToken, String openid,
String name, String fopenid) {
List params = new ArrayList();
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
connect.addNotNullParameter(params, "name", name);
connect.addNotNullParameter(params, "fopenid", fopenid);
String json = connect.get("https://graph.qq.com/user/get_other_info", params);
JSONObject jsonObject = new JSONObject(json);
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result(error);
}
return Result.parse(jsonObject.getJSONObject("data"), WeiboUser.class);
}
/**
* 获取登录用户的听众列表。
*
* 文档地址:http://wiki.connect.qq.com/get_fanslist
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param reqNum 必须。请求获取的听众个数。取值范围为1-30。
* @param startIndex 必须。请求获取听众列表的起始位置。第一页:0;继续向下翻页:reqnum*(page-1)。
*/
public Result getFansList(String accessToken, String openid, int reqNum, int startIndex) {
return getFansList(connect.getClientId(), accessToken, openid, reqNum, startIndex, null, null,
null);
}
/**
* 获取登录用户的听众列表。
*
* 文档地址:http://wiki.connect.qq.com/get_fanslist
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param reqNum 必须。请求获取的听众个数。取值范围为1-30。
* @param startIndex 必须。请求获取听众列表的起始位置。第一页:0;继续向下翻页:reqnum*(page-1)。
* @param newMode
* 获取听众信息的模式。获取听众信息的模式,默认值为0。0:旧模式,新添加的听众信息排在前面,最多只能拉取1000个听众的信息。1:新模式,可以拉取所有听众的信息,暂时不支持排序。
* @param install 判断获取的是安装应用的听众,还是未安装应用的听众。 0:不考虑该参数;1:获取已安装应用的听众信息;2:获取未安装应用的听众信息。
* @param sex 按性别过滤标识,默认为0。此参数当mode=0时使用,支持排序。 1:获取的是男性听众信息;2:获取的是女性听众信息;0:不进行性别过滤,获取所有听众信息。
*/
public Result getFansList(String oAuthConsumerKey, String accessToken, String openid,
int reqNum, int startIndex, Boolean newMode, Integer install, Integer sex) {
List params = new ArrayList();
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
connect.addParameter(params, "reqnum", reqNum);
connect.addParameter(params, "startindex", startIndex);
if (Boolean.TRUE.equals(newMode)) {
connect.addParameter(params, "mode", "1");
}
connect.addNotNullParameter(params, "install", install);
connect.addNotNullParameter(params, "sex", sex);
String json = connect.get("https://graph.qq.com/relation/get_fanslist", params);
JSONObject jsonObject = new JSONObject(json);
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result(error);
}
return Result.parse(jsonObject.getJSONObject("data"), FanList.class);
}
/**
* 获取登录用户收听的人的列表。
*
* 文档地址:http://wiki.connect.qq.com/get_idollist
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param reqNum 必须。请求获取的听众个数。取值范围为1-30。
* @param startIndex 必须。请求获取听众列表的起始位置。第一页:0;继续向下翻页:reqnum*(page-1)。
*/
public Result getIdolList(String accessToken, String openid, int reqNum, int startIndex) {
return getIdolList(connect.getClientId(), accessToken, openid, reqNum, startIndex, null, null);
}
/**
* 获取登录用户收听的人的列表。
*
* 文档地址:http://wiki.connect.qq.com/get_idollist
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param reqNum 必须。请求获取的听众个数。取值范围为1-30。
* @param startIndex 必须。请求获取听众列表的起始位置。第一页:0;继续向下翻页:reqnum*(page-1)。
* @param newMode 获取收听的人的信息模式,默认为0。
* 0:旧模式,新添加的收听的人信息排在前面,最多只能拉取1000个收听的人的信息。1:新模式,最多可拉取10000个收听的人的信息,暂不支持排序。
* @param install 判断获取的是安装了应用的收听好友,还是未安装应用的收听好友。0:不考虑该参数;1:获取已安装应用的收听好友信息;2:获取未安装应用的收听好友信息。
*/
public Result getIdolList(String oAuthConsumerKey, String accessToken, String openid,
int reqNum, int startIndex, Boolean newMode, Integer install) {
List params = new ArrayList();
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
connect.addParameter(params, "reqnum", reqNum);
connect.addParameter(params, "startindex", startIndex);
if (Boolean.TRUE.equals(newMode)) {
connect.addParameter(params, "mode", "1");
}
connect.addNotNullParameter(params, "install", install);
String json = connect.get("https://graph.qq.com/relation/get_idollist", params);
JSONObject jsonObject = new JSONObject(json);
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result(error);
}
return Result.parse(jsonObject.getJSONObject("data"), IdolList.class);
}
/**
* 获取一条微博的转播或评论信息列表。
*
* 文档地址:http://wiki.connect.qq.com/get_repost_list
*
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param reqNum 必须。请求获取的听众个数。取值范围为1-30。
* @param startIndex 必须。请求获取听众列表的起始位置。第一页:0;继续向下翻页:reqnum*(page-1)。
*/
public Result getRepostList(String accessToken, String openid, int flag,
String rootId, int pageFlag, int pageTime, int reqNum, String twitterId) {
return getRepostList(connect.getClientId(), accessToken, openid, flag, rootId, pageFlag,
pageTime, reqNum, twitterId);
}
/**
* 获取一条微博的转播或评论信息列表。
*
* 文档地址:http://wiki.connect.qq.com/get_repost_list
*
* @param oAuthConsumerKey 申请QQ登录成功后,分配给应用的appid
* @param accessToken 可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
* @param openid 用户的ID,与QQ号码一一对应。
* @param flag 标识获取的是转播列表还是点评列表。0:获取转播列表;1:获取点评列表;2:转播列表和点评列表都获取。
* @param rootId 转发或点评的源微博的ID。
* @param pageFlag 分页标识。0:第一页;1:向下翻页;2:向上翻页。
* @param pageTime 分页标识。0:第一页;1:向下翻页;2:向上翻页。
* @param reqNum 每次请求记录的条数。取值为1-100条。
* @param twitterId 翻页时使用。第1-100条:0;继续向下翻页:上一次请求返回的最后一条记录id。
*/
public Result getRepostList(String oAuthConsumerKey, String accessToken,
String openid, int flag, String rootId, int pageFlag, int pageTime, int reqNum,
String twitterId) {
List params = new ArrayList();
connect.addParameter(params, "oauth_consumer_key", oAuthConsumerKey);
connect.addParameter(params, "access_token", accessToken);
connect.addParameter(params, "openid", openid);
connect.addParameter(params, "format", "json");
connect.addParameter(params, "flag", flag);
connect.addParameter(params, "rootid", rootId);
connect.addParameter(params, "pageflag", pageFlag);
connect.addParameter(params, "pagetime", pageTime);
connect.addParameter(params, "reqnum", reqNum);
connect.addParameter(params, "twitterid", twitterId);
String json = connect.get("https://graph.qq.com/t/get_repost_list", params);
JSONObject jsonObject = new JSONObject(json);
Error error = Error.parse(jsonObject);
if (error != null) {
return new Result(error);
}
return Result.parse(jsonObject.getJSONObject("data"), RepostList.class);
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/AccessToken.java
================================================
package com.belerweb.social.qq.connect.bean;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class AccessToken extends JsonBean {
public AccessToken() {}
private AccessToken(JSONObject jsonObject) {
super(jsonObject);
}
private String token;// 授权令牌,Access_Token。
private Long expiresIn;// 该access token的有效期,单位为秒。
private String refreshToken;// 在授权自动续期步骤中,获取新的Access_Token时需要提供的参数。
/**
* 授权令牌,Access_Token。
*/
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
/**
* 该access token的有效期,单位为秒。
*/
public Long getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(Long expiresIn) {
this.expiresIn = expiresIn;
}
/**
* 在授权自动续期步骤中,获取新的Access_Token时需要提供的参数。
*/
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public static AccessToken parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
AccessToken obj = new AccessToken(jsonObject);
obj.token = jsonObject.getString("access_token");
obj.expiresIn = Result.parseLong(jsonObject.opt("expires_in"));
obj.refreshToken = Result.toString(jsonObject.opt("refresh_token"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Album.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.Date;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class Album extends JsonBean {
public Album() {}
private Album(JSONObject jsonObject) {
super(jsonObject);
}
private String albumId;
private String classId;
private Date createTime;
private String name;
private String description;
private String cover;
private Integer picNum;
public String getAlbumId() {
return albumId;
}
public void setAlbumId(String albumId) {
this.albumId = albumId;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public Integer getPicNum() {
return picNum;
}
public void setPicNum(Integer picNum) {
this.picNum = picNum;
}
public static Album parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
Album obj = new Album(jsonObject);
obj.albumId = Result.toString(jsonObject.get("albumid"));
obj.classId = Result.toString(jsonObject.opt("classid"));
obj.createTime = Result.parseTimeSeconds(jsonObject.opt("createtime"));
obj.name = Result.toString(jsonObject.opt("name"));
obj.description = Result.toString(jsonObject.opt("desc"));
obj.cover = Result.toString(jsonObject.opt("coverurl"));
obj.picNum = Result.parseInteger(jsonObject.opt("picnum"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/AlbumPrivilege.java
================================================
package com.belerweb.social.qq.connect.bean;
public enum AlbumPrivilege {
PUBLIC(1), PRIVATE(3), FRIEND(4), QUESTION(5);
private Integer value;
private AlbumPrivilege(Integer value) {
this.value = value;
}
public Integer value() {
return value;
}
@Override
public String toString() {
return value.toString();
}
public static AlbumPrivilege parse(Integer value) {
if (value == null) {
return null;
}
if (value == 1) {
return PUBLIC;
}
if (value == 3) {
return PRIVATE;
}
if (value == 4) {
return FRIEND;
}
if (value == 5) {
return QUESTION;
}
return null;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Company.java
================================================
package com.belerweb.social.qq.connect.bean;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class Company extends JsonBean {
public Company() {}
private Company(JSONObject jsonObject) {
super(jsonObject);
}
private String id;// 公司id。
private String companyName;// 公司名称。
private String departmentName;// 部门名称。
private Integer beginYear;// 开始年。
private Integer endYear;// 结束年。
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public Integer getBeginYear() {
return beginYear;
}
public void setBeginYear(Integer beginYear) {
this.beginYear = beginYear;
}
public Integer getEndYear() {
return endYear;
}
public void setEndYear(Integer endYear) {
this.endYear = endYear;
}
public static Company parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
Company obj = new Company(jsonObject);
obj.id = Result.toString(jsonObject.get("id"));
obj.companyName = Result.toString(jsonObject.opt("company_name"));
obj.departmentName = Result.toString(jsonObject.opt("department_name"));
obj.beginYear = Result.parseInteger(jsonObject.opt("begin_year"));
obj.endYear = Result.parseInteger(jsonObject.opt("end_year"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Display.java
================================================
package com.belerweb.social.qq.connect.bean;
public enum Display {
DEFAULT,
MOBILE;
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Education.java
================================================
package com.belerweb.social.qq.connect.bean;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class Education extends JsonBean {
public Education() {}
private Education(JSONObject jsonObject) {
super(jsonObject);
}
private String id;// 教育信息记录ID。
private Integer year;// 入学年。
private String schoolId;// 学校ID。学校ID与学校具体信息的对应关系请参见教育信息数据库。
private String departmentId;// 院系ID。院系ID与院系具体信息的对应关系请参见教育信息数据库。
private Integer level;// 学历级别。
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getYear() {
return year;
}
public void setYear(Integer year) {
this.year = year;
}
public String getSchoolId() {
return schoolId;
}
public void setSchoolId(String schoolId) {
this.schoolId = schoolId;
}
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
public static Education parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
Education obj = new Education(jsonObject);
obj.id = Result.toString(jsonObject.get("id"));
obj.schoolId = Result.toString(jsonObject.opt("company_name"));
obj.departmentId = Result.toString(jsonObject.opt("department_name"));
obj.year = Result.parseInteger(jsonObject.opt("begin_year"));
obj.level = Result.parseInteger(jsonObject.opt("end_year"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/FanList.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.Date;
import java.util.List;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class FanList extends JsonBean {
public FanList() {}
private FanList(JSONObject jsonObject) {
super(jsonObject);
}
private Date timestamp;
private Boolean hasNext;
private List fans;
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public Boolean getHasNext() {
return hasNext;
}
public void setHasNext(Boolean hasNext) {
this.hasNext = hasNext;
}
public List getFans() {
return fans;
}
public void setFans(List fans) {
this.fans = fans;
}
public static FanList parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
FanList obj = new FanList(jsonObject);
obj.timestamp = Result.parseTimeSeconds(jsonObject.get("timestamp"));
obj.hasNext = Result.parseBoolean(jsonObject.get("hasnext"));
obj.fans = Result.parse(jsonObject.optJSONArray("info"), WeiboUser.class);
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Gut.java
================================================
package com.belerweb.social.qq.connect.bean;
/**
* QQ登录页面版本
*/
public enum Gut {
WML(1),
XHTML(2);
private int value;
private Gut(int value) {
this.value = value;
}
public int value() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/IdolList.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.Date;
import java.util.List;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class IdolList extends JsonBean {
public IdolList() {}
private IdolList(JSONObject jsonObject) {
super(jsonObject);
}
private Date timestamp;
private Boolean hasNext;
private List fans;
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public Boolean getHasNext() {
return hasNext;
}
public void setHasNext(Boolean hasNext) {
this.hasNext = hasNext;
}
public List getFans() {
return fans;
}
public void setFans(List fans) {
this.fans = fans;
}
public static IdolList parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
IdolList obj = new IdolList(jsonObject);
obj.timestamp = Result.parseTimeSeconds(jsonObject.get("timestamp"));
obj.hasNext = Result.parseBoolean(jsonObject.get("hasnext"));
obj.fans = Result.parse(jsonObject.optJSONArray("info"), WeiboUser.class);
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Image.java
================================================
package com.belerweb.social.qq.connect.bean;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class Image extends JsonBean {
public Image() {}
private Image(JSONObject jsonObject) {
super(jsonObject);
}
private String url;
private Integer width;
private Integer height;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public static Image parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
Image obj = new Image(jsonObject);
obj.url = Result.toString(jsonObject.opt("url"));
obj.width = Result.parseInteger(jsonObject.opt("width"));
obj.height = Result.parseInteger(jsonObject.opt("height"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Music.java
================================================
package com.belerweb.social.qq.connect.bean;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class Music extends JsonBean {
public Music() {}
private Music(JSONObject jsonObject) {
super(jsonObject);
}
private String author;// 演唱者。
private String url;// 音频地址。
private String title;// 音频名字,歌名。
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public static Music parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
Music obj = new Music(jsonObject);
obj.author = Result.toString(jsonObject.opt("author"));
obj.url = Result.toString(jsonObject.opt("url"));
obj.title = Result.toString(jsonObject.opt("title"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/NewT.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.Date;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
/**
* 新发布的微博的返回信息
*/
public class NewT extends JsonBean {
public NewT() {}
private NewT(JSONObject jsonObject) {
super(jsonObject);
}
private Long id;// 微博的ID,用来唯一标识一条微博。
private Date time;// 微博的发表时间。
private String imgUrl;// 图片分享后的url地址。
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public static NewT parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
NewT obj = new NewT(jsonObject);
obj.id = Result.parseLong(jsonObject.get("id"));
obj.time = new Date(Result.parseLong(jsonObject.get("time")) * 1000);
obj.imgUrl = jsonObject.optString("imgurl");
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/OpenID.java
================================================
package com.belerweb.social.qq.connect.bean;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
public class OpenID extends JsonBean {
public OpenID() {}
private OpenID(JSONObject jsonObject) {
super(jsonObject);
}
private String clientId;
private String openId; // openid是此网站上唯一对应用户身份的标识,网站可将此ID进行存储便于用户下次登录时辨识其身份,或将其与用户在网站上的原有账号进行绑定。
/**
* openid是此网站上唯一对应用户身份的标识,网站可将此ID进行存储便于用户下次登录时辨识其身份,或将其与用户在网站上的原有账号进行绑定。
*/
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public static OpenID parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
OpenID obj = new OpenID(jsonObject);
obj.clientId = jsonObject.getString("client_id");
obj.openId = jsonObject.getString("openid");
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Photo.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.Date;
import java.util.Locale;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class Photo extends JsonBean {
public Photo() {}
private Photo(JSONObject jsonObject) {
super(jsonObject);
}
private String sLoc;
private String lLoc;
private String name;
private String description;
private Date updatedTime;
private Date uploadedTime;
private String smallUrl;
private Image largeImage;
public String getsLoc() {
return sLoc;
}
public void setsLoc(String sLoc) {
this.sLoc = sLoc;
}
public String getlLoc() {
return lLoc;
}
public void setlLoc(String lLoc) {
this.lLoc = lLoc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getUpdatedTime() {
return updatedTime;
}
public void setUpdatedTime(Date updatedTime) {
this.updatedTime = updatedTime;
}
public Date getUploadedTime() {
return uploadedTime;
}
public void setUploadedTime(Date uploadedTime) {
this.uploadedTime = uploadedTime;
}
public String getSmallUrl() {
return smallUrl;
}
public void setSmallUrl(String smallUrl) {
this.smallUrl = smallUrl;
}
public Image getLargeImage() {
return largeImage;
}
public void setLargeImage(Image largeImage) {
this.largeImage = largeImage;
}
public static Photo parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
Photo obj = new Photo(jsonObject);
obj.sLoc = Result.toString(jsonObject.opt("sloc"));
obj.lLoc = Result.toString(jsonObject.opt("lloc"));
obj.name = Result.toString(jsonObject.opt("name"));
obj.description = Result.toString(jsonObject.opt("desc"));
obj.updatedTime = Result.parseTimeSeconds(jsonObject.opt("updated_time"));
obj.uploadedTime =
Result.parseDate(jsonObject.opt("uploaded_time"), "yyyy-MM-dd HH:mm:ss", Locale.CHINA);
obj.smallUrl = Result.toString(jsonObject.opt("small_url"));
obj.largeImage = Image.parse(jsonObject.optJSONObject("large_image"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/PicUploadResult.java
================================================
package com.belerweb.social.qq.connect.bean;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class PicUploadResult extends JsonBean {
public PicUploadResult() {}
private PicUploadResult(JSONObject jsonObject) {
super(jsonObject);
}
private String albumId;
private String lLoc;
private String sLoc;
private String largeUrl;
private String smallUrl;
private Integer width;
private Integer height;
public String getAlbumId() {
return albumId;
}
public void setAlbumId(String albumId) {
this.albumId = albumId;
}
public String getlLoc() {
return lLoc;
}
public void setlLoc(String lLoc) {
this.lLoc = lLoc;
}
public String getsLoc() {
return sLoc;
}
public void setsLoc(String sLoc) {
this.sLoc = sLoc;
}
public String getLargeUrl() {
return largeUrl;
}
public void setLargeUrl(String largeUrl) {
this.largeUrl = largeUrl;
}
public String getSmallUrl() {
return smallUrl;
}
public void setSmallUrl(String smallUrl) {
this.smallUrl = smallUrl;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public static PicUploadResult parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
PicUploadResult obj = new PicUploadResult(jsonObject);
obj.albumId = Result.toString(jsonObject.opt("albumid"));
obj.lLoc = Result.toString(jsonObject.opt("lloc"));
obj.sLoc = Result.toString(jsonObject.opt("sloc"));
obj.largeUrl = Result.toString(jsonObject.opt("large_url"));
obj.smallUrl = Result.toString(jsonObject.opt("small_url"));
obj.width = Result.parseInteger(jsonObject.opt("width"));
obj.height = Result.parseInteger(jsonObject.opt("height"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/RepostList.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class RepostList extends JsonBean {
public RepostList() {}
private RepostList(JSONObject jsonObject) {
super(jsonObject);
}
private Date timestamp;
private Boolean hasNext;
private Integer totalNum;
private List tweets;
private Map nameNickMap = new HashMap();
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public Boolean getHasNext() {
return hasNext;
}
public void setHasNext(Boolean hasNext) {
this.hasNext = hasNext;
}
public Integer getTotalNum() {
return totalNum;
}
public void setTotalNum(Integer totalNum) {
this.totalNum = totalNum;
}
public List getTweets() {
return tweets;
}
public void setTweets(List tweets) {
this.tweets = tweets;
}
public static RepostList parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
RepostList obj = new RepostList(jsonObject);
obj.timestamp = Result.parseTimeSeconds(jsonObject.get("timestamp"));
obj.hasNext = Result.parseBoolean(jsonObject.get("hasnext"));
obj.totalNum = Result.parseInteger(jsonObject.get("totalnum"));
obj.tweets = Result.parse(jsonObject.optJSONArray("info"), TweetInfo.class);
JSONObject map = jsonObject.optJSONObject("user");
if (map != null) {
Iterator> keys = map.keys();
while (keys.hasNext()) {
String key = keys.next().toString();
obj.nameNickMap.put(key, map.get(key).toString());
}
}
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Scope.java
================================================
package com.belerweb.social.qq.connect.bean;
/**
* 请求用户授权时向用户显示的可进行授权的列表。
*/
public enum Scope {
/**
* do_like
*/
DO_LIKE("do_like"),
/**
* 获取登录用户的昵称、头像、性别
*/
GET_USER_INFO("get_user_info"),
/**
* 获取登录用户的昵称、头像、性别
*/
GET_SIMPLE_USERINFO("get_simple_userinfo"),
/**
* 获取QQ会员的基本信息
*/
GET_VIP_INFO("get_vip_info"),
/**
* 获取QQ会员的高级信息
*/
GET_VIP_RICH_INFO("get_vip_rich_info"),
/**
* 发表日志到QQ空间
*/
ADD_ONE_BLOG("add_one_blog"),
/**
* 获取用户QQ空间相册列表
*/
LIST_ALBUM("list_album"),
/**
* 上传一张照片到QQ空间相册
*/
UPLOAD_PIC("upload_pic"),
/**
* 在用户的空间相册里,创建一个新的个人相册
*/
ADD_ALBUM("add_album"),
/**
* 获取用户QQ空间相册中的照片列表
*/
LIST_PHOTO("list_photo"),
/**
* 获取登录用户在腾讯微博详细资料
*/
GET_INFO("get_info"),
/**
* 发表一条微博
*/
ADD_T("add_t"),
/**
* 删除一条微博
*/
DEL_T("del_t"),
/**
* 发表一条带图片的微博
*/
ADD_PIC_T("add_pic_t"),
/**
* 获取单条微博的转发或点评列表
*/
GET_REPOST_LIST("get_repost_list"),
/**
* 获取他人微博资料
*/
GET_OTHER_INFO("get_other_info"),
/**
* 我的微博粉丝列表
*/
GET_FANSLIST("get_fanslist"),
/**
* 我的微博偶像列表
*/
GET_IDOLLIST("get_idollist"),
/**
* 收听某个微博用户
*/
ADD_IDOL("add_idol"),
/**
* 取消收听某个微博用户
*/
DEL_IDOL("del_idol"),
/**
* 在这个网站上将展现您财付通登记的收货地址
*/
GET_TENPAY_ADDR("get_tenpay_addr");
private String scope;
private Scope(String scope) {
this.scope = scope;
}
public String value() {
return scope;
}
@Override
public String toString() {
return scope;
}
public static final Scope[] ALL = new Scope[] {Scope.DO_LIKE, Scope.GET_USER_INFO,
Scope.GET_SIMPLE_USERINFO, Scope.GET_VIP_INFO, Scope.GET_VIP_RICH_INFO, Scope.ADD_ONE_BLOG,
Scope.LIST_ALBUM, Scope.UPLOAD_PIC, Scope.ADD_ALBUM, Scope.LIST_PHOTO, Scope.GET_INFO,
Scope.ADD_T, Scope.DEL_T, Scope.ADD_PIC_T, Scope.GET_REPOST_LIST, Scope.GET_OTHER_INFO,
Scope.GET_FANSLIST, Scope.GET_IDOLLIST, Scope.ADD_IDOL, Scope.DEL_IDOL,
Scope.GET_TENPAY_ADDR,};
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/SendPrivate.java
================================================
package com.belerweb.social.qq.connect.bean;
public enum SendPrivate {
IDOL(0), FRIEND(1), PUBLIC(2);
private Integer value;
private SendPrivate(Integer value) {
this.value = value;
}
public Integer value() {
return value;
}
@Override
public String toString() {
return value.toString();
}
public static SendPrivate parse(Integer value) {
if (value == null) {
return null;
}
if (value == 0) {
return IDOL;
}
if (value == 1) {
return FRIEND;
}
if (value == 2) {
return PUBLIC;
}
return null;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Tag.java
================================================
package com.belerweb.social.qq.connect.bean;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class Tag extends JsonBean {
public Tag() {}
private Tag(JSONObject jsonObject) {
super(jsonObject);
}
private String id;// 个人标签id。
private String name;// 标签名。
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static Tag parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
Tag obj = new Tag(jsonObject);
obj.id = Result.toString(jsonObject.get("id"));
obj.name = Result.toString(jsonObject.opt("name"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/TenpayAddress.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.Date;
/**
* 财付通收货地址
*/
public class TenpayAddress {
private Integer index;// 收货信息的索引编号
private Integer regionId;// 收货信息的地区编号
private String street;// 收货信息的收货地址
private String zipcode;// 收货信息的邮编
private String mobile;// 收货信息的收货人移动电话
private String tel;// 收货信息的收货人固定电话
private String name;// 收货信息的收货人姓名
private Date created;// 收货信息的创建时间
private Date modified;// 收货信息上一次被修改的时间
private Date lastUsed;// 收货信息上一次被使用的时间
private Integer usedCount;// 收货信息被使用过的次数
private Integer total;// 该用户财付通收货地址的个数
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public Integer getRegionId() {
return regionId;
}
public void setRegionId(Integer regionId) {
this.regionId = regionId;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
public Date getLastUsed() {
return lastUsed;
}
public void setLastUsed(Date lastUsed) {
this.lastUsed = lastUsed;
}
public Integer getUsedCount() {
return usedCount;
}
public void setUsedCount(Integer usedCount) {
this.usedCount = usedCount;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/TweetInfo.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.Date;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class TweetInfo extends JsonBean {
public TweetInfo() {}
private TweetInfo(JSONObject jsonObject) {
super(jsonObject);
}
private String id;// 微博唯一id。
private String countryCode;// 发表微博时所作的国家代码。
private String provinceCode;// 发表微博时所作的省份代码。
private String cityCode;// 发表微博时所作的城市代码。
private String emotionType;// 心情类型。
private String emotionUrl;// 心情图片url。
private String from;// 来源。
private String fromUrl;// 来源url。
private String image;// 图片url。
private String geo;// 地理位置信息。
private String location;// 发表者所在地。
private Double longitude;// 经度。
private Double latitude;// 纬度。
private Music music;
private String origText;// 微博原始内容。
private Boolean self;// 是否自已发的的微博
private Integer status;// 表示微博的状态。0:正常;1:微博被系统删除;2:审核中;3;微博被用户删除;4:源微博被系统审核删除。
private String text;// 微博内容。
private Date timestamp;// 服务器时间戳,不能用于翻页。
private Integer type;// 表示微博的类型。1:原创发表;2:转播;3:私信;4:回复;5:没有内容的回复;6:提及;7:评论。
private Video video;// 视频信息。
private Integer count;// 转播次数。
private Integer mCount;// 评论数。
private Boolean isVip;// 用户是否为微博认证用户
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getProvinceCode() {
return provinceCode;
}
public void setProvinceCode(String provinceCode) {
this.provinceCode = provinceCode;
}
public String getCityCode() {
return cityCode;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public String getEmotionType() {
return emotionType;
}
public void setEmotionType(String emotionType) {
this.emotionType = emotionType;
}
public String getEmotionUrl() {
return emotionUrl;
}
public void setEmotionUrl(String emotionUrl) {
this.emotionUrl = emotionUrl;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getFromUrl() {
return fromUrl;
}
public void setFromUrl(String fromUrl) {
this.fromUrl = fromUrl;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getGeo() {
return geo;
}
public void setGeo(String geo) {
this.geo = geo;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Music getMusic() {
return music;
}
public void setMusic(Music music) {
this.music = music;
}
public String getOrigText() {
return origText;
}
public void setOrigText(String origText) {
this.origText = origText;
}
public Boolean getSelf() {
return self;
}
public void setSelf(Boolean self) {
this.self = self;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public Video getVideo() {
return video;
}
public void setVideo(Video video) {
this.video = video;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public Integer getmCount() {
return mCount;
}
public void setmCount(Integer mCount) {
this.mCount = mCount;
}
public Boolean getIsVip() {
return isVip;
}
public void setIsVip(Boolean isVip) {
this.isVip = isVip;
}
public static TweetInfo parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
TweetInfo obj = new TweetInfo(jsonObject);
obj.id = Result.toString(jsonObject.get("id"));
obj.countryCode = Result.toString(jsonObject.opt("country_code"));
obj.provinceCode = Result.toString(jsonObject.opt("province_code"));
obj.cityCode = Result.toString(jsonObject.opt("city_code"));
obj.emotionType = Result.toString(jsonObject.opt("emotiontype"));
obj.emotionUrl = Result.toString(jsonObject.opt("emotionurl"));
obj.from = Result.toString(jsonObject.opt("from"));
obj.fromUrl = Result.toString(jsonObject.opt("fromurl"));
obj.image = Result.toString(jsonObject.opt("image"));
obj.geo = Result.toString(jsonObject.opt("geo"));
obj.location = Result.toString(jsonObject.opt("location"));
obj.longitude = Result.parseDouble(jsonObject.opt("longitude"));
obj.latitude = Result.parseDouble(jsonObject.opt("latitude"));
obj.music = Music.parse(jsonObject.optJSONObject("music"));
obj.origText = Result.toString(jsonObject.opt("origtext"));
obj.self = Result.parseBoolean(jsonObject.opt("self"));
obj.status = Result.parseInteger(jsonObject.opt("status"));
obj.text = Result.toString(jsonObject.opt("text"));
obj.timestamp = Result.parseTimeSeconds(jsonObject.opt("timestamp"));
obj.type = Result.parseInteger(jsonObject.opt("type"));
obj.video = Video.parse(jsonObject.optJSONObject("video"));
obj.count = Result.parseInteger(jsonObject.opt("count"));
obj.mCount = Result.parseInteger(jsonObject.opt("mcount"));
obj.isVip = Result.parseBoolean(jsonObject.opt("isvip"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/User.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.Date;
import org.json.JSONObject;
import com.belerweb.social.bean.Gender;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class User extends JsonBean {
public User() {}
private User(JSONObject jsonObject) {
super(jsonObject);
}
private String nickname;// 用户在QQ空间的昵称。
private String figureUrl;// 大小为30×30像素的QQ空间头像URL。
private String figureUrl1;// 大小为50×50像素的QQ空间头像URL。
private String figureUrl2;// 大小为100×100像素的QQ空间头像URL。
private String figureUrlQQ1;// 大小为40×40像素的QQ头像URL。 40x40像素则是一定会有。
private String figureUrlQQ2;// 大小为100×100像素的QQ头像URL。需要注意,不是所有的用户都拥有QQ的100x100的头像。
private Gender gender;// 性别。 如果获取不到则默认返回"男"
private Boolean isYellowVip;// 标识用户是否为黄钻用户
private Boolean vip;// 标识用户是否为黄钻用户
private Integer yellowVipLevel;// 黄钻等级
private Integer level;// 黄钻等级
private Boolean isYellowYearVip;// 标识是否为年费黄钻用户
private Boolean isQQVip;// 标识是否QQ会员
private Integer qqVipLevel;// QQ会员等级
private Boolean isQQYearVip;// 标识是否为年费QQ会员
private Boolean isLost;
private Date qqVipStart;// QQ会员最后一次充值时间
private Date qqVipEnd;// QQ会员期限
private Integer qqVipPayway;// QQ会员充值方式
private Date qqYearVipStart;// QQ年费会员最后一次充值时间
private Date qqYearVipEnd;// QQ年费会员期限
private Integer qqYearVipPayway;// QQ年费会员充值方式
private Date qqZuanhuangStart;// QQ钻皇最后一次充值时间
private Date qqZuanhuangEnd;// QQ钻皇期限
private Integer qqZuanhuangPayway;// QQ钻皇充值方式
private Date qqHaohuaStart;// 豪华版QQ会员最后一次充值时间
private Date qqHaohuaEnd;// 豪华版QQ会员期限
private Integer qqHaohuaPayway;// 豪华版QQ会员充值方式
private Date qqSvipStart;// QQ SVIP最后一次充值时间,预留字段,当前信息无效
private Date qqSvipEnd;// QQ SVIP期限,预留字段,当前信息无效
private Integer qqSvipPayway;// QQ SVIP充值方式,预留字段,当前信息无效
private Date historyPayTime;// 非会员历史充值时间,仅在用户是非会员时信息有效
private Date historyEndTime;// 非会员历史充值到期时间,仅在用户是非会员时信息有效
/**
* 用户在QQ空间的昵称。
*/
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
/**
* 大小为30×30像素的QQ空间头像URL。
*/
public String getFigureUrl() {
return figureUrl;
}
public void setFigureUrl(String figureUrl) {
this.figureUrl = figureUrl;
}
/**
* 大小为50×50像素的QQ空间头像URL。
*/
public String getFigureUrl1() {
return figureUrl1;
}
public void setFigureUrl1(String figureUrl1) {
this.figureUrl1 = figureUrl1;
}
/**
* 大小为100×100像素的QQ空间头像URL。
*/
public String getFigureUrl2() {
return figureUrl2;
}
public void setFigureUrl2(String figureUrl2) {
this.figureUrl2 = figureUrl2;
}
/**
* 大小为40×40像素的QQ头像URL。 40x40像素则是一定会有。
*/
public String getFigureUrlQQ1() {
return figureUrlQQ1;
}
public void setFigureUrlQQ1(String figureUrlQQ1) {
this.figureUrlQQ1 = figureUrlQQ1;
}
/**
* 大小为100×100像素的QQ头像URL。需要注意,不是所有的用户都拥有QQ的100x100的头像。
*/
public String getFigureUrlQQ2() {
return figureUrlQQ2;
}
public void setFigureUrlQQ2(String figureUrlQQ2) {
this.figureUrlQQ2 = figureUrlQQ2;
}
/**
* 性别。 如果获取不到则默认返回"男"
*/
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
/**
* 标识用户是否为黄钻用户
*/
public Boolean getIsYellowVip() {
return isYellowVip;
}
public void setIsYellowVip(Boolean isYellowVip) {
this.isYellowVip = isYellowVip;
}
/**
* 标识用户是否为黄钻用户
*/
public Boolean getVip() {
return vip;
}
public void setVip(Boolean vip) {
this.vip = vip;
}
/**
* 黄钻等级
*/
public Integer getYellowVipLevel() {
return yellowVipLevel;
}
public void setYellowVipLevel(Integer yellowVipLevel) {
this.yellowVipLevel = yellowVipLevel;
}
/**
* 黄钻等级
*/
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
/**
* 标识是否为年费黄钻用户
*/
public Boolean getIsYellowYearVip() {
return isYellowYearVip;
}
public void setIsYellowYearVip(Boolean isYellowYearVip) {
this.isYellowYearVip = isYellowYearVip;
}
/**
* 标识是否QQ会员
*/
public Boolean getIsQQVip() {
return isQQVip;
}
public void setIsQQVip(Boolean isQQVip) {
this.isQQVip = isQQVip;
}
/**
* QQ会员等级
*/
public Integer getQqVipLevel() {
return qqVipLevel;
}
public void setQqVipLevel(Integer qqVipLevel) {
this.qqVipLevel = qqVipLevel;
}
/**
* 是否是QQ年费会员
*/
public Boolean getIsQQYearVip() {
return isQQYearVip;
}
public void setIsQQYearVip(Boolean isQQYearVip) {
this.isQQYearVip = isQQYearVip;
}
public Boolean getIsLost() {
return isLost;
}
public void setIsLost(Boolean isLost) {
this.isLost = isLost;
}
/**
* QQ会员最后一次充值时间
*/
public Date getQqVipStart() {
return qqVipStart;
}
public void setQqVipStart(Date qqVipStart) {
this.qqVipStart = qqVipStart;
}
/**
* QQ会员期限
*/
public Date getQqVipEnd() {
return qqVipEnd;
}
public void setQqVipEnd(Date qqVipEnd) {
this.qqVipEnd = qqVipEnd;
}
/**
* QQ会员充值方式
*/
public Integer getQqVipPayway() {
return qqVipPayway;
}
public void setQqVipPayway(Integer qqVipPayway) {
this.qqVipPayway = qqVipPayway;
}
/**
* QQ年费会员最后一次充值时间
*/
public Date getQqYearVipStart() {
return qqYearVipStart;
}
public void setQqYearVipStart(Date qqYearVipStart) {
this.qqYearVipStart = qqYearVipStart;
}
/**
* QQ年费会员期限
*/
public Date getQqYearVipEnd() {
return qqYearVipEnd;
}
public void setQqYearVipEnd(Date qqYearVipEnd) {
this.qqYearVipEnd = qqYearVipEnd;
}
/**
* QQ年费会员充值方式
*/
public Integer getQqYearVipPayway() {
return qqYearVipPayway;
}
public void setQqYearVipPayway(Integer qqYearVipPayway) {
this.qqYearVipPayway = qqYearVipPayway;
}
/**
* QQ钻皇最后一次充值时间
*/
public Date getQqZuanhuangStart() {
return qqZuanhuangStart;
}
public void setQqZuanhuangStart(Date qqZuanhuangStart) {
this.qqZuanhuangStart = qqZuanhuangStart;
}
/**
* QQ钻皇期限
*/
public Date getQqZuanhuangEnd() {
return qqZuanhuangEnd;
}
public void setQqZuanhuangEnd(Date qqZuanhuangEnd) {
this.qqZuanhuangEnd = qqZuanhuangEnd;
}
/**
* QQ钻皇充值方式
*/
public Integer getQqZuanhuangPayway() {
return qqZuanhuangPayway;
}
public void setQqZuanhuangPayway(Integer qqZuanhuangPayway) {
this.qqZuanhuangPayway = qqZuanhuangPayway;
}
/**
* 豪华版QQ会员最后一次充值时间
*/
public Date getQqHaohuaStart() {
return qqHaohuaStart;
}
public void setQqHaohuaStart(Date qqHaohuaStart) {
this.qqHaohuaStart = qqHaohuaStart;
}
/**
* 豪华版QQ会员期限
*/
public Date getQqHaohuaEnd() {
return qqHaohuaEnd;
}
public void setQqHaohuaEnd(Date qqHaohuaEnd) {
this.qqHaohuaEnd = qqHaohuaEnd;
}
/**
* 豪华版QQ会员充值方式
*/
public Integer getQqHaohuaPayway() {
return qqHaohuaPayway;
}
public void setQqHaohuaPayway(Integer qqHaohuaPayway) {
this.qqHaohuaPayway = qqHaohuaPayway;
}
/**
* QQ SVIP最后一次充值时间,预留字段,当前信息无效
*/
public Date getQqSvipStart() {
return qqSvipStart;
}
public void setQqSvipStart(Date qqSvipStart) {
this.qqSvipStart = qqSvipStart;
}
/**
* QQ SVIP期限,预留字段,当前信息无效
*/
public Date getQqSvipEnd() {
return qqSvipEnd;
}
public void setQqSvipEnd(Date qqSvipEnd) {
this.qqSvipEnd = qqSvipEnd;
}
/**
* QQ SVIP充值方式,预留字段,当前信息无效
*/
public Integer getQqSvipPayway() {
return qqSvipPayway;
}
public void setQqSvipPayway(Integer qqSvipPayway) {
this.qqSvipPayway = qqSvipPayway;
}
/**
* 非会员历史充值时间,仅在用户是非会员时信息有效
*/
public Date getHistoryPayTime() {
return historyPayTime;
}
public void setHistoryPayTime(Date historyPayTime) {
this.historyPayTime = historyPayTime;
}
/**
* 非会员历史充值到期时间,仅在用户是非会员时信息有效
*/
public Date getHistoryEndTime() {
return historyEndTime;
}
public void setHistoryEndTime(Date historyEndTime) {
this.historyEndTime = historyEndTime;
}
public static User parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
User obj = new User(jsonObject);
obj.nickname = Result.toString(jsonObject.opt("nickname"));
obj.figureUrl = Result.toString(jsonObject.opt("figureurl"));
obj.figureUrl1 = Result.toString(jsonObject.opt("figureurl_1"));
obj.figureUrl2 = Result.toString(jsonObject.opt("figureurl_2"));
obj.figureUrlQQ1 = Result.toString(jsonObject.opt("figureurl_qq_1"));
obj.figureUrlQQ2 = Result.toString(jsonObject.opt("figureurl_qq_2"));
obj.gender = Gender.parse(jsonObject.optString("gender", null));
obj.isYellowVip = Result.parseBoolean(jsonObject.opt("is_yellow_vip"));
obj.vip = Result.parseBoolean(jsonObject.opt("vip"));
obj.yellowVipLevel = Result.parseInteger(jsonObject.opt("yellow_vip_level"));
obj.level = Result.parseInteger(jsonObject.opt("level"));
obj.isYellowYearVip = Result.parseBoolean(jsonObject.opt("is_yellow_year_vip"));
obj.isQQVip = Result.parseBoolean(jsonObject.opt("is_qq_vip"));
obj.qqVipLevel = Result.parseInteger(jsonObject.opt("qq_vip_level"));
obj.isQQYearVip = Result.parseBoolean(jsonObject.opt("is_qq_year_vip"));
obj.isLost = Result.parseBoolean(jsonObject.opt("is_lost"));
obj.qqVipStart = Result.parseTimeSeconds(jsonObject.opt("qq_vip_start"));
obj.qqVipEnd = Result.parseTimeSeconds(jsonObject.opt("qq_vip_end"));
obj.qqVipPayway = Result.parseInteger(jsonObject.opt("qq_vip_payway"));
obj.qqYearVipStart = Result.parseTimeSeconds(jsonObject.opt("qq_year_vip_start"));
obj.qqYearVipEnd = Result.parseTimeSeconds(jsonObject.opt("qq_year_vip_end"));
obj.qqYearVipPayway = Result.parseInteger(jsonObject.opt("qq_year_vip_payway"));
obj.qqZuanhuangStart = Result.parseTimeSeconds(jsonObject.opt("qq_zuanhuang_start"));
obj.qqZuanhuangEnd = Result.parseTimeSeconds(jsonObject.opt("qq_zuanhuang_end"));
obj.qqZuanhuangPayway = Result.parseInteger(jsonObject.opt("qq_zuanhuang_payway"));
obj.qqHaohuaStart = Result.parseTimeSeconds(jsonObject.opt("qq_haohua_start"));
obj.qqHaohuaEnd = Result.parseTimeSeconds(jsonObject.opt("qq_haohua_end"));
obj.qqHaohuaPayway = Result.parseInteger(jsonObject.opt("qq_haohua_payway"));
obj.qqSvipStart = Result.parseTimeSeconds(jsonObject.opt("qq_svip_start"));
obj.qqSvipEnd = Result.parseTimeSeconds(jsonObject.opt("qq_svip_end"));
obj.qqSvipPayway = Result.parseInteger(jsonObject.opt("qq_svip_payway"));
obj.historyPayTime = Result.parseTimeSeconds(jsonObject.opt("history_pay_time"));
obj.historyEndTime = Result.parseTimeSeconds(jsonObject.opt("history_end_time"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/Video.java
================================================
package com.belerweb.social.qq.connect.bean;
import org.json.JSONObject;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class Video extends JsonBean {
public Video() {}
private Video(JSONObject jsonObject) {
super(jsonObject);
}
private String picUrl;// 缩略图。
private String player;// 播放器地址。
private String realUrl;// 视频原地址。
private String shortUrl;// 视频的短url。
private String title;// 视频标题。
public String getPicUrl() {
return picUrl;
}
public void setPicUrl(String picUrl) {
this.picUrl = picUrl;
}
public String getPlayer() {
return player;
}
public void setPlayer(String player) {
this.player = player;
}
public String getRealUrl() {
return realUrl;
}
public void setRealUrl(String realUrl) {
this.realUrl = realUrl;
}
public String getShortUrl() {
return shortUrl;
}
public void setShortUrl(String shortUrl) {
this.shortUrl = shortUrl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public static Video parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
Video obj = new Video(jsonObject);
obj.picUrl = Result.toString(jsonObject.opt("picurl"));
obj.player = Result.toString(jsonObject.opt("player"));
obj.realUrl = Result.toString(jsonObject.opt("realurl"));
obj.shortUrl = Result.toString(jsonObject.opt("shorturl"));
obj.title = Result.toString(jsonObject.opt("title"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/connect/bean/WeiboUser.java
================================================
package com.belerweb.social.qq.connect.bean;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.json.JSONArray;
import org.json.JSONObject;
import com.belerweb.social.bean.Gender;
import com.belerweb.social.bean.JsonBean;
import com.belerweb.social.bean.Result;
public class WeiboUser extends JsonBean {
public WeiboUser() {}
private WeiboUser(JSONObject jsonObject) {
super(jsonObject);
}
private String openId;// 登录用户的唯一ID,与name一一对应。
private String name;// 登录用户的帐号名
private String nick;// 登录用户昵称。
private Date regTime;// 登录注册时间。
private Date birth;
private String countryCode;
private String provinceCode;
private String cityCode;
private List companies;
private List educations;
private Integer fansNum;// 登录用户听众数。
private Integer favNum;// 登录用户收藏数。
private String head;
private String homeCountryCode;// 登录用户家乡所在国家代码。
private String homeProvinceCode;// 登录用户家乡所在省份代码。
private String homeCityCode;// 登录用户家乡所在城市代码。
private String hometownCode;// 登录用户家乡所在城镇代码。
private String homepage;// 个人主页。
private Integer idolNum;// 登录用户收听的人数。
private String industryCode;// 行业ID。
private String introduction;// 登录用户的个人介绍。
private Boolean isEnt;// 登录用户是否为企业机构
private Boolean isMyBlack;// 是否在当前用户的黑名单中
private Boolean isMyFans;// 是否是当前用户的听众
private Boolean isMyIdol;// 是否是当前用户的偶像
private Boolean isRealName;// 登录用户是否实名认证
private Boolean isVip;// 登录用户是否为微博认证用户
private String location;// 登录用户所在地。
private Integer mutualFansNum;// 登录用户的互听好友数
private SendPrivate sendPrivate;// 是否允许所有人给当前用户发私信。
private Gender gender;
private List tags;
private List tweets;
private Integer tweetNum;
private String verifyInfo;
private Integer exp;
private Integer level;
private String seqId;
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNick() {
return nick;
}
public void setNick(String nick) {
this.nick = nick;
}
public Date getRegTime() {
return regTime;
}
public void setRegTime(Date regTime) {
this.regTime = regTime;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getProvinceCode() {
return provinceCode;
}
public void setProvinceCode(String provinceCode) {
this.provinceCode = provinceCode;
}
public String getCityCode() {
return cityCode;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public List getCompanies() {
return companies;
}
public void setCompanies(List companies) {
this.companies = companies;
}
public List getEducations() {
return educations;
}
public void setEducations(List educations) {
this.educations = educations;
}
public Integer getFansNum() {
return fansNum;
}
public void setFansNum(Integer fansNum) {
this.fansNum = fansNum;
}
public Integer getFavNum() {
return favNum;
}
public void setFavNum(Integer favNum) {
this.favNum = favNum;
}
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getHomeCountryCode() {
return homeCountryCode;
}
public void setHomeCountryCode(String homeCountryCode) {
this.homeCountryCode = homeCountryCode;
}
public String getHomeProvinceCode() {
return homeProvinceCode;
}
public void setHomeProvinceCode(String homeProvinceCode) {
this.homeProvinceCode = homeProvinceCode;
}
public String getHomeCityCode() {
return homeCityCode;
}
public void setHomeCityCode(String homeCityCode) {
this.homeCityCode = homeCityCode;
}
public String getHometownCode() {
return hometownCode;
}
public void setHometownCode(String hometownCode) {
this.hometownCode = hometownCode;
}
public String getHomepage() {
return homepage;
}
public void setHomepage(String homepage) {
this.homepage = homepage;
}
public Integer getIdolNum() {
return idolNum;
}
public void setIdolNum(Integer idolNum) {
this.idolNum = idolNum;
}
public String getIndustryCode() {
return industryCode;
}
public void setIndustryCode(String industryCode) {
this.industryCode = industryCode;
}
public String getIntroduction() {
return introduction;
}
public void setIntroduction(String introduction) {
this.introduction = introduction;
}
public Boolean getIsEnt() {
return isEnt;
}
public void setIsEnt(Boolean isEnt) {
this.isEnt = isEnt;
}
public Boolean getIsMyBlack() {
return isMyBlack;
}
public void setIsMyBlack(Boolean isMyBlack) {
this.isMyBlack = isMyBlack;
}
public Boolean getIsMyFans() {
return isMyFans;
}
public void setIsMyFans(Boolean isMyFans) {
this.isMyFans = isMyFans;
}
public Boolean getIsMyIdol() {
return isMyIdol;
}
public void setIsMyIdol(Boolean isMyIdol) {
this.isMyIdol = isMyIdol;
}
public Boolean getIsRealName() {
return isRealName;
}
public void setIsRealName(Boolean isRealName) {
this.isRealName = isRealName;
}
public Boolean getIsVip() {
return isVip;
}
public void setIsVip(Boolean isVip) {
this.isVip = isVip;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Integer getMutualFansNum() {
return mutualFansNum;
}
public void setMutualFansNum(Integer mutualFansNum) {
this.mutualFansNum = mutualFansNum;
}
public SendPrivate getSendPrivate() {
return sendPrivate;
}
public void setSendPrivate(SendPrivate sendPrivate) {
this.sendPrivate = sendPrivate;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public List getTags() {
return tags;
}
public void setTags(List tags) {
this.tags = tags;
}
public List getTweets() {
return tweets;
}
public void setTweets(List tweets) {
this.tweets = tweets;
}
public Integer getTweetNum() {
return tweetNum;
}
public void setTweetNum(Integer tweetNum) {
this.tweetNum = tweetNum;
}
public String getVerifyInfo() {
return verifyInfo;
}
public void setVerifyInfo(String verifyInfo) {
this.verifyInfo = verifyInfo;
}
public Integer getExp() {
return exp;
}
public void setExp(Integer exp) {
this.exp = exp;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
public String getSeqId() {
return seqId;
}
public void setSeqId(String seqId) {
this.seqId = seqId;
}
public static WeiboUser parse(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
WeiboUser obj = new WeiboUser(jsonObject);
obj.openId = Result.toString(jsonObject.get("openid"));
obj.name = Result.toString(jsonObject.opt("name"));
obj.nick = Result.toString(jsonObject.opt("nick"));
obj.regTime = Result.parseTimeSeconds(jsonObject.opt("regtime"));
Object year = jsonObject.get("birth_year");
Object month = jsonObject.get("birth_month");
Object day = jsonObject.get("birth_day");
obj.birth =
Result.parseDate(year.toString() + month.toString() + day.toString(), "yyyy-MM-dd",
Locale.CHINA);
obj.countryCode = Result.toString(jsonObject.opt("country_code"));
obj.provinceCode = Result.toString(jsonObject.opt("province_code"));
obj.cityCode = Result.toString(jsonObject.opt("city_code"));
JSONArray jsonArray = jsonObject.optJSONArray("comp");
if (jsonArray != null) {
List companies = new ArrayList();
for (int i = 0; i < jsonArray.length(); i++) {
companies.add(Company.parse(jsonArray.optJSONObject(i)));
}
obj.companies = companies;
}
jsonArray = jsonObject.optJSONArray("edu");
if (jsonArray != null) {
List educations = new ArrayList();
for (int i = 0; i < jsonArray.length(); i++) {
educations.add(Education.parse(jsonArray.optJSONObject(i)));
}
obj.educations = educations;
}
obj.fansNum = Result.parseInteger(jsonObject.opt("fansnum"));
obj.favNum = Result.parseInteger(jsonObject.opt("favnum"));
obj.head = Result.toString(jsonObject.opt("head"));
obj.homeCountryCode = Result.toString(jsonObject.opt("homecountry_code"));
obj.homeProvinceCode = Result.toString(jsonObject.opt("homeprovince_code"));
obj.homeCityCode = Result.toString(jsonObject.opt("homecity_code"));
obj.hometownCode = Result.toString(jsonObject.opt("hometown_code"));
obj.homepage = Result.toString(jsonObject.opt("homepage"));
obj.idolNum = Result.parseInteger(jsonObject.opt("idolnum"));
obj.industryCode = Result.toString(jsonObject.opt("industry_code"));
obj.introduction = Result.toString(jsonObject.opt("introduction"));
obj.isEnt = Result.parseBoolean(jsonObject.opt("isent"));
obj.isMyBlack = Result.parseBoolean(jsonObject.opt("ismyblack"));
obj.isMyFans = Result.parseBoolean(jsonObject.opt("ismyfans"));
obj.isMyIdol = Result.parseBoolean(jsonObject.opt("isMyIdol"));
obj.isRealName = Result.parseBoolean(jsonObject.opt("isrealname"));
obj.isVip = Result.parseBoolean(jsonObject.opt("isvip"));
obj.location = Result.toString(jsonObject.opt("location"));
obj.mutualFansNum = Result.parseInteger(jsonObject.opt("mutual_fans_num"));
obj.sendPrivate = SendPrivate.parse(Result.parseInteger(jsonObject.opt("send_private_flag")));
obj.gender = Gender.parse(Result.parseInteger(jsonObject.opt("sex")));
jsonArray = jsonObject.optJSONArray("tag");
if (jsonArray != null) {
List tags = new ArrayList();
for (int i = 0; i < jsonArray.length(); i++) {
tags.add(Tag.parse(jsonArray.optJSONObject(i)));
}
obj.tags = tags;
}
jsonArray = jsonObject.optJSONArray("tweetinfo");
if (jsonArray == null) {
jsonArray = jsonObject.optJSONArray("tweet");
}
if (jsonArray != null) {
List tweets = new ArrayList();
for (int i = 0; i < jsonArray.length(); i++) {
tweets.add(TweetInfo.parse(jsonArray.optJSONObject(i)));
}
obj.tweets = tweets;
}
obj.tweetNum = Result.parseInteger(jsonObject.opt("tweetnum"));
obj.verifyInfo = Result.toString(jsonObject.opt("verifyinfo"));
obj.exp = Result.parseInteger(jsonObject.opt("exp"));
obj.level = Result.parseInteger(jsonObject.opt("level"));
obj.seqId = Result.toString(jsonObject.opt("seqid"));
return obj;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/mail/api/Contact.java
================================================
package com.belerweb.social.qq.mail.api;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.jsoup.Jsoup;
import org.jsoup.nodes.DataNode;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.belerweb.social.captcha.api.Yundama;
import com.belerweb.social.captcha.bean.YundamaType;
import com.belerweb.social.exception.SocialException;
import com.belerweb.social.http.Http;
import com.belerweb.social.qq.mail.bean.Group;
import com.belerweb.social.qq.mail.bean.User;
import com.belerweb.social.qq.mail.bean.ValidationCode;
/**
* 获取QQ邮箱联系人
*/
public class Contact {
private static final Pattern PATTERN = Pattern.compile("sid=([0-9a-zA-Z-_]+)[&\"]");
private HttpClient http;
private String email;
private String password;
private Yundama yundama;
private String sid;
/**
* 创建一个QQ邮箱联系人API
*
* @param email QQ邮箱地址
* @param password QQ邮箱密码
*/
public Contact(String email, String password, Yundama yundama) {
this.email = email;
this.password = password;
this.yundama = yundama;
http = Http.newClient();
}
private List get(Group group) throws SocialException {
HttpGet request =
new HttpGet("http://mail.qq.com/cgi-bin/laddr_list?sid=" + sid
+ "&operate=view&t=contact&view=" + group.getType()
+ (group.getId() != null ? ("&groupid=" + group.getId()) : "&loc=frame_html,,,23"));
request.addHeader(new BasicHeader("Referer",
"http://mail.qq.com/cgi-bin/laddr_list?operate=view&t=contact&view=normal&loc=frame_html,,,23&sid="
+ sid));
request.addHeader(new BasicHeader("Accept-Language", "zh-cn,zh"));
request
.addHeader(new BasicHeader("Referer", "http://mail.qq.com/cgi-bin/frame_html?sid=" + sid));
try {
HttpResponse response = http.execute(request);
StatusLine statusLine = response.getStatusLine();
if (statusLine == null || statusLine.getStatusCode() != HttpStatus.SC_OK
|| response.getEntity() == null) {
throw new SocialException(String.valueOf(statusLine));
}
String result = IOUtils.toString(response.getEntity().getContent(), "GB18030");
request.releaseConnection();
List groups = null;
Document doc = Jsoup.parse(result);
Elements scripts = doc.select("script");
for (Element el : scripts) {
for (DataNode node : el.dataNodes()) {
String script = node.getWholeData().trim();
if (script.startsWith("var goListData")) {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
List users = new ArrayList();
Bindings bindings = engine.createBindings();
bindings.put("users", users);
script =
script
+ "(function(){for(var i in goListData.oList){var o=goListData.oList[i];var u=new com.belerweb.social.qq.mail.bean.User();u.setId(o.sId);u.setType(o.sItemType);u.setLevel(o.sLevel);u.setName(o.oName.length?o.oName[0].sVal:'');u.setFamilyName((o.oFamilyName&&o.oFamilyName.length)?o.oFamilyName[0].sVal:'');u.setGivenName((o.oGivenName&&o.oGivenName.length)?o.oGivenName[0].sVal:'');u.setCustom((o.oCustom&&o.oCustom.length)?o.oCustom[0].sVal:'');u.setNickName((o.oQQNickName&&o.oQQNickName.length)?o.oQQNickName[0].sVal:'');u.setRelate((o.oRelate&&o.oRelate.length)?o.oRelate[0].sVal:'');u.setUrl((o.oUrl&&o.oUrl.length)?o.oUrl[0].sVal:'');u.setDate((o.oDate&&o.oDate.length)?o.oDate[0].sVal:'');u.setBirthday((o.oBirthday&&o.oBirthday.length)?o.oBirthday[0].sVal:'');u.setIm((o.oIM&&o.oIM.length)?o.oIM[0].sVal:'');u.setNote((o.oNote&&o.oNote.length)?o.oNote[0].sVal:'');var es=new java.util.ArrayList();for(var j in o.oEmail){var obj=o.oEmail[j];var e=new com.belerweb.social.qq.mail.bean.Email();e.setEmail(obj.sVal);e.setLabel(obj.sLabel?obj.sLabel:'');e.setType(obj.sType?obj.sType:'');es.add(e)}u.setEmails(es);var ts=new java.util.ArrayList();for(var j in o.oTel){var obj=o.oTel[j];var t=new com.belerweb.social.qq.mail.bean.Tel();t.setNum(obj.sVal);t.setLabel(obj.sLabel?obj.sLabel:'');t.setType(obj.sType?obj.sType:'');ts.add(t)}u.setTels(ts);if(o.oOrg&&o.oOrg.length){var org=new com.belerweb.social.qq.mail.bean.Org();org.setOrg1(o.oOrg[0].sOrg1);org.setOrg2(o.oOrg[0].sOrg2);org.setTitle(o.oOrg[0].sTitle);u.setOrg(org)}if(o.oAdr&&o.oAdr.length){var adr=new com.belerweb.social.qq.mail.bean.Address();adr.setLabel(o.oAdr[0].sLabel);adr.setType(o.oAdr[0].sType);adr.setCountry(o.oAdr[0].sCountry);adr.setProvince(o.oAdr[0].sProvince);adr.setCity(o.oAdr[0].sCity);adr.setStreet(o.oAdr[0].sStreet);adr.setPostcode(o.oAdr[0].sPostcode);u.setAddress(adr)}users.add(u)}})();";
if (group.getId() == null) {
groups = new ArrayList();
bindings.put("groups", groups);
script =
script
+ "(function(){for(var k in goGroupData){for(var i in goGroupData[k].oList){var obj=goGroupData[k].oList[i];var g=new com.belerweb.social.qq.mail.bean.Group();g.setId(obj.sId);g.setType(obj.sSubType);g.setName(obj.sName);groups.add(g);}}})();";
}
engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
engine.eval(script);
group.setUsers(users);
}
}
}
return groups;
} catch (ClientProtocolException e) {
throw new SocialException(e);
} catch (IOException e) {
throw new SocialException(e);
} catch (ScriptException e) {
throw new SocialException(e);
}
}
/**
* 按分组获取所有QQ邮箱中的联系人,包括QQ联系人
*/
public List get() throws SocialException {
List result = new ArrayList();
login();
Group group = new Group();
group.setType("normal");
group.setName("全部");
group.setOwner(email);
List groups = get(group);
result.add(group);
for (Group group2 : groups) {
get(group2);
group2.setOwner(email);
result.add(group2);
}
return result;
}
/**
* QQ邮箱登录,如果登录成功则返回sid,登录失败抛出异常
*/
public String login() throws SocialException {
ValidationCode validationCode = check();
String vc = validationCode.getCode();
if (validationCode.need()) {
vc = yundama.decode(getValidationCode(), YundamaType.ALPHABETIC4).getResult();
}
try {
String code = DigestUtils.md5Hex(password).toUpperCase();
byte[] byte1 = Hex.decodeHex(code.toCharArray());
byte[] byte2 = Hex.decodeHex(validationCode.getUid().toCharArray());
byte[] bytes = new byte[byte1.length + byte2.length];
System.arraycopy(byte1, 0, bytes, 0, byte1.length);
System.arraycopy(byte2, 0, bytes, byte1.length, byte2.length);
code = DigestUtils.md5Hex(bytes).toUpperCase();
code = DigestUtils.md5Hex(code + vc.toUpperCase()).toUpperCase();
List params = new ArrayList();
params.add(new BasicNameValuePair("aid", "522005705"));
params.add(new BasicNameValuePair("ptlang", "2052"));
params.add(new BasicNameValuePair("js_type", "2"));
params.add(new BasicNameValuePair("js_ver", "10009"));
params.add(new BasicNameValuePair("fp", "loginerroralert"));
params.add(new BasicNameValuePair("wording", "快速登录"));
params.add(new BasicNameValuePair("mibao_css", "m_ptmail"));
params.add(new BasicNameValuePair("u1", URLEncoder.encode(
"https://mail.qq.com/cgi-bin/login?vt=passport&vm=wpt&ft=ptlogin&lang=cn&ss=&validcnt=&clientaddr="
+ email, "UTF-8")));
params.add(new BasicNameValuePair("css",
"https://mail.qq.com/zh_CN/htmledition/style/fast_login181b91.css"));
params.add(new BasicNameValuePair("daid", "4"));
params.add(new BasicNameValuePair("dummy", ""));
params.add(new BasicNameValuePair("from_ui", "1"));
params.add(new BasicNameValuePair("g", "1"));
params.add(new BasicNameValuePair("h", "1"));
params.add(new BasicNameValuePair("ptredirect", "1"));
params.add(new BasicNameValuePair("t", "1"));
params.add(new BasicNameValuePair("action", "4-20-" + RandomStringUtils.randomNumeric(5)));
params.add(new BasicNameValuePair("p", code));
params.add(new BasicNameValuePair("u", email));
params.add(new BasicNameValuePair("u_domain", email.substring(email.indexOf("@"))));
params.add(new BasicNameValuePair("uin", email.substring(0, email.indexOf("@"))));
params.add(new BasicNameValuePair("verifycode", vc));
HttpGet request =
new HttpGet("https://ssl.ptlogin2.qq.com/login?" + StringUtils.join(params, "&"));
request
.addHeader(new BasicHeader("Referer", "https://mail.qq.com/cgi-bin/loginpage?lang=cn"));
request.addHeader(new BasicHeader("Accept-Language", "zh-cn,zh"));
HttpResponse response = http.execute(request);
StatusLine statusLine = response.getStatusLine();
if (statusLine == null || statusLine.getStatusCode() != HttpStatus.SC_OK
|| response.getEntity() == null) {
throw new SocialException(String.valueOf(statusLine));
}
String result = IOUtils.toString(response.getEntity().getContent());
request.releaseConnection();
String[] str = result.substring(7, result.length() - 1).split(",");
if (!"0".equals(str[0].trim().substring(1, str[0].length() - 1))) {
throw new SocialException(str[4]);
}
request = new HttpGet(str[2].trim().substring(1, str[2].length() - 1));
response = http.execute(request);
statusLine = response.getStatusLine();
if (statusLine == null || statusLine.getStatusCode() != HttpStatus.SC_OK
|| response.getEntity() == null) {
throw new SocialException(String.valueOf(statusLine));
}
result = IOUtils.toString(response.getEntity().getContent(), "GB18030");
request.releaseConnection();
Matcher matcher = PATTERN.matcher(result);
if (matcher.find()) {
this.sid = matcher.group(1);
} else {
if (!result.contains("看不清")) {
Document doc = Jsoup.parse(result);
Elements scripts = doc.select("script");
boolean status = false;
for (Element el : scripts) {
for (DataNode node : el.dataNodes()) {
String script = node.getWholeData().trim();
if (script.startsWith("var urlHead")) {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
script = script.replace("window.location.replace(targetUrl);", "");
try {
engine.eval(script);
String url = engine.get("targetUrl").toString();
request = new HttpGet(url);
response = http.execute(request);
result = IOUtils.toString(response.getEntity().getContent(), "GB18030");
status = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
if (!status) {
// throw new SocialException("没有获取到sid");
}
}
vc = yundama.decode(getValidationCode2(), YundamaType.ALPHABETIC4).getResult();
params = new ArrayList();
params.add(new BasicNameValuePair("btlogin", "登录"));
params.add(new BasicNameValuePair("delegate_url", ""));
params.add(new BasicNameValuePair("sid", ""));
params.add(new BasicNameValuePair("uin", email.substring(0, email.indexOf("@"))));
params.add(new BasicNameValuePair("verifycode", vc));
params.add(new BasicNameValuePair("vt", "passport"));
HttpPost post = new HttpPost("https://mail.qq.com/cgi-bin/login?sid=");
post.setConfig(RequestConfig.custom().setRedirectsEnabled(false)
.setRelativeRedirectsAllowed(false).setCircularRedirectsAllowed(false).build());
post.setEntity(new UrlEncodedFormEntity(params));
response = http.execute(post);
try {
result = IOUtils.toString(response.getEntity().getContent(), "GB18030");
matcher = PATTERN.matcher(result);
if (matcher.find()) {
this.sid = matcher.group(1);
} else {
matcher = PATTERN.matcher(response.getFirstHeader("Location").getValue());
if (matcher.find()) {
this.sid = matcher.group(1);
} else {
throw new SocialException("没有获取到sid");
}
}
} catch (Exception e) {
throw new SocialException("没有获取到sid");
}
}
return this.sid;
} catch (DecoderException e) {
throw new SocialException(e);
} catch (ClientProtocolException e) {
throw new SocialException(e);
} catch (IOException e) {
throw new SocialException(e);
}
}
/**
* 检查QQ邮箱登录是否需要验证码
*/
public ValidationCode check() throws SocialException {
List params = new ArrayList();
params.add(new BasicNameValuePair("appid", "522005705"));
params.add(new BasicNameValuePair("ptlang", "2052"));
params.add(new BasicNameValuePair("js_type", "2"));
params.add(new BasicNameValuePair("js_ver", "10009"));
params.add(new BasicNameValuePair("r", String.valueOf(Math.random())));
params.add(new BasicNameValuePair("uin", email));
HttpGet request =
new HttpGet("https://ssl.ptlogin2.qq.com/check?" + StringUtils.join(params, "&"));
request.addHeader(new BasicHeader("Referer", "https://mail.qq.com/cgi-bin/loginpage?lang=cn"));
request.addHeader(new BasicHeader("Accept-Language", "zh-cn,zh"));
try {
HttpResponse response = http.execute(request);
StatusLine statusLine = response.getStatusLine();
if (statusLine == null || statusLine.getStatusCode() != HttpStatus.SC_OK
|| response.getEntity() == null) {
throw new SocialException(String.valueOf(statusLine));
}
String result = IOUtils.toString(response.getEntity().getContent());
request.releaseConnection();
return new ValidationCode(result);
} catch (ClientProtocolException e) {
throw new SocialException(e);
} catch (IOException e) {
throw new SocialException(e);
}
}
/**
* 获取验证码
*/
public byte[] getValidationCode() throws SocialException {
List params = new ArrayList();
params.add(new BasicNameValuePair("aid", "522005705"));
params.add(new BasicNameValuePair("r", String.valueOf(Math.random())));
params.add(new BasicNameValuePair("uin", email));
HttpGet request =
new HttpGet("https://ssl.captcha.qq.com/getimage?" + StringUtils.join(params, "&"));
request.addHeader(new BasicHeader("Referer", "https://mail.qq.com/cgi-bin/loginpage?lang=cn"));
request.addHeader(new BasicHeader("Accept-Language", "zh-cn,zh"));
try {
HttpResponse response = http.execute(request);
StatusLine statusLine = response.getStatusLine();
if (statusLine == null || statusLine.getStatusCode() != HttpStatus.SC_OK
|| response.getEntity() == null) {
throw new SocialException(String.valueOf(statusLine));
}
byte[] result = IOUtils.toByteArray(response.getEntity().getContent());
request.releaseConnection();
return result;
} catch (ClientProtocolException e) {
throw new SocialException(e);
} catch (IOException e) {
throw new SocialException(e);
}
}
/**
* 获取验证码2
*/
public byte[] getValidationCode2() throws SocialException {
List params = new ArrayList();
params.add(new BasicNameValuePair("aid", "23000101"));
params.add(new BasicNameValuePair("f", "html"));
params.add(new BasicNameValuePair("ck", "1"));
params.add(new BasicNameValuePair("r", String.valueOf(Math.random())));
HttpGet request =
new HttpGet("https://mail.qq.com/cgi-bin/getverifyimage?" + StringUtils.join(params, "&"));
request.addHeader(new BasicHeader("Referer",
" https://mail.qq.com/cgi-bin/loginpage?errtype=3"));
request.addHeader(new BasicHeader("Accept-Language", "zh-cn,zh"));
try {
HttpResponse response = http.execute(request);
StatusLine statusLine = response.getStatusLine();
if (statusLine == null || statusLine.getStatusCode() != HttpStatus.SC_OK
|| response.getEntity() == null) {
throw new SocialException(String.valueOf(statusLine));
}
byte[] result = IOUtils.toByteArray(response.getEntity().getContent());
request.releaseConnection();
return result;
} catch (ClientProtocolException e) {
throw new SocialException(e);
} catch (IOException e) {
throw new SocialException(e);
}
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/mail/bean/Address.java
================================================
package com.belerweb.social.qq.mail.bean;
public class Address {
private String label;
private String type;
private String country;
private String province;
private String city;
private String street;
private String postcode;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getPostcode() {
return postcode;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/mail/bean/Email.java
================================================
package com.belerweb.social.qq.mail.bean;
public class Email {
private String label;
private String type;
private String email;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/mail/bean/Group.java
================================================
package com.belerweb.social.qq.mail.bean;
import java.util.List;
public class Group {
private String id;
private String type;
private String name;
private List users;
private String owner;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getUsers() {
return users;
}
public void setUsers(List users) {
this.users = users;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/mail/bean/Org.java
================================================
package com.belerweb.social.qq.mail.bean;
public class Org {
private String org1;
private String org2;
private String title;
public String getOrg1() {
return org1;
}
public void setOrg1(String org1) {
this.org1 = org1;
}
public String getOrg2() {
return org2;
}
public void setOrg2(String org2) {
this.org2 = org2;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/mail/bean/Tel.java
================================================
package com.belerweb.social.qq.mail.bean;
public class Tel {
private String label;
private String type;
private String num;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/mail/bean/User.java
================================================
package com.belerweb.social.qq.mail.bean;
import java.util.List;
public class User {
private String id;
private String level;
private String type;
private String name;
private String nickName;
private String familyName;
private String givenName;
private String relate;
private String url;
private String date;
private String birthday;
private String im;
private String custom;
private String note;
private Address address;
private Org org;
private List emails;
private List tels;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getFamilyName() {
return familyName;
}
public void setFamilyName(String familyName) {
this.familyName = familyName;
}
public String getGivenName() {
return givenName;
}
public void setGivenName(String givenName) {
this.givenName = givenName;
}
public String getRelate() {
return relate;
}
public void setRelate(String relate) {
this.relate = relate;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getIm() {
return im;
}
public void setIm(String im) {
this.im = im;
}
public String getCustom() {
return custom;
}
public void setCustom(String custom) {
this.custom = custom;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Org getOrg() {
return org;
}
public void setOrg(Org org) {
this.org = org;
}
public List getEmails() {
return emails;
}
public void setEmails(List emails) {
this.emails = emails;
}
public List getTels() {
return tels;
}
public void setTels(List tels) {
this.tels = tels;
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/mail/bean/ValidationCode.java
================================================
package com.belerweb.social.qq.mail.bean;
public class ValidationCode {
private String status;
private String code;
private String uid;
public ValidationCode() {}
public ValidationCode(String response) {
String[] str = response.substring(13, response.length() - 2).split(",");
status = str[0].trim().substring(1, str[0].length() - 1);
code = str[1].trim().substring(1, str[1].length() - 1);
uid = str[2].trim().substring(1, str[2].length() - 1).replaceAll("\\\\x", "");
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public boolean need() {
return !"0".equals(status);
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/qzone/api/Visitor.java
================================================
package com.belerweb.social.qq.qzone.api;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.belerweb.social.captcha.api.Yundama;
import com.belerweb.social.captcha.bean.YundamaType;
import com.belerweb.social.exception.SocialException;
import com.belerweb.social.http.Http;
import com.belerweb.social.http.HttpException;
import com.belerweb.social.qq.mail.bean.ValidationCode;
public class Visitor {
private static final Logger LOGGER = LoggerFactory.getLogger(Visitor.class);
private String qq;
private String password;
private Yundama yundama;
private HttpClient http;
private String loginUi;
private String loginSig;
private String skey;
private boolean session;
public Visitor(String qq, String password, Yundama yundama) {
this.qq = qq;
this.password = password;
this.yundama = yundama;
this.http = Http.newClient();
}
private void openLogin() throws ClientProtocolException, IOException, HttpException {
String uri = "http://user.qzone.qq.com/" + qq + "/friendvisitor";
HttpResponse response = http.execute(new HttpGet(uri));
if (!Http.isRequestSuccess(response)) {
throw new SocialException("Step 1, open login ui failed.");
}
Document doc = Jsoup.parse(Http.responseToString(response));
loginUi = doc.select("#login_frame").get(0).attr("src");
HttpGet request = new HttpGet(loginUi);
request.addHeader(new BasicHeader("Referer", uri));
response = http.execute(request);
if (!Http.isRequestSuccess(response)) {
throw new SocialException("Step 2, open login ui failed.");
}
doc = Jsoup.parse(Http.responseToString(response));
Matcher matcher =
Pattern.compile("login_sig\\s*:\\s*[\"']([^\"']+)[\"']").matcher(
doc.select("script").get(0).html());
if (!matcher.find()) {
throw new SocialException("Step 3, login page isn't contain login_sig.");
}
loginSig = matcher.group(1);
}
private ValidationCode loginCheck() throws ClientProtocolException, IOException, HttpException {
List params = new ArrayList();
params.add(new BasicNameValuePair("regmaster", ""));
params.add(new BasicNameValuePair("uin", qq));
params.add(new BasicNameValuePair("appid", "549000912"));
params.add(new BasicNameValuePair("js_ver", "10064"));
params.add(new BasicNameValuePair("js_type", "1"));
params.add(new BasicNameValuePair("login_sig", loginSig));
params
.add(new BasicNameValuePair("u1", "http://qzs.qq.com/qzone/v5/loginsucc.html?para=reload"));
params.add(new BasicNameValuePair("r", String.valueOf(Math.random())));
HttpGet request =
new HttpGet("http://check.ptlogin2.qq.com/check?" + StringUtils.join(params, "&"));
request.addHeader(new BasicHeader("Referer", loginUi));
request.addHeader(new BasicHeader("Accept-Language", "zh-cn,zh"));
HttpResponse response = http.execute(request);
if (!Http.isRequestSuccess(response)) {
throw new SocialException("Step 4, check if validation code failed.");
}
return new ValidationCode(Http.responseToString(response));
}
private byte[] getValidationCode() throws ClientProtocolException, IOException, HttpException {
List params = new ArrayList();
params.add(new BasicNameValuePair("uin", qq));
params.add(new BasicNameValuePair("aid", "549000912"));
params.add(new BasicNameValuePair(String.valueOf(Math.random()), ""));
HttpGet request =
new HttpGet("http://captcha.qq.com/getimage?" + StringUtils.join(params, "&"));
request.addHeader(new BasicHeader("Referer", loginUi));
request.addHeader(new BasicHeader("Accept-Language", "zh-cn,zh"));
HttpResponse response = http.execute(request);
if (!Http.isRequestSuccess(response)) {
throw new SocialException("Step 5, get validation code image failed.");
}
return IOUtils.toByteArray(response.getEntity().getContent());
}
private void login() throws ClientProtocolException, IOException, DecoderException, HttpException {
openLogin();
ValidationCode validationCode = loginCheck();
String code = validationCode.getCode();
if (validationCode.need()) {
LOGGER.debug("Qzone visitor need validation code.");
code = yundama.decode(getValidationCode(), YundamaType.ALPHANUMERIC).getResult();
LOGGER.debug("Qzone visitor validation code is {}.", code);
}
String p = DigestUtils.md5Hex(password).toUpperCase();
byte[] byte1 = Hex.decodeHex(p.toCharArray());
byte[] byte2 = Hex.decodeHex(validationCode.getUid().toCharArray());
byte[] bytes = new byte[byte1.length + byte2.length];
System.arraycopy(byte1, 0, bytes, 0, byte1.length);
System.arraycopy(byte2, 0, bytes, byte1.length, byte2.length);
p = DigestUtils.md5Hex(bytes).toUpperCase();
p = DigestUtils.md5Hex(p + code.toUpperCase()).toUpperCase();
List params = new ArrayList();
params.add(new BasicNameValuePair("u", qq));
params.add(new BasicNameValuePair("p", p));
params.add(new BasicNameValuePair("verifycode", code));
params.add(new BasicNameValuePair("aid", "549000912"));
params.add(new BasicNameValuePair("u1",
"http%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dreload"));
params.add(new BasicNameValuePair("h", "1"));
params.add(new BasicNameValuePair("ptredirect", "0"));
params.add(new BasicNameValuePair("ptlang", "2052"));
params.add(new BasicNameValuePair("from_ui", "1"));
params.add(new BasicNameValuePair("dump", ""));
params.add(new BasicNameValuePair("low_login_enable", "0"));
params.add(new BasicNameValuePair("regmaster", ""));
params.add(new BasicNameValuePair("fp", "loginerroralert"));
params.add(new BasicNameValuePair("action", "2-22-1389885147889"));
params.add(new BasicNameValuePair("mibao_css", ""));
params.add(new BasicNameValuePair("t", "1"));
params.add(new BasicNameValuePair("g", "1"));
params.add(new BasicNameValuePair("js_ver", "10064"));
params.add(new BasicNameValuePair("js_type", "1"));
params.add(new BasicNameValuePair("login_sig", loginSig));
params.add(new BasicNameValuePair("pt_rsa", "0"));
HttpGet request = new HttpGet("http://ptlogin2.qq.com/login?" + StringUtils.join(params, "&"));
request.addHeader(new BasicHeader("Referer", loginUi));
request.addHeader(new BasicHeader("Accept-Language", "zh-cn,zh"));
HttpResponse response = http.execute(request);
if (!Http.isRequestSuccess(response)) {
throw new SocialException("Step 6, login failed.");
}
LOGGER.debug("Qzone visitor login end.");
String html = Http.responseToString(response);
if (!html.contains("登录成功")) {
throw new SocialException("Step 7, login failed.");
}
for (Header header : response.getHeaders("Set-Cookie")) {
Matcher matcher = Pattern.compile("skey=([^;]+);").matcher(header.getValue());
if (matcher.find()) {
skey = matcher.group(1);
session = true;
LOGGER.debug("Qzone visitor login success.");
}
}
if (!session) {
throw new SocialException("Step 8, get skey failed.");
}
}
public JSONObject getSimple() throws SocialException {
LOGGER.debug("Qzone visitor getSimple begin.");
try {
if (!session) {
LOGGER.debug("Qzone visitor need login.");
login();
} else {
LOGGER.debug("Qzone in session.");
}
long gtk = 5381;
for (int i = 0, len = skey.length(); i < len; ++i) {
gtk += (gtk << 5) + skey.charAt(i);
}
gtk = gtk & 2147483647;
List params = new ArrayList();
params.add(new BasicNameValuePair("uin", qq));
params.add(new BasicNameValuePair("mask", "2"));
params.add(new BasicNameValuePair("clear", "1"));
params.add(new BasicNameValuePair("mod", "8"));
params.add(new BasicNameValuePair("fupdate", "1"));
params.add(new BasicNameValuePair("random", String.valueOf(Math.random())));
params.add(new BasicNameValuePair("g_tk", String.valueOf(gtk)));
HttpGet request =
new HttpGet("http://g.qzone.qq.com/cgi-bin/friendshow/cgi_get_visitor_simple?"
+ StringUtils.join(params, "&"));
request.addHeader(new BasicHeader("Referer",
"http://ctc.qzs.qq.com/qzone/v8/pages/visitors/refuse.html"));
request.addHeader(new BasicHeader("Accept-Language", "zh-cn,zh"));
HttpResponse response = http.execute(request);
if (!Http.isRequestSuccess(response)) {
throw new SocialException("Step 9, get visitor simple failed.");
}
LOGGER.debug("Qzone visitor getSimple end.");
String html = Http.responseToString(response);
JSONObject json =
new JSONObject(html.substring(html.indexOf("{"), html.lastIndexOf("}") + 1));
if (json.getInt("code") != 0) {
LOGGER.debug("Qzone visitor getSimple error: {}", html);
session = false;
http = Http.newClient();
loginUi = null;
loginSig = null;
skey = null;
return getSimple();
}
LOGGER.debug("Qzone visitor getSimple success.");
return json;
} catch (ClientProtocolException e) {
throw new SocialException(e);
} catch (IOException e) {
throw new SocialException(e);
} catch (HttpException e) {
throw new SocialException(e);
} catch (DecoderException e) {
throw new SocialException(e);
}
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/t/api/OAuth2.java
================================================
package com.belerweb.social.qq.t.api;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import com.belerweb.social.API;
public final class OAuth2 extends API {
OAuth2(QQT t) {
super(t);
}
/**
* 获取Authorization Code
*
* 从 {@link QQT} 从获取clientId,redirectUri,responseType为code ,其余参数默认
*
* @see OAuth2#authorize(String, String, String, String, String, Boolean)
*/
public String authorize() {
return authorize(t.getRedirectUri());
}
/**
* 获取Authorization Code
*
* 从 {@link QQT} 从获取clientId,responseType为code ,其余参数默认
*
* @see OAuth2#authorize(String, String, String, String, String, Boolean)
*/
public String authorize(String redirectUri) {
return authorize(t.getClientId(), redirectUri, "code", null, null, null);
}
/**
* 获取Authorization Code
*
* 文档地址:http://wiki.t.qq.com/使用authorization_code获取access_token
*
* @param clientId 必须,申请应用时分配的app_key
* @param redirectUri 必须,授权回调地址,必须和应用注册的地址一致(地址长度上限为256个字节)
* @param responseType 必须,授权类型,为code
* @param wap
* 主要用于指定手机授权页的版本,无此参数默认显示pc授权页面。wap=1时,跳转到wap1.0的授权页。wap=2时,跳转到wap2.0的授权页。不带本参数时,手机访问默认跳到wap2
* .0的授权页
* @param state
* 用于保持请求和回调的状态,授权请求成功后原样带回给第三方。该参数用于防止csrf攻击(跨站请求伪造攻击),强烈建议第三方带上该参数。参数设置建议为简单随机数+session的方式
* @param forceLogin 针对pc授权页。forcelogin=true,强制弹出登录授权页面
* forcelogin=false,用户已经登录并且已经授权第三方应用,则不再弹出授权页面 默认为forcelogin=true
*/
public String authorize(String clientId, String redirectUri, String responseType, String wap,
String state, Boolean forceLogin) {
List params = new ArrayList();
t.addParameter(params, "client_id", clientId);
t.addParameter(params, "redirect_uri", redirectUri);
t.addParameter(params, "response_type", responseType);
t.addNotNullParameter(params, "wap", wap);
t.addNotNullParameter(params, "state", state);
t.addTrueParameter(params, "forcelogin", forceLogin);
return "https://open.t.qq.com/cgi-bin/oauth2/authorize?" + StringUtils.join(params, "&");
}
}
================================================
FILE: src/main/java/com/belerweb/social/qq/t/api/QQT.java
================================================
package com.belerweb.social.qq.t.api;
import com.belerweb.social.SDK;
public final class QQT extends SDK {
private String clientId;
private String clientSecret;
private String redirectUri;
public QQT(String clientId, String clientSecret) {
this.clientId = clientId;
this.clientSecret = clientSecret;
}
public QQT(String clientId, String clientSecret, String redirectUri) {
this(clientId, clientSecret);
this.redirectUri = redirectUri;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getRedirectUri() {
return redirectUri;
}
public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
}
================================================
FILE: src/main/java/com/belerweb/social/weibo/api/OAuth2.java
================================================
package com.belerweb.social.weibo.api;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import org.json.JSONObject;
import com.belerweb.social.API;
import com.belerweb.social.bean.Error;
import com.belerweb.social.bean.Result;
import com.belerweb.social.exception.SocialException;
import com.belerweb.social.weibo.bean.AccessToken;
import com.belerweb.social.weibo.bean.Display;
import com.belerweb.social.weibo.bean.Scope;
import com.belerweb.social.weibo.bean.TokenInfo;
public final class OAuth2 extends API {
OAuth2(Weibo weibo) {
super(weibo);
}
/**
* OAuth2的authorize接口
*
* 从 {@link Weibo} 从获取clientId,redirectUri,scope 使用 {@link Scope#ALL},其余参数默认
*
* @see OAuth2#authorize(String, String, Scope[], String, Display, Boolean, String)
*/
public String authorize() {
return authorize(weibo.getRedirectUri());
}
/**
* OAuth2的authorize接口
*
* 从 {@link Weibo} 从获取clientId,scope 使用 {@link Scope#ALL},其余参数默认
*
* @see OAuth2#authorize(String, String, Scope[], String, Display, Boolean, String)
*
* @param redirectUri 授权回调地址,站外应用需与设置的回调地址一致,站内应用需填写canvas page的地址。
*/
public String authorize(String redirectUri) {
return authorize(weibo.getClientId(), redirectUri, new Scope[] {Scope.ALL}, null, null, null,
null);
}
/**
* OAuth2的authorize接口
*
* 文档地址:http://open.weibo.com/wiki/Oauth2/authorize
*
* @param clientId 申请应用时分配的AppKey。
* @param redirectUri 授权回调地址,站外应用需与设置的回调地址一致,站内应用需填写canvas page的地址。
* @param scope 申请scope权限所需参数,可一次申请多个scope权限,用逗号分隔。使用文档
* @param state 用于保持请求和回调的状态,在回调时,会在Query
* Parameter中回传该参数。开发者可以用这个参数验证请求有效性,也可以记录用户请求授权页前的位置。这个参数可用于防止跨站请求伪造(CSRF)攻击
* @param display 授权页面的终端类型,取值见下面的说明。
* @param forceLogin 是否强制用户重新登录,true:是,false:否。默认false。
* @param language 授权页语言,缺省为中文简体版,en为英文版。
*/
public String authorize(String clientId, String redirectUri, Scope[] scope, String state,
Display display, Boolean forceLogin, String language) {
List params = new ArrayList();
weibo.addParameter(params, "client_id", clientId);
weibo.addParameter(params, "redirect_uri", redirectUri);
if (scope != null) {
weibo.addParameter(params, "scope", StringUtils.join(scope, ","));
}
weibo.addNotNullParameter(params, "state", state);
weibo.addNotNullParameter(params, "display", display);
weibo.addTrueParameter(params, "forcelogin", forceLogin);
weibo.addNotNullParameter(params, "language", language);
return "https://api.weibo.com/oauth2/authorize?" + StringUtils.join(params, "&");
}
/**
* 从 {@link Weibo} 从获取clientId,clientSecret,grantType,redirectUri 使用 authorization_code
*
* @see OAuth2#accessToken(String, String, String, String, String)
*/
public Result accessToken(String code) {
return accessToken(code, weibo.getRedirectUri());
}
/**
* 从 {@link Weibo} 从获取clientId,clientSecret,grantType 使用 authorization_code
*
* @see OAuth2#accessToken(String, String, String, String, String)
*/
public Result accessToken(String code, String redirectUri) {
return accessToken(weibo.getClientId(), weibo.getClientSecret(), "authorization_code", code,
redirectUri);
}
/**
* OAuth2的access_token接口
*
* 文档地址:http://open.weibo.com/wiki/OAuth2/access_token
*
* @param clientId 申请应用时分配的AppKey。
* @param clientSecret 申请应用时分配的AppSecret。
* @param grantType 请求的类型,填写authorization_code
* @param code grant_type为authorization_code时,调用authorize获得的code值。
* @param redirectUri grant_type为authorization_code时,回调地址,需需与注册应用里的回调地址一致。
*/
public Result accessToken(String clientId, String clientSecret, String grantType,
String code, String redirectUri) {
List params = new ArrayList();
weibo.addParameter(params, "client_id", clientId);
weibo.addParameter(params, "client_secret", clientSecret);
weibo.addParameter(params, "grant_type", grantType);
if ("authorization_code".equals(grantType)) {
weibo.addParameter(params, "code", code);
weibo.addParameter(params, "redirect_uri", redirectUri);
}
String result = weibo.post("https://api.weibo.com/oauth2/access_token", params);
return Result.parse(result, AccessToken.class);
}
/**
* 查询用户access_token的授权相关信息,包括授权时间,过期时间和scope权限。
*
* 文档地址:http://open.weibo.com/wiki/Oauth2/get_token_info
*
* @param accessToken 用户授权时生成的access_token。
*/
public Result getTokenInfo(String accessToken) {
List params = new ArrayList();
weibo.addParameter(params, "access_token", accessToken);
String result = weibo.post("https://api.weibo.com/oauth2/get_token_info", params);
return Result.parse(result, TokenInfo.class);
}
/**
* 用于OAuth1.0 access token 更换至 OAuth2.0 access
* token,帮助开发者使用新版接口和OAuth2.0时平滑迁移用户。详细的OAuth1.0调用方式和SDK资源参见:http://open.weibo.com/wiki/Oauth
*
* 文档地址:http://open.weibo.com/wiki/Oauth2/get_oauth2_token
*
* @param oauthConsumerKey 创建应用时生成的APP KEY。
* @param oauthToken oauth的token。
* @param oauthSignatureMethod 签名方法,建议使用“HMAC-SHA1”。
* @param oauthTimestamp 生成Base String时的时间戳。
* @param oauthNonce 单次值,一个随机字符串,防止重复攻击。该参数只支持ASCII码的字符串。
* @param oauthVersion OAuth协议版本。填写“1.0”。
* @param oauthSignature 签名值,是由根据上面的几个参数生成的 Base String经HMAC-SHA1算法计算得出。
*/
public void getOAuth2Token(String oauthConsumerKey, String oauthToken,
String oauthSignatureMethod, Long oauthTimestamp, String oauthNonce, String oauthVersion,
String oauthSignature) {
throw new SocialException("方法还未实现...");
}
/**
* 授权回收接口,帮助开发者主动取消用户的授权。
*
* 文档地址:http://open.weibo.com/wiki/Oauth2/revokeoauth2
*
* @param accessToken 用户授权应用的access_token
*/
public Result revokeOAuth2(String accessToken) {
List params = new ArrayList();
weibo.addParameter(params, "access_token", accessToken);
String json = weibo.post("https://api.weibo.com/oauth2/revokeoauth2", params);
JSONObject jsonObject = new JSONObject(json);
Error error = Error.parse(jsonObject);
if (error == null) {
return new Result(Result.parseBoolean(jsonObject.get("result")));
}
return new Result(error);
}
}
================================================
FILE: src/main/java/com/belerweb/social/weibo/api/User.java
================================================
package com.belerweb.social.weibo.api;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import com.belerweb.social.API;
import com.belerweb.social.bean.Result;
import com.belerweb.social.exception.SocialException;
import com.belerweb.social.weibo.bean.UserCounts;
/**
* 读取用户信息接口
*/
public final class User extends API {
protected User(Weibo weibo) {
super(weibo);
}
/**
* 获取用户信息/根据用户ID获取用户信息
*
* 访问级别:普通接口
*
* 频次限制:是
*
* 文档地址:https://api.weibo.com/2/users/show.json
*
* @param source 采用OAuth授权方式不需要此参数,其他授权方式为必填参数,数值为应用的AppKey。
* @param accessToken 采用OAuth授权方式为必填参数,其他授权方式不需要此参数,OAuth授权后获得。
* @param uid 需要查询的用户ID。
* @param screename 需要查询的用户昵称。
*
* 参数uid与screen_name二者必选其一,且只能选其一
*/
public Result show(String source, String accessToken,
String uid, String screenName) {
List params = new ArrayList