去掉httpclient依赖

This commit is contained in:
jinyu 2015-05-30 20:35:54 +08:00
parent a818ea42d7
commit 305738e832
119 changed files with 4621 additions and 850 deletions

View File

@ -299,4 +299,8 @@
* 2015-05-20
+ **weixin4j-server**: released 1.0.1
+ **weixin4j-server**: released 1.0.1
* 2015-05-30
**大的调整去掉httpclient依赖**

View File

@ -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>

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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() + "]";
}
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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";
}

View File

@ -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);
}

View File

@ -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 + "]";
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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 + "]";
}
}

View File

@ -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 + "]";
}
}

View File

@ -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;
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
}
}

View 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
}
}

View File

@ -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() {
}
}

View File

@ -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();
}
}

View File

@ -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";
}

View File

@ -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;
}
}
}

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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");
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.http;
package com.foxinmy.weixin4j.http.weixin;
import java.io.Serializable;

View File

@ -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;
}
}

View File

@ -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());
}
}
}

View File

@ -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);
}
}

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.http;
package com.foxinmy.weixin4j.http.weixin;
import java.io.Serializable;

View File

@ -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>

View File

@ -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 {

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.util;
package com.foxinmy.weixin4j.page;
import java.io.Serializable;
import java.util.Iterator;

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.util;
package com.foxinmy.weixin4j.page;
import java.io.Serializable;
import java.util.ArrayList;

View File

@ -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;

View File

@ -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 {

View File

@ -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) {
;

View File

@ -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;
/**
* 签名工具类

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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>() {
});
}

View File

@ -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()

View File

@ -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());

View File

@ -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));

View File

@ -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();

View File

@ -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());

View File

@ -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;

View File

@ -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();

View File

@ -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());

View File

@ -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>() {

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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 {

View File

@ -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));

View File

@ -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());

View File

@ -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;
/**
* 语义理解结果

View File

@ -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>() {
});

View File

@ -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;

View File

@ -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;
/**

View File

@ -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"));

View File

@ -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());

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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",

View File

@ -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;

View File

@ -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