去掉httpclient依赖
This commit is contained in:
parent
a818ea42d7
commit
305738e832
@ -299,4 +299,8 @@
|
||||
|
||||
* 2015-05-20
|
||||
|
||||
+ **weixin4j-server**: released 1.0.1
|
||||
+ **weixin4j-server**: released 1.0.1
|
||||
|
||||
* 2015-05-30
|
||||
|
||||
**大的调整:去掉httpclient依赖**
|
||||
@ -17,37 +17,6 @@
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.4.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>4.2.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.2.5</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
<version>4.2.6</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
|
||||
@ -5,7 +5,7 @@ import java.util.ResourceBundle;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.xml.Map2ObjectConverter;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
import com.thoughtworks.xstream.core.ClassLoaderReference;
|
||||
@ -22,7 +22,7 @@ import com.thoughtworks.xstream.mapper.DefaultMapper;
|
||||
* @see <a href="http://qydev.weixin.qq.com/wiki/index.php">微信企业号API文档</a>
|
||||
*/
|
||||
public abstract class BaseApi {
|
||||
protected final HttpRequest request = new HttpRequest();
|
||||
protected final WeixinHttpClient weixinClient = new WeixinHttpClient();
|
||||
protected final static XmlStream mapXstream = XmlStream.get();
|
||||
static {
|
||||
mapXstream.alias("xml", Map.class);
|
||||
|
||||
@ -0,0 +1,84 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* reference of apache pivot
|
||||
*
|
||||
* @className AbstractHttpMessage
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public abstract class AbstractHttpMessage implements HttpMessage {
|
||||
|
||||
protected final List<Header> headers;
|
||||
|
||||
public AbstractHttpMessage() {
|
||||
this.headers = new ArrayList<Header>(16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header[] getAllHeaders() {
|
||||
return headers.toArray(new Header[headers.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsHeader(String name) {
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
Header header = headers.get(i);
|
||||
if (name.equalsIgnoreCase(header.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeaders(Header... headers) {
|
||||
this.headers.clear();
|
||||
if (headers == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
this.headers.add(headers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header[] getHeaders(String name) {
|
||||
List<Header> headersFound = new ArrayList<Header>();
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
Header header = headers.get(i);
|
||||
if (name.equalsIgnoreCase(header.getName())) {
|
||||
headersFound.add(header);
|
||||
}
|
||||
}
|
||||
return headersFound.toArray(new Header[headersFound.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header getFirstHeader(String name) {
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
Header header = headers.get(i);
|
||||
if (name.equalsIgnoreCase(header.getName())) {
|
||||
return header;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header getLastHeader(String name) {
|
||||
// start at the end of the list and work backwards
|
||||
for (int i = headers.size() - 1; i >= 0; i--) {
|
||||
Header header = headers.get(i);
|
||||
if (name.equalsIgnoreCase(header.getName())) {
|
||||
return header;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* reference of apache pivot
|
||||
*
|
||||
* @className AbstractHttpRequest
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public abstract class AbstractHttpRequest extends AbstractHttpMessage implements
|
||||
HttpRequest {
|
||||
|
||||
@Override
|
||||
public HttpVersion getProtocolVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpParams getParams() {
|
||||
return new HttpParams();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHeader(Header header) {
|
||||
super.headers.add(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeHeader(String name) {
|
||||
List<Header> headersFound = new ArrayList<Header>();
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
Header header = headers.get(i);
|
||||
if (header.getName().equalsIgnoreCase(name)) {
|
||||
headersFound.add(header);
|
||||
}
|
||||
}
|
||||
return super.headers.removeAll(headersFound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeHeader(Header header) {
|
||||
return super.headers.remove(header);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
|
||||
/**
|
||||
* reference of apache pivot
|
||||
*
|
||||
* @className ContentType
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public final class ContentType implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1544245878894784980L;
|
||||
|
||||
public static final ContentType APPLICATION_ATOM_XML = create(
|
||||
"application/atom+xml", Consts.UTF_8);
|
||||
public static final ContentType APPLICATION_FORM_URLENCODED = create(
|
||||
"application/x-www-form-urlencoded", Consts.UTF_8);
|
||||
public static final ContentType APPLICATION_JSON = create(
|
||||
"application/json", Consts.UTF_8);
|
||||
public static final ContentType APPLICATION_OCTET_STREAM = create(
|
||||
"application/octet-stream", (Charset) null);
|
||||
public static final ContentType APPLICATION_SVG_XML = create(
|
||||
"application/svg+xml", Consts.UTF_8);
|
||||
public static final ContentType APPLICATION_XHTML_XML = create(
|
||||
"application/xhtml+xml", Consts.UTF_8);
|
||||
public static final ContentType APPLICATION_XML = create("application/xml",
|
||||
Consts.UTF_8);
|
||||
public static final ContentType MULTIPART_FORM_DATA = create(
|
||||
"multipart/form-data", Consts.UTF_8);
|
||||
public static final ContentType TEXT_HTML = create("text/html",
|
||||
Consts.UTF_8);
|
||||
public static final ContentType TEXT_PLAIN = create("text/plain",
|
||||
Consts.UTF_8);
|
||||
public static final ContentType TEXT_XML = create("text/xml", Consts.UTF_8);
|
||||
public static final ContentType WILDCARD = create("*/*", (Charset) null);
|
||||
|
||||
// defaults
|
||||
public static final ContentType DEFAULT_TEXT = TEXT_PLAIN;
|
||||
public static final ContentType DEFAULT_BINARY = APPLICATION_OCTET_STREAM;
|
||||
|
||||
private final String mimeType;
|
||||
private final Charset charset;
|
||||
|
||||
ContentType(final String mimeType, final Charset charset) {
|
||||
this.mimeType = mimeType;
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return this.mimeType;
|
||||
}
|
||||
|
||||
public Charset getCharset() {
|
||||
return this.charset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(this.mimeType);
|
||||
if (this.charset != null) {
|
||||
buf.append("; charset=");
|
||||
buf.append(this.charset.name());
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static boolean valid(final String s) {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch == '"' || ch == ',' || ch == ';') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static ContentType create(final String mimeType,
|
||||
final Charset charset) {
|
||||
if (mimeType == null) {
|
||||
throw new IllegalArgumentException("MIME type may not be null");
|
||||
}
|
||||
String type = mimeType.trim().toLowerCase(Locale.US);
|
||||
if (type.length() == 0) {
|
||||
throw new IllegalArgumentException("MIME type may not be empty");
|
||||
}
|
||||
if (!valid(type)) {
|
||||
throw new IllegalArgumentException(
|
||||
"MIME type may not contain reserved characters");
|
||||
}
|
||||
return new ContentType(type, charset);
|
||||
}
|
||||
|
||||
public static ContentType create(final String mimeType) {
|
||||
return new ContentType(mimeType, (Charset) null);
|
||||
}
|
||||
|
||||
public static ContentType create(final String mimeType, final String charset)
|
||||
throws UnsupportedCharsetException {
|
||||
return create(
|
||||
mimeType,
|
||||
(charset != null && charset.length() > 0) ? Charset
|
||||
.forName(charset) : null);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
|
||||
/**
|
||||
* header like key-value
|
||||
* @className Header
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class Header extends NameValue {
|
||||
|
||||
private static final long serialVersionUID = -9029136315985402716L;
|
||||
|
||||
public Header(String name, String value) {
|
||||
super(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Header [name=" + getName() + ", value=" + getValue() + "]";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* HTTP 接口
|
||||
*
|
||||
* @className HttpClient
|
||||
* @author jy
|
||||
* @date 2015年5月30日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public interface HttpClient {
|
||||
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param request
|
||||
* 请求
|
||||
* @return 响应
|
||||
* @throws IOException
|
||||
*/
|
||||
HttpResponse execute(HttpRequest request) throws IOException;
|
||||
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param request
|
||||
* 请求
|
||||
* @param handler
|
||||
* 处理器
|
||||
* @return 泛型处理结果
|
||||
* @throws IOException
|
||||
*/
|
||||
<T> T execute(HttpRequest request, ResponseHandler<? extends T> handler)
|
||||
throws IOException;
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import com.foxinmy.weixin4j.http.entity.HttpEntity;
|
||||
|
||||
/**
|
||||
* request with entity
|
||||
*
|
||||
* @className HttpEntityRequest
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public abstract class HttpEntityRequest extends AbstractHttpRequest {
|
||||
public abstract HttpEntity getEntity();
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* GET 请求
|
||||
* @className HttpGet
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class HttpGet extends AbstractHttpRequest {
|
||||
|
||||
private final URI uri;
|
||||
|
||||
public HttpGet(final URI uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public HttpGet(final String uri) {
|
||||
this(URI.create(uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpMethod getMethod() {
|
||||
return HttpMethod.GET;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
/**
|
||||
* HTTP messages consist of requests from client to server and responses from
|
||||
* server to client.
|
||||
*
|
||||
* @className HttpMessage
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public interface HttpMessage {
|
||||
|
||||
/**
|
||||
* HTTP版本
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
HttpVersion getProtocolVersion();
|
||||
|
||||
/**
|
||||
* 全部表头
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Header[] getAllHeaders();
|
||||
|
||||
/**
|
||||
* 设置表头
|
||||
*
|
||||
* @param headers
|
||||
*/
|
||||
void setHeaders(Header... headers);
|
||||
|
||||
/**
|
||||
* 是否包含某一表头
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
boolean containsHeader(String name);
|
||||
|
||||
/**
|
||||
* 名称查找表头
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
Header[] getHeaders(String name);
|
||||
|
||||
/**
|
||||
* 查找最先匹配表头
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
Header getFirstHeader(String name);
|
||||
|
||||
/**
|
||||
* 查找最后匹配表头
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
Header getLastHeader(String name);
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
/**
|
||||
* 请求方法
|
||||
*
|
||||
* @className HttpMethod
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum HttpMethod {
|
||||
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class HttpParams {
|
||||
private Map<String, String> params;
|
||||
|
||||
public HttpParams() {
|
||||
this.params = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
public void setAllowUserInteraction(boolean allowUserInteraction) {
|
||||
params.put(HttpProtocolParams.ALLOW_USER_INTERACTION,
|
||||
Boolean.toString(allowUserInteraction));
|
||||
}
|
||||
|
||||
public boolean getAllowUserInteraction() {
|
||||
String allowUserInteraction = params
|
||||
.get(HttpProtocolParams.ALLOW_USER_INTERACTION);
|
||||
return allowUserInteraction != null
|
||||
&& Boolean.parseBoolean(allowUserInteraction);
|
||||
}
|
||||
|
||||
public void setConnectTimeout(int timeout) {
|
||||
if (timeout < 0) {
|
||||
timeout = 0;
|
||||
}
|
||||
params.put(HttpProtocolParams.CONNECT_TIMEOUT,
|
||||
Integer.toString(timeout));
|
||||
}
|
||||
|
||||
public int getConnectTimeout() {
|
||||
String timeout = params.get(HttpProtocolParams.CONNECT_TIMEOUT);
|
||||
if (timeout == null) {
|
||||
return 5000;
|
||||
}
|
||||
return Integer.parseInt(timeout);
|
||||
}
|
||||
|
||||
public void setReadTimeout(int timeout) {
|
||||
if (timeout < 0) {
|
||||
timeout = 5000;
|
||||
}
|
||||
params.put(HttpProtocolParams.READ_TIMEOUT, Integer.toString(timeout));
|
||||
}
|
||||
|
||||
public int getReadTimeout() {
|
||||
String timeout = params.get(HttpProtocolParams.READ_TIMEOUT);
|
||||
if (timeout == null) {
|
||||
return 5000;
|
||||
}
|
||||
return Integer.parseInt(timeout);
|
||||
}
|
||||
|
||||
public void setIfmodifiedsince(long ifmodifiedsince) {
|
||||
if (ifmodifiedsince < 0) {
|
||||
ifmodifiedsince = 5000;
|
||||
}
|
||||
params.put(HttpProtocolParams.IFMODIFIED_SINCE,
|
||||
Long.toString(ifmodifiedsince));
|
||||
}
|
||||
|
||||
public long getIfmodifiedsince() {
|
||||
String ifmodifiedsince = params
|
||||
.get(HttpProtocolParams.IFMODIFIED_SINCE);
|
||||
if (ifmodifiedsince == null) {
|
||||
return 0l;
|
||||
}
|
||||
return Long.parseLong(ifmodifiedsince);
|
||||
}
|
||||
|
||||
public void setFollowRedirects(boolean followRedirects) {
|
||||
params.put(HttpProtocolParams.FOLLOW_REDIRECTS,
|
||||
Boolean.toString(followRedirects));
|
||||
}
|
||||
|
||||
public boolean getFollowRedirects() {
|
||||
String followRedirects = params
|
||||
.get(HttpProtocolParams.FOLLOW_REDIRECTS);
|
||||
return followRedirects != null && Boolean.parseBoolean(followRedirects);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import com.foxinmy.weixin4j.http.entity.HttpEntity;
|
||||
|
||||
/**
|
||||
* POST 请求
|
||||
*
|
||||
* @className HttpPost
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class HttpPost extends HttpEntityRequest {
|
||||
|
||||
private final URI uri;
|
||||
|
||||
public HttpPost(final URI uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public HttpPost(final String uri) {
|
||||
this(URI.create(uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpMethod getMethod() {
|
||||
return HttpMethod.POST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
private HttpEntity entity;
|
||||
|
||||
@Override
|
||||
public HttpEntity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void setEntity(HttpEntity httpEntity) {
|
||||
this.entity = httpEntity;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
public final class HttpProtocolParams {
|
||||
public final static String ALLOW_USER_INTERACTION = "http.allow.user.interaction";
|
||||
public final static String CONNECT_TIMEOUT = "http.connect.timeout";
|
||||
public final static String READ_TIMEOUT = "http.connect.timeout";
|
||||
public final static String IFMODIFIED_SINCE = "http.ifmodified.since";
|
||||
public final static String FOLLOW_REDIRECTS = "http.follow.redirects";
|
||||
}
|
||||
@ -1,281 +1,59 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpHeaders;
|
||||
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.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.client.params.ClientPNames;
|
||||
import org.apache.http.client.params.CookiePolicy;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.FileEntity;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.entity.mime.MultipartEntity;
|
||||
import org.apache.http.impl.client.AbstractHttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.impl.conn.PoolingClientConnectionManager;
|
||||
import org.apache.http.params.CoreConnectionPNames;
|
||||
import org.apache.http.params.CoreProtocolPNames;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import com.alibaba.fastjson.JSONException;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.util.ErrorUtil;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.thoughtworks.xstream.mapper.CannotResolveClassException;
|
||||
|
||||
/**
|
||||
* 调用微信相关接口的HttpRequest,对于其他请求可能并不适用
|
||||
*
|
||||
* @className HttpRequest
|
||||
* @author jy
|
||||
* @date 2014年8月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class HttpRequest {
|
||||
|
||||
protected AbstractHttpClient client;
|
||||
|
||||
public HttpRequest() {
|
||||
this(150, 100, 10000, 10000);
|
||||
}
|
||||
|
||||
public HttpRequest(int maxConPerRoute, int maxTotal, int socketTimeout,
|
||||
int connectionTimeout) {
|
||||
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
|
||||
// 指定IP并发最大数
|
||||
connectionManager.setDefaultMaxPerRoute(maxConPerRoute);
|
||||
// socket最大创建数
|
||||
connectionManager.setMaxTotal(maxTotal);
|
||||
|
||||
client = new DefaultHttpClient(connectionManager);
|
||||
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,
|
||||
socketTimeout);
|
||||
client.getParams().setParameter(
|
||||
CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout);
|
||||
client.getParams().setBooleanParameter(
|
||||
CoreConnectionPNames.TCP_NODELAY, false);
|
||||
client.getParams().setParameter(
|
||||
CoreConnectionPNames.SOCKET_BUFFER_SIZE, 1024 * 1024);
|
||||
client.getParams().setParameter(ClientPNames.COOKIE_POLICY,
|
||||
CookiePolicy.IGNORE_COOKIES);
|
||||
client.getParams().setParameter(
|
||||
CoreProtocolPNames.HTTP_CONTENT_CHARSET, Consts.UTF_8);
|
||||
client.getParams().setParameter(HttpHeaders.CONTENT_ENCODING,
|
||||
Consts.UTF_8);
|
||||
client.getParams().setParameter(HttpHeaders.ACCEPT_CHARSET,
|
||||
Consts.UTF_8);
|
||||
}
|
||||
|
||||
public Response get(String url) throws WeixinException {
|
||||
return get(url, (Parameter[]) null);
|
||||
}
|
||||
|
||||
public Response get(String url, Map<String, String> para)
|
||||
throws WeixinException {
|
||||
return get(
|
||||
String.format("%s?%s", url,
|
||||
MapUtil.toJoinString(para, false, false, null)),
|
||||
(Parameter[]) null);
|
||||
}
|
||||
|
||||
public Response get(String url, Parameter... parameters)
|
||||
throws WeixinException {
|
||||
StringBuilder sb = new StringBuilder(url);
|
||||
if (parameters != null && parameters.length > 0) {
|
||||
if (url.indexOf("?") < 0) {
|
||||
sb.append("?");
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(String.format("%s=%s", parameters[0].getName(),
|
||||
parameters[0].getValue()));
|
||||
if (parameters.length > 1) {
|
||||
for (int i = 1; i < parameters.length; i++) {
|
||||
sb.append(parameters[i].toGetPara());
|
||||
}
|
||||
}
|
||||
}
|
||||
return doRequest(new HttpGet(sb.toString()));
|
||||
}
|
||||
|
||||
public Response post(String url) throws WeixinException {
|
||||
return post(url, (Parameter[]) null);
|
||||
}
|
||||
|
||||
public Response post(String url, Parameter... parameters)
|
||||
throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
if (parameters != null && parameters.length > 0) {
|
||||
List<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
for (Parameter parameter : parameters) {
|
||||
params.add(parameter.toPostPara());
|
||||
}
|
||||
method.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));
|
||||
}
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
public Response post(String url, String body) throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
method.setEntity(new StringEntity(body, ContentType.create(
|
||||
ContentType.DEFAULT_TEXT.getMimeType(), Consts.UTF_8)));
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
public Response post(String url, byte[] bytes) throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
method.setEntity(new ByteArrayEntity(bytes, ContentType.create(
|
||||
ContentType.MULTIPART_FORM_DATA.getMimeType(), Consts.UTF_8)));
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
public Response post(String url, File file) throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
method.setEntity(new FileEntity(file, ContentType.create(
|
||||
ContentType.APPLICATION_OCTET_STREAM.getMimeType(),
|
||||
Consts.UTF_8)));
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
public Response post(String url, PartParameter... paramters)
|
||||
throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
MultipartEntity entity = new MultipartEntity();
|
||||
for (PartParameter paramter : paramters) {
|
||||
entity.addPart(paramter.getName(), paramter.getContentBody());
|
||||
}
|
||||
method.setEntity(entity);
|
||||
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
protected Response doRequest(HttpRequestBase request)
|
||||
throws WeixinException {
|
||||
Response response = null;
|
||||
try {
|
||||
HttpResponse httpResponse = client.execute(request);
|
||||
StatusLine statusLine = httpResponse.getStatusLine();
|
||||
HttpEntity httpEntity = httpResponse.getEntity();
|
||||
int status = statusLine.getStatusCode();
|
||||
if (status != HttpStatus.SC_OK) {
|
||||
throw new WeixinException(Integer.toString(status),
|
||||
"request fail");
|
||||
}
|
||||
// 301或者302
|
||||
if (status == HttpStatus.SC_MOVED_PERMANENTLY
|
||||
|| status == HttpStatus.SC_MOVED_TEMPORARILY) {
|
||||
throw new WeixinException(Integer.toString(status),
|
||||
String.format("the page was redirected to %s",
|
||||
httpResponse.getFirstHeader("location")));
|
||||
}
|
||||
|
||||
byte[] data = EntityUtils.toByteArray(httpEntity);
|
||||
response = new Response();
|
||||
response.setBody(data);
|
||||
response.setStatusCode(status);
|
||||
response.setStatusText(statusLine.getReasonPhrase());
|
||||
response.setStream(new ByteArrayInputStream(data));
|
||||
response.setText(new String(data, Consts.UTF_8));
|
||||
EntityUtils.consume(httpEntity);
|
||||
Header contentType = httpResponse
|
||||
.getFirstHeader(HttpHeaders.CONTENT_TYPE);
|
||||
Header disposition = httpResponse
|
||||
.getFirstHeader("Content-disposition");
|
||||
// json
|
||||
if (contentType.getValue().contains(
|
||||
ContentType.APPLICATION_JSON.getMimeType())
|
||||
|| (disposition != null && disposition.getValue().indexOf(
|
||||
".json") > 0)) {
|
||||
checkJson(response);
|
||||
} else if (contentType.getValue().contains(
|
||||
ContentType.TEXT_XML.getMimeType())) {
|
||||
checkXml(response);
|
||||
} else if (contentType.getValue().contains(
|
||||
ContentType.TEXT_PLAIN.getMimeType())
|
||||
|| contentType.getValue().contains(
|
||||
ContentType.TEXT_HTML.getMimeType())) {
|
||||
try {
|
||||
checkJson(response);
|
||||
return response;
|
||||
} catch (JSONException e) {
|
||||
;
|
||||
}
|
||||
try {
|
||||
checkXml(response);
|
||||
return response;
|
||||
} catch (CannotResolveClassException ex) {
|
||||
;
|
||||
}
|
||||
throw new WeixinException(response.getAsString());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
request.releaseConnection();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
private void checkJson(Response response) throws WeixinException {
|
||||
JsonResult jsonResult = response.getAsJsonResult();
|
||||
response.setJsonResult(true);
|
||||
if (jsonResult.getCode() != 0) {
|
||||
if (StringUtil.isBlank(jsonResult.getDesc())) {
|
||||
jsonResult.setDesc(ErrorUtil.getText(Integer
|
||||
.toString(jsonResult.getCode())));
|
||||
}
|
||||
throw new WeixinException(Integer.toString(jsonResult.getCode()),
|
||||
jsonResult.getDesc());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkXml(Response response) throws WeixinException {
|
||||
XmlResult xmlResult = null;
|
||||
try {
|
||||
xmlResult = response.getAsXmlResult();
|
||||
} catch (CannotResolveClassException ex) {
|
||||
// <?xml><root><data..../data></root>
|
||||
String newXml = response.getAsString()
|
||||
.replaceFirst("<root>", "<xml>")
|
||||
.replaceFirst("<retcode>", "<return_code>")
|
||||
.replaceFirst("</retcode>", "</return_code>")
|
||||
.replaceFirst("<retmsg>", "<return_msg>")
|
||||
.replaceFirst("</retmsg>", "</return_msg>")
|
||||
.replaceFirst("</root>", "</xml>");
|
||||
response.setText(newXml);
|
||||
xmlResult = response.getAsXmlResult();
|
||||
}
|
||||
response.setXmlResult(true);
|
||||
if (xmlResult.getReturnCode().equals("0")) {
|
||||
return;
|
||||
}
|
||||
if (!xmlResult.getReturnCode().equalsIgnoreCase(
|
||||
com.foxinmy.weixin4j.model.Consts.SUCCESS)) {
|
||||
throw new WeixinException(xmlResult.getReturnCode(),
|
||||
xmlResult.getReturnMsg());
|
||||
}
|
||||
if (!xmlResult.getResultCode().equalsIgnoreCase(
|
||||
com.foxinmy.weixin4j.model.Consts.SUCCESS)) {
|
||||
throw new WeixinException(xmlResult.getErrCode(),
|
||||
xmlResult.getErrCodeDes());
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* HTTP 请求
|
||||
*
|
||||
* @className HttpRequest
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public interface HttpRequest extends HttpMessage {
|
||||
|
||||
/**
|
||||
* 请求方式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
HttpMethod getMethod();
|
||||
|
||||
/**
|
||||
* 请求路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
URI getURI();
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
HttpParams getParams();
|
||||
|
||||
/**
|
||||
* 新增表头
|
||||
*
|
||||
* @param header
|
||||
*/
|
||||
void addHeader(Header header);
|
||||
|
||||
/**
|
||||
* 移除表头
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
boolean removeHeader(String name);
|
||||
|
||||
/**
|
||||
* 移除表头
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
boolean removeHeader(Header name);
|
||||
}
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
/**
|
||||
* HTTP 响应
|
||||
*
|
||||
* @className HttpResponse
|
||||
* @author jy
|
||||
* @date 2015年5月30日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class HttpResponse extends AbstractHttpMessage implements HttpMessage {
|
||||
|
||||
private HttpVersion httpVersion;
|
||||
private StatusLine statusLine;
|
||||
private byte[] content;
|
||||
|
||||
@Override
|
||||
public HttpVersion getProtocolVersion() {
|
||||
return httpVersion;
|
||||
}
|
||||
|
||||
public StatusLine getStatusLine() {
|
||||
return statusLine;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setStatusLine(StatusLine statusLine) {
|
||||
this.statusLine = statusLine;
|
||||
}
|
||||
|
||||
public void setContent(byte[] content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public HttpVersion getHttpVersion() {
|
||||
return httpVersion;
|
||||
}
|
||||
|
||||
public void setHttpVersion(HttpVersion httpVersion) {
|
||||
this.httpVersion = httpVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HttpResponse [httpVersion=" + httpVersion + ", statusLine="
|
||||
+ statusLine + "]";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
/**
|
||||
* Constants enumerating the HTTP status codes. All status codes defined in
|
||||
* RFC1945 (HTTP/1.0), RFC2616 (HTTP/1.1), and RFC2518 (WebDAV) are listed.
|
||||
*
|
||||
* @see StatusLine
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class HttpStatus {
|
||||
|
||||
// --- 1xx Informational ---
|
||||
|
||||
/** <tt>100 Continue</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_CONTINUE = 100;
|
||||
/** <tt>101 Switching Protocols</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_SWITCHING_PROTOCOLS = 101;
|
||||
/** <tt>102 Processing</tt> (WebDAV - RFC 2518) */
|
||||
public static final int SC_PROCESSING = 102;
|
||||
|
||||
// --- 2xx Success ---
|
||||
|
||||
/** <tt>200 OK</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_OK = 200;
|
||||
/** <tt>201 Created</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_CREATED = 201;
|
||||
/** <tt>202 Accepted</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_ACCEPTED = 202;
|
||||
/** <tt>203 Non Authoritative Information</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
|
||||
/** <tt>204 No Content</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_NO_CONTENT = 204;
|
||||
/** <tt>205 Reset Content</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_RESET_CONTENT = 205;
|
||||
/** <tt>206 Partial Content</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_PARTIAL_CONTENT = 206;
|
||||
/**
|
||||
* <tt>207 Multi-Status</tt> (WebDAV - RFC 2518) or <tt>207 Partial Update
|
||||
* OK</tt> (HTTP/1.1 - draft-ietf-http-v11-spec-rev-01?)
|
||||
*/
|
||||
public static final int SC_MULTI_STATUS = 207;
|
||||
|
||||
// --- 3xx Redirection ---
|
||||
|
||||
/** <tt>300 Mutliple Choices</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_MULTIPLE_CHOICES = 300;
|
||||
/** <tt>301 Moved Permanently</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_MOVED_PERMANENTLY = 301;
|
||||
/**
|
||||
* <tt>302 Moved Temporarily</tt> (Sometimes <tt>Found</tt>) (HTTP/1.0 - RFC
|
||||
* 1945)
|
||||
*/
|
||||
public static final int SC_MOVED_TEMPORARILY = 302;
|
||||
/** <tt>303 See Other</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_SEE_OTHER = 303;
|
||||
/** <tt>304 Not Modified</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_NOT_MODIFIED = 304;
|
||||
/** <tt>305 Use Proxy</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_USE_PROXY = 305;
|
||||
/** <tt>307 Temporary Redirect</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_TEMPORARY_REDIRECT = 307;
|
||||
|
||||
// --- 4xx Client Error ---
|
||||
|
||||
/** <tt>400 Bad Request</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_BAD_REQUEST = 400;
|
||||
/** <tt>401 Unauthorized</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_UNAUTHORIZED = 401;
|
||||
/** <tt>402 Payment Required</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_PAYMENT_REQUIRED = 402;
|
||||
/** <tt>403 Forbidden</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_FORBIDDEN = 403;
|
||||
/** <tt>404 Not Found</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_NOT_FOUND = 404;
|
||||
/** <tt>405 Method Not Allowed</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_METHOD_NOT_ALLOWED = 405;
|
||||
/** <tt>406 Not Acceptable</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_NOT_ACCEPTABLE = 406;
|
||||
/** <tt>407 Proxy Authentication Required</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
|
||||
/** <tt>408 Request Timeout</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_REQUEST_TIMEOUT = 408;
|
||||
/** <tt>409 Conflict</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_CONFLICT = 409;
|
||||
/** <tt>410 Gone</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_GONE = 410;
|
||||
/** <tt>411 Length Required</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_LENGTH_REQUIRED = 411;
|
||||
/** <tt>412 Precondition Failed</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_PRECONDITION_FAILED = 412;
|
||||
/** <tt>413 Request Entity Too Large</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_REQUEST_TOO_LONG = 413;
|
||||
/** <tt>414 Request-URI Too Long</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_REQUEST_URI_TOO_LONG = 414;
|
||||
/** <tt>415 Unsupported Media Type</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
|
||||
/** <tt>416 Requested Range Not Satisfiable</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
|
||||
/** <tt>417 Expectation Failed</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_EXPECTATION_FAILED = 417;
|
||||
|
||||
/**
|
||||
* Static constant for a 418 error. <tt>418 Unprocessable Entity</tt>
|
||||
* (WebDAV drafts?) or <tt>418 Reauthentication Required</tt> (HTTP/1.1
|
||||
* drafts?)
|
||||
*/
|
||||
// not used
|
||||
// public static final int SC_UNPROCESSABLE_ENTITY = 418;
|
||||
|
||||
/**
|
||||
* Static constant for a 419 error.
|
||||
* <tt>419 Insufficient Space on Resource</tt> (WebDAV -
|
||||
* draft-ietf-webdav-protocol-05?) or
|
||||
* <tt>419 Proxy Reauthentication Required</tt> (HTTP/1.1 drafts?)
|
||||
*/
|
||||
public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419;
|
||||
/**
|
||||
* Static constant for a 420 error. <tt>420 Method Failure</tt> (WebDAV -
|
||||
* draft-ietf-webdav-protocol-05?)
|
||||
*/
|
||||
public static final int SC_METHOD_FAILURE = 420;
|
||||
/** <tt>422 Unprocessable Entity</tt> (WebDAV - RFC 2518) */
|
||||
public static final int SC_UNPROCESSABLE_ENTITY = 422;
|
||||
/** <tt>423 Locked</tt> (WebDAV - RFC 2518) */
|
||||
public static final int SC_LOCKED = 423;
|
||||
/** <tt>424 Failed Dependency</tt> (WebDAV - RFC 2518) */
|
||||
public static final int SC_FAILED_DEPENDENCY = 424;
|
||||
|
||||
// --- 5xx Server Error ---
|
||||
|
||||
/** <tt>500 Server Error</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_INTERNAL_SERVER_ERROR = 500;
|
||||
/** <tt>501 Not Implemented</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_NOT_IMPLEMENTED = 501;
|
||||
/** <tt>502 Bad Gateway</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_BAD_GATEWAY = 502;
|
||||
/** <tt>503 Service Unavailable</tt> (HTTP/1.0 - RFC 1945) */
|
||||
public static final int SC_SERVICE_UNAVAILABLE = 503;
|
||||
/** <tt>504 Gateway Timeout</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_GATEWAY_TIMEOUT = 504;
|
||||
/** <tt>505 HTTP Version Not Supported</tt> (HTTP/1.1 - RFC 2616) */
|
||||
public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
|
||||
|
||||
/** <tt>507 Insufficient Storage</tt> (WebDAV - RFC 2518) */
|
||||
public static final int SC_INSUFFICIENT_STORAGE = 507;
|
||||
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* reference of apache pivot
|
||||
*
|
||||
* @className HttpVersion
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class HttpVersion implements Comparable<HttpVersion> {
|
||||
|
||||
private static final Pattern VERSION_PATTERN = Pattern
|
||||
.compile("(\\S+)/(\\d+)\\.(\\d+)");
|
||||
|
||||
public static final String HTTP_1_0_STRING = "HTTP/1.0";
|
||||
public static final String HTTP_1_1_STRING = "HTTP/1.1";
|
||||
|
||||
/**
|
||||
* HTTP/1.0
|
||||
*/
|
||||
public static final HttpVersion HTTP_1_0 = new HttpVersion("HTTP", 1, 0,
|
||||
false);
|
||||
|
||||
/**
|
||||
* HTTP/1.1
|
||||
*/
|
||||
public static final HttpVersion HTTP_1_1 = new HttpVersion("HTTP", 1, 1,
|
||||
true);
|
||||
|
||||
private final String protocol;
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final boolean keepAlive;
|
||||
private final String text;
|
||||
|
||||
public HttpVersion(String text, boolean keepAlive) {
|
||||
if (text == null) {
|
||||
throw new NullPointerException("text");
|
||||
}
|
||||
|
||||
text = text.trim().toUpperCase();
|
||||
if (text.isEmpty()) {
|
||||
throw new IllegalArgumentException("empty text");
|
||||
}
|
||||
Matcher m = VERSION_PATTERN.matcher(text);
|
||||
if (!m.matches()) {
|
||||
throw new IllegalArgumentException("invalid version format: "
|
||||
+ text);
|
||||
}
|
||||
this.protocol = m.group(1);
|
||||
this.major = Integer.parseInt(m.group(2));
|
||||
this.minor = Integer.parseInt(m.group(3));
|
||||
this.keepAlive = keepAlive;
|
||||
this.text = protocol + '/' + major + '.' + minor;
|
||||
}
|
||||
|
||||
public HttpVersion(String protocol, int major, int minor, boolean keepAlive) {
|
||||
this.protocol = protocol;
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.keepAlive = keepAlive;
|
||||
this.text = protocol + '/' + major + '.' + minor;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public int getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
public int getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
public boolean isKeepAlive() {
|
||||
return keepAlive;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (protocol.hashCode() * 31 + major) * 31 + minor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof HttpVersion)) {
|
||||
return false;
|
||||
}
|
||||
HttpVersion that = (HttpVersion) o;
|
||||
return minor == that.minor && major == that.major
|
||||
&& protocol.equals(that.protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(HttpVersion o) {
|
||||
int v = protocol.compareTo(o.protocol);
|
||||
if (v != 0) {
|
||||
return v;
|
||||
}
|
||||
v = major - o.major;
|
||||
if (v != 0) {
|
||||
return v;
|
||||
}
|
||||
return minor - o.minor;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class NameValue implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4557003825642138566L;
|
||||
|
||||
private final String name;
|
||||
private final String value;
|
||||
|
||||
public NameValue(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
public class Parameter {
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Parameter() {
|
||||
|
||||
}
|
||||
|
||||
public Parameter(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String toGetPara() {
|
||||
try {
|
||||
return String.format("&%s=%s", name,
|
||||
URLEncoder.encode(value, Consts.UTF_8.name()));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return String.format("&%s=%s", name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public NameValuePair toPostPara() {
|
||||
try {
|
||||
return new BasicNameValuePair(name, URLEncoder.encode(value,
|
||||
Consts.UTF_8.name()));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return new BasicNameValuePair(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("[Parameter name=%s, value=%s]", name, value);
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import org.apache.http.entity.mime.content.ContentBody;
|
||||
|
||||
public class PartParameter {
|
||||
private String name;
|
||||
private ContentBody contentBody;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ContentBody getContentBody() {
|
||||
return contentBody;
|
||||
}
|
||||
|
||||
public void setContentBody(ContentBody contentBody) {
|
||||
this.contentBody = contentBody;
|
||||
}
|
||||
|
||||
public PartParameter(String name, ContentBody contentBody) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.contentBody = contentBody;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PartParameter [name=" + name + ", contentBody=" + contentBody + "]";
|
||||
}
|
||||
}
|
||||
@ -1,110 +0,0 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
public class Response {
|
||||
|
||||
private String text;
|
||||
private int statusCode;
|
||||
private String statusText;
|
||||
private byte[] body;
|
||||
private InputStream stream;
|
||||
private boolean isJsonResult;
|
||||
private boolean isXmlResult;
|
||||
|
||||
public Response() {
|
||||
}
|
||||
|
||||
public Response(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void setJsonResult(boolean isJsonResult) {
|
||||
this.isJsonResult = isJsonResult;
|
||||
}
|
||||
|
||||
public void setXmlResult(boolean isXmlResult) {
|
||||
this.isXmlResult = isXmlResult;
|
||||
}
|
||||
|
||||
public String getAsString() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public JsonResult getAsJsonResult() {
|
||||
return JSON.parseObject(text, JsonResult.class);
|
||||
}
|
||||
|
||||
public JSONObject getAsJson() {
|
||||
return JSON.parseObject(text);
|
||||
}
|
||||
|
||||
public <T> T getAsObject(TypeReference<T> typeReference) {
|
||||
if (isJsonResult) {
|
||||
return JSON.parseObject(text, typeReference);
|
||||
}
|
||||
if (isXmlResult) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<T> clazz = (Class<T>) typeReference.getType();
|
||||
return XmlStream.get(text, clazz);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public XmlResult getAsXmlResult() {
|
||||
return XmlStream.get(text, XmlResult.class);
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public void setStatusCode(int statusCode) {
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public String getStatusText() {
|
||||
return statusText;
|
||||
}
|
||||
|
||||
public void setStatusText(String statusText) {
|
||||
this.statusText = statusText;
|
||||
}
|
||||
|
||||
public byte[] getBody() {
|
||||
return (byte[]) body.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* May expose internal representation by incorporating reference to mutable
|
||||
* object
|
||||
*/
|
||||
public void setBody(byte[] body) {
|
||||
this.body = (byte[]) body.clone();
|
||||
}
|
||||
|
||||
public InputStream getStream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
public void setStream(InputStream stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Response [text=" + text + ", statusCode=" + statusCode
|
||||
+ ", statusText=" + statusText + ", stream=" + stream
|
||||
+ ", isJsonResult=" + isJsonResult + ", isXmlResult="
|
||||
+ isXmlResult + "]";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 响应处理
|
||||
*
|
||||
* @className ResponseHandler
|
||||
* @author jy
|
||||
* @date 2015年5月30日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public interface ResponseHandler<T> {
|
||||
T handleResponse(HttpResponse response) throws IOException;
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
import org.apache.http.conn.scheme.SchemeSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
|
||||
/**
|
||||
* ssl请求
|
||||
*
|
||||
* @className SSLHttpRequest
|
||||
* @author jy
|
||||
* @date 2014年11月6日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class SSLHttpRequest extends HttpRequest {
|
||||
|
||||
public SSLHttpRequest(String password, InputStream inputStream) {
|
||||
super();
|
||||
try {
|
||||
KeyStore trustStore = KeyStore
|
||||
.getInstance(com.foxinmy.weixin4j.model.Consts.PKCS12);
|
||||
trustStore.load(inputStream, password.toCharArray());
|
||||
SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore,
|
||||
password);
|
||||
client.getConnectionManager().getSchemeRegistry()
|
||||
.register(new Scheme("https", 443, socketFactory));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SSLHttpRequest(SSLContext sslContext) {
|
||||
super();
|
||||
SchemeSocketFactory socketFactory = new SSLSocketFactory(sslContext);
|
||||
client.getConnectionManager().getSchemeRegistry()
|
||||
.register(new Scheme("https", 443, socketFactory));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,200 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import com.foxinmy.weixin4j.http.entity.HttpEntity;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
|
||||
/**
|
||||
* HTTP 简单实现
|
||||
*
|
||||
* @className SimpleHttpClient
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class SimpleHttpClient implements HttpClient {
|
||||
|
||||
protected HostnameVerifier createHostnameVerifier() {
|
||||
return new HostnameVerifier() {
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected X509TrustManager createX509TrustManager() {
|
||||
return new X509TrustManager() {
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(
|
||||
X509Certificate[] paramArrayOfX509Certificate,
|
||||
String paramString) throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(
|
||||
X509Certificate[] paramArrayOfX509Certificate,
|
||||
String paramString) throws CertificateException {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected HttpURLConnection createHttpConnection(URI uri)
|
||||
throws IOException {
|
||||
URL url = uri.toURL();
|
||||
if (uri.getScheme().equals("https")) {
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url
|
||||
.openConnection();
|
||||
SSLContext sslContext = null;
|
||||
try {
|
||||
sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null,
|
||||
new X509TrustManager[] { createX509TrustManager() },
|
||||
new java.security.SecureRandom());
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
connection.setSSLSocketFactory(sslContext.getSocketFactory());
|
||||
connection.setHostnameVerifier(createHostnameVerifier());
|
||||
return connection;
|
||||
} else {
|
||||
return (HttpURLConnection) url.openConnection();
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, String> createDefualtHeader() {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("User-Agent", "simple httpclient/java 1.5");
|
||||
params.put("Accept", "text/xml,text/javascript");
|
||||
params.put("Accept-Charset", Consts.UTF_8.name());
|
||||
params.put("Accept-Encoding", Consts.UTF_8.name());
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResponse execute(HttpRequest request) throws IOException {
|
||||
// create connection object
|
||||
HttpURLConnection connection = createHttpConnection(request.getURI());
|
||||
// set parameters
|
||||
HttpParams params = request.getParams();
|
||||
connection.setRequestMethod(request.getMethod().name());
|
||||
connection.setAllowUserInteraction(params.getAllowUserInteraction());
|
||||
connection.setConnectTimeout(params.getConnectTimeout());
|
||||
connection.setReadTimeout(params.getReadTimeout());
|
||||
connection.setIfModifiedSince(params.getIfmodifiedsince());
|
||||
connection.setInstanceFollowRedirects(params.getFollowRedirects());
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
// set headers
|
||||
Header[] headers = request.getAllHeaders();
|
||||
for (Header header : headers) {
|
||||
connection.setRequestProperty(header.getName(), header.getValue());
|
||||
}
|
||||
for (Iterator<Entry<String, String>> headerIterator = createDefualtHeader()
|
||||
.entrySet().iterator(); headerIterator.hasNext();) {
|
||||
Entry<String, String> header = headerIterator.next();
|
||||
connection.setRequestProperty(header.getKey(), header.getValue());
|
||||
}
|
||||
HttpEntity httpEntity = null;
|
||||
if (request instanceof HttpEntityRequest) {
|
||||
httpEntity = ((HttpEntityRequest) request).getEntity();
|
||||
connection.setUseCaches(false);
|
||||
connection.setFixedLengthStreamingMode(httpEntity
|
||||
.getContentLength());
|
||||
connection.setRequestProperty("Content-Type", httpEntity
|
||||
.getContentType().getMimeType());
|
||||
}
|
||||
connection.connect();
|
||||
// open stream
|
||||
if (httpEntity != null) {
|
||||
OutputStream output = connection.getOutputStream();
|
||||
httpEntity.writeTo(output);
|
||||
output.flush();
|
||||
output.close();
|
||||
}
|
||||
// building response object
|
||||
StatusLine statusLine = new StatusLine(connection.getResponseCode(),
|
||||
connection.getResponseMessage());
|
||||
byte[] content = null;
|
||||
if (statusLine.getStatusCode() < 300) {
|
||||
ByteArrayOutputStream os = null;
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = connection.getInputStream();
|
||||
os = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[4096];
|
||||
int n = 0;
|
||||
while (-1 != (n = is.read(buffer))) {
|
||||
os.write(buffer, 0, n);
|
||||
}
|
||||
content = os.toByteArray();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
} finally {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
HttpResponse response = new HttpResponse();
|
||||
String httpVersion = connection.getHeaderField(null);
|
||||
if (httpVersion != null) {
|
||||
if (httpVersion.contains(HttpVersion.HTTP_1_0_STRING)) {
|
||||
response.setHttpVersion(HttpVersion.HTTP_1_0);
|
||||
} else if (httpVersion.contains(HttpVersion.HTTP_1_1_STRING)) {
|
||||
response.setHttpVersion(HttpVersion.HTTP_1_1);
|
||||
} else {
|
||||
response.setHttpVersion(new HttpVersion(httpVersion, true));
|
||||
}
|
||||
}
|
||||
List<Header> responseHeaders = new ArrayList<Header>();
|
||||
Map<String, List<String>> headerFields = connection.getHeaderFields();
|
||||
for (Iterator<Entry<String, List<String>>> headerIterator = headerFields
|
||||
.entrySet().iterator(); headerIterator.hasNext();) {
|
||||
Entry<String, List<String>> headerEntry = headerIterator.next();
|
||||
for (String value : headerEntry.getValue()) {
|
||||
responseHeaders.add(new Header(headerEntry.getKey(), value));
|
||||
}
|
||||
}
|
||||
response.setHeaders(responseHeaders.toArray(new Header[responseHeaders
|
||||
.size()]));
|
||||
response.setStatusLine(statusLine);
|
||||
response.setContent(content);
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(HttpRequest request,
|
||||
ResponseHandler<? extends T> handler) throws IOException {
|
||||
return handler.handleResponse(execute(request));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 状态码
|
||||
*
|
||||
* @className StatusLine
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class StatusLine implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4182333834588893408L;
|
||||
|
||||
private final int statusCode;
|
||||
private final String statusText;
|
||||
|
||||
public StatusLine(int statusCode, String statusText) {
|
||||
this.statusCode = statusCode;
|
||||
this.statusText = statusText;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public String getStatusText() {
|
||||
return statusText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return statusCode + "," + statusText;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
|
||||
/**
|
||||
* 键值对参数
|
||||
*
|
||||
* @className UrlEncodeParameter
|
||||
* @author jy
|
||||
* @date 2015年5月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class UrlEncodeParameter extends NameValue {
|
||||
|
||||
private static final long serialVersionUID = -115491642760990655L;
|
||||
|
||||
public UrlEncodeParameter(String name, String value) {
|
||||
super(name, value);
|
||||
}
|
||||
|
||||
public String encodingParameter() {
|
||||
try {
|
||||
return String.format("&%s=%s", getName(),
|
||||
URLEncoder.encode(getValue(), Consts.UTF_8.name()));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return String.format("&%s=%s", getName(), getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("[HttpParameter name=%s, value=%s]", getName(),
|
||||
getValue());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class AbstractContentBody implements ContentBody {
|
||||
|
||||
private final String mimeType;
|
||||
private final String mediaType;
|
||||
private final String subType;
|
||||
|
||||
public AbstractContentBody(final String mimeType) {
|
||||
super();
|
||||
if (mimeType == null) {
|
||||
throw new IllegalArgumentException("MIME type may not be null");
|
||||
}
|
||||
this.mimeType = mimeType;
|
||||
int i = mimeType.indexOf('/');
|
||||
if (i != -1) {
|
||||
this.mediaType = mimeType.substring(0, i);
|
||||
this.subType = mimeType.substring(i + 1);
|
||||
} else {
|
||||
this.mediaType = mimeType;
|
||||
this.subType = null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return this.mimeType;
|
||||
}
|
||||
|
||||
public String getMediaType() {
|
||||
return this.mediaType;
|
||||
}
|
||||
|
||||
public String getSubType() {
|
||||
return this.subType;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Body part that is built using a byte array containing a file.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public class ByteArrayBody extends AbstractContentBody {
|
||||
|
||||
/**
|
||||
* The contents of the file contained in this part.
|
||||
*/
|
||||
private final byte[] data;
|
||||
|
||||
/**
|
||||
* The name of the file contained in this part.
|
||||
*/
|
||||
private final String filename;
|
||||
|
||||
/**
|
||||
* Creates a new ByteArrayBody.
|
||||
*
|
||||
* @param data The contents of the file contained in this part.
|
||||
* @param mimeType The mime type of the file contained in this part.
|
||||
* @param filename The name of the file contained in this part.
|
||||
*/
|
||||
public ByteArrayBody(final byte[] data, final String mimeType, final String filename) {
|
||||
super(mimeType);
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("byte[] may not be null");
|
||||
}
|
||||
this.data = data;
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ByteArrayBody.
|
||||
*
|
||||
* @param data The contents of the file contained in this part.
|
||||
* @param filename The name of the file contained in this part.
|
||||
*/
|
||||
public ByteArrayBody(final byte[] data, final String filename) {
|
||||
this(data, "application/octet-stream", filename);
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
public void writeTo(final OutputStream out) throws IOException {
|
||||
out.write(data);
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getTransferEncoding() {
|
||||
return MIME.ENC_BINARY;
|
||||
}
|
||||
|
||||
public long getContentLength() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,345 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* A resizable byte array.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class ByteArrayBuffer implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4359112959524048036L;
|
||||
|
||||
private byte[] buffer;
|
||||
private int len;
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link ByteArrayBuffer} with the given initial
|
||||
* capacity.
|
||||
*
|
||||
* @param capacity the capacity
|
||||
*/
|
||||
public ByteArrayBuffer(int capacity) {
|
||||
super();
|
||||
if (capacity < 0) {
|
||||
throw new IllegalArgumentException("Buffer capacity may not be negative");
|
||||
}
|
||||
this.buffer = new byte[capacity];
|
||||
}
|
||||
|
||||
private void expand(int newlen) {
|
||||
byte newbuffer[] = new byte[Math.max(this.buffer.length << 1, newlen)];
|
||||
System.arraycopy(this.buffer, 0, newbuffer, 0, this.len);
|
||||
this.buffer = newbuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends <code>len</code> bytes to this buffer from the given source
|
||||
* array starting at index <code>off</code>. The capacity of the buffer
|
||||
* is increased, if necessary, to accommodate all <code>len</code> bytes.
|
||||
*
|
||||
* @param b the bytes to be appended.
|
||||
* @param off the index of the first byte to append.
|
||||
* @param len the number of bytes to append.
|
||||
* @throws IndexOutOfBoundsException if <code>off</code> if out of
|
||||
* range, <code>len</code> is negative, or
|
||||
* <code>off</code> + <code>len</code> is out of range.
|
||||
*/
|
||||
public void append(final byte[] b, int off, int len) {
|
||||
if (b == null) {
|
||||
return;
|
||||
}
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) < 0) || ((off + len) > b.length)) {
|
||||
throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length);
|
||||
}
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
int newlen = this.len + len;
|
||||
if (newlen > this.buffer.length) {
|
||||
expand(newlen);
|
||||
}
|
||||
System.arraycopy(b, off, this.buffer, this.len, len);
|
||||
this.len = newlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends <code>b</code> byte to this buffer. The capacity of the buffer
|
||||
* is increased, if necessary, to accommodate the additional byte.
|
||||
*
|
||||
* @param b the byte to be appended.
|
||||
*/
|
||||
public void append(int b) {
|
||||
int newlen = this.len + 1;
|
||||
if (newlen > this.buffer.length) {
|
||||
expand(newlen);
|
||||
}
|
||||
this.buffer[this.len] = (byte)b;
|
||||
this.len = newlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends <code>len</code> chars to this buffer from the given source
|
||||
* array starting at index <code>off</code>. The capacity of the buffer
|
||||
* is increased if necessary to accommodate all <code>len</code> chars.
|
||||
* <p>
|
||||
* The chars are converted to bytes using simple cast.
|
||||
*
|
||||
* @param b the chars to be appended.
|
||||
* @param off the index of the first char to append.
|
||||
* @param len the number of bytes to append.
|
||||
* @throws IndexOutOfBoundsException if <code>off</code> if out of
|
||||
* range, <code>len</code> is negative, or
|
||||
* <code>off</code> + <code>len</code> is out of range.
|
||||
*/
|
||||
public void append(final char[] b, int off, int len) {
|
||||
if (b == null) {
|
||||
return;
|
||||
}
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) < 0) || ((off + len) > b.length)) {
|
||||
throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length);
|
||||
}
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
int oldlen = this.len;
|
||||
int newlen = oldlen + len;
|
||||
if (newlen > this.buffer.length) {
|
||||
expand(newlen);
|
||||
}
|
||||
for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) {
|
||||
this.buffer[i2] = (byte) b[i1];
|
||||
}
|
||||
this.len = newlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends <code>len</code> chars to this buffer from the given source
|
||||
* char array buffer starting at index <code>off</code>. The capacity
|
||||
* of the buffer is increased if necessary to accommodate all
|
||||
* <code>len</code> chars.
|
||||
* <p>
|
||||
* The chars are converted to bytes using simple cast.
|
||||
*
|
||||
* @param b the chars to be appended.
|
||||
* @param off the index of the first char to append.
|
||||
* @param len the number of bytes to append.
|
||||
* @throws IndexOutOfBoundsException if <code>off</code> if out of
|
||||
* range, <code>len</code> is negative, or
|
||||
* <code>off</code> + <code>len</code> is out of range.
|
||||
*/
|
||||
public void append(final CharArrayBuffer b, int off, int len) {
|
||||
if (b == null) {
|
||||
return;
|
||||
}
|
||||
append(b.buffer(), off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears content of the buffer. The underlying byte array is not resized.
|
||||
*/
|
||||
public void clear() {
|
||||
this.len = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the content of this buffer to an array of bytes.
|
||||
*
|
||||
* @return byte array
|
||||
*/
|
||||
public byte[] toByteArray() {
|
||||
byte[] b = new byte[this.len];
|
||||
if (this.len > 0) {
|
||||
System.arraycopy(this.buffer, 0, b, 0, this.len);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>byte</code> value in this buffer at the specified
|
||||
* index. The index argument must be greater than or equal to
|
||||
* <code>0</code>, and less than the length of this buffer.
|
||||
*
|
||||
* @param i the index of the desired byte value.
|
||||
* @return the byte value at the specified index.
|
||||
* @throws IndexOutOfBoundsException if <code>index</code> is
|
||||
* negative or greater than or equal to {@link #length()}.
|
||||
*/
|
||||
public int byteAt(int i) {
|
||||
return this.buffer[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current capacity. The capacity is the amount of storage
|
||||
* available for newly appended bytes, beyond which an allocation
|
||||
* will occur.
|
||||
*
|
||||
* @return the current capacity
|
||||
*/
|
||||
public int capacity() {
|
||||
return this.buffer.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the buffer (byte count).
|
||||
*
|
||||
* @return the length of the buffer
|
||||
*/
|
||||
public int length() {
|
||||
return this.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the capacity is at least equal to the specified minimum.
|
||||
* If the current capacity is less than the argument, then a new internal
|
||||
* array is allocated with greater capacity. If the <code>required</code>
|
||||
* argument is non-positive, this method takes no action.
|
||||
*
|
||||
* @param required the minimum required capacity.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public void ensureCapacity(int required) {
|
||||
if (required <= 0) {
|
||||
return;
|
||||
}
|
||||
int available = this.buffer.length - this.len;
|
||||
if (required > available) {
|
||||
expand(this.len + required);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns reference to the underlying byte array.
|
||||
*
|
||||
* @return the byte array.
|
||||
*/
|
||||
public byte[] buffer() {
|
||||
return this.buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length of the buffer. The new length value is expected to be
|
||||
* less than the current capacity and greater than or equal to
|
||||
* <code>0</code>.
|
||||
*
|
||||
* @param len the new length
|
||||
* @throws IndexOutOfBoundsException if the
|
||||
* <code>len</code> argument is greater than the current
|
||||
* capacity of the buffer or less than <code>0</code>.
|
||||
*/
|
||||
public void setLength(int len) {
|
||||
if (len < 0 || len > this.buffer.length) {
|
||||
throw new IndexOutOfBoundsException("len: "+len+" < 0 or > buffer len: "+this.buffer.length);
|
||||
}
|
||||
this.len = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this buffer is empty, that is, its
|
||||
* {@link #length()} is equal to <code>0</code>.
|
||||
* @return <code>true</code> if this buffer is empty, <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return this.len == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this buffer is full, that is, its
|
||||
* {@link #length()} is equal to its {@link #capacity()}.
|
||||
* @return <code>true</code> if this buffer is full, <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isFull() {
|
||||
return this.len == this.buffer.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index within this buffer of the first occurrence of the
|
||||
* specified byte, starting the search at the specified
|
||||
* <code>beginIndex</code> and finishing at <code>endIndex</code>.
|
||||
* If no such byte occurs in this buffer within the specified bounds,
|
||||
* <code>-1</code> is returned.
|
||||
* <p>
|
||||
* There is no restriction on the value of <code>beginIndex</code> and
|
||||
* <code>endIndex</code>. If <code>beginIndex</code> is negative,
|
||||
* it has the same effect as if it were zero. If <code>endIndex</code> is
|
||||
* greater than {@link #length()}, it has the same effect as if it were
|
||||
* {@link #length()}. If the <code>beginIndex</code> is greater than
|
||||
* the <code>endIndex</code>, <code>-1</code> is returned.
|
||||
*
|
||||
* @param b the byte to search for.
|
||||
* @param beginIndex the index to start the search from.
|
||||
* @param endIndex the index to finish the search at.
|
||||
* @return the index of the first occurrence of the byte in the buffer
|
||||
* within the given bounds, or <code>-1</code> if the byte does
|
||||
* not occur.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public int indexOf(byte b, int beginIndex, int endIndex) {
|
||||
if (beginIndex < 0) {
|
||||
beginIndex = 0;
|
||||
}
|
||||
if (endIndex > this.len) {
|
||||
endIndex = this.len;
|
||||
}
|
||||
if (beginIndex > endIndex) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = beginIndex; i < endIndex; i++) {
|
||||
if (this.buffer[i] == b) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index within this buffer of the first occurrence of the
|
||||
* specified byte, starting the search at <code>0</code> and finishing
|
||||
* at {@link #length()}. If no such byte occurs in this buffer within
|
||||
* those bounds, <code>-1</code> is returned.
|
||||
*
|
||||
* @param b the byte to search for.
|
||||
* @return the index of the first occurrence of the byte in the
|
||||
* buffer, or <code>-1</code> if the byte does not occur.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public int indexOf(byte b) {
|
||||
return indexOf(b, 0, this.len);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,460 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A resizable char array.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class CharArrayBuffer implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6208952725094867135L;
|
||||
|
||||
private char[] buffer;
|
||||
private int len;
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link CharArrayBuffer} with the given initial
|
||||
* capacity.
|
||||
*
|
||||
* @param capacity the capacity
|
||||
*/
|
||||
public CharArrayBuffer(int capacity) {
|
||||
super();
|
||||
if (capacity < 0) {
|
||||
throw new IllegalArgumentException("Buffer capacity may not be negative");
|
||||
}
|
||||
this.buffer = new char[capacity];
|
||||
}
|
||||
|
||||
private void expand(int newlen) {
|
||||
char newbuffer[] = new char[Math.max(this.buffer.length << 1, newlen)];
|
||||
System.arraycopy(this.buffer, 0, newbuffer, 0, this.len);
|
||||
this.buffer = newbuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends <code>len</code> chars to this buffer from the given source
|
||||
* array starting at index <code>off</code>. The capacity of the buffer
|
||||
* is increased, if necessary, to accommodate all <code>len</code> chars.
|
||||
*
|
||||
* @param b the chars to be appended.
|
||||
* @param off the index of the first char to append.
|
||||
* @param len the number of chars to append.
|
||||
* @throws IndexOutOfBoundsException if <code>off</code> is out of
|
||||
* range, <code>len</code> is negative, or
|
||||
* <code>off</code> + <code>len</code> is out of range.
|
||||
*/
|
||||
public void append(final char[] b, int off, int len) {
|
||||
if (b == null) {
|
||||
return;
|
||||
}
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) < 0) || ((off + len) > b.length)) {
|
||||
throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length);
|
||||
}
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
int newlen = this.len + len;
|
||||
if (newlen > this.buffer.length) {
|
||||
expand(newlen);
|
||||
}
|
||||
System.arraycopy(b, off, this.buffer, this.len, len);
|
||||
this.len = newlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends chars of the given string to this buffer. The capacity of the
|
||||
* buffer is increased, if necessary, to accommodate all chars.
|
||||
*
|
||||
* @param str the string.
|
||||
*/
|
||||
public void append(String str) {
|
||||
if (str == null) {
|
||||
str = "null";
|
||||
}
|
||||
int strlen = str.length();
|
||||
int newlen = this.len + strlen;
|
||||
if (newlen > this.buffer.length) {
|
||||
expand(newlen);
|
||||
}
|
||||
str.getChars(0, strlen, this.buffer, this.len);
|
||||
this.len = newlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends <code>len</code> chars to this buffer from the given source
|
||||
* buffer starting at index <code>off</code>. The capacity of the
|
||||
* destination buffer is increased, if necessary, to accommodate all
|
||||
* <code>len</code> chars.
|
||||
*
|
||||
* @param b the source buffer to be appended.
|
||||
* @param off the index of the first char to append.
|
||||
* @param len the number of chars to append.
|
||||
* @throws IndexOutOfBoundsException if <code>off</code> is out of
|
||||
* range, <code>len</code> is negative, or
|
||||
* <code>off</code> + <code>len</code> is out of range.
|
||||
*/
|
||||
public void append(final CharArrayBuffer b, int off, int len) {
|
||||
if (b == null) {
|
||||
return;
|
||||
}
|
||||
append(b.buffer, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all chars to this buffer from the given source buffer starting
|
||||
* at index <code>0</code>. The capacity of the destination buffer is
|
||||
* increased, if necessary, to accommodate all {@link #length()} chars.
|
||||
*
|
||||
* @param b the source buffer to be appended.
|
||||
*/
|
||||
public void append(final CharArrayBuffer b) {
|
||||
if (b == null) {
|
||||
return;
|
||||
}
|
||||
append(b.buffer,0, b.len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends <code>ch</code> char to this buffer. The capacity of the buffer
|
||||
* is increased, if necessary, to accommodate the additional char.
|
||||
*
|
||||
* @param ch the char to be appended.
|
||||
*/
|
||||
public void append(char ch) {
|
||||
int newlen = this.len + 1;
|
||||
if (newlen > this.buffer.length) {
|
||||
expand(newlen);
|
||||
}
|
||||
this.buffer[this.len] = ch;
|
||||
this.len = newlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends <code>len</code> bytes to this buffer from the given source
|
||||
* array starting at index <code>off</code>. The capacity of the buffer
|
||||
* is increased, if necessary, to accommodate all <code>len</code> bytes.
|
||||
* <p>
|
||||
* The bytes are converted to chars using simple cast.
|
||||
*
|
||||
* @param b the bytes to be appended.
|
||||
* @param off the index of the first byte to append.
|
||||
* @param len the number of bytes to append.
|
||||
* @throws IndexOutOfBoundsException if <code>off</code> is out of
|
||||
* range, <code>len</code> is negative, or
|
||||
* <code>off</code> + <code>len</code> is out of range.
|
||||
*/
|
||||
public void append(final byte[] b, int off, int len) {
|
||||
if (b == null) {
|
||||
return;
|
||||
}
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) < 0) || ((off + len) > b.length)) {
|
||||
throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length);
|
||||
}
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
int oldlen = this.len;
|
||||
int newlen = oldlen + len;
|
||||
if (newlen > this.buffer.length) {
|
||||
expand(newlen);
|
||||
}
|
||||
for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) {
|
||||
this.buffer[i2] = (char) (b[i1] & 0xff);
|
||||
}
|
||||
this.len = newlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends <code>len</code> bytes to this buffer from the given source
|
||||
* array starting at index <code>off</code>. The capacity of the buffer
|
||||
* is increased, if necessary, to accommodate all <code>len</code> bytes.
|
||||
* <p>
|
||||
* The bytes are converted to chars using simple cast.
|
||||
*
|
||||
* @param b the bytes to be appended.
|
||||
* @param off the index of the first byte to append.
|
||||
* @param len the number of bytes to append.
|
||||
* @throws IndexOutOfBoundsException if <code>off</code> is out of
|
||||
* range, <code>len</code> is negative, or
|
||||
* <code>off</code> + <code>len</code> is out of range.
|
||||
*/
|
||||
public void append(final ByteArrayBuffer b, int off, int len) {
|
||||
if (b == null) {
|
||||
return;
|
||||
}
|
||||
append(b.buffer(), off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends chars of the textual representation of the given object to this
|
||||
* buffer. The capacity of the buffer is increased, if necessary, to
|
||||
* accommodate all chars.
|
||||
*
|
||||
* @param obj the object.
|
||||
*/
|
||||
public void append(final Object obj) {
|
||||
append(String.valueOf(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears content of the buffer. The underlying char array is not resized.
|
||||
*/
|
||||
public void clear() {
|
||||
this.len = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the content of this buffer to an array of chars.
|
||||
*
|
||||
* @return char array
|
||||
*/
|
||||
public char[] toCharArray() {
|
||||
char[] b = new char[this.len];
|
||||
if (this.len > 0) {
|
||||
System.arraycopy(this.buffer, 0, b, 0, this.len);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>char</code> value in this buffer at the specified
|
||||
* index. The index argument must be greater than or equal to
|
||||
* <code>0</code>, and less than the length of this buffer.
|
||||
*
|
||||
* @param i the index of the desired char value.
|
||||
* @return the char value at the specified index.
|
||||
* @throws IndexOutOfBoundsException if <code>index</code> is
|
||||
* negative or greater than or equal to {@link #length()}.
|
||||
*/
|
||||
public char charAt(int i) {
|
||||
return this.buffer[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns reference to the underlying char array.
|
||||
*
|
||||
* @return the char array.
|
||||
*/
|
||||
public char[] buffer() {
|
||||
return this.buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current capacity. The capacity is the amount of storage
|
||||
* available for newly appended chars, beyond which an allocation will
|
||||
* occur.
|
||||
*
|
||||
* @return the current capacity
|
||||
*/
|
||||
public int capacity() {
|
||||
return this.buffer.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the buffer (char count).
|
||||
*
|
||||
* @return the length of the buffer
|
||||
*/
|
||||
public int length() {
|
||||
return this.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the capacity is at least equal to the specified minimum.
|
||||
* If the current capacity is less than the argument, then a new internal
|
||||
* array is allocated with greater capacity. If the <code>required</code>
|
||||
* argument is non-positive, this method takes no action.
|
||||
*
|
||||
* @param required the minimum required capacity.
|
||||
*/
|
||||
public void ensureCapacity(int required) {
|
||||
if (required <= 0) {
|
||||
return;
|
||||
}
|
||||
int available = this.buffer.length - this.len;
|
||||
if (required > available) {
|
||||
expand(this.len + required);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length of the buffer. The new length value is expected to be
|
||||
* less than the current capacity and greater than or equal to
|
||||
* <code>0</code>.
|
||||
*
|
||||
* @param len the new length
|
||||
* @throws IndexOutOfBoundsException if the
|
||||
* <code>len</code> argument is greater than the current
|
||||
* capacity of the buffer or less than <code>0</code>.
|
||||
*/
|
||||
public void setLength(int len) {
|
||||
if (len < 0 || len > this.buffer.length) {
|
||||
throw new IndexOutOfBoundsException("len: "+len+" < 0 or > buffer len: "+this.buffer.length);
|
||||
}
|
||||
this.len = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this buffer is empty, that is, its
|
||||
* {@link #length()} is equal to <code>0</code>.
|
||||
* @return <code>true</code> if this buffer is empty, <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return this.len == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this buffer is full, that is, its
|
||||
* {@link #length()} is equal to its {@link #capacity()}.
|
||||
* @return <code>true</code> if this buffer is full, <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isFull() {
|
||||
return this.len == this.buffer.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index within this buffer of the first occurrence of the
|
||||
* specified character, starting the search at the specified
|
||||
* <code>beginIndex</code> and finishing at <code>endIndex</code>.
|
||||
* If no such character occurs in this buffer within the specified bounds,
|
||||
* <code>-1</code> is returned.
|
||||
* <p>
|
||||
* There is no restriction on the value of <code>beginIndex</code> and
|
||||
* <code>endIndex</code>. If <code>beginIndex</code> is negative,
|
||||
* it has the same effect as if it were zero. If <code>endIndex</code> is
|
||||
* greater than {@link #length()}, it has the same effect as if it were
|
||||
* {@link #length()}. If the <code>beginIndex</code> is greater than
|
||||
* the <code>endIndex</code>, <code>-1</code> is returned.
|
||||
*
|
||||
* @param ch the char to search for.
|
||||
* @param beginIndex the index to start the search from.
|
||||
* @param endIndex the index to finish the search at.
|
||||
* @return the index of the first occurrence of the character in the buffer
|
||||
* within the given bounds, or <code>-1</code> if the character does
|
||||
* not occur.
|
||||
*/
|
||||
public int indexOf(int ch, int beginIndex, int endIndex) {
|
||||
if (beginIndex < 0) {
|
||||
beginIndex = 0;
|
||||
}
|
||||
if (endIndex > this.len) {
|
||||
endIndex = this.len;
|
||||
}
|
||||
if (beginIndex > endIndex) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = beginIndex; i < endIndex; i++) {
|
||||
if (this.buffer[i] == ch) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index within this buffer of the first occurrence of the
|
||||
* specified character, starting the search at <code>0</code> and finishing
|
||||
* at {@link #length()}. If no such character occurs in this buffer within
|
||||
* those bounds, <code>-1</code> is returned.
|
||||
*
|
||||
* @param ch the char to search for.
|
||||
* @return the index of the first occurrence of the character in the
|
||||
* buffer, or <code>-1</code> if the character does not occur.
|
||||
*/
|
||||
public int indexOf(int ch) {
|
||||
return indexOf(ch, 0, this.len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a substring of this buffer. The substring begins at the specified
|
||||
* <code>beginIndex</code> and extends to the character at index
|
||||
* <code>endIndex - 1</code>.
|
||||
*
|
||||
* @param beginIndex the beginning index, inclusive.
|
||||
* @param endIndex the ending index, exclusive.
|
||||
* @return the specified substring.
|
||||
* @exception StringIndexOutOfBoundsException if the
|
||||
* <code>beginIndex</code> is negative, or
|
||||
* <code>endIndex</code> is larger than the length of this
|
||||
* buffer, or <code>beginIndex</code> is larger than
|
||||
* <code>endIndex</code>.
|
||||
*/
|
||||
public String substring(int beginIndex, int endIndex) {
|
||||
return new String(this.buffer, beginIndex, endIndex - beginIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a substring of this buffer with leading and trailing whitespace
|
||||
* omitted. The substring begins with the first non-whitespace character
|
||||
* from <code>beginIndex</code> and extends to the last
|
||||
* non-whitespace character with the index lesser than
|
||||
* <code>endIndex</code>.
|
||||
*
|
||||
* @param beginIndex the beginning index, inclusive.
|
||||
* @param endIndex the ending index, exclusive.
|
||||
* @return the specified substring.
|
||||
* @exception IndexOutOfBoundsException if the
|
||||
* <code>beginIndex</code> is negative, or
|
||||
* <code>endIndex</code> is larger than the length of this
|
||||
* buffer, or <code>beginIndex</code> is larger than
|
||||
* <code>endIndex</code>.
|
||||
*/
|
||||
public String substringTrimmed(int beginIndex, int endIndex) {
|
||||
if (beginIndex < 0) {
|
||||
throw new IndexOutOfBoundsException("Negative beginIndex: "+beginIndex);
|
||||
}
|
||||
if (endIndex > this.len) {
|
||||
throw new IndexOutOfBoundsException("endIndex: "+endIndex+" > length: "+this.len);
|
||||
}
|
||||
if (beginIndex > endIndex) {
|
||||
throw new IndexOutOfBoundsException("beginIndex: "+beginIndex+" > endIndex: "+endIndex);
|
||||
}
|
||||
while (beginIndex < endIndex && HTTP.isWhitespace(this.buffer[beginIndex])) {
|
||||
beginIndex++;
|
||||
}
|
||||
while (endIndex > beginIndex && HTTP.isWhitespace(this.buffer[endIndex - 1])) {
|
||||
endIndex--;
|
||||
}
|
||||
return new String(this.buffer, beginIndex, endIndex - beginIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(this.buffer, 0, this.len);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public interface ContentBody extends ContentDescriptor {
|
||||
|
||||
String getFilename();
|
||||
|
||||
void writeTo(OutputStream out) throws IOException;
|
||||
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
/**
|
||||
* Represents common content properties.
|
||||
*/
|
||||
public interface ContentDescriptor {
|
||||
|
||||
/**
|
||||
* Returns the body descriptors MIME type.
|
||||
* @see #getMediaType()
|
||||
* @see #getSubType()
|
||||
* @return The MIME type, which has been parsed from the
|
||||
* content-type definition. Must not be null, but
|
||||
* "text/plain", if no content-type was specified.
|
||||
*/
|
||||
String getMimeType();
|
||||
|
||||
/**
|
||||
* Gets the defaulted MIME media type for this content.
|
||||
* For example <code>TEXT</code>, <code>IMAGE</code>, <code>MULTIPART</code>
|
||||
* @see #getMimeType()
|
||||
* @return the MIME media type when content-type specified,
|
||||
* otherwise the correct default (<code>TEXT</code>)
|
||||
*/
|
||||
String getMediaType();
|
||||
|
||||
/**
|
||||
* Gets the defaulted MIME sub type for this content.
|
||||
* @see #getMimeType()
|
||||
* @return the MIME media type when content-type is specified,
|
||||
* otherwise the correct default (<code>PLAIN</code>)
|
||||
*/
|
||||
String getSubType();
|
||||
|
||||
/**
|
||||
* <p>The body descriptors character set, defaulted appropriately for the MIME type.</p>
|
||||
* <p>
|
||||
* For <code>TEXT</code> types, this will be defaulted to <code>us-ascii</code>.
|
||||
* For other types, when the charset parameter is missing this property will be null.
|
||||
* </p>
|
||||
* @return Character set, which has been parsed from the
|
||||
* content-type definition. Not null for <code>TEXT</code> types, when unset will
|
||||
* be set to default <code>us-ascii</code>. For other types, when unset,
|
||||
* null will be returned.
|
||||
*/
|
||||
String getCharset();
|
||||
|
||||
/**
|
||||
* Returns the body descriptors transfer encoding.
|
||||
* @return The transfer encoding. Must not be null, but "7bit",
|
||||
* if no transfer-encoding was specified.
|
||||
*/
|
||||
String getTransferEncoding();
|
||||
|
||||
/**
|
||||
* Returns the body descriptors content-length.
|
||||
* @return Content length, if known, or -1, to indicate the absence of a
|
||||
* content-length header.
|
||||
*/
|
||||
long getContentLength();
|
||||
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class FileBody extends AbstractContentBody {
|
||||
|
||||
private final File file;
|
||||
private final String filename;
|
||||
private final String charset;
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public FileBody(final File file,
|
||||
final String filename,
|
||||
final String mimeType,
|
||||
final String charset) {
|
||||
super(mimeType);
|
||||
if (file == null) {
|
||||
throw new IllegalArgumentException("File may not be null");
|
||||
}
|
||||
this.file = file;
|
||||
if (filename != null)
|
||||
this.filename = filename;
|
||||
else
|
||||
this.filename = file.getName();
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public FileBody(final File file,
|
||||
final String mimeType,
|
||||
final String charset) {
|
||||
this(file, null, mimeType, charset);
|
||||
}
|
||||
|
||||
public FileBody(final File file, final String mimeType) {
|
||||
this(file, mimeType, null);
|
||||
}
|
||||
|
||||
public FileBody(final File file) {
|
||||
this(file, "application/octet-stream");
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new FileInputStream(this.file);
|
||||
}
|
||||
|
||||
public void writeTo(final OutputStream out) throws IOException {
|
||||
if (out == null) {
|
||||
throw new IllegalArgumentException("Output stream may not be null");
|
||||
}
|
||||
InputStream in = new FileInputStream(this.file);
|
||||
try {
|
||||
byte[] tmp = new byte[4096];
|
||||
int l;
|
||||
while ((l = in.read(tmp)) != -1) {
|
||||
out.write(tmp, 0, l);
|
||||
}
|
||||
out.flush();
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
public String getTransferEncoding() {
|
||||
return MIME.ENC_BINARY;
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
return charset;
|
||||
}
|
||||
|
||||
public long getContentLength() {
|
||||
return this.file.length();
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return this.file;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import com.foxinmy.weixin4j.http.NameValue;
|
||||
|
||||
|
||||
/**
|
||||
* FormBodyPart class represents a content body that can be used as a part of multipart encoded
|
||||
* entities. This class automatically populates the header with standard fields based on
|
||||
* the content description of the enclosed body.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class FormBodyPart {
|
||||
|
||||
private final String name;
|
||||
private final Header header;
|
||||
|
||||
private final ContentBody body;
|
||||
|
||||
public FormBodyPart(final String name, final ContentBody body) {
|
||||
super();
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException("Name may not be null");
|
||||
}
|
||||
if (body == null) {
|
||||
throw new IllegalArgumentException("Body may not be null");
|
||||
}
|
||||
this.name = name;
|
||||
this.body = body;
|
||||
this.header = new Header();
|
||||
|
||||
generateContentDisp(body);
|
||||
generateContentType(body);
|
||||
generateTransferEncoding(body);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public ContentBody getBody() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
public Header getHeader() {
|
||||
return this.header;
|
||||
}
|
||||
|
||||
public void addField(final String name, final String value) {
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException("Field name may not be null");
|
||||
}
|
||||
this.header.addField(new NameValue(name, value));
|
||||
}
|
||||
|
||||
protected void generateContentDisp(final ContentBody body) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("form-data; name=\"");
|
||||
buffer.append(getName());
|
||||
buffer.append("\"");
|
||||
if (body.getFilename() != null) {
|
||||
buffer.append("; filename=\"");
|
||||
buffer.append(body.getFilename());
|
||||
buffer.append("\"");
|
||||
}
|
||||
addField(MIME.CONTENT_DISPOSITION, buffer.toString());
|
||||
}
|
||||
|
||||
protected void generateContentType(final ContentBody body) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append(body.getMimeType()); // MimeType cannot be null
|
||||
if (body.getCharset() != null) { // charset may legitimately be null
|
||||
buffer.append("; charset=");
|
||||
buffer.append(body.getCharset());
|
||||
}
|
||||
addField(MIME.CONTENT_TYPE, buffer.toString());
|
||||
}
|
||||
|
||||
protected void generateTransferEncoding(final ContentBody body) {
|
||||
addField(MIME.CONTENT_TRANSFER_ENC, body.getTransferEncoding()); // TE cannot be null
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
|
||||
/**
|
||||
* Constants and static helpers related to the HTTP protocol.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class HTTP {
|
||||
|
||||
public static final int CR = 13; // <US-ASCII CR, carriage return (13)>
|
||||
public static final int LF = 10; // <US-ASCII LF, linefeed (10)>
|
||||
public static final int SP = 32; // <US-ASCII SP, space (32)>
|
||||
public static final int HT = 9; // <US-ASCII HT, horizontal-tab (9)>
|
||||
|
||||
/** HTTP header definitions */
|
||||
public static final String TRANSFER_ENCODING = "Transfer-Encoding";
|
||||
public static final String CONTENT_LEN = "Content-Length";
|
||||
public static final String CONTENT_TYPE = "Content-Type";
|
||||
public static final String CONTENT_ENCODING = "Content-Encoding";
|
||||
public static final String EXPECT_DIRECTIVE = "Expect";
|
||||
public static final String CONN_DIRECTIVE = "Connection";
|
||||
public static final String TARGET_HOST = "Host";
|
||||
public static final String USER_AGENT = "User-Agent";
|
||||
public static final String DATE_HEADER = "Date";
|
||||
public static final String SERVER_HEADER = "Server";
|
||||
|
||||
/** HTTP expectations */
|
||||
public static final String EXPECT_CONTINUE = "100-continue";
|
||||
|
||||
/** HTTP connection control */
|
||||
public static final String CONN_CLOSE = "Close";
|
||||
public static final String CONN_KEEP_ALIVE = "Keep-Alive";
|
||||
|
||||
/** Transfer encoding definitions */
|
||||
public static final String CHUNK_CODING = "chunked";
|
||||
public static final String IDENTITY_CODING = "identity";
|
||||
|
||||
public static boolean isWhitespace(char ch) {
|
||||
return ch == SP || ch == HT || ch == CR || ch == LF;
|
||||
}
|
||||
|
||||
private HTTP() {
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import com.foxinmy.weixin4j.http.NameValue;
|
||||
|
||||
/**
|
||||
* The header of an entity (see RFC 2045).
|
||||
*/
|
||||
public class Header implements Iterable<NameValue> {
|
||||
|
||||
private final List<NameValue> fields;
|
||||
private final Map<String, List<NameValue>> fieldMap;
|
||||
|
||||
public Header() {
|
||||
super();
|
||||
this.fields = new LinkedList<NameValue>();
|
||||
this.fieldMap = new HashMap<String, List<NameValue>>();
|
||||
}
|
||||
|
||||
public void addField(final NameValue field) {
|
||||
if (field == null) {
|
||||
return;
|
||||
}
|
||||
String key = field.getName().toLowerCase(Locale.US);
|
||||
List<NameValue> values = this.fieldMap.get(key);
|
||||
if (values == null) {
|
||||
values = new LinkedList<NameValue>();
|
||||
this.fieldMap.put(key, values);
|
||||
}
|
||||
values.add(field);
|
||||
this.fields.add(field);
|
||||
}
|
||||
|
||||
public List<NameValue> getFields() {
|
||||
return new ArrayList<NameValue>(this.fields);
|
||||
}
|
||||
|
||||
public NameValue getField(final String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
String key = name.toLowerCase(Locale.US);
|
||||
List<NameValue> list = this.fieldMap.get(key);
|
||||
if (list != null && !list.isEmpty()) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<NameValue> getFields(final String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
String key = name.toLowerCase(Locale.US);
|
||||
List<NameValue> list = this.fieldMap.get(key);
|
||||
if (list == null || list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
return new ArrayList<NameValue>(list);
|
||||
}
|
||||
}
|
||||
|
||||
public int removeFields(final String name) {
|
||||
if (name == null) {
|
||||
return 0;
|
||||
}
|
||||
String key = name.toLowerCase(Locale.US);
|
||||
List<NameValue> removed = fieldMap.remove(key);
|
||||
if (removed == null || removed.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
this.fields.removeAll(removed);
|
||||
return removed.size();
|
||||
}
|
||||
|
||||
public void setField(final NameValue field) {
|
||||
if (field == null) {
|
||||
return;
|
||||
}
|
||||
String key = field.getName().toLowerCase(Locale.US);
|
||||
List<NameValue> list = fieldMap.get(key);
|
||||
if (list == null || list.isEmpty()) {
|
||||
addField(field);
|
||||
return;
|
||||
}
|
||||
list.clear();
|
||||
list.add(field);
|
||||
int firstOccurrence = -1;
|
||||
int index = 0;
|
||||
for (Iterator<NameValue> it = this.fields.iterator(); it.hasNext(); index++) {
|
||||
NameValue f = it.next();
|
||||
if (f.getName().equalsIgnoreCase(field.getName())) {
|
||||
it.remove();
|
||||
if (firstOccurrence == -1) {
|
||||
firstOccurrence = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.fields.add(firstOccurrence, field);
|
||||
}
|
||||
|
||||
public Iterator<NameValue> iterator() {
|
||||
return Collections.unmodifiableList(fields).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.fields.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
/**
|
||||
* Constants enumerating the HTTP headers. All headers defined in RFC1945 (HTTP/1.0), RFC2616 (HTTP/1.1), and RFC2518
|
||||
* (WebDAV) are listed.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public final class HttpHeaders {
|
||||
|
||||
private HttpHeaders() {
|
||||
}
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.1 */
|
||||
public static final String ACCEPT = "Accept";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.2 */
|
||||
public static final String ACCEPT_CHARSET = "Accept-Charset";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.3 */
|
||||
public static final String ACCEPT_ENCODING = "Accept-Encoding";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.4 */
|
||||
public static final String ACCEPT_LANGUAGE = "Accept-Language";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.5 */
|
||||
public static final String ACCEPT_RANGES = "Accept-Ranges";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.6 */
|
||||
public static final String AGE = "Age";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.1, RFC 2616 (HTTP/1.1) Section 14.7 */
|
||||
public static final String ALLOW = "Allow";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.2, RFC 2616 (HTTP/1.1) Section 14.8 */
|
||||
public static final String AUTHORIZATION = "Authorization";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.9 */
|
||||
public static final String CACHE_CONTROL = "Cache-Control";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.10 */
|
||||
public static final String CONNECTION = "Connection";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.3, RFC 2616 (HTTP/1.1) Section 14.11 */
|
||||
public static final String CONTENT_ENCODING = "Content-Encoding";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.12 */
|
||||
public static final String CONTENT_LANGUAGE = "Content-Language";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.4, RFC 2616 (HTTP/1.1) Section 14.13 */
|
||||
public static final String CONTENT_LENGTH = "Content-Length";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.14 */
|
||||
public static final String CONTENT_LOCATION = "Content-Location";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.15 */
|
||||
public static final String CONTENT_MD5 = "Content-MD5";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.16 */
|
||||
public static final String CONTENT_RANGE = "Content-Range";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.5, RFC 2616 (HTTP/1.1) Section 14.17 */
|
||||
public static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.6, RFC 2616 (HTTP/1.1) Section 14.18 */
|
||||
public static final String DATE = "Date";
|
||||
|
||||
/** RFC 2518 (WevDAV) Section 9.1 */
|
||||
public static final String DAV = "Dav";
|
||||
|
||||
/** RFC 2518 (WevDAV) Section 9.2 */
|
||||
public static final String DEPTH = "Depth";
|
||||
|
||||
/** RFC 2518 (WevDAV) Section 9.3 */
|
||||
public static final String DESTINATION = "Destination";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.19 */
|
||||
public static final String ETAG = "ETag";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.20 */
|
||||
public static final String EXPECT = "Expect";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.7, RFC 2616 (HTTP/1.1) Section 14.21 */
|
||||
public static final String EXPIRES = "Expires";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.8, RFC 2616 (HTTP/1.1) Section 14.22 */
|
||||
public static final String FROM = "From";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.23 */
|
||||
public static final String HOST = "Host";
|
||||
|
||||
/** RFC 2518 (WevDAV) Section 9.4 */
|
||||
public static final String IF = "If";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.24 */
|
||||
public static final String IF_MATCH = "If-Match";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.9, RFC 2616 (HTTP/1.1) Section 14.25 */
|
||||
public static final String IF_MODIFIED_SINCE = "If-Modified-Since";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.26 */
|
||||
public static final String IF_NONE_MATCH = "If-None-Match";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.27 */
|
||||
public static final String IF_RANGE = "If-Range";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.28 */
|
||||
public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.10, RFC 2616 (HTTP/1.1) Section 14.29 */
|
||||
public static final String LAST_MODIFIED = "Last-Modified";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.11, RFC 2616 (HTTP/1.1) Section 14.30 */
|
||||
public static final String LOCATION = "Location";
|
||||
|
||||
/** RFC 2518 (WevDAV) Section 9.5 */
|
||||
public static final String LOCK_TOKEN = "Lock-Token";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.31 */
|
||||
public static final String MAX_FORWARDS = "Max-Forwards";
|
||||
|
||||
/** RFC 2518 (WevDAV) Section 9.6 */
|
||||
public static final String OVERWRITE = "Overwrite";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.12, RFC 2616 (HTTP/1.1) Section 14.32 */
|
||||
public static final String PRAGMA = "Pragma";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.33 */
|
||||
public static final String PROXY_AUTHENTICATE = "Proxy-Authenticate";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.34 */
|
||||
public static final String PROXY_AUTHORIZATION = "Proxy-Authorization";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.35 */
|
||||
public static final String RANGE = "Range";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.13, RFC 2616 (HTTP/1.1) Section 14.36 */
|
||||
public static final String REFERER = "Referer";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.37 */
|
||||
public static final String RETRY_AFTER = "Retry-After";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.14, RFC 2616 (HTTP/1.1) Section 14.38 */
|
||||
public static final String SERVER = "Server";
|
||||
|
||||
/** RFC 2518 (WevDAV) Section 9.7 */
|
||||
public static final String STATUS_URI = "Status-URI";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.39 */
|
||||
public static final String TE = "TE";
|
||||
|
||||
/** RFC 2518 (WevDAV) Section 9.8 */
|
||||
public static final String TIMEOUT = "Timeout";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.40 */
|
||||
public static final String TRAILER = "Trailer";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.41 */
|
||||
public static final String TRANSFER_ENCODING = "Transfer-Encoding";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.42 */
|
||||
public static final String UPGRADE = "Upgrade";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.15, RFC 2616 (HTTP/1.1) Section 14.43 */
|
||||
public static final String USER_AGENT = "User-Agent";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.44 */
|
||||
public static final String VARY = "Vary";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.45 */
|
||||
public static final String VIA = "Via";
|
||||
|
||||
/** RFC 2616 (HTTP/1.1) Section 14.46 */
|
||||
public static final String WARNING = "Warning";
|
||||
|
||||
/** RFC 1945 (HTTP/1.0) Section 10.16, RFC 2616 (HTTP/1.1) Section 14.47 */
|
||||
public static final String WWW_AUTHENTICATE = "WWW-Authenticate";
|
||||
|
||||
}
|
||||
@ -0,0 +1,278 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.foxinmy.weixin4j.http.NameValue;
|
||||
|
||||
/**
|
||||
* HttpMultipart represents a collection of MIME multipart encoded content
|
||||
* bodies. This class is capable of operating either in the strict (RFC 822, RFC
|
||||
* 2045, RFC 2046 compliant) or the browser compatible modes.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class HttpMultipart {
|
||||
|
||||
private static ByteArrayBuffer encode(final Charset charset,
|
||||
final String string) {
|
||||
ByteBuffer encoded = charset.encode(CharBuffer.wrap(string));
|
||||
ByteArrayBuffer bab = new ByteArrayBuffer(encoded.remaining());
|
||||
bab.append(encoded.array(), encoded.position(), encoded.remaining());
|
||||
return bab;
|
||||
}
|
||||
|
||||
private static void writeBytes(final ByteArrayBuffer b,
|
||||
final OutputStream out) throws IOException {
|
||||
out.write(b.buffer(), 0, b.length());
|
||||
}
|
||||
|
||||
private static void writeBytes(final String s, final Charset charset,
|
||||
final OutputStream out) throws IOException {
|
||||
ByteArrayBuffer b = encode(charset, s);
|
||||
writeBytes(b, out);
|
||||
}
|
||||
|
||||
private static void writeBytes(final String s, final OutputStream out)
|
||||
throws IOException {
|
||||
ByteArrayBuffer b = encode(MIME.DEFAULT_CHARSET, s);
|
||||
writeBytes(b, out);
|
||||
}
|
||||
|
||||
private static void writeField(final NameValue field, final OutputStream out)
|
||||
throws IOException {
|
||||
writeBytes(field.getName(), out);
|
||||
writeBytes(FIELD_SEP, out);
|
||||
writeBytes(field.getValue(), out);
|
||||
writeBytes(CR_LF, out);
|
||||
}
|
||||
|
||||
private static void writeField(final NameValue field, final Charset charset,
|
||||
final OutputStream out) throws IOException {
|
||||
writeBytes(field.getName(), charset, out);
|
||||
writeBytes(FIELD_SEP, out);
|
||||
writeBytes(field.getValue(), charset, out);
|
||||
writeBytes(CR_LF, out);
|
||||
}
|
||||
|
||||
private static final ByteArrayBuffer FIELD_SEP = encode(
|
||||
MIME.DEFAULT_CHARSET, ": ");
|
||||
private static final ByteArrayBuffer CR_LF = encode(MIME.DEFAULT_CHARSET,
|
||||
"\r\n");
|
||||
private static final ByteArrayBuffer TWO_DASHES = encode(
|
||||
MIME.DEFAULT_CHARSET, "--");
|
||||
|
||||
private final String subType;
|
||||
private final Charset charset;
|
||||
private final String boundary;
|
||||
private final List<FormBodyPart> parts;
|
||||
|
||||
private final HttpMultipartMode mode;
|
||||
|
||||
/**
|
||||
* Creates an instance with the specified settings.
|
||||
*
|
||||
* @param subType
|
||||
* mime subtype - must not be {@code null}
|
||||
* @param charset
|
||||
* the character set to use. May be {@code null}, in which case
|
||||
* {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used.
|
||||
* @param boundary
|
||||
* to use - must not be {@code null}
|
||||
* @param mode
|
||||
* the mode to use
|
||||
* @throws IllegalArgumentException
|
||||
* if charset is null or boundary is null
|
||||
*/
|
||||
public HttpMultipart(final String subType, final Charset charset,
|
||||
final String boundary, HttpMultipartMode mode) {
|
||||
super();
|
||||
if (subType == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Multipart subtype may not be null");
|
||||
}
|
||||
if (boundary == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Multipart boundary may not be null");
|
||||
}
|
||||
this.subType = subType;
|
||||
this.charset = charset != null ? charset : MIME.DEFAULT_CHARSET;
|
||||
this.boundary = boundary;
|
||||
this.parts = new ArrayList<FormBodyPart>();
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the specified settings. Mode is set to
|
||||
* {@link HttpMultipartMode#STRICT}
|
||||
*
|
||||
* @param subType
|
||||
* mime subtype - must not be {@code null}
|
||||
* @param charset
|
||||
* the character set to use. May be {@code null}, in which case
|
||||
* {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used.
|
||||
* @param boundary
|
||||
* to use - must not be {@code null}
|
||||
* @throws IllegalArgumentException
|
||||
* if charset is null or boundary is null
|
||||
*/
|
||||
public HttpMultipart(final String subType, final Charset charset,
|
||||
final String boundary) {
|
||||
this(subType, charset, boundary, HttpMultipartMode.STRICT);
|
||||
}
|
||||
|
||||
public HttpMultipart(final String subType, final String boundary) {
|
||||
this(subType, null, boundary);
|
||||
}
|
||||
|
||||
public String getSubType() {
|
||||
return this.subType;
|
||||
}
|
||||
|
||||
public Charset getCharset() {
|
||||
return this.charset;
|
||||
}
|
||||
|
||||
public HttpMultipartMode getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public List<FormBodyPart> getBodyParts() {
|
||||
return this.parts;
|
||||
}
|
||||
|
||||
public void addBodyPart(final FormBodyPart part) {
|
||||
if (part == null) {
|
||||
return;
|
||||
}
|
||||
this.parts.add(part);
|
||||
}
|
||||
|
||||
public String getBoundary() {
|
||||
return this.boundary;
|
||||
}
|
||||
|
||||
private void doWriteTo(final HttpMultipartMode mode,
|
||||
final OutputStream out, boolean writeContent) throws IOException {
|
||||
|
||||
ByteArrayBuffer boundary = encode(this.charset, getBoundary());
|
||||
for (FormBodyPart part : this.parts) {
|
||||
writeBytes(TWO_DASHES, out);
|
||||
writeBytes(boundary, out);
|
||||
writeBytes(CR_LF, out);
|
||||
|
||||
Header header = part.getHeader();
|
||||
|
||||
switch (mode) {
|
||||
case STRICT:
|
||||
for (NameValue field : header) {
|
||||
writeField(field, out);
|
||||
}
|
||||
break;
|
||||
case BROWSER_COMPATIBLE:
|
||||
// Only write Content-Disposition
|
||||
// Use content charset
|
||||
NameValue cd = part.getHeader().getField(
|
||||
MIME.CONTENT_DISPOSITION);
|
||||
writeField(cd, this.charset, out);
|
||||
String filename = part.getBody().getFilename();
|
||||
if (filename != null) {
|
||||
NameValue ct = part.getHeader().getField(MIME.CONTENT_TYPE);
|
||||
writeField(ct, this.charset, out);
|
||||
}
|
||||
break;
|
||||
}
|
||||
writeBytes(CR_LF, out);
|
||||
|
||||
if (writeContent) {
|
||||
part.getBody().writeTo(out);
|
||||
}
|
||||
writeBytes(CR_LF, out);
|
||||
}
|
||||
writeBytes(TWO_DASHES, out);
|
||||
writeBytes(boundary, out);
|
||||
writeBytes(TWO_DASHES, out);
|
||||
writeBytes(CR_LF, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the content in the multipart/form encoding. This method
|
||||
* produces slightly different formatting depending on its compatibility
|
||||
* mode.
|
||||
*
|
||||
* @see #getMode()
|
||||
*/
|
||||
public void writeTo(final OutputStream out) throws IOException {
|
||||
doWriteTo(this.mode, out, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the total length of the multipart content (content length of
|
||||
* individual parts plus that of extra elements required to delimit the
|
||||
* parts from one another). If any of the @{link BodyPart}s contained in
|
||||
* this object is of a streaming entity of unknown length the total length
|
||||
* is also unknown.
|
||||
* <p/>
|
||||
* This method buffers only a small amount of data in order to determine the
|
||||
* total length of the entire entity. The content of individual parts is not
|
||||
* buffered.
|
||||
*
|
||||
* @return total length of the multipart entity if known, <code>-1</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public long getTotalLength() {
|
||||
long contentLen = 0;
|
||||
for (FormBodyPart part : this.parts) {
|
||||
ContentBody body = part.getBody();
|
||||
long len = body.getContentLength();
|
||||
if (len >= 0) {
|
||||
contentLen += len;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
try {
|
||||
doWriteTo(this.mode, out, false);
|
||||
byte[] extra = out.toByteArray();
|
||||
return contentLen + extra.length;
|
||||
} catch (IOException ex) {
|
||||
// Should never happen
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
public enum HttpMultipartMode {
|
||||
|
||||
/** RFC 822, RFC 2045, RFC 2046 compliant */
|
||||
STRICT,
|
||||
/**
|
||||
* browser-compatible mode, i.e. only write Content-Disposition; use content
|
||||
* charset
|
||||
*/
|
||||
BROWSER_COMPATIBLE
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class InputStreamBody extends AbstractContentBody {
|
||||
|
||||
private final InputStream in;
|
||||
private final String filename;
|
||||
|
||||
public InputStreamBody(final InputStream in, final String mimeType, final String filename) {
|
||||
super(mimeType);
|
||||
if (in == null) {
|
||||
throw new IllegalArgumentException("Input stream may not be null");
|
||||
}
|
||||
this.in = in;
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public InputStreamBody(final InputStream in, final String filename) {
|
||||
this(in, "application/octet-stream", filename);
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return this.in;
|
||||
}
|
||||
|
||||
public void writeTo(final OutputStream out) throws IOException {
|
||||
if (out == null) {
|
||||
throw new IllegalArgumentException("Output stream may not be null");
|
||||
}
|
||||
try {
|
||||
byte[] tmp = new byte[4096];
|
||||
int l;
|
||||
while ((l = this.in.read(tmp)) != -1) {
|
||||
out.write(tmp, 0, l);
|
||||
}
|
||||
out.flush();
|
||||
} finally {
|
||||
this.in.close();
|
||||
}
|
||||
}
|
||||
|
||||
public String getTransferEncoding() {
|
||||
return MIME.ENC_BINARY;
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getContentLength() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return this.filename;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class MIME {
|
||||
|
||||
public static final String CONTENT_TYPE = "Content-Type";
|
||||
public static final String CONTENT_TRANSFER_ENC = "Content-Transfer-Encoding";
|
||||
public static final String CONTENT_DISPOSITION = "Content-Disposition";
|
||||
|
||||
public static final String ENC_8BIT = "8bit";
|
||||
public static final String ENC_BINARY = "binary";
|
||||
|
||||
/** The default character set to be used, i.e. "US-ASCII" */
|
||||
public static final Charset DEFAULT_CHARSET = Charset.forName("US-ASCII");
|
||||
|
||||
}
|
||||
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Random;
|
||||
|
||||
import com.foxinmy.weixin4j.http.ContentType;
|
||||
import com.foxinmy.weixin4j.http.entity.HttpEntity;
|
||||
|
||||
/**
|
||||
* Multipart/form coded HTTP entity consisting of multiple body parts.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class MultipartEntity implements HttpEntity {
|
||||
|
||||
/**
|
||||
* The pool of ASCII chars to be used for generating a multipart boundary.
|
||||
*/
|
||||
private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
.toCharArray();
|
||||
|
||||
private final HttpMultipart multipart;
|
||||
|
||||
// @GuardedBy("dirty") // we always read dirty before accessing length
|
||||
private long length;
|
||||
private volatile boolean dirty; // used to decide whether to recalculate
|
||||
// length
|
||||
|
||||
/**
|
||||
* Creates an instance using the specified parameters
|
||||
*
|
||||
* @param mode
|
||||
* the mode to use, may be {@code null}, in which case
|
||||
* {@link HttpMultipartMode#STRICT} is used
|
||||
* @param boundary
|
||||
* the boundary string, may be {@code null}, in which case
|
||||
* {@link #generateBoundary()} is invoked to create the string
|
||||
* @param charset
|
||||
* the character set to use, may be {@code null}, in which case
|
||||
* {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used.
|
||||
*/
|
||||
public MultipartEntity(HttpMultipartMode mode, String boundary,
|
||||
Charset charset) {
|
||||
super();
|
||||
if (boundary == null) {
|
||||
boundary = generateBoundary();
|
||||
}
|
||||
if (mode == null) {
|
||||
mode = HttpMultipartMode.STRICT;
|
||||
}
|
||||
this.multipart = new HttpMultipart("form-data", charset, boundary, mode);
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance using the specified {@link HttpMultipartMode} mode.
|
||||
* Boundary and charset are set to {@code null}.
|
||||
*
|
||||
* @param mode
|
||||
* the desired mode
|
||||
*/
|
||||
public MultipartEntity(final HttpMultipartMode mode) {
|
||||
this(mode, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance using mode {@link HttpMultipartMode#STRICT}
|
||||
*/
|
||||
public MultipartEntity() {
|
||||
this(HttpMultipartMode.STRICT, null, null);
|
||||
}
|
||||
|
||||
protected String generateBoundary() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
Random rand = new Random();
|
||||
int count = rand.nextInt(11) + 30; // a random size from 30 to 40
|
||||
for (int i = 0; i < count; i++) {
|
||||
buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void addPart(final FormBodyPart bodyPart) {
|
||||
this.multipart.addBodyPart(bodyPart);
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
public void addPart(final String name, final ContentBody contentBody) {
|
||||
addPart(new FormBodyPart(name, contentBody));
|
||||
}
|
||||
|
||||
public boolean isRepeatable() {
|
||||
for (FormBodyPart part : this.multipart.getBodyParts()) {
|
||||
ContentBody body = part.getBody();
|
||||
if (body.getContentLength() < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isChunked() {
|
||||
return !isRepeatable();
|
||||
}
|
||||
|
||||
public boolean isStreaming() {
|
||||
return !isRepeatable();
|
||||
}
|
||||
|
||||
public long getContentLength() {
|
||||
if (this.dirty) {
|
||||
this.length = this.multipart.getTotalLength();
|
||||
this.dirty = false;
|
||||
}
|
||||
return this.length;
|
||||
}
|
||||
|
||||
public ContentType getContentType() {
|
||||
return ContentType.MULTIPART_FORM_DATA;
|
||||
}
|
||||
|
||||
public void consumeContent() throws IOException,
|
||||
UnsupportedOperationException {
|
||||
if (isStreaming()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Streaming entity does not implement #consumeContent()");
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream getContent() throws IOException,
|
||||
UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException(
|
||||
"Multipart form entity does not implement #getContent()");
|
||||
}
|
||||
|
||||
public void writeTo(final OutputStream outstream) throws IOException {
|
||||
this.multipart.writeTo(outstream);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.foxinmy.weixin4j.http.apache;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class StringBody extends AbstractContentBody {
|
||||
|
||||
private final byte[] content;
|
||||
private final Charset charset;
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public static StringBody create(
|
||||
final String text,
|
||||
final String mimeType,
|
||||
final Charset charset) throws IllegalArgumentException {
|
||||
try {
|
||||
return new StringBody(text, mimeType, charset);
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new IllegalArgumentException("Charset " + charset + " is not supported", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public static StringBody create(
|
||||
final String text, final Charset charset) throws IllegalArgumentException {
|
||||
return create(text, null, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public static StringBody create(final String text) throws IllegalArgumentException {
|
||||
return create(text, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a StringBody from the specified text, mime type and character set.
|
||||
*
|
||||
* @param text to be used for the body, not {@code null}
|
||||
* @param mimeType the mime type, not {@code null}
|
||||
* @param charset the character set, may be {@code null}, in which case the US-ASCII charset is used
|
||||
* @throws UnsupportedEncodingException
|
||||
* @throws IllegalArgumentException if the {@code text} parameter is null
|
||||
*/
|
||||
public StringBody(
|
||||
final String text,
|
||||
final String mimeType,
|
||||
Charset charset) throws UnsupportedEncodingException {
|
||||
super(mimeType);
|
||||
if (text == null) {
|
||||
throw new IllegalArgumentException("Text may not be null");
|
||||
}
|
||||
if (charset == null) {
|
||||
charset = Charset.forName("US-ASCII");
|
||||
}
|
||||
this.content = text.getBytes(charset.name());
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a StringBody from the specified text and character set.
|
||||
* The mime type is set to "text/plain".
|
||||
*
|
||||
* @param text to be used for the body, not {@code null}
|
||||
* @param charset the character set, may be {@code null}, in which case the US-ASCII charset is used
|
||||
* @throws UnsupportedEncodingException
|
||||
* @throws IllegalArgumentException if the {@code text} parameter is null
|
||||
*/
|
||||
public StringBody(final String text, final Charset charset) throws UnsupportedEncodingException {
|
||||
this(text, "text/plain", charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a StringBody from the specified text.
|
||||
* The mime type is set to "text/plain".
|
||||
* The hosts default charset is used.
|
||||
*
|
||||
* @param text to be used for the body, not {@code null}
|
||||
* @throws UnsupportedEncodingException
|
||||
* @throws IllegalArgumentException if the {@code text} parameter is null
|
||||
*/
|
||||
public StringBody(final String text) throws UnsupportedEncodingException {
|
||||
this(text, "text/plain", null);
|
||||
}
|
||||
|
||||
public Reader getReader() {
|
||||
return new InputStreamReader(
|
||||
new ByteArrayInputStream(this.content),
|
||||
this.charset);
|
||||
}
|
||||
|
||||
public void writeTo(final OutputStream out) throws IOException {
|
||||
if (out == null) {
|
||||
throw new IllegalArgumentException("Output stream may not be null");
|
||||
}
|
||||
InputStream in = new ByteArrayInputStream(this.content);
|
||||
byte[] tmp = new byte[4096];
|
||||
int l;
|
||||
while ((l = in.read(tmp)) != -1) {
|
||||
out.write(tmp, 0, l);
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public String getTransferEncoding() {
|
||||
return MIME.ENC_8BIT;
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
return this.charset.name();
|
||||
}
|
||||
|
||||
public long getContentLength() {
|
||||
return this.content.length;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.foxinmy.weixin4j.http.entity;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.foxinmy.weixin4j.http.ContentType;
|
||||
|
||||
public class ByteArrayEntity implements HttpEntity {
|
||||
|
||||
private final ContentType contentType;
|
||||
private final byte[] content;
|
||||
private final int off, len;
|
||||
|
||||
public ByteArrayEntity(byte[] content) {
|
||||
this(content, ContentType.DEFAULT_BINARY);
|
||||
}
|
||||
|
||||
public ByteArrayEntity(byte[] content, ContentType contentType) {
|
||||
this(content, 0, content.length, contentType);
|
||||
}
|
||||
|
||||
public ByteArrayEntity(byte[] content, int off, int len,
|
||||
ContentType contentType) {
|
||||
this.content = content;
|
||||
this.off = off;
|
||||
this.len = len;
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentLength() {
|
||||
return len;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getContent() throws IOException {
|
||||
return new ByteArrayInputStream(this.content, this.off, this.len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(OutputStream outstream) throws IOException {
|
||||
outstream.write(this.content, this.off, this.len);
|
||||
outstream.flush();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package com.foxinmy.weixin4j.http.entity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.foxinmy.weixin4j.http.ContentType;
|
||||
|
||||
public class FileEntity implements HttpEntity {
|
||||
|
||||
private final File file;
|
||||
private final ContentType contentType;
|
||||
|
||||
public FileEntity(File file) {
|
||||
this(file, ContentType.DEFAULT_BINARY);
|
||||
}
|
||||
|
||||
public FileEntity(File file, ContentType contentType) {
|
||||
this.file = file;
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentLength() {
|
||||
return this.file.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getContent() throws IOException {
|
||||
return new FileInputStream(this.file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(OutputStream outstream) throws IOException {
|
||||
InputStream instream = new FileInputStream(this.file);
|
||||
try {
|
||||
byte[] tmp = new byte[4096];
|
||||
int l;
|
||||
while ((l = instream.read(tmp)) != -1) {
|
||||
outstream.write(tmp, 0, l);
|
||||
}
|
||||
outstream.flush();
|
||||
} finally {
|
||||
instream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.foxinmy.weixin4j.http.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.foxinmy.weixin4j.http.ContentType;
|
||||
import com.foxinmy.weixin4j.http.UrlEncodeParameter;
|
||||
|
||||
public class FormUrlEntity extends StringEntity {
|
||||
private static final String PARAMETER_SEPARATOR = "&";
|
||||
|
||||
public FormUrlEntity(List<UrlEncodeParameter> parameters) {
|
||||
super(formatParameters(parameters),
|
||||
ContentType.APPLICATION_FORM_URLENCODED);
|
||||
}
|
||||
|
||||
private static String formatParameters(List<UrlEncodeParameter> parameters) {
|
||||
final StringBuilder body = new StringBuilder();
|
||||
UrlEncodeParameter parameter = parameters.get(0);
|
||||
body.append(parameter.encodingParameter());
|
||||
for (int i = 1; i < parameters.size(); i++) {
|
||||
body.append(PARAMETER_SEPARATOR);
|
||||
parameter = parameters.get(i);
|
||||
body.append(parameter.encodingParameter());
|
||||
}
|
||||
return body.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.foxinmy.weixin4j.http.entity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.foxinmy.weixin4j.http.ContentType;
|
||||
|
||||
public interface HttpEntity {
|
||||
|
||||
ContentType getContentType();
|
||||
|
||||
long getContentLength();
|
||||
|
||||
InputStream getContent() throws IOException;
|
||||
|
||||
void writeTo(OutputStream outstream) throws IOException;
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.foxinmy.weixin4j.http.entity;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.foxinmy.weixin4j.http.ContentType;
|
||||
|
||||
public class StringEntity implements HttpEntity {
|
||||
private final byte[] content;
|
||||
private final ContentType contentType;
|
||||
|
||||
public StringEntity(String body) {
|
||||
this(body, ContentType.DEFAULT_TEXT);
|
||||
}
|
||||
|
||||
public StringEntity(String body, ContentType contentType) {
|
||||
this.content = body.getBytes();
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentLength() {
|
||||
return this.content.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getContent() throws IOException {
|
||||
return new ByteArrayInputStream(this.content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(OutputStream outstream) throws IOException {
|
||||
outstream.write(this.content);
|
||||
outstream.flush();
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
package com.foxinmy.weixin4j.http.weixin;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
package com.foxinmy.weixin4j.http.weixin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.KeyStore;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
|
||||
/**
|
||||
* ssl请求
|
||||
*
|
||||
* @className SSLHttpClinet
|
||||
* @author jy
|
||||
* @date 2014年11月6日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class SSLHttpClinet extends WeixinHttpClient {
|
||||
|
||||
private final SSLContext sslContext;
|
||||
|
||||
public SSLHttpClinet(String password, InputStream inputStream)
|
||||
throws WeixinException {
|
||||
try {
|
||||
KeyStore keyStore = KeyStore
|
||||
.getInstance(com.foxinmy.weixin4j.model.Consts.PKCS12);
|
||||
keyStore.load(inputStream, password.toCharArray());
|
||||
KeyManagerFactory kmf = KeyManagerFactory
|
||||
.getInstance(com.foxinmy.weixin4j.model.Consts.SunX509);
|
||||
kmf.init(keyStore, password.toCharArray());
|
||||
sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(kmf.getKeyManagers(), null,
|
||||
new java.security.SecureRandom());
|
||||
} catch (Exception e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public SSLHttpClinet(SSLContext sslContext) {
|
||||
this.sslContext = sslContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpURLConnection createHttpConnection(URI uri)
|
||||
throws IOException {
|
||||
URL url = uri.toURL();
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url
|
||||
.openConnection();
|
||||
connection.setSSLSocketFactory(sslContext.getSocketFactory());
|
||||
connection.setHostnameVerifier(super.createHostnameVerifier());
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,213 @@
|
||||
package com.foxinmy.weixin4j.http.weixin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONException;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.ContentType;
|
||||
import com.foxinmy.weixin4j.http.Header;
|
||||
import com.foxinmy.weixin4j.http.HttpGet;
|
||||
import com.foxinmy.weixin4j.http.HttpPost;
|
||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||
import com.foxinmy.weixin4j.http.HttpResponse;
|
||||
import com.foxinmy.weixin4j.http.SimpleHttpClient;
|
||||
import com.foxinmy.weixin4j.http.StatusLine;
|
||||
import com.foxinmy.weixin4j.http.UrlEncodeParameter;
|
||||
import com.foxinmy.weixin4j.http.apache.FormBodyPart;
|
||||
import com.foxinmy.weixin4j.http.apache.HttpHeaders;
|
||||
import com.foxinmy.weixin4j.http.apache.MultipartEntity;
|
||||
import com.foxinmy.weixin4j.http.entity.ByteArrayEntity;
|
||||
import com.foxinmy.weixin4j.http.entity.FileEntity;
|
||||
import com.foxinmy.weixin4j.http.entity.FormUrlEntity;
|
||||
import com.foxinmy.weixin4j.http.entity.StringEntity;
|
||||
import com.foxinmy.weixin4j.util.ErrorUtil;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
import com.thoughtworks.xstream.mapper.CannotResolveClassException;
|
||||
|
||||
public class WeixinHttpClient extends SimpleHttpClient {
|
||||
|
||||
@Override
|
||||
protected Map<String, String> createDefualtHeader() {
|
||||
Map<String, String> params = super.createDefualtHeader();
|
||||
params.put(HttpHeaders.USER_AGENT, "weixin4j client/1.5");
|
||||
return params;
|
||||
}
|
||||
|
||||
public WeixinResponse get(String url) throws WeixinException {
|
||||
return get(url, (UrlEncodeParameter[]) null);
|
||||
}
|
||||
|
||||
public WeixinResponse get(String url, Map<String, String> para)
|
||||
throws WeixinException {
|
||||
return get(
|
||||
String.format("%s?%s", url,
|
||||
MapUtil.toJoinString(para, false, false, null)),
|
||||
(UrlEncodeParameter[]) null);
|
||||
}
|
||||
|
||||
public WeixinResponse get(String url, UrlEncodeParameter... parameters)
|
||||
throws WeixinException {
|
||||
StringBuilder sb = new StringBuilder(url);
|
||||
if (parameters != null && parameters.length > 0) {
|
||||
if (url.indexOf("?") < 0) {
|
||||
sb.append("?");
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(parameters[0].encodingParameter());
|
||||
if (parameters.length > 1) {
|
||||
for (int i = 1; i < parameters.length; i++) {
|
||||
sb.append(parameters[i].encodingParameter());
|
||||
}
|
||||
}
|
||||
}
|
||||
return doRequest(new HttpGet(sb.toString()));
|
||||
}
|
||||
|
||||
public WeixinResponse post(String url) throws WeixinException {
|
||||
return post(url, (UrlEncodeParameter[]) null);
|
||||
}
|
||||
|
||||
public WeixinResponse post(String url, UrlEncodeParameter... parameters)
|
||||
throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
if (parameters != null && parameters.length > 0) {
|
||||
method.setEntity(new FormUrlEntity(Arrays.asList(parameters)));
|
||||
}
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
public WeixinResponse post(String url, String body) throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
method.setEntity(new StringEntity(body));
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
public WeixinResponse post(String url, byte[] bytes) throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
method.setEntity(new ByteArrayEntity(bytes,
|
||||
ContentType.MULTIPART_FORM_DATA));
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
public WeixinResponse post(String url, File file) throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
method.setEntity(new FileEntity(file));
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
public WeixinResponse post(String url, FormBodyPart... paramters)
|
||||
throws WeixinException {
|
||||
HttpPost method = new HttpPost(url);
|
||||
MultipartEntity entity = new MultipartEntity();
|
||||
for (FormBodyPart paramter : paramters) {
|
||||
entity.addPart(paramter);
|
||||
}
|
||||
method.setEntity(entity);
|
||||
|
||||
return doRequest(method);
|
||||
}
|
||||
|
||||
protected WeixinResponse doRequest(HttpRequest request)
|
||||
throws WeixinException {
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
HttpResponse httpResponse = execute(request);
|
||||
StatusLine statusLine = httpResponse.getStatusLine();
|
||||
if (statusLine.getStatusCode() >= 300) {
|
||||
throw new WeixinException(String.format("request fail : %d-%s",
|
||||
statusLine.getStatusCode(), statusLine.getStatusText()));
|
||||
}
|
||||
response = new WeixinResponse();
|
||||
response.setContent(httpResponse.getContent());
|
||||
response.setHeaders(httpResponse.getAllHeaders());
|
||||
response.setHttpVersion(httpResponse.getHttpVersion());
|
||||
response.setStatusLine(httpResponse.getStatusLine());
|
||||
Header contentType = httpResponse
|
||||
.getFirstHeader(HttpHeaders.CONTENT_TYPE);
|
||||
Header disposition = httpResponse
|
||||
.getFirstHeader("Content-disposition");
|
||||
// json
|
||||
if (contentType.getValue().contains(
|
||||
ContentType.APPLICATION_JSON.getMimeType())
|
||||
|| (disposition != null && disposition.getValue().indexOf(
|
||||
".json") > 0)) {
|
||||
checkJson(response);
|
||||
} else if (contentType.getValue().contains(
|
||||
ContentType.TEXT_XML.getMimeType())) {
|
||||
checkXml(response);
|
||||
} else if (contentType.getValue().contains(
|
||||
ContentType.TEXT_PLAIN.getMimeType())
|
||||
|| contentType.getValue().contains(
|
||||
ContentType.TEXT_HTML.getMimeType())) {
|
||||
try {
|
||||
checkJson(response);
|
||||
return response;
|
||||
} catch (JSONException e) {
|
||||
;
|
||||
}
|
||||
try {
|
||||
checkXml(response);
|
||||
return response;
|
||||
} catch (CannotResolveClassException ex) {
|
||||
;
|
||||
}
|
||||
throw new WeixinException(response.getAsString());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
// request.releaseConnection();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
private void checkJson(WeixinResponse response) throws WeixinException {
|
||||
JsonResult jsonResult = response.getAsJsonResult();
|
||||
response.setJsonResult(true);
|
||||
if (jsonResult.getCode() != 0) {
|
||||
if (StringUtil.isBlank(jsonResult.getDesc())) {
|
||||
jsonResult.setDesc(ErrorUtil.getText(Integer
|
||||
.toString(jsonResult.getCode())));
|
||||
}
|
||||
throw new WeixinException(Integer.toString(jsonResult.getCode()),
|
||||
jsonResult.getDesc());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkXml(WeixinResponse response) throws WeixinException {
|
||||
XmlResult xmlResult = null;
|
||||
try {
|
||||
xmlResult = response.getAsXmlResult();
|
||||
} catch (CannotResolveClassException ex) {
|
||||
// <?xml><root><data..../data></root>
|
||||
String newXml = response.getAsString()
|
||||
.replaceFirst("<root>", "<xml>")
|
||||
.replaceFirst("<retcode>", "<return_code>")
|
||||
.replaceFirst("</retcode>", "</return_code>")
|
||||
.replaceFirst("<retmsg>", "<return_msg>")
|
||||
.replaceFirst("</retmsg>", "</return_msg>")
|
||||
.replaceFirst("</root>", "</xml>");
|
||||
xmlResult = XmlStream.get(newXml, XmlResult.class);
|
||||
}
|
||||
response.setXmlResult(true);
|
||||
if (xmlResult.getReturnCode().equals("0")) {
|
||||
return;
|
||||
}
|
||||
if (!xmlResult.getReturnCode().equalsIgnoreCase(
|
||||
com.foxinmy.weixin4j.model.Consts.SUCCESS)) {
|
||||
throw new WeixinException(xmlResult.getReturnCode(),
|
||||
xmlResult.getReturnMsg());
|
||||
}
|
||||
if (!xmlResult.getResultCode().equalsIgnoreCase(
|
||||
com.foxinmy.weixin4j.model.Consts.SUCCESS)) {
|
||||
throw new WeixinException(xmlResult.getErrCode(),
|
||||
xmlResult.getErrCodeDes());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package com.foxinmy.weixin4j.http.weixin;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.http.HttpResponse;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
public class WeixinResponse extends HttpResponse {
|
||||
|
||||
private boolean isJsonResult;
|
||||
private boolean isXmlResult;
|
||||
private String text;
|
||||
|
||||
public void setJsonResult(boolean isJsonResult) {
|
||||
this.isJsonResult = isJsonResult;
|
||||
}
|
||||
|
||||
public void setXmlResult(boolean isXmlResult) {
|
||||
this.isXmlResult = isXmlResult;
|
||||
}
|
||||
|
||||
public String getAsString() {
|
||||
if (text == null) {
|
||||
text = StringUtil.newStringUtf8(getContent());
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public JsonResult getAsJsonResult() {
|
||||
return JSON.parseObject(getAsString(), JsonResult.class);
|
||||
}
|
||||
|
||||
public JSONObject getAsJson() {
|
||||
return JSON.parseObject(getAsString());
|
||||
}
|
||||
|
||||
public <T> T getAsObject(TypeReference<T> typeReference) {
|
||||
if (isJsonResult) {
|
||||
return JSON.parseObject(getAsString(), typeReference);
|
||||
}
|
||||
if (isXmlResult) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<T> clazz = (Class<T>) typeReference.getType();
|
||||
return XmlStream.get(getAsString(), clazz);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public XmlResult getAsXmlResult() {
|
||||
return XmlStream.get(getAsString(), XmlResult.class);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
package com.foxinmy.weixin4j.http.weixin;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -529,7 +529,7 @@
|
||||
<error>
|
||||
<code>45008</code>
|
||||
<desc>article size out of limit</desc>
|
||||
<text>article参数超过限制</text>
|
||||
<text>图文消息的文章数量不能超过10条</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>45009</code>
|
||||
@ -861,6 +861,10 @@
|
||||
<code>82003</code>
|
||||
<text>不合法的TagID列表长度</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>82004</code>
|
||||
<text>微信版本号过低</text>
|
||||
</error>
|
||||
<!-- 语义理解API错误 -->
|
||||
<error>
|
||||
<code>7000000</code>
|
||||
@ -1,15 +1,15 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
package com.foxinmy.weixin4j.page;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.foxinmy.weixin4j.util.Sort.Direction;
|
||||
import com.foxinmy.weixin4j.page.Sort.Direction;
|
||||
|
||||
/**
|
||||
* @className Pageable
|
||||
* @author jy
|
||||
* @date 2014年12月27日
|
||||
* @since JDK 1.7
|
||||
* @see org.springframework.data.domain.Pageable
|
||||
* @see com.foxinmy.weixin4j.page.springframework.data.domain.Pageable
|
||||
*/
|
||||
public class Pageable implements Serializable {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
package com.foxinmy.weixin4j.page;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
package com.foxinmy.weixin4j.page;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
@ -19,7 +19,6 @@ import com.thoughtworks.xstream.XStream;
|
||||
* @date 2015年1月9日
|
||||
* @since JDK 1.7
|
||||
* @see com.foxinmy.weixin4j.token.TokenCreator
|
||||
* @see com.foxinmy.weixin4j.mp.token.WeixinTokenCreator
|
||||
*/
|
||||
public class FileTokenHolder implements TokenHolder {
|
||||
private final XStream xstream;
|
||||
|
||||
@ -17,7 +17,6 @@ import com.foxinmy.weixin4j.util.StringUtil;
|
||||
* @date 2015年1月9日
|
||||
* @since JDK 1.7
|
||||
* @see com.foxinmy.weixin4j.token.TokenCreator
|
||||
* @see com.foxinmy.weixin4j.mp.token.WeixinTokenCreator
|
||||
*/
|
||||
public class RedisTokenHolder implements TokenHolder {
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
|
||||
/**
|
||||
* 接口调用错误获取
|
||||
@ -29,7 +29,7 @@ public final class ErrorUtil {
|
||||
static {
|
||||
errorCacheMap = new HashMap<String, String>();
|
||||
try {
|
||||
errorXmlByteArray = IOUtil.toByteArray(Response.class
|
||||
errorXmlByteArray = IOUtil.toByteArray(WeixinResponse.class
|
||||
.getResourceAsStream("error.xml"));
|
||||
} catch (IOException e) {
|
||||
;
|
||||
|
||||
@ -7,10 +7,9 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
|
||||
/**
|
||||
* 签名工具类
|
||||
|
||||
@ -10,7 +10,7 @@ package com.foxinmy.weixin4j.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
|
||||
/**
|
||||
* 提供基于PKCS7算法的加解密接口</br>
|
||||
|
||||
@ -5,8 +5,8 @@ import java.util.Date;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.mp.api.CashApi;
|
||||
import com.foxinmy.weixin4j.mp.api.CouponApi;
|
||||
import com.foxinmy.weixin4j.mp.api.Pay2Api;
|
||||
|
||||
@ -6,7 +6,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.model.Button;
|
||||
import com.foxinmy.weixin4j.mp.api.CustomApi;
|
||||
import com.foxinmy.weixin4j.mp.api.DataApi;
|
||||
|
||||
@ -10,8 +10,8 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.SSLHttpRequest;
|
||||
import com.foxinmy.weixin4j.http.weixin.SSLHttpClinet;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.MPPayment;
|
||||
@ -66,11 +66,11 @@ public class CashApi extends MpApi {
|
||||
obj.put("sign", sign);
|
||||
String param = map2xml(new HashMap<String, Object>(obj));
|
||||
String redpack_send_uri = getRequestUri("redpack_send_uri");
|
||||
Response response = null;
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpRequest request = new SSLHttpRequest(
|
||||
SSLHttpClinet request = new SSLHttpClinet(
|
||||
weixinAccount.getMchId(), ca);
|
||||
response = request.post(redpack_send_uri, param);
|
||||
} catch (WeixinException e) {
|
||||
@ -116,11 +116,11 @@ public class CashApi extends MpApi {
|
||||
obj.put("sign", sign);
|
||||
String param = map2xml(new HashMap<String, Object>(obj));
|
||||
String mp_payment_uri = getRequestUri("mp_payment_uri");
|
||||
Response response = null;
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpRequest request = new SSLHttpRequest(
|
||||
SSLHttpClinet request = new SSLHttpClinet(
|
||||
weixinAccount.getMchId(), ca);
|
||||
response = request.post(mp_payment_uri, param);
|
||||
} catch (WeixinException e) {
|
||||
|
||||
@ -9,8 +9,8 @@ import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.SSLHttpRequest;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.http.weixin.SSLHttpClinet;
|
||||
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
||||
import com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail;
|
||||
@ -75,11 +75,11 @@ public class CouponApi extends MpApi {
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String coupon_send_uri = getRequestUri("coupon_send_uri");
|
||||
Response response = null;
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpRequest request = new SSLHttpRequest(
|
||||
SSLHttpClinet request = new SSLHttpClinet(
|
||||
weixinAccount.getMchId(), ca);
|
||||
response = request.post(coupon_send_uri, param);
|
||||
} catch (WeixinException e) {
|
||||
@ -118,7 +118,7 @@ public class CouponApi extends MpApi {
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String couponstock_query_uri = getRequestUri("couponstock_query_uri");
|
||||
Response response = request.post(couponstock_query_uri, param);
|
||||
WeixinResponse response = weixinClient.post(couponstock_query_uri, param);
|
||||
return response.getAsObject(new TypeReference<CouponStock>() {
|
||||
});
|
||||
}
|
||||
@ -142,7 +142,7 @@ public class CouponApi extends MpApi {
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String coupondetail_query_uri = getRequestUri("coupondetail_query_uri");
|
||||
Response response = request.post(coupondetail_query_uri, param);
|
||||
WeixinResponse response = weixinClient.post(coupondetail_query_uri, param);
|
||||
return response.getAsObject(new TypeReference<CouponDetail>() {
|
||||
});
|
||||
}
|
||||
|
||||
@ -6,15 +6,14 @@ import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.entity.mime.content.ByteArrayBody;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.PartParameter;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.apache.ByteArrayBody;
|
||||
import com.foxinmy.weixin4j.http.apache.FormBodyPart;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.CustomRecord;
|
||||
import com.foxinmy.weixin4j.mp.model.KfAccount;
|
||||
@ -72,7 +71,7 @@ public class CustomApi extends MpApi {
|
||||
obj.put("pageindex", pageindex);
|
||||
String custom_record_uri = getRequestUri("custom_record_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(custom_record_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -102,12 +101,12 @@ public class CustomApi extends MpApi {
|
||||
String text = "";
|
||||
if (isOnline) {
|
||||
String getonlinekflist_uri = getRequestUri("getonlinekflist_uri");
|
||||
Response response = request.post(String.format(getonlinekflist_uri,
|
||||
WeixinResponse response = weixinClient.post(String.format(getonlinekflist_uri,
|
||||
token.getAccessToken()));
|
||||
text = response.getAsJson().getString("kf_online_list");
|
||||
} else {
|
||||
String getkflist_uri = getRequestUri("getkflist_uri");
|
||||
Response response = request.post(String.format(getkflist_uri,
|
||||
WeixinResponse response = weixinClient.post(String.format(getkflist_uri,
|
||||
token.getAccessToken()));
|
||||
text = response.getAsJson().getString("kf_list");
|
||||
}
|
||||
@ -139,7 +138,7 @@ public class CustomApi extends MpApi {
|
||||
obj.put("password", DigestUtil.MD5(pwd));
|
||||
String custom_add_uri = getRequestUri("custom_add_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(custom_add_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
return response.getAsJsonResult();
|
||||
@ -170,7 +169,7 @@ public class CustomApi extends MpApi {
|
||||
obj.put("password", DigestUtil.MD5(pwd));
|
||||
String custom_update_uri = getRequestUri("custom_update_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(custom_update_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
return response.getAsJsonResult();
|
||||
@ -196,10 +195,10 @@ public class CustomApi extends MpApi {
|
||||
Token token = tokenHolder.getToken();
|
||||
String custom_uploadheadimg_uri = getRequestUri("custom_uploadheadimg_uri");
|
||||
byte[] bytes = IOUtil.toByteArray(new FileInputStream(headimg));
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(custom_uploadheadimg_uri, token.getAccessToken(),
|
||||
id),
|
||||
new PartParameter("media", new ByteArrayBody(bytes, headimg
|
||||
new FormBodyPart("media", new ByteArrayBody(bytes, headimg
|
||||
.getName())));
|
||||
|
||||
return response.getAsJsonResult();
|
||||
@ -220,7 +219,7 @@ public class CustomApi extends MpApi {
|
||||
public JsonResult deleteAccount(String id) throws WeixinException {
|
||||
Token token = tokenHolder.getToken();
|
||||
String custom_delete_uri = getRequestUri("custom_delete_uri");
|
||||
Response response = request.get(String.format(custom_delete_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(custom_delete_uri,
|
||||
token.getAccessToken(), id));
|
||||
|
||||
return response.getAsJsonResult();
|
||||
@ -252,7 +251,7 @@ public class CustomApi extends MpApi {
|
||||
obj.put("openid", userOpenId);
|
||||
obj.put("kf_account", kfAccount);
|
||||
obj.put("text", text);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(kfsession_create_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -281,7 +280,7 @@ public class CustomApi extends MpApi {
|
||||
obj.put("openid", userOpenId);
|
||||
obj.put("kf_account", kfAccount);
|
||||
obj.put("text", text);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(kfsession_close_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -302,7 +301,7 @@ public class CustomApi extends MpApi {
|
||||
public KfSession getKfSession(String userOpenId) throws WeixinException {
|
||||
Token token = tokenHolder.getToken();
|
||||
String kfsession_get_uri = getRequestUri("kfsession_get_uri");
|
||||
Response response = request.get(String.format(kfsession_get_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(kfsession_get_uri,
|
||||
token.getAccessToken(), userOpenId));
|
||||
|
||||
KfSession session = response
|
||||
@ -327,7 +326,7 @@ public class CustomApi extends MpApi {
|
||||
throws WeixinException {
|
||||
Token token = tokenHolder.getToken();
|
||||
String kfsession_list_uri = getRequestUri("kfsession_list_uri");
|
||||
Response response = request.get(String.format(kfsession_list_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(kfsession_list_uri,
|
||||
token.getAccessToken(), kfAccount));
|
||||
|
||||
List<KfSession> sessionList = JSON.parseArray(response.getAsJson()
|
||||
@ -347,7 +346,7 @@ public class CustomApi extends MpApi {
|
||||
public List<KfSession> getKfSessionWaitList() throws WeixinException {
|
||||
Token token = tokenHolder.getToken();
|
||||
String kfsession_wait_uri = getRequestUri("kfsession_wait_uri");
|
||||
Response response = request.get(String.format(kfsession_wait_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(kfsession_wait_uri,
|
||||
token.getAccessToken()));
|
||||
|
||||
List<KfSession> sessionList = JSON.parseArray(response.getAsJson()
|
||||
|
||||
@ -7,7 +7,7 @@ import java.util.List;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.type.DatacubeType;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
@ -123,7 +123,7 @@ public class DataApi extends MpApi {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("begin_date", DateUtil.fortmat2yyyy_MM_dd(beginDate));
|
||||
obj.put("end_date", DateUtil.fortmat2yyyy_MM_dd(endDate));
|
||||
Response response = request.post(String.format(datacube_uri,
|
||||
WeixinResponse response = weixinClient.post(String.format(datacube_uri,
|
||||
datacubeType.name().toLowerCase(), token.getAccessToken()), obj
|
||||
.toJSONString());
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@ import java.util.List;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.Group;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
@ -46,7 +46,7 @@ public class GroupApi extends MpApi {
|
||||
String group_create_uri = getRequestUri("group_create_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Group group = new Group(name);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(group_create_uri, token.getAccessToken()),
|
||||
group.toCreateJson());
|
||||
|
||||
@ -65,7 +65,7 @@ public class GroupApi extends MpApi {
|
||||
public List<Group> getGroups() throws WeixinException {
|
||||
String group_get_uri = getRequestUri("group_get_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(group_get_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(group_get_uri,
|
||||
token.getAccessToken()));
|
||||
|
||||
return JSON.parseArray(response.getAsJson().getString("groups"),
|
||||
@ -86,7 +86,7 @@ public class GroupApi extends MpApi {
|
||||
public int getGroupByOpenId(String openId) throws WeixinException {
|
||||
String group_getid_uri = getRequestUri("group_getid_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(group_getid_uri, token.getAccessToken()),
|
||||
String.format("{\"openid\":\"%s\"}", openId));
|
||||
|
||||
@ -112,7 +112,7 @@ public class GroupApi extends MpApi {
|
||||
Token token = tokenHolder.getToken();
|
||||
Group group = new Group(groupId, name);
|
||||
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(group_modify_uri, token.getAccessToken()),
|
||||
group.toModifyJson());
|
||||
return response.getAsJsonResult();
|
||||
@ -134,7 +134,7 @@ public class GroupApi extends MpApi {
|
||||
throws WeixinException {
|
||||
String group_move_uri = getRequestUri("group_move_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(String.format(group_move_uri,
|
||||
WeixinResponse response = weixinClient.post(String.format(group_move_uri,
|
||||
token.getAccessToken()), String.format(
|
||||
"{\"openid\":\"%s\",\"to_groupid\":%d}", openId, groupId));
|
||||
|
||||
@ -160,7 +160,7 @@ public class GroupApi extends MpApi {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("to_groupid", groupId);
|
||||
obj.put("openid_list", openIds);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(group_batchmove_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -180,7 +180,7 @@ public class GroupApi extends MpApi {
|
||||
public JsonResult deleteGroup(int groupId) throws WeixinException {
|
||||
String group_delete_uri = getRequestUri("group_delete_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(group_delete_uri, token.getAccessToken()),
|
||||
String.format("{\"group\":{\"id\":%d}}", groupId));
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ import com.alibaba.fastjson.JSONPath;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Button;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.AutoReplySetting;
|
||||
@ -53,7 +53,7 @@ public class HelperApi extends MpApi {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("action", "long2short");
|
||||
obj.put("long_url", url);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(shorturl_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -75,7 +75,7 @@ public class HelperApi extends MpApi {
|
||||
public SemResult semantic(SemQuery semQuery) throws WeixinException {
|
||||
String semantic_uri = getRequestUri("semantic_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(semantic_uri, token.getAccessToken()),
|
||||
semQuery.toJson());
|
||||
return response.getAsObject(new TypeReference<SemResult>() {
|
||||
@ -93,7 +93,7 @@ public class HelperApi extends MpApi {
|
||||
public List<String> getcallbackip() throws WeixinException {
|
||||
String getcallbackip_uri = getRequestUri("getcallbackip_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(String.format(getcallbackip_uri,
|
||||
WeixinResponse response = weixinClient.post(String.format(getcallbackip_uri,
|
||||
token.getAccessToken()));
|
||||
return JSON.parseArray(response.getAsJson().getString("ip_list"),
|
||||
String.class);
|
||||
@ -115,7 +115,7 @@ public class HelperApi extends MpApi {
|
||||
public MenuSetting getMenuSetting() throws WeixinException {
|
||||
String menu_get_selfmenu_uri = getRequestUri("menu_get_selfmenu_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(menu_get_selfmenu_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(menu_get_selfmenu_uri,
|
||||
token.getAccessToken()));
|
||||
JSONObject result = response.getAsJson();
|
||||
|
||||
@ -188,7 +188,7 @@ public class HelperApi extends MpApi {
|
||||
public AutoReplySetting getAutoReplySetting() throws WeixinException {
|
||||
String autoreply_setting_get_uri = getRequestUri("autoreply_setting_get_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(
|
||||
WeixinResponse response = weixinClient.get(String.format(
|
||||
autoreply_setting_get_uri, token.getAccessToken()));
|
||||
|
||||
JSONObject result = response.getAsJson();
|
||||
|
||||
@ -6,8 +6,8 @@ import java.util.List;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.tuple.MassTuple;
|
||||
@ -53,7 +53,7 @@ public class MassApi extends MpApi {
|
||||
Token token = tokenHolder.getToken();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("articles", articles);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(article_upload_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -76,7 +76,7 @@ public class MassApi extends MpApi {
|
||||
public String uploadVideo(Video video) throws WeixinException {
|
||||
String video_upload_uri = getRequestUri("video_upload_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(video_upload_uri, token.getAccessToken()),
|
||||
JSON.toJSONString(video));
|
||||
|
||||
@ -150,7 +150,7 @@ public class MassApi extends MpApi {
|
||||
obj.put("msgtype", msgtype);
|
||||
String mass_group_uri = getRequestUri("mass_group_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(mass_group_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -216,7 +216,7 @@ public class MassApi extends MpApi {
|
||||
obj.put("msgtype", msgtype);
|
||||
String mass_openid_uri = getRequestUri("mass_openid_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(mass_openid_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -262,7 +262,7 @@ public class MassApi extends MpApi {
|
||||
obj.put("msgid", msgid);
|
||||
String mass_delete_uri = getRequestUri("mass_delete_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(mass_delete_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -291,7 +291,7 @@ public class MassApi extends MpApi {
|
||||
obj.put("msgtype", msgtype);
|
||||
String mass_preview_uri = getRequestUri("mass_preview_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(mass_preview_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -314,7 +314,7 @@ public class MassApi extends MpApi {
|
||||
obj.put("msg_id", msgId);
|
||||
String mass_get_uri = getRequestUri("mass_get_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(mass_get_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
|
||||
@ -9,17 +9,16 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.entity.mime.content.ByteArrayBody;
|
||||
import org.apache.http.entity.mime.content.StringBody;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.PartParameter;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.apache.ByteArrayBody;
|
||||
import com.foxinmy.weixin4j.http.apache.FormBodyPart;
|
||||
import com.foxinmy.weixin4j.http.apache.StringBody;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.MediaCounter;
|
||||
@ -126,22 +125,22 @@ public class MediaApi extends MpApi {
|
||||
"please invoke uploadMaterialVideo method");
|
||||
}
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = null;
|
||||
WeixinResponse response = null;
|
||||
if (isMaterial) {
|
||||
String material_media_upload_uri = getRequestUri("material_media_upload_uri");
|
||||
try {
|
||||
response = request.post(String.format(
|
||||
response = weixinClient.post(String.format(
|
||||
material_media_upload_uri, token.getAccessToken()),
|
||||
new PartParameter("media", new ByteArrayBody(bytes,
|
||||
fileName)), new PartParameter("type",
|
||||
new FormBodyPart("media", new ByteArrayBody(bytes,
|
||||
fileName)), new FormBodyPart("type",
|
||||
new StringBody(mediaType, Consts.UTF_8)));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
; // ignore
|
||||
}
|
||||
} else {
|
||||
String file_upload_uri = getRequestUri("file_upload_uri");
|
||||
response = request.post(String.format(file_upload_uri,
|
||||
token.getAccessToken(), mediaType), new PartParameter(
|
||||
response = weixinClient.post(String.format(file_upload_uri,
|
||||
token.getAccessToken(), mediaType), new FormBodyPart(
|
||||
"media", new ByteArrayBody(bytes, fileName)));
|
||||
}
|
||||
return response.getAsJson().getString("media_id");
|
||||
@ -220,20 +219,20 @@ public class MediaApi extends MpApi {
|
||||
public byte[] downloadMedia(String mediaId, boolean isMaterial)
|
||||
throws WeixinException {
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = null;
|
||||
WeixinResponse response = null;
|
||||
if (isMaterial) {
|
||||
JSONObject media = new JSONObject();
|
||||
media.put("media_id", mediaId);
|
||||
String material_media_download_uri = getRequestUri("material_media_download_uri");
|
||||
response = request.post(
|
||||
response = weixinClient.post(
|
||||
String.format(material_media_download_uri,
|
||||
token.getAccessToken()), media.toJSONString());
|
||||
} else {
|
||||
String file_download_uri = getRequestUri("file_download_uri");
|
||||
response = request.get(String.format(file_download_uri,
|
||||
response = weixinClient.get(String.format(file_download_uri,
|
||||
token.getAccessToken(), mediaId));
|
||||
}
|
||||
return response.getBody();
|
||||
return response.getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,7 +256,7 @@ public class MediaApi extends MpApi {
|
||||
String material_article_upload_uri = getRequestUri("material_article_upload_uri");
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("articles", articles);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(material_article_upload_uri,
|
||||
token.getAccessToken()), obj.toJSONString());
|
||||
|
||||
@ -306,7 +305,7 @@ public class MediaApi extends MpApi {
|
||||
obj.put("articles", articles);
|
||||
obj.put("media_id", mediaId);
|
||||
obj.put("index", index);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(material_article_update_uri,
|
||||
token.getAccessToken()), obj.toJSONString());
|
||||
|
||||
@ -329,7 +328,7 @@ public class MediaApi extends MpApi {
|
||||
String material_media_del_uri = getRequestUri("material_media_del_uri");
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("media_id", mediaId);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(material_media_del_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -360,14 +359,14 @@ public class MediaApi extends MpApi {
|
||||
description.put("title", title);
|
||||
description.put("introduction", introduction);
|
||||
byte[] bytes = IOUtil.toByteArray(new FileInputStream(file));
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(material_media_upload_uri,
|
||||
token.getAccessToken()),
|
||||
new PartParameter("media", new ByteArrayBody(bytes, file
|
||||
new FormBodyPart("media", new ByteArrayBody(bytes, file
|
||||
.getName())),
|
||||
new PartParameter("type", new StringBody(MediaType.video
|
||||
new FormBodyPart("type", new StringBody(MediaType.video
|
||||
.name(), Consts.UTF_8)),
|
||||
new PartParameter("description", new StringBody(description
|
||||
new FormBodyPart("description", new StringBody(description
|
||||
.toJSONString(), Consts.UTF_8)));
|
||||
return response.getAsJson().getString("media_id");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
@ -387,7 +386,7 @@ public class MediaApi extends MpApi {
|
||||
public MediaCounter countMaterialMedia() throws WeixinException {
|
||||
Token token = tokenHolder.getToken();
|
||||
String material_media_count_uri = getRequestUri("material_media_count_uri");
|
||||
Response response = request.get(String.format(material_media_count_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(material_media_count_uri,
|
||||
token.getAccessToken()));
|
||||
|
||||
return response.getAsObject(new TypeReference<MediaCounter>() {
|
||||
@ -419,7 +418,7 @@ public class MediaApi extends MpApi {
|
||||
obj.put("type", mediaType.name());
|
||||
obj.put("offset", offset);
|
||||
obj.put("count", count);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(material_media_list_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
MediaRecord mediaRecord = null;
|
||||
|
||||
@ -11,8 +11,8 @@ import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
|
||||
import com.alibaba.fastjson.parser.deserializer.ParseProcess;
|
||||
import com.alibaba.fastjson.serializer.NameFilter;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Button;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
@ -50,7 +50,7 @@ public class MenuApi extends MpApi {
|
||||
Token token = tokenHolder.getToken();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("button", btnList);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(menu_create_uri, token.getAccessToken()),
|
||||
JSON.toJSONString(obj, new NameFilter() {
|
||||
@Override
|
||||
@ -87,7 +87,7 @@ public class MenuApi extends MpApi {
|
||||
public List<Button> getMenu() throws WeixinException {
|
||||
String menu_get_uri = getRequestUri("menu_get_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(menu_get_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(menu_get_uri,
|
||||
token.getAccessToken()));
|
||||
|
||||
JSONArray buttons = response.getAsJson().getJSONObject("menu")
|
||||
@ -117,7 +117,7 @@ public class MenuApi extends MpApi {
|
||||
public JsonResult deleteMenu() throws WeixinException {
|
||||
String menu_delete_uri = getRequestUri("menu_delete_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(menu_delete_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(menu_delete_uri,
|
||||
token.getAccessToken()));
|
||||
|
||||
return response.getAsJsonResult();
|
||||
|
||||
@ -2,8 +2,8 @@ package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.message.NotifyMessage;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
@ -76,7 +76,7 @@ public class NotifyApi extends MpApi {
|
||||
}
|
||||
String custom_notify_uri = getRequestUri("custom_notify_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(custom_notify_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import java.net.URLEncoder;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.mp.model.OauthToken;
|
||||
@ -92,7 +92,7 @@ public class OauthApi extends MpApi {
|
||||
public OauthToken getOauthToken(String code, String appid, String appsecret)
|
||||
throws WeixinException {
|
||||
String user_token_uri = getRequestUri("sns_user_token_uri");
|
||||
Response response = request.get(String.format(user_token_uri, appid,
|
||||
WeixinResponse response = weixinClient.get(String.format(user_token_uri, appid,
|
||||
appsecret, code));
|
||||
|
||||
return response.getAsObject(new TypeReference<OauthToken>() {
|
||||
@ -122,7 +122,7 @@ public class OauthApi extends MpApi {
|
||||
public OauthToken refreshToken(String appId, String refreshToken)
|
||||
throws WeixinException {
|
||||
String sns_token_refresh_uri = getRequestUri("sns_token_refresh_uri");
|
||||
Response response = request.get(String.format(sns_token_refresh_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(sns_token_refresh_uri,
|
||||
appId, refreshToken));
|
||||
|
||||
return response.getAsObject(new TypeReference<OauthToken>() {
|
||||
@ -141,7 +141,7 @@ public class OauthApi extends MpApi {
|
||||
public boolean authAccessToken(String accessToken, String openId) {
|
||||
String sns_auth_token_uri = getRequestUri("sns_auth_token_uri");
|
||||
try {
|
||||
request.get(String.format(sns_auth_token_uri, accessToken, openId));
|
||||
weixinClient.get(String.format(sns_auth_token_uri, accessToken, openId));
|
||||
return true;
|
||||
} catch (WeixinException e) {
|
||||
;
|
||||
@ -164,7 +164,7 @@ public class OauthApi extends MpApi {
|
||||
*/
|
||||
public User getUser(OauthToken token) throws WeixinException {
|
||||
String user_info_uri = getRequestUri("sns_user_info_uri");
|
||||
Response response = request.get(String.format(user_info_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(user_info_uri,
|
||||
token.getAccessToken(), token.getOpenid()));
|
||||
|
||||
return response.getAsObject(new TypeReference<User>() {
|
||||
|
||||
@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
@ -22,15 +23,14 @@ import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.SSLHttpRequest;
|
||||
import com.foxinmy.weixin4j.http.weixin.SSLHttpClinet;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
||||
@ -106,7 +106,7 @@ public class Pay2Api extends PayApi {
|
||||
obj.put("app_signature", signature);
|
||||
obj.put("sign_method", SignType.SHA1.name().toLowerCase());
|
||||
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(orderquery_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
@ -153,7 +153,7 @@ public class Pay2Api extends PayApi {
|
||||
String outRefundNo, double totalFee, double refundFee,
|
||||
String opUserId, Map<String, String> mopara) throws WeixinException {
|
||||
String refund_uri = getRequestUri("refund_v2_uri");
|
||||
Response response = null;
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
@ -214,7 +214,7 @@ public class Pay2Api extends PayApi {
|
||||
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
|
||||
new SecureRandom());
|
||||
|
||||
SSLHttpRequest request = new SSLHttpRequest(ctx);
|
||||
SSLHttpClinet request = new SSLHttpClinet(ctx);
|
||||
response = request.get(refund_uri, map);
|
||||
} catch (WeixinException e) {
|
||||
throw e;
|
||||
@ -385,19 +385,18 @@ public class Pay2Api extends PayApi {
|
||||
map.put("cft_signtype", "0");
|
||||
map.put("mchtype", Integer.toString(billType.getVal()));
|
||||
map.put("key", weixinAccount.getPartnerKey());
|
||||
String sign = DigestUtil.MD5(MapUtil
|
||||
.toJoinString(map, false, false));
|
||||
String sign = DigestUtil.MD5(MapUtil.toJoinString(map, false, false));
|
||||
map.put("sign", sign.toLowerCase());
|
||||
Response response = request.get(downloadbill_uri, map);
|
||||
WeixinResponse response = weixinClient.get(downloadbill_uri, map);
|
||||
BufferedReader reader = null;
|
||||
BufferedWriter writer = null;
|
||||
FileWriter fw = null;
|
||||
try {
|
||||
fw = new FileWriter(file);
|
||||
writer = new BufferedWriter(fw);
|
||||
reader = new BufferedReader(
|
||||
new InputStreamReader(response.getStream(),
|
||||
com.foxinmy.weixin4j.model.Consts.GBK));
|
||||
reader = new BufferedReader(new InputStreamReader(
|
||||
new ByteArrayInputStream(response.getContent()),
|
||||
com.foxinmy.weixin4j.model.Consts.GBK));
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
writer.write(line);
|
||||
@ -442,7 +441,7 @@ public class Pay2Api extends PayApi {
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPartnerKey());
|
||||
map.put("sign", sign.toLowerCase());
|
||||
Response response = request.get(refundquery_uri, map);
|
||||
WeixinResponse response = weixinClient.get(refundquery_uri, map);
|
||||
return RefundConverter.fromXML(response.getAsString(),
|
||||
RefundRecord.class);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
@ -15,14 +16,13 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.SSLHttpRequest;
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.SSLHttpClinet;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
||||
import com.foxinmy.weixin4j.mp.payment.conver.CouponConverter;
|
||||
@ -79,7 +79,7 @@ public class Pay3Api extends PayApi {
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String orderquery_uri = getRequestUri("orderquery_v3_uri");
|
||||
Response response = request.post(orderquery_uri, param);
|
||||
WeixinResponse response = weixinClient.post(orderquery_uri, param);
|
||||
return CouponConverter.fromXML(response.getAsString(), Order.class);
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ public class Pay3Api extends PayApi {
|
||||
String outRefundNo, double totalFee, double refundFee,
|
||||
String opUserId, Map<String, String> mopara) throws WeixinException {
|
||||
String refund_uri = getRequestUri("refund_v3_uri");
|
||||
Response response = null;
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
@ -140,8 +140,8 @@ public class Pay3Api extends PayApi {
|
||||
.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
SSLHttpRequest request = new SSLHttpRequest(
|
||||
weixinAccount.getMchId(), ca);
|
||||
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
|
||||
ca);
|
||||
response = request.post(refund_uri, param);
|
||||
} catch (WeixinException e) {
|
||||
throw e;
|
||||
@ -212,15 +212,15 @@ public class Pay3Api extends PayApi {
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpRequest request = new SSLHttpRequest(
|
||||
weixinAccount.getMchId(), ca);
|
||||
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
|
||||
ca);
|
||||
String reverse_uri = getRequestUri("reverse_uri");
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
String sign = PayUtil
|
||||
.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
Response response = request.post(reverse_uri, param);
|
||||
WeixinResponse response = request.post(reverse_uri, param);
|
||||
return response.getAsObject(new TypeReference<ApiResult>() {
|
||||
});
|
||||
} catch (IOException e) {
|
||||
@ -258,7 +258,7 @@ public class Pay3Api extends PayApi {
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String shorturl_uri = getRequestUri("p_shorturl_uri");
|
||||
Response response = request.post(shorturl_uri, param);
|
||||
WeixinResponse response = weixinClient.post(shorturl_uri, param);
|
||||
map = xml2map(response.getAsString());
|
||||
return map.get("short_url");
|
||||
}
|
||||
@ -285,7 +285,7 @@ public class Pay3Api extends PayApi {
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String closeorder_uri = getRequestUri("closeorder_uri");
|
||||
Response response = request.post(closeorder_uri, param);
|
||||
WeixinResponse response = weixinClient.post(closeorder_uri, param);
|
||||
return response.getAsObject(new TypeReference<ApiResult>() {
|
||||
});
|
||||
}
|
||||
@ -333,7 +333,7 @@ public class Pay3Api extends PayApi {
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
Response response = request.post(downloadbill_uri, param);
|
||||
WeixinResponse response = weixinClient.post(downloadbill_uri, param);
|
||||
|
||||
BufferedReader reader = null;
|
||||
BufferedWriter writer = null;
|
||||
@ -341,9 +341,9 @@ public class Pay3Api extends PayApi {
|
||||
try {
|
||||
fw = new FileWriter(file);
|
||||
writer = new BufferedWriter(fw);
|
||||
reader = new BufferedReader(
|
||||
new InputStreamReader(response.getStream(),
|
||||
com.foxinmy.weixin4j.model.Consts.GBK));
|
||||
reader = new BufferedReader(new InputStreamReader(
|
||||
new ByteArrayInputStream(response.getContent()),
|
||||
com.foxinmy.weixin4j.model.Consts.GBK));
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
writer.write(line);
|
||||
@ -392,7 +392,7 @@ public class Pay3Api extends PayApi {
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
Response response = request.post(refundquery_uri, param);
|
||||
WeixinResponse response = weixinClient.post(refundquery_uri, param);
|
||||
return RefundConverter.fromXML(response.getAsString(),
|
||||
RefundRecord.class);
|
||||
}
|
||||
@ -433,7 +433,7 @@ public class Pay3Api extends PayApi {
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
Response response = request.post(pay_report_uri, param);
|
||||
WeixinResponse response = weixinClient.post(pay_report_uri, param);
|
||||
return response.getAsXmlResult();
|
||||
}
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@ import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
||||
@ -73,7 +73,7 @@ public abstract class PayApi extends MpApi {
|
||||
map.put("app_signature", PayUtil.paysignSha(map));
|
||||
map.put("sign_method", SignType.SHA1.name().toLowerCase());
|
||||
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(delivernotify_uri, token.getAccessToken()),
|
||||
JSON.toJSONString(map));
|
||||
return response.getAsJsonResult();
|
||||
@ -93,7 +93,7 @@ public abstract class PayApi extends MpApi {
|
||||
throws WeixinException {
|
||||
String payfeedback_update_uri = getRequestUri("payfeedback_update_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(payfeedback_update_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(payfeedback_update_uri,
|
||||
token.getAccessToken(), openId, feedbackId));
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import java.io.OutputStream;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.QRParameter;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
@ -48,7 +48,7 @@ public class QrApi extends MpApi {
|
||||
private JSONObject doQR(QRParameter parameter) throws WeixinException {
|
||||
Token token = tokenHolder.getToken();
|
||||
String qr_uri = getRequestUri("qr_ticket_uri");
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(qr_uri, token.getAccessToken()),
|
||||
parameter.getContent());
|
||||
return response.getAsJson();
|
||||
@ -68,9 +68,10 @@ public class QrApi extends MpApi {
|
||||
public byte[] getQRData(QRParameter parameter) throws WeixinException {
|
||||
String ticket = doQR(parameter).getString("ticket");
|
||||
String qr_uri = getRequestUri("qr_image_uri");
|
||||
Response response = request.get(String.format(qr_uri, ticket));
|
||||
WeixinResponse response = weixinClient.get(String
|
||||
.format(qr_uri, ticket));
|
||||
|
||||
return response.getBody();
|
||||
return response.getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,13 +100,8 @@ public class QrApi extends MpApi {
|
||||
byte[] datas = getQRData(parameter);
|
||||
OutputStream os = null;
|
||||
try {
|
||||
if (file.createNewFile()) {
|
||||
os = new FileOutputStream(file);
|
||||
os.write(datas);
|
||||
} else {
|
||||
throw new WeixinException(String.format("create file fail:%s",
|
||||
file.getAbsolutePath()));
|
||||
}
|
||||
os = new FileOutputStream(file);
|
||||
os.write(datas);
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
|
||||
@ -3,8 +3,8 @@ package com.foxinmy.weixin4j.mp.api;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.message.TemplateMessage;
|
||||
import com.foxinmy.weixin4j.mp.type.IndustryType;
|
||||
@ -47,7 +47,7 @@ public class TmplApi extends MpApi {
|
||||
}
|
||||
Token token = tokenHolder.getToken();
|
||||
String template_set_industry_uri = getRequestUri("template_set_industry_uri");
|
||||
Response response = request.post(String.format(
|
||||
WeixinResponse response = weixinClient.post(String.format(
|
||||
template_set_industry_uri, token.getAccessToken()), obj
|
||||
.toJSONString());
|
||||
|
||||
@ -67,7 +67,7 @@ public class TmplApi extends MpApi {
|
||||
public String getTemplateId(String shortId) throws WeixinException {
|
||||
Token token = tokenHolder.getToken();
|
||||
String template_getid_uri = getRequestUri("template_getid_uri");
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(template_getid_uri, token.getAccessToken()),
|
||||
String.format("{\"template_id_short\":\"%s\"}", shortId));
|
||||
|
||||
@ -90,7 +90,7 @@ public class TmplApi extends MpApi {
|
||||
throws WeixinException {
|
||||
Token token = tokenHolder.getToken();
|
||||
String template_send_uri = getRequestUri("template_send_uri");
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(template_send_uri, token.getAccessToken()),
|
||||
JSON.toJSONString(tplMessage));
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.Following;
|
||||
import com.foxinmy.weixin4j.mp.model.User;
|
||||
@ -69,7 +69,7 @@ public class UserApi extends MpApi {
|
||||
public User getUser(String openId, Lang lang) throws WeixinException {
|
||||
String user_info_uri = getRequestUri("api_user_info_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(user_info_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(user_info_uri,
|
||||
token.getAccessToken(), openId, lang.name()));
|
||||
|
||||
return response.getAsObject(new TypeReference<User>() {
|
||||
@ -90,7 +90,7 @@ public class UserApi extends MpApi {
|
||||
public Following getFollowing(String nextOpenId) throws WeixinException {
|
||||
String following_uri = getRequestUri("following_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(following_uri,
|
||||
WeixinResponse response = weixinClient.get(String.format(following_uri,
|
||||
token.getAccessToken(), nextOpenId == null ? "" : nextOpenId));
|
||||
|
||||
Following following = response
|
||||
@ -156,7 +156,7 @@ public class UserApi extends MpApi {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("openid", openId);
|
||||
obj.put("remark", remark);
|
||||
Response response = request.post(
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(updateremark_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ package com.foxinmy.weixin4j.mp.model;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
|
||||
/**
|
||||
* 语义理解结果
|
||||
|
||||
@ -7,8 +7,8 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.PayException;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.JsPayRequestV2;
|
||||
@ -151,7 +151,7 @@ public class PayUtil {
|
||||
// stringSignTemp 进行 md5 运算
|
||||
// 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。
|
||||
sb.append("&key=").append(paySignKey);
|
||||
return DigestUtil.SHA1(sb.toString()).toUpperCase();
|
||||
return DigestUtil.MD5(sb.toString()).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,15 +219,15 @@ public class PayUtil {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1">统一下单接口</a>
|
||||
* @return 预支付对象
|
||||
*/
|
||||
private final static WeixinHttpClient httpClient = new WeixinHttpClient();
|
||||
public static PrePay createPrePay(PayPackageV3 payPackage, String paySignKey)
|
||||
throws PayException {
|
||||
if (StringUtil.isBlank(payPackage.getSign())) {
|
||||
payPackage.setSign(paysignMd5(payPackage, paySignKey));
|
||||
}
|
||||
String payJsRequestXml = XmlStream.to(payPackage).replaceAll("__", "_");
|
||||
HttpRequest request = new HttpRequest();
|
||||
try {
|
||||
Response response = request.post(Consts.UNIFIEDORDER,
|
||||
WeixinResponse response = httpClient.post(Consts.UNIFIEDORDER,
|
||||
payJsRequestXml);
|
||||
PrePay prePay = response.getAsObject(new TypeReference<PrePay>() {
|
||||
});
|
||||
@ -407,8 +407,7 @@ public class PayUtil {
|
||||
String sign = paysignMd5(payPackage, weixinAccount.getPaySignKey());
|
||||
payPackage.setSign(sign);
|
||||
String para = XmlStream.to(payPackage).replaceAll("__", "_");
|
||||
HttpRequest request = new HttpRequest();
|
||||
Response response = request.post(Consts.MICROPAYURL, para);
|
||||
WeixinResponse response = httpClient.post(Consts.MICROPAYURL, para);
|
||||
return response
|
||||
.getAsObject(new TypeReference<com.foxinmy.weixin4j.mp.payment.v3.Order>() {
|
||||
});
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
|
||||
@ -2,8 +2,8 @@ package com.foxinmy.weixin4j.mp.token;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.token.TokenCreator;
|
||||
@ -24,7 +24,7 @@ public class WeixinJSTicketCreator implements TokenCreator {
|
||||
|
||||
private final String appid;
|
||||
private final TokenHolder weixinTokenHolder;
|
||||
private final HttpRequest request;
|
||||
private final WeixinHttpClient httpClient;
|
||||
|
||||
/**
|
||||
* jssdk
|
||||
@ -37,7 +37,7 @@ public class WeixinJSTicketCreator implements TokenCreator {
|
||||
public WeixinJSTicketCreator(String appid, TokenHolder weixinTokenHolder) {
|
||||
this.appid = appid;
|
||||
this.weixinTokenHolder = weixinTokenHolder;
|
||||
this.request = new HttpRequest();
|
||||
this.httpClient = new WeixinHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -47,7 +47,7 @@ public class WeixinJSTicketCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public Token createToken() throws WeixinException {
|
||||
Response response = request.get(String.format(Consts.MP_JS_TICKET_URL,
|
||||
WeixinResponse response = httpClient.get(String.format(Consts.MP_JS_TICKET_URL,
|
||||
weixinTokenHolder.getToken().getAccessToken()));
|
||||
JSONObject result = response.getAsJson();
|
||||
Token token = new Token(result.getString("ticket"));
|
||||
|
||||
@ -2,8 +2,8 @@ package com.foxinmy.weixin4j.mp.token;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
@ -23,7 +23,7 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
*/
|
||||
public class WeixinTokenCreator implements TokenCreator {
|
||||
|
||||
private final HttpRequest request;
|
||||
private final WeixinHttpClient httpClient;
|
||||
private final String appid;
|
||||
private final String secret;
|
||||
|
||||
@ -31,13 +31,13 @@ public class WeixinTokenCreator implements TokenCreator {
|
||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
this.appid = weixinAccount.getId();
|
||||
this.secret = weixinAccount.getSecret();
|
||||
this.request = new HttpRequest();
|
||||
this.httpClient = new WeixinHttpClient();
|
||||
}
|
||||
|
||||
public WeixinTokenCreator(String appid, String secret) {
|
||||
this.appid = appid;
|
||||
this.secret = secret;
|
||||
this.request = new HttpRequest();
|
||||
this.httpClient = new WeixinHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -49,7 +49,7 @@ public class WeixinTokenCreator implements TokenCreator {
|
||||
public Token createToken() throws WeixinException {
|
||||
String tokenUrl = String.format(Consts.MP_ASSESS_TOKEN_URL, appid,
|
||||
secret);
|
||||
Response response = request.get(tokenUrl);
|
||||
WeixinResponse response = httpClient.get(tokenUrl);
|
||||
Token token = response.getAsObject(new TypeReference<Token>() {
|
||||
});
|
||||
token.setTime(System.currentTimeMillis());
|
||||
|
||||
@ -30,12 +30,13 @@ public class CouponTest {
|
||||
protected final static WeixinPayProxy WEIXINPAY;
|
||||
protected final static WeixinMpAccount ACCOUNT;
|
||||
static {
|
||||
ACCOUNT = new WeixinMpAccount("公众号的id", "公众号的secret", "公众号的支付密钥",
|
||||
"商户平台的id");
|
||||
ACCOUNT = new WeixinMpAccount("appid",
|
||||
"appsecret",
|
||||
"paysing", "mchid");
|
||||
WEIXINPAY = new WeixinPayProxy(ACCOUNT, new FileTokenHolder(
|
||||
new WeixinTokenCreator(ACCOUNT.getId(), ACCOUNT.getSecret())));
|
||||
}
|
||||
protected final File caFile = new File("证书文件的路径(*.p12)");
|
||||
protected final File caFile = new File("证书文件路径(*.p12)");
|
||||
|
||||
@Test
|
||||
public void sendCoupon() throws WeixinException {
|
||||
|
||||
@ -11,7 +11,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.CustomApi;
|
||||
import com.foxinmy.weixin4j.mp.model.CustomRecord;
|
||||
import com.foxinmy.weixin4j.mp.model.KfAccount;
|
||||
|
||||
@ -7,7 +7,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.GroupApi;
|
||||
import com.foxinmy.weixin4j.mp.model.Group;
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.MassApi;
|
||||
import com.foxinmy.weixin4j.mp.api.MediaApi;
|
||||
import com.foxinmy.weixin4j.tuple.Image;
|
||||
|
||||
@ -10,7 +10,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.MediaApi;
|
||||
import com.foxinmy.weixin4j.mp.model.MediaCounter;
|
||||
import com.foxinmy.weixin4j.mp.model.MediaItem;
|
||||
|
||||
@ -8,7 +8,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.model.Button;
|
||||
import com.foxinmy.weixin4j.mp.api.MenuApi;
|
||||
import com.foxinmy.weixin4j.type.ButtonType;
|
||||
|
||||
@ -8,7 +8,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.MediaApi;
|
||||
import com.foxinmy.weixin4j.mp.api.NotifyApi;
|
||||
import com.foxinmy.weixin4j.mp.message.NotifyMessage;
|
||||
|
||||
@ -9,7 +9,7 @@ import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.PayException;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.mp.WeixinPayProxy;
|
||||
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
||||
@ -29,8 +29,8 @@ public class PayTest {
|
||||
private final static WeixinMpAccount ACCOUNT2;
|
||||
private final static WeixinMpAccount ACCOUNT3;
|
||||
static {
|
||||
ACCOUNT2 = new WeixinMpAccount("请填入v2版本的appid", "请填入v2版本的appsecret",
|
||||
"请填入v2版本的paysignkey", "请填入v2版本的partnerId", "请填入v2版本的partnerKey");
|
||||
ACCOUNT2 = new WeixinMpAccount("请填入v2版本的appid", "请填入v2版本的appSecret",
|
||||
"请填入v3版本的paysignkey", "请填入v2版本的partnerId", "请填入v2版本的partnerKey");
|
||||
PAY2 = new WeixinPayProxy(ACCOUNT2, new FileTokenHolder(
|
||||
new WeixinTokenCreator(ACCOUNT2.getId(), ACCOUNT2.getSecret())));
|
||||
ACCOUNT3 = new WeixinMpAccount("请填入v3版本的appid", "请填入v3版本的appSecret",
|
||||
|
||||
@ -5,7 +5,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.TmplApi;
|
||||
import com.foxinmy.weixin4j.mp.message.TemplateMessage;
|
||||
import com.foxinmy.weixin4j.mp.type.IndustryType;
|
||||
|
||||
@ -7,7 +7,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.UserApi;
|
||||
import com.foxinmy.weixin4j.mp.model.User;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user