This commit is contained in:
jinyu 2018-07-08 22:10:56 +08:00
parent a6ec644596
commit b2ca23721e
19 changed files with 197 additions and 193 deletions

View File

@ -810,4 +810,13 @@
* 2018-06-14
+ version upgrade to 1.8.0
+ 新增了微信小程序相关的支持 API 实现
* 2018-07-08
+ [XEE](https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet)bug修复
+ 上传媒体文件content-length为-1导致503问题修复
+ release1.8.2版本

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
<packaging>pom</packaging>
<name>weixin4j</name>
<url>https://github.com/foxinmy/weixin4j</url>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<artifactId>weixin4j-base</artifactId>
<name>weixin4j-base</name>
@ -71,11 +71,5 @@
<version>3.0.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.19</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -50,7 +50,8 @@ public class InputStreamBody extends AbstractContentBody {
* @since 4.1
*
*/
public InputStreamBody(final InputStream in, final String mimeType, final String filename) {
public InputStreamBody(final InputStream in, final String mimeType,
final String filename) {
this(in, ContentType.create(mimeType), filename);
}
@ -61,7 +62,8 @@ public class InputStreamBody extends AbstractContentBody {
/**
* @since 4.3
*/
public InputStreamBody(final InputStream in, final ContentType contentType, final String filename) {
public InputStreamBody(final InputStream in, final ContentType contentType,
final String filename) {
super(contentType);
this.in = in;
this.filename = filename;
@ -99,8 +101,12 @@ public class InputStreamBody extends AbstractContentBody {
@Override
public long getContentLength() {
try {
return in.available();
} catch (IOException e) {
return -1;
}
}
@Override
public String getFilename() {

View File

@ -42,10 +42,8 @@ class MultipartFormEntity implements HttpEntity {
private final ContentType contentType;
private final long contentLength;
MultipartFormEntity(
final AbstractMultipartForm multipart,
final ContentType contentType,
final long contentLength) {
MultipartFormEntity(final AbstractMultipartForm multipart,
final ContentType contentType, final long contentLength) {
super();
this.multipart = multipart;
this.contentType = contentType;
@ -81,8 +79,9 @@ class MultipartFormEntity implements HttpEntity {
public InputStream getContent() throws IOException {
if (this.contentLength < 0) {
throw new IllegalArgumentException("Content length is unknown");
} else if (this.contentLength > 25 * 1024) {
throw new IllegalArgumentException("Content length is too long: " + this.contentLength);
} else if (this.contentLength > 5 * 1024 * 1024) {
throw new IllegalArgumentException("Content length is too long: "
+ this.contentLength);
}
final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
writeTo(outstream);

View File

@ -23,7 +23,6 @@ import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.util.EntityUtils;
import com.foxinmy.weixin4j.http.AbstractHttpClient;
@ -31,7 +30,6 @@ import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpMethod;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.apache.mime.MultipartEntity;
import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.util.StringUtil;
@ -119,18 +117,12 @@ public abstract class HttpComponent4 extends AbstractHttpClient {
protected void resolveContent(HttpEntity entity, HttpRequestBase httpRequest)
throws IOException {
if (entity != null) {
AbstractHttpEntity httpEntity = null;
if (entity instanceof MultipartEntity) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
entity.writeTo(os);
os.flush();
httpEntity = new org.apache.http.entity.ByteArrayEntity(
AbstractHttpEntity httpEntity = new org.apache.http.entity.ByteArrayEntity(
os.toByteArray());
os.close();
} else {
httpEntity = new InputStreamEntity(entity.getContent(),
entity.getContentLength());
}
httpEntity.setContentType(entity.getContentType().toString());
((HttpEntityEnclosingRequestBase) httpRequest)
.setEntity(httpEntity);

View File

@ -6,6 +6,8 @@ import java.util.List;
import java.util.Map.Entry;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;
import com.foxinmy.weixin4j.http.AbstractHttpClient;
import com.foxinmy.weixin4j.http.HttpClientException;
@ -20,6 +22,7 @@ import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.Util;
/**
* OkHttp2
@ -130,7 +133,13 @@ public class OkHttpClient2 extends AbstractHttpClient {
@Override
public void writeTo(BufferedSink sink) throws IOException {
entity.writeTo(sink.outputStream());
Source source = null;
try {
source = Okio.source(entity.getContent());
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
}
}
@Override

View File

@ -28,7 +28,6 @@ public class OkHttpClient2Factory extends HttpClientFactory {
okClient.setHostnameVerifier(HttpClientFactory.AllowHostnameVerifier.GLOBAL);
okClient.setSslSocketFactory(HttpClientFactory.allowSSLContext()
.getSocketFactory());
}
public OkHttpClient2Factory(OkHttpClient okClient) {

View File

@ -71,7 +71,7 @@ public class SceneInfoApp {
* @return
*/
public static SceneInfoApp createAndroidAPP(String appName, String packageName) {
SceneInfoApp app = new SceneInfoApp("IOS", appName, packageName);
SceneInfoApp app = new SceneInfoApp("Android", appName, packageName);
String sceneInfo = String
.format("{\"type\": \"%s\",\"app_name\": \"%s\",\"package_name\": \"%s\"}",
app.getType(), app.getName(), app.getPath());

View File

@ -19,6 +19,7 @@ import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
@ -26,7 +27,9 @@ import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.sax.SAXSource;
import org.xml.sax.InputSource;
import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.util.Consts;
@ -45,6 +48,16 @@ public final class XmlStream {
private final static String ROOT_ELEMENT_XML = "xml";
private final static String XML_VERSION = "1.0";
private final static ConcurrentHashMap<Class<?>, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class<?>, JAXBContext>();
private final static SAXParserFactory spf = SAXParserFactory.newInstance();
static {
try {
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
} catch (Exception e) {
;
}
}
/**
* Xml2Bean
@ -60,25 +73,17 @@ public final class XmlStream {
JAXBContext jaxbContext = getJaxbContext(clazz);
try {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Source source = new StreamSource(content);
XmlRootElement rootElement = clazz
.getAnnotation(XmlRootElement.class);
Source source = new SAXSource(spf.newSAXParser().getXMLReader(), new InputSource(content));
XmlRootElement rootElement = clazz.getAnnotation(XmlRootElement.class);
if (rootElement == null
|| rootElement.name().equals(
XmlRootElement.class.getMethod("name")
.getDefaultValue().toString())) {
JAXBElement<T> jaxbElement = unmarshaller.unmarshal(source,
clazz);
|| rootElement.name().equals(XmlRootElement.class.getMethod("name").getDefaultValue().toString())) {
JAXBElement<T> jaxbElement = unmarshaller.unmarshal(source, clazz);
return jaxbElement.getValue();
} else {
return (T) unmarshaller.unmarshal(source);
}
} catch (JAXBException ex) {
throw new RuntimeException("Could not unmarshaller class [" + clazz
+ "]: " + ex.getMessage(), ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Could not unmarshaller class [" + clazz
+ "]: " + ex.getMessage(), ex);
} catch (Exception ex) {
throw new RuntimeException("Could not unmarshaller class [" + clazz + "]", ex);
} finally {
if (content != null) {
try {
@ -100,8 +105,7 @@ public final class XmlStream {
* @return
*/
public static <T> T fromXML(String content, Class<T> clazz) {
return fromXML(
new ByteArrayInputStream(content.getBytes(Consts.UTF_8)), clazz);
return fromXML(new ByteArrayInputStream(content.getBytes(Consts.UTF_8)), clazz);
}
/**
@ -114,8 +118,7 @@ public final class XmlStream {
public static String map2xml(Map<String, String> map) {
StringWriter sw = new StringWriter();
try {
XMLStreamWriter xw = XMLOutputFactory.newInstance()
.createXMLStreamWriter(sw);
XMLStreamWriter xw = XMLOutputFactory.newInstance().createXMLStreamWriter(sw);
xw.writeStartDocument(Consts.UTF_8.name(), XML_VERSION);
xw.writeStartElement(ROOT_ELEMENT_XML);
for (Entry<String, String> entry : map.entrySet()) {
@ -151,8 +154,7 @@ public final class XmlStream {
public static String map2xml(JSONObject json) {
StringWriter sw = new StringWriter();
try {
XMLStreamWriter xw = XMLOutputFactory.newInstance()
.createXMLStreamWriter(sw);
XMLStreamWriter xw = XMLOutputFactory.newInstance().createXMLStreamWriter(sw);
xw.writeStartDocument(Consts.UTF_8.name(), XML_VERSION);
xw.writeStartElement(ROOT_ELEMENT_XML);
for (Entry<String, Object> entry : json.entrySet()) {
@ -189,8 +191,7 @@ public final class XmlStream {
Map<String, String> map = new HashMap<String, String>();
StringReader sr = new StringReader(content);
try {
XMLStreamReader xr = XMLInputFactory.newInstance()
.createXMLStreamReader(sr);
XMLStreamReader xr = XMLInputFactory.newInstance().createXMLStreamReader(sr);
while (true) {
int event = xr.next();
if (event == XMLStreamConstants.END_DOCUMENT) {
@ -246,25 +247,16 @@ public final class XmlStream {
JAXBContext jaxbContext = getJaxbContext(clazz);
try {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING,
Consts.UTF_8.name());
XmlRootElement rootElement = clazz
.getAnnotation(XmlRootElement.class);
marshaller.setProperty(Marshaller.JAXB_ENCODING, Consts.UTF_8.name());
XmlRootElement rootElement = clazz.getAnnotation(XmlRootElement.class);
if (rootElement == null
|| rootElement.name().equals(
XmlRootElement.class.getMethod("name")
.getDefaultValue().toString())) {
marshaller.marshal(new JAXBElement<T>(new QName(
ROOT_ELEMENT_XML), clazz, t), os);
|| rootElement.name().equals(XmlRootElement.class.getMethod("name").getDefaultValue().toString())) {
marshaller.marshal(new JAXBElement<T>(new QName(ROOT_ELEMENT_XML), clazz, t), os);
} else {
marshaller.marshal(t, os);
}
} catch (JAXBException ex) {
throw new RuntimeException("Could not marshal class [" + clazz
+ "]: " + ex.getMessage(), ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Could not marshaller class [" + clazz
+ "]: " + ex.getMessage(), ex);
} catch (Exception ex) {
throw new RuntimeException("Could not marshal class [" + clazz + "] ", ex);
} finally {
if (os != null) {
try {
@ -283,9 +275,7 @@ public final class XmlStream {
jaxbContext = JAXBContext.newInstance(clazz);
jaxbContexts.putIfAbsent(clazz, jaxbContext);
} catch (JAXBException ex) {
throw new RuntimeException(
"Could not instantiate JAXBContext for class [" + clazz
+ "]: " + ex.getMessage(), ex);
throw new RuntimeException("Could not instantiate JAXBContext for class [" + clazz + "] ", ex);
}
}
return jaxbContext;

View File

@ -33,3 +33,4 @@ Thumbs.db
bin
/target/
/target/
/target/

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<packaging>war</packaging>
<artifactId>weixin4j-example</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<artifactId>weixin4j-mp</artifactId>
<name>weixin4j-mp</name>
@ -29,11 +29,5 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.8</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@ -82,6 +83,18 @@ public class MediaTest extends TokenTest {
System.err.println(mediaId);
}
@Test
public void uploadVideo() throws WeixinException, FileNotFoundException {
InputStream is = new FileInputStream("/Users/jy/Downloads/test.mp4");
String fileName = "视频文件名";
String title = "视频标题";
String description = "视频描述";
MpVideo mpVideo = mediaApi
.uploadVideo(is, fileName, title, description);
Assert.assertTrue(mpVideo.getMediaId() != null);
System.err.println(mpVideo.getMediaId());
}
@Test
public void uploadMaterialArticle() throws WeixinException {
List<MpArticle> articles = new ArrayList<MpArticle>();
@ -94,7 +107,8 @@ public class MediaTest extends TokenTest {
@Test
public void downloadArticle() throws WeixinException {
List<MpArticle> articles = mediaApi.downloadArticle("DVWwU0u9ommOTPgyJszpK943IWCCVAcFGNmiIBObf5E");
List<MpArticle> articles = mediaApi
.downloadArticle("DVWwU0u9ommOTPgyJszpK943IWCCVAcFGNmiIBObf5E");
Assert.assertTrue(articles != null && !articles.isEmpty());
System.err.println(articles);
}
@ -138,15 +152,4 @@ public class MediaTest extends TokenTest {
.listAllMaterialMedia(MediaType.image);
System.err.println(mediaList);
}
@Test
public void uploadVideo() throws WeixinException {
InputStream is = null;
String fileName = "视频文件名";
String title = "视频标题";
String description = "视频描述";
MpVideo mpVideo = mediaApi
.uploadVideo(is, fileName, title, description);
Assert.assertTrue(mpVideo.getMediaId() != null);
}
}

View File

@ -95,4 +95,12 @@ public class XmlstreamTest {
sb.toString(),
com.foxinmy.weixin4j.payment.mch.RefundRecord.class));
}
public static void main(String[] args) throws Exception{
XmlstreamTest.xml2order();
XmlstreamTest.xml2refundRecordV2();
XmlstreamTest.xml2refundRecordV3();
XmlstreamTest.map2xml();
XmlstreamTest.object2xmlWithRootElement();
}
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<artifactId>weixin4j-qy</artifactId>
<name>weixin4j-qy</name>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<artifactId>weixin4j-server</artifactId>
<version>1.1.9</version>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<artifactId>weixin4j-serverX</artifactId>
<version>0.0.1</version>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<artifactId>weixin4j-wxa</artifactId>
<name>weixin4j-wxa</name>